Skip to content

Commit

Permalink
avm2: Fix indirect event dispatching
Browse files Browse the repository at this point in the history
  • Loading branch information
adrian17 committed Dec 5, 2022
1 parent 823965a commit 7b64fcf
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 4 deletions.
9 changes: 5 additions & 4 deletions core/src/avm2/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ pub fn parent_of(target: Object<'_>) -> Option<Object<'_>> {
/// call the wrong handlers.
pub fn dispatch_event_to_target<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
dispatcher: Object<'gc>,
target: Object<'gc>,
event: Object<'gc>,
) -> Result<(), Error<'gc>> {
Expand All @@ -379,7 +380,7 @@ pub fn dispatch_event_to_target<'gc>(
event.as_event().unwrap().event_type(),
target
);
let dispatch_list = target
let dispatch_list = dispatcher
.get_property(
&Multiname::new(Namespace::private(NS_EVENT_DISPATCHER), "dispatch_list"),
activation,
Expand Down Expand Up @@ -463,7 +464,7 @@ pub fn dispatch_event<'gc>(
break;
}

dispatch_event_to_target(activation, *ancestor, event)?;
dispatch_event_to_target(activation, *ancestor, *ancestor, event)?;
}

event
Expand All @@ -472,7 +473,7 @@ pub fn dispatch_event<'gc>(
.set_phase(EventPhase::AtTarget);

if !event.as_event().unwrap().is_propagation_stopped() {
dispatch_event_to_target(activation, target, event)?;
dispatch_event_to_target(activation, this, target, event)?;
}

event
Expand All @@ -486,7 +487,7 @@ pub fn dispatch_event<'gc>(
break;
}

dispatch_event_to_target(activation, *ancestor, event)?;
dispatch_event_to_target(activation, *ancestor, *ancestor, event)?;
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/tests/regression_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ swf_tests! {
(as3_eventdispatcher_dispatchevent_handlerorder, "avm2/eventdispatcher_dispatchevent_handlerorder", 1),
(as3_eventdispatcher_dispatchevent_this, "avm2/eventdispatcher_dispatchevent_this", 1),
(as3_eventdispatcher_dispatchevent, "avm2/eventdispatcher_dispatchevent", 1),
(as3_eventdispatcher_dispatchevent_indirect, "avm2/eventdispatcher_dispatchevent_indirect", 1),
(as3_eventdispatcher_haseventlistener, "avm2/eventdispatcher_haseventlistener", 1),
(as3_eventdispatcher_tostring, "avm2/eventdispatcher_tostring", 1),
(as3_eventdispatcher_willtrigger, "avm2/eventdispatcher_willtrigger", 1),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// compiled with mxmlc

import flash.display.MovieClip;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;

package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.EventDispatcher;

public class Test extends MovieClip {
public function Test() {
var mc = new MovieClip();
addChild(mc);
var child = new MovieClip();
mc.addChild(child);

child.addEventListener("asdf", function(e){
trace("in child " + e.eventPhase);
});
mc.addEventListener("asdf", function(e){
trace("in mc " + e.eventPhase);
});
addEventListener("asdf", function(e){
trace("in root " + e.eventPhase);
});

child.dispatchEvent(new Event("asdf", true));

trace();
var dispatcher = new EventDispatcher(child);
dispatcher.addEventListener("asdf", function(e){
trace("in child's dispatcher " + e.eventPhase);
});

dispatcher.dispatchEvent(new Event("asdf", true));

}

}
}

class MyObject implements IEventDispatcher {
private var dispatcher:EventDispatcher;
public function MyObject() {
dispatcher = new EventDispatcher(this);
}
public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{
dispatcher.addEventListener(type, listener, useCapture, priority);
}
public function dispatchEvent(evt:Event):Boolean{
return dispatcher.dispatchEvent(evt);
}
public function hasEventListener(type:String):Boolean{
return dispatcher.hasEventListener(type);
}
public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{
dispatcher.removeEventListener(type, listener, useCapture);
}
public function willTrigger(type:String):Boolean {
return dispatcher.willTrigger(type);
}
}

var object = new MyObject();
object.dispatchEvent(new Event("asdf"));
object.addEventListener("asdf", function(){ trace("in listener") })
object.dispatchEvent(new Event("asdf"));
trace();
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
in listener

in child 2
in mc 3
in root 3

in child's dispatcher 2
in mc 3
in root 3
Binary file not shown.

0 comments on commit 7b64fcf

Please sign in to comment.