AS3 Broadcaster Class
Monday, June 23rd, 2008![]()
This is something simple enough that I hesitate to post it, but maybe someone else can benefit. Plus, I always try to have something new on Mondays. Anyway, this a technique I once used back in the dark ages of ActionScript development (meaning AS2). Last week, however, I suddenly had need of it again.
The Scenario
The AS3 event model is a pretty slick deal- much better than the six different ways we used to do it back in AS2. However, I ran into a spot last week in which it failed me. I had several different components in completely different parts of an application, and I wanted them all to listen to each other. That in itself is no problem. The problem was that I also wanted them to be completely unaware of each other, in hopes of keeping the code a bit more encapsulated. So how does one listen for an event that comes from a source whose very existence is unknown?
Option #1
Option #1 was to make all my events bubble, and have each component add event listeners to some display list parent that all the components shared. This would ensure that everyone got their events, but it makes everyone dependent on the current setup. What if I wanted to move a component elsewhere and now it didn’t share that parent? Plus, it’s not a solution that is guaranteed to work in a different app. Plus, it involves children referencing their parent, which I am against on a fundamental, perhaps even a spiritual level. So, scratch Option #1.
Option #2
Then I thought maybe each component should store a reference to all the other components. But once again, you can throw the whole “loosely-coupled” idea out the window. Something about this solution just didn’t feel right.
Option #3
Option #3 was the old AS2 method of creating a central static Broadcaster class and telling everyone to listen to it. Now the only dependency each component had was to one static communication class. Everything else could change as long as they were listening to the Broadcaster. And so, as my great-grandmother has told me, sometimes the old ways are best.
Source
There’s really not much to explain with this class. The only challenge was making a static class into an EventDispatcher, but that turned out to be pretty easy (thanks to G. Skinner, who originally gave me the idea for a static EventDispatcher). Behold:
/**
* A central event broadcaster
*
* @author Zack Jordan
* { P I X E L W E L D E R S . C O M }
*/
package com.pixelwelders.events
{
import flash.events.Event;
import flash.events.EventDispatcher;
public class Broadcaster
{
private static var eventDispatcher : EventDispatcher;
/**
* Broadcasts an event to all listeners
* To listen to any and all events, use Broadcaster.addEventListener()
*
* @param event The Event to broadcast
* @return nothing
*/
public static function broadcast( event:Event ): void
{
dispatchEvent( event );
}
// === S T A T I C E V E N T D I S P A T C H E R ===
public static function addEventListener( type:String, listener:Function, useCapture:Boolean=false,
priority:int=0, useWeakReference:Boolean=true ):void
{
if ( !eventDispatcher ) eventDispatcher = new EventDispatcher();
eventDispatcher.addEventListener( type, listener, useCapture, priority, useWeakReference );
}
public static function removeEventListener( type:String, listener:Function, useCapture:Boolean=false ):void
{
if ( eventDispatcher ) eventDispatcher.removeEventListener( type, listener, useCapture );
}
public static function dispatchEvent( p_event:Event ):void
{
if ( eventDispatcher ) eventDispatcher.dispatchEvent( p_event );
}
}
}
As you can see, this is just a static wrapper for an instance of EventDispatcher. I just route all the methods of the EventDispatcher to static methods, and voilá. As always, if you can think of a better way, just drop it in the comments.