Event Control System

Reynaldo February 26th, 2008

When working on large scale projects or even small projects, I try to be as organized as possible. That’s why I love to use patterns such as the Command pattern or the Model View Controller pattern, organization. Every class has their job to do. Some classes have no idea whats going on outside of them and do only as they’re told while other classes take the role of a “Command Center of Operations” listening to events and delegating tasks to sub classes or”minion” classes.

One thing that I strive to always keep on point is communication between classes via events. It’s really not any fun when you have a rogue event being fired from somewhere; it then being handled and you have no idea who’s doing what :( that’s where an “Event Control System” comes in really handy!

An Event Control System is composed basically of a pair of classes which handle all the global, project specific firing of and listening of events.

The first class I tend to call “EventCentral.as”. The EventCentral is a Singleton class which extends flash.events.EventDispatcher and is used across the project classes to dispatch and listen to project events. The project events are basically all public static constants in the second class called “ProjectEvent.as”. The ProjectEvent extends flash.events.Events.

The good thing about extending the Events class, or any class for that matter, is that you can add additional functionality. In the case of the ProjectEvent class, we add a “params” object which the custom event which is fired can carry or piggyback. Any event handler can then pull this “params” object from the event being listened to. This is an example as to how the classes would be used:

First import the class:

import EventCentral;
import ProjectEvent;

To dispatch an event, it would look like this:

EventCentral.getInstance().dispatcheEvent(new ProjectEvent(ProjectEvent.SOME_EVENT, {name:"Reynaldo"}));

To listen to and handle the event:

EventCentral.getinstance().addEventListener(ProjectEvent.SOME_EVENT, someEventhandler);
function someEventhandler($event:ProjectEvent):void
{
    trace($event.params.name)
}

Thats it! Just remember not to have a slew of events handling absolutely everything in your projects, I’ve had bad experiences when abusing this method. But enough chit chat, you can find the two classes with an example here:

CentralEventSystem.zip

5 Responses to “Event Control System”

  1. Tahir Ahmedon 24 Jul 2008 at 4:52 am

    Hi Reynaldo,

    I have a little concern on ProjectEvent.as Class.

    I need to pass Array, XML and String Objects to the parent class listening to the events but I am unable to do it. Is it because ProjectEvent Class only allows to throw objects of Object Class and not objects of any other class.

    Do I have to extend your class to make it capable of doing it (i.e. passing objects of other Classes)? If that so, then what would be the syntax as I am fairly new to ActionScript 3.0.

    Can you please explain or give me a solution?

    Quick reply would be really helpful (as if this needs any conversation back and forth).

    Thanks.
    Tahir.

  2. Danielon 05 Nov 2008 at 8:22 pm

    Thanks for this class, it’s very helpful.
    You just forgot to camelcase getInstance at this line
    EventCentral.getinstance().addEventListener(ProjectEvent.SOME_EVENT, someEventhandler);

  3. Scotton 30 Nov 2008 at 6:38 pm

    Hi Reynaldo,
    This is a fantastic idea, but Im having a problem using the class, I keep receiving an undefined property error on the function I am trying to call from the Event Handeler,

    eg:

    Class 1.as

    package {
    import scottking.EventCentral;
    import scottking.ProjectEvent;

    ….

    EventCentral.getInstance().addEventListener(ProjectEvent.SOME_EVENT, handleClickedPic);
    private function handleClickedPic($event:ProjectEvent):void{
    trace($event.params.name)
    //clickedPic($event.params.name);
    }

    Class 2:

    package scottking{

    import scottking.EventCentral;
    import scottking.ProjectEvent;

    EventCentral.getInstance().dispatchEvent(new ProjectEvent(ProjectEvent.SOME_EVENT, { name:”Reynaldo” }));

    And the error:
    1120: Access of undefined property handleClickedPic.

    Do you have any ideas as to the cause of the error?

    Many thanks,
    Scott

  4. DJon 16 Dec 2008 at 3:15 pm

    Make sure you fla document class link is Main and it is in the same folder that the fla is in and create a folder named com and place the orginal .as filesin there. Then delete the time line code.
    resave the fla.

    here are my files:

    Main.as————–
    package {
    //imports
    import flash.display.Sprite;
    import com.EventCentral;
    import com.ProjectEvent;
    //class
    public class Main extends Sprite {
    //Vars

    //Constructor
    public function Main() {
    trace(”[Main] : constructed”);
    EventCentral.getInstance().addEventListener(ProjectEvent.SOME_EVENT, handleSomeEvent);
    fnInit();
    }//ends Constructor
    // fnInit
    private function fnInit():void {
    EventCentral.getInstance().dispatchEvent(new ProjectEvent(ProjectEvent.SOME_EVENT, {name:”Reynaldo”}));
    }//Ends fnInit
    //handleSomeEvent
    private function handleSomeEvent($event:ProjectEvent):void {
    trace($event.params.name);
    }//Ends handleSomeEvent

    }//ends Class
    }// ends Package
    I place both of the Classes in a com folder
    ProjectEvent.as————————-
    package com
    {
    /*
    imports
    */
    import flash.events.Event;
    /*
    class
    */
    public class ProjectEvent extends Event
    {
    /*
    variables
    */
    public static const SOME_EVENT:String = “ProjectEvent.onSomeEvent”

    public var params:Object;
    /*
    Constructor
    */

    /**
    * ProjectEvent constructor
    * @param $type : the event string
    * @param $params : an object containing any number of values to be sent to listeneers
    * @return : a reference ot the event
    *
    */
    public function ProjectEvent($type:String, $params:Object = null)
    {
    trace(”[ProjectEvent] : constructed”);
    super($type, true, true);
    this.params = $params
    }

    /**
    * Overrides the flash.events.Event’s clone method
    * @return Event
    *
    */
    public override function clone():Event
    {
    return new ProjectEvent(this.type, this.params);
    }

    /**
    * Overrides the flash.events.Event’s toString method
    * @return String - Class name
    *
    */
    override public function toString():String
    {
    return (”[Event ProjectEvent]“);
    }
    }

    }

    EventCentral.as————————-
    package com{
    /*
    imports
    */
    import flash.events.EventDispatcher;
    import flash.events.Event;
    /*
    class
    */
    public class EventCentral extends EventDispatcher {
    /*
    variables
    */
    private static var instance:EventCentral = new EventCentral();

    /*
    constructor
    */
    public function EventCentral():void {
    super();
    if (instance) {
    throw new Error(”EventCentral is a Singleton and can only be accessed through EventCentral.getInstance()”);
    }
    trace(”[EventCentral] : constructed”);
    }
    public static function getInstance():EventCentral {
    return instance;
    }
    /**
    * Overrides the dispatchEvent method in flash.events.EventDispatcher
    * @param $event : any qualified event
    * @return Boolean
    *
    */
    public override function dispatchEvent($event:Event):Boolean {
    return super.dispatchEvent($event);
    }
    }
    }

    Hope this helps.

  5. DJon 16 Dec 2008 at 3:26 pm

    also make sure to clean up your Event Listeners with “removeEventListener” after you have defined your event has fired and the var has been declared. If you do not remove the listener it will stay in memory.

    Example:
    EventCentral.getInstance().removeEventListener(ProjectEvent.SOME_EVENT, handleSomeEvent);

Trackback URI | Comments RSS

Leave a Reply

  • Friends

  • Props

  • Donations

  • website counter
  • Archives

  • Feedburner