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:




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.
Thanks for this class, it’s very helpful.
You just forgot to camelcase getInstance at this line
EventCentral.getinstance().addEventListener(ProjectEvent.SOME_EVENT, someEventhandler);
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
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.
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);