I still have more critique in me, but first I'll eat a little humble pie. I haven't actually worked much with custom events in the display list. Most of my AS3 development has been in code libraries that operate independently of the display list. Thus, my custom events generally don't need to bubble or cancel. So when I look at the AS3 event system, I see APIs that often add clutter without a benefit to my project. For developers building RIAs, AS3 event capturing, targeting, bubbling and canceling is wonderful. The standard is called DOM Level 3 Events for a reason. It's great if you're in a DOM, but that doesn't mean it's the most usable solution for events in general. But I'll have to leave that discussion for the next critique.
What I've learned about AS3 events in the last 3 weeks
- Custom events can bubble when you dispatch them from a DisplayObject.
I'd never tried this, and thought that only Flash Player events (MouseEvent, etc.) could bubble.
- Custom events can be canceled.
The Event APIs cancelable, preventDefault() and isDefaultPrevented() are not just for Flash Player events.
- Despite Grant Skinner's argument for using weak listeners, some experienced developers choose not to.
Some say relying on weak references has caused more problems than anticipated. However, Grant advocated always removing listeners explicitly. Weak references are just "an added level of security".
- Flash Player 9 didn't always garbage collect weak references.
This is fixed in Player 10.
- Storing method references in a weak keys Dictionaryis buggy.
References may be duplicated or garbage collected prematurely. Technically, this isn't part of AS3 events. But when trying to extend the event system, you may use a Dictionary to store listeners or callbacks. Developers who've done this have learned not to use weak keys.
- When an event has no listeners, EventDispatcher.dispatchEvent() is unnecessarily slow.
Grant Skinner's patch is a 5x speedup, apparently.
- Some say listener priorities are smelly.
Like MovieClip.depth in AS2, priority numbers introduce dependencies into your code. These become increasingly difficult to manage in larger systems, as new code must take into account the priorities in existing code.
An alternative is to rely on the order the listeners are added. The original dispatcher can add itself as a listener first and thus ensure it has first crack at the event. Unless a different listener misbehaves and steals the spotlight with a higher priority...
This is an interesting one. I haven't had to deal with this issue and I'm not sure what I think yet. The listener order does start to feel similar to the stacking of movie clips in AS2. Who's going to come out on top? Do we need an equivalent of getNextHighestDepth() for listener priorities [shudder]? I'm reminded of how the Macromedia V2 components would grab the highest possible depth with its own depth manager, rendering getNextHighestDepth() useless. Is there a word for bad nostalgia? How about "nastalgia"?