EventDispatcher Usage Revisited

I had a problem in an app I was building at home for fun in Central. As the app got more complex, I started adding more and more events that I needed my AppController to keep track of. AppController being a class that runs as the Singleton in the Application part of Central. For things totally unrelated, it was pretty easy to map the events generated by a player such as “play” to a class method called “play”, and for a Playlist’s “selectedIndexChange” to be mapped to a class method of “selectedIndexChange”. However…

10 Replies to “EventDispatcher Usage Revisited”

  1. Grr… It’s not working in Central. I think, however, this is a problem with EventDispatcher losing scope because it works up until the point dispatchEvent is called… the problem is (what I said would never happen) is that the function is running in the scope of the homeskillet that is generating the event. Heck with this, I’m using Grants…

  2. It’s all good; I re-read his post based on your suggestion in case I missed something; and indeed I did. His class is actually a Responder like object that forwards the event. However, with the amount of event’s I’m registering, I’ve kept to my base class using EventDispatcher, and therefore have little overhead.

    …or maybe I’ve switched my event engine too much in my Flash career and am just too tired today to switch again. Maybe tomorrow.

  3. oh I see the problem. In the EventDispatcher if what you are adding is a method (function) it applys the function to the queueObj. However, I beleive that applything the method to the queueObj was an oversight. By changeing the apply in the dispatchQueue method from this:

    o.apply(queueObj, [eventObj]);

    to this:

    o.apply(eventObj.target, [eventObj]);

    Allows the event dispatcher to use the proper scope if one is provided. If not the scope remains unchanged from the current functionality.

    I’ve come to this conclusion for a couple reasons:

    1) everything *seems* to work as intened and scope is being applied correctly.

    2) The following code from the dispatchEvent method seemed odd because it was not being used anywhere else in the class and it logically looked like it would solve any scope issues.

    if (eventObj.target == undefined)
    eventObj.target = this;

    At anyrate here is a working example using my edited EventDispatcher method (free typed in here might be some typos):

    // SUBJECT
    class Subject
    {

    // Interface for EventDispatcher
    // didnt want to type a interface, lazy
    public var dispatchEvent:Function;
    public var addEventListener:Function;

    // Instance name used to identify scope
    private var name:String = “Subject”;

    // Constructor inits Dispatcher
    public function Subject()
    {
    EventDispatcher.initialize(this);
    }

    // broadcast the event uses target to pass in scope
    public function triggerUpdate(scope){
    dispatchEvent({type:”update”,target:scope});
    }

    }

    // Observer: Class that Watches Subject
    class Observer
    {

    private var m_Subject:Subject;
    private var name:String = “Observer”;

    public function Observer()
    {
    m_Subject = new Subject();
    m_Subject.addEventListener(“update”,onUpdate)
    }

    public function onUpdate()
    {
    trace(“Updated: “+name);
    }

    // trigger event and passes scope
    public function triggerUpdate()
    {
    m_Subject.triggerUpdate(this);
    }

    }

    // root timeline
    var name = “root”;
    function update(){
    trace(name);
    }

    // uses the timeline as the listener
    var TestSubject = new Subject();
    TestSubject.addEventListener(“update”,update);
    TestSubject.update();

    // uses a class as the listener
    var TestObserver = new Observer();
    TestObserver.triggerUpdate();

Comments are closed.