Skip to content

Commit

Permalink
Add capture to ADDED/REMOVED_FROM_STAGE events (close openfl#1510)
Browse files Browse the repository at this point in the history
  • Loading branch information
jgranick committed Mar 30, 2017
1 parent 2ffbe3f commit d61c8dc
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 83 deletions.
101 changes: 100 additions & 1 deletion openfl/display/DisplayObject.hx
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,42 @@ class DisplayObject extends EventDispatcher implements IBitmapDrawable #if openf
}


private function __dispatchChildren (event:Event):Bool {
private function __dispatchChildren (event:Event, stack:Vector<DisplayObject>):Bool {

event.target = this;

if (parent != null) {

event.eventPhase = CAPTURING_PHASE;

if (parent == stage) {

parent.__dispatchEvent (event);

} else {

var parent = parent;
var i = 0;

while (parent != null) {

stack[i] = parent;
parent = parent.parent;
i++;

}

for (j in 0...i) {

stack[i - j - 1].__dispatchEvent (event);

}

}

}

event.eventPhase = AT_TARGET;

return __dispatchEvent (event);

Expand Down Expand Up @@ -387,6 +422,70 @@ class DisplayObject extends EventDispatcher implements IBitmapDrawable #if openf
}


private function __dispatchStack (event:Event, stack:Array<DisplayObject>):Void {

var target:DisplayObject;
var length = stack.length;

if (length == 0) {

event.eventPhase = EventPhase.AT_TARGET;
target = cast event.target;
target.__dispatch (event);

} else {

event.eventPhase = EventPhase.CAPTURING_PHASE;
event.target = stack[stack.length - 1];

for (i in 0...length - 1) {

stack[i].__dispatch (event);

if (event.__isCanceled) {

return;

}

}

event.eventPhase = EventPhase.AT_TARGET;
target = cast event.target;
target.__dispatch (event);

if (event.__isCanceled) {

return;

}

if (event.bubbles) {

event.eventPhase = EventPhase.BUBBLING_PHASE;
var i = length - 2;

while (i >= 0) {

stack[i].__dispatch (event);

if (event.__isCanceled) {

return;

}

i--;

}

}

}

}


private function __enterFrame (deltaTime:Int):Void {


Expand Down
17 changes: 10 additions & 7 deletions openfl/display/DisplayObjectContainer.hx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class DisplayObjectContainer extends InteractiveObject {
public var tabChildren:Bool;

private var __removedChildren:Vector<DisplayObject>;
private var __tempStack:Vector<DisplayObject>;


private function new () {
Expand All @@ -42,6 +43,7 @@ class DisplayObjectContainer extends InteractiveObject {

__children = new Array<DisplayObject> ();
__removedChildren = new Vector<DisplayObject> ();
__tempStack = new Vector<DisplayObject> ();

}

Expand Down Expand Up @@ -99,7 +101,8 @@ class DisplayObjectContainer extends InteractiveObject {

if (addedToStage) {

child.__dispatchChildren (new Event (Event.ADDED_TO_STAGE, false, false));
child.__dispatchChildren (new Event (Event.ADDED_TO_STAGE, false, false), __tempStack);
__tempStack.length = 0;

}

Expand Down Expand Up @@ -198,7 +201,9 @@ class DisplayObjectContainer extends InteractiveObject {

}

child.__dispatchChildren (new Event (Event.REMOVED_FROM_STAGE, false, false));
child.__dispatchChildren (new Event (Event.REMOVED_FROM_STAGE, false, false), __tempStack);
__tempStack.length = 0;

child.__setStageReference (null);

}
Expand Down Expand Up @@ -326,17 +331,15 @@ class DisplayObjectContainer extends InteractiveObject {
}


private override function __dispatchChildren (event:Event):Bool {
private override function __dispatchChildren (event:Event, stack:Vector<DisplayObject>):Bool {

var success = __dispatchEvent (event);
var success = super.__dispatchChildren (event, stack);

if (success && __children != null) {

for (child in __children) {

event.target = child;

if (!child.__dispatchChildren (event)) {
if (!child.__dispatchChildren (event, stack)) {

return false;

Expand Down
84 changes: 10 additions & 74 deletions openfl/display/Stage.hx
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ class Stage extends DisplayObjectContainer implements IModule {
if (stack.length > 0) {

stack.reverse ();
__fireEvent (event, stack);
__dispatchStack (event, stack);

} else {

Expand Down Expand Up @@ -1155,70 +1155,6 @@ class Stage extends DisplayObjectContainer implements IModule {
}


private function __fireEvent (event:Event, stack:Array<DisplayObject>):Void {

var target:DisplayObject;
var length = stack.length;

if (length == 0) {

event.eventPhase = EventPhase.AT_TARGET;
target = cast event.target;
target.__dispatch (event);

} else {

event.eventPhase = EventPhase.CAPTURING_PHASE;
event.target = stack[stack.length - 1];

for (i in 0...length - 1) {

stack[i].__dispatch (event);

if (event.__isCanceled) {

return;

}

}

event.eventPhase = EventPhase.AT_TARGET;
target = cast event.target;
target.__dispatch (event);

if (event.__isCanceled) {

return;

}

if (event.bubbles) {

event.eventPhase = EventPhase.BUBBLING_PHASE;
var i = length - 2;

while (i >= 0) {

stack[i].__dispatch (event);

if (event.__isCanceled) {

return;

}

i--;

}

}

}

}


private override function __getInteractive (stack:Array<DisplayObject>):Bool {

if (stack != null) {
Expand Down Expand Up @@ -1288,7 +1224,7 @@ class Stage extends DisplayObjectContainer implements IModule {
var event = new KeyboardEvent (type, true, true, charCode, keyCode, keyLocation, __macKeyboard ? modifier.ctrlKey || modifier.metaKey : modifier.ctrlKey, modifier.altKey, modifier.shiftKey, modifier.ctrlKey, modifier.metaKey);

stack.reverse ();
__fireEvent (event, stack);
__dispatchStack (event, stack);

if (event.__preventDefault) {

Expand Down Expand Up @@ -1409,18 +1345,18 @@ class Stage extends DisplayObjectContainer implements IModule {

}

__fireEvent (MouseEvent.__create (type, button, __mouseX, __mouseY, (target == this ? targetPoint : target.globalToLocal (targetPoint)), target), stack);
__dispatchStack (MouseEvent.__create (type, button, __mouseX, __mouseY, (target == this ? targetPoint : target.globalToLocal (targetPoint)), target), stack);

if (clickType != null) {

__fireEvent (MouseEvent.__create (clickType, button, __mouseX, __mouseY, (target == this ? targetPoint : target.globalToLocal (targetPoint)), target), stack);
__dispatchStack (MouseEvent.__create (clickType, button, __mouseX, __mouseY, (target == this ? targetPoint : target.globalToLocal (targetPoint)), target), stack);

if (type == MouseEvent.MOUSE_UP && cast (target, openfl.display.InteractiveObject).doubleClickEnabled) {

var currentTime = Lib.getTimer ();
if (currentTime - __lastClickTime < 500) {

__fireEvent (MouseEvent.__create (MouseEvent.DOUBLE_CLICK, button, __mouseX, __mouseY, (target == this ? targetPoint : target.globalToLocal (targetPoint)), target), stack);
__dispatchStack (MouseEvent.__create (MouseEvent.DOUBLE_CLICK, button, __mouseX, __mouseY, (target == this ? targetPoint : target.globalToLocal (targetPoint)), target), stack);
__lastClickTime = 0;

} else {
Expand Down Expand Up @@ -1597,7 +1533,7 @@ class Stage extends DisplayObjectContainer implements IModule {
__displayMatrix.__transformInversePoint (targetPoint);
var delta = Std.int (deltaY);

__fireEvent (MouseEvent.__create (MouseEvent.MOUSE_WHEEL, 0, __mouseX, __mouseY, (target == this ? targetPoint : target.globalToLocal (targetPoint)), target, delta), stack);
__dispatchStack (MouseEvent.__create (MouseEvent.MOUSE_WHEEL, 0, __mouseX, __mouseY, (target == this ? targetPoint : target.globalToLocal (targetPoint)), target, delta), stack);

}

Expand All @@ -1622,15 +1558,15 @@ class Stage extends DisplayObjectContainer implements IModule {
touchEvent.touchPointID = touch.id;
touchEvent.isPrimaryTouchPoint = (__primaryTouch == touch);

__fireEvent (touchEvent, __stack);
__dispatchStack (touchEvent, __stack);

} else {

var touchEvent = TouchEvent.__create (type, null, touchX, touchY, point, this);
touchEvent.touchPointID = touch.id;
touchEvent.isPrimaryTouchPoint = (__primaryTouch == touch);

__fireEvent (touchEvent, [ stage ]);
__dispatchStack (touchEvent, [ stage ]);

}

Expand Down Expand Up @@ -1890,7 +1826,7 @@ class Stage extends DisplayObjectContainer implements IModule {
var stack = new Array <DisplayObject> ();
oldFocus.__getInteractive (stack);
stack.reverse ();
__fireEvent (event, stack);
__dispatchStack (event, stack);

}

Expand All @@ -1900,7 +1836,7 @@ class Stage extends DisplayObjectContainer implements IModule {
var stack = new Array <DisplayObject> ();
value.__getInteractive (stack);
stack.reverse ();
__fireEvent (event, stack);
__dispatchStack (event, stack);

}

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test/openfl/events/EventDispatcherTest.hx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class EventDispatcherTest {

// TODO: this dispatchEvent will never go through CAPTURING_PHASE.
// It needs to come from Stage
// (or possibly through e.g. DisplayObject.__fireEvent)
// (or possibly through e.g. DisplayObject.__dispatchStack)
// See FocusEventTest for an example.
//DISABLED//Assert.isTrue (correctPhase);

Expand Down

0 comments on commit d61c8dc

Please sign in to comment.