'How does one target specific object of a gui for an event flow?

I'm working on a javascript framework for creating simple animations on an html canvas with nested sprites using a basic composite pattern.

I've been modeling my work on Clutter and Flash (very similar structure). A "Stage" holds all of the items on screen, which are "DisplayObjects". These can be aggregated in a "DisplayObjectContainer", which inherits from "DisplayObject". The "Stage" itself is also a "DisplayObjectContainer". All of these inherit from an "EventDispatcher".

I've spent the better part of the last few days reading about the event flow of these systems and searching for examples in various open source projects.

From what I understand, when an event is dispatched, it should follow a certain propagation path: it flows from the stage, into the display object hierarchy (the "capture" phase) until it reaches the "target" of that event, and then "bubbles" back up the display hierarchy. If this isn't clear enough, the images located here should help explain:

http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e4f.html

http://docs.clutter-project.org/docs/clutter/1.4/event-flow.png

There is an aspect of this that I'm failing to understand, and I can't tell if it's just me or if this is as unclear as I think it is:

Suppose I'm dealing with clicks. I click on the display and use the browser's native event handling to retrieve the x/y coordinates of the click, and then send that down the display hierarchy to determine which object I've clicked.

Until now, this WAS the "capture" phase in my code. But this is completely at odds with the documentation which says the target should already be attached to the event by the time it enters the event flow.

Am I really supposed to traverse my graph of display items twice?

Any advice or expertise on the issue would be highly appreciated.



Solution 1:[1]

Interesting question! Yes, I believe you would need to traverse your DisplayList first to calculate the event target before beginning the capture phase of your event-flow. Never having designed an event system, I'm not completely sure about this, but perhaps when you calculate the target object you could cache the hierarchical route and use that as the basis of your event-flow rather than traversing the DisplayList again.

The bit that you're unclear on, I think, is more obvious if you consider it in terms of implementation rather than in the abstract of designing an event system (and the terminology of existing event systems). Imagine, a widget consisting of a parent object, and a number of child items which need to react to mouse clicks. You might decide you want to listen for events on the parent object only, but react according to the target object from which the event originated. In ActionScript, if you're using the capture phase of the event-flow, your handler would fire before the target of the event is reached but, in this case, the target is an essential property of the event object.

As suggested in the comments, it might be worth looking at the source code for easeljs since it claims to provide an API "that is familiar to Flash developers". However, note that easeljs does not currently support a full-featured event flow for performance reasons (see here).

My two pennies; event-flow is tricky enough to understand (let alone design) and implementing a full-featured event system may be at odds with your goal of creating a light-weight library. I would suggest you keep it simple at this stage and only add features such as event bubbling if you find you need them.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1