[xinf] DOM Events?
daniel fischer
dan at f3c.com
Thu Jun 22 14:47:48 CEST 2006
hey,
in quest for a solid event model for xinf, i've found that the W3C DOM2 Event model[1] and the AS3 one[2] are *very* similar (and also similar to how i currently do it in xinf[3]). In fact, the only real difference i see is that DOM uses an EventListener interface (with a handleEvent function), while AS3 uses only a function as EventListener.
I've attached a quick writeup of the DOM Event model as haXe interfaces. Here's the rundown:
* uses subclasses of Event for specific data (like MouseEvent.clientX).
* uses Strings as event type identifiers, defined as static variables in the corresponding classes (like MouseEvent.MOUSE_DOWN, but Event.ENTER_FRAME).
* DOM events use an EventListener object like this:
interface EventListener {
function handleEvent( evt:Event ) :Void;
}
while AS3 uses functions as first-class objects, like:
function(evt:Event):void
* both DOM and AS3 events differentiate 3 phases of event handling: CAPTURE, AT_TARGET and BUBBLING. I am unsure for what the CAPTURE phase (passing the event "down" from parent to child) actually is good for- the current xinf implementation doesn't support this (tho it could probably be done), events are delivered to the target first, and then passed on upward until it hits Root.
I think this should easily satisfy Hank's requirements- you can use a single EventDispatcher(AS3)/EventTarget(DOM) as a "bus", if you like.. As for Nicolas' ideas about making it Real Easy(TM) from the API users side, i'm a bit unsure- but i think some convenience classes could make it happen.
From how i see it, the abstract Event passed to your handler has to be casted to the specific subclass if you want to access the event-specific data (like x/y for mouse events). So how about going with EventListener as objects, then implementing something like:
class CastingEventListener<T:Event> {
private var f:T->Void;
public function new( _f:T->Void ) :Void {
f = _f;
}
public function handleEvent( evt:Event ) :Void {
var e:T = cast(evt,T);
f(e);
}
}
this way, you could do:
public function onMouseDown( e:MouseEvent ) :Void {
...
}
...
addEventListener( MouseEvent.MOUSE_DOWN, new CastingEventListener<MouseEvent>( onMouseDown ) );
...
open issues for me are:
* how to make it convenient to remove a listener. automatic delegate functions are fine, but make it hard to reference the same handler. but also, storing the EventListener you create just to be able to unregister it seems a bit harsh to me.
* maybe, a convenience class like MouseEventDispatcher, that has properties for the event handler functions (a la onMouseDown) which will dynamically (un)register the Listeners when the property is set, will do the trick?
anyhow, i'm currently opting for using the DOM event model simply because it's a standard :). I'd throw out the event phases though, unless someone can provide a good sample where CAPTURE events really make sense. I'd keep the stopPropagation(), preventDefault() and canBubble.
comments appreciated,
-dan
[1] http://www.w3.org/TR/DOM-Level-2-Events/idl-definitions.html
[2] http://livedocs.macromedia.com/labs/1/flex20beta3/langref/flash/events/package-detail.html
[3] http://xinf.org/trac/browser/trunk/xinf/event
--
http://0xDF.com/
http://iterative.org/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: DOMEvents.hx
Type: application/octet-stream
Size: 1848 bytes
Desc: not available
Url : http://xinf.org/pipermail/xinf/attachments/20060622/dfe5b1b0/attachment.obj
More information about the xinf
mailing list