Ultrashock Tutorials > FlashMX > Events and ASBroadcaster  
 
by: Robert Penner, robertpenner.com

Source File

 
Events and ASBroadcaster
 

In Listeners: An Introduction, we learned the key concepts of event-based programming and listeners. In this tutorial, we'll explore the more nitty-gritty details of how event sources use ASBroadcaster, an undocumented object.

Quick Review

We saw previously that various built-in Flash objects are event sources. For instance, the Mouse object broadcasts the events mouseDown, mouseUp, and mouseMove. The Mouse object has addListener() and removeListener() methods, which subscribe objects to its events. A listening object should have event handler methods, such as onMouseDown(), which respond to the events emanating from Mouse.

Digging Deeper

As this point, we may ask: how does Mouse broadcast its events? And is it possible for us to broadcast our own events in the same manner?

It turns out that Mouse has a semi-hidden, undocumented method called broadcastMessage(). We can verify this with the following code:

trace (typeof Mouse.broadcastMessage); // output: function

There is also an array hidden in Mouse, called _listeners:

trace (Mouse._listeners instanceof Array); // output: true

The above code shows that Mouse._listeners is an instance of the Array class.

Whenever you add a listener, it is stored in Mouse._listeners. We can test this out by adding _level0 as a listener:

Mouse.addListener (_level0);
trace (Mouse._listeners); // output: _level0

We see that Mouse._listeners has one element: the movie clip _level0.

The Key, Selection, and Stage objects also add listeners and broadcast events. If we do similar detective work on them as with Mouse, we find that these objects have the same hidden features:

trace (typeof Key.broadcastMessage); // output: function
trace (Key._listeners instanceof Array); // output: true
// same results for Selection and Stage

Core Abilities of Event Sources

Let's generalize from these results. If a built-in object obj is an event source, it has the following methods and properties:

  1. obj.addListener()
  2. obj.removeListener()
  3. obj.broadcastMessage()
  4. obj._listeners

This makes perfect sense. After all, an event source needs to do four key things:

  1. subscribe an object
  2. unsubscribe an object
  3. send a message to all subscribers
  4. keep a list of subscribers

But how do the built-in event sources gain these abilities?

ASBroadcaster

Flash detectives has discovered an undocumented global object called ASBroadcaster. You can dig it up yourself with this snippet of code:

ASSetPropFlags (_global, null, 8, 1);
for (var i in _global) trace (i);

This will spit out an intriguing list of objects and functions like "NetStream," "MMSave," and yes, "ASBroadcaster." (The ASSetPropFlags() command is another undocumented feature, which is used here to "unhide" an object's properties.)

We can list all of ASBroadcaster's methods and properties with this code:

ASSetPropFlags (ASBroadcaster, null, 8, 1);
for (var i in ASBroadcaster) trace (i);

This list is sent to the Output window:

// ASBroadcaster properties and methods
initialize
removeListener
addListener
broadcastMessage
prototype
__proto__
constructor

The last three properties on the list are standard issue for objects, but the first four look interesting. We have addListener() and removeListener(), as well as a new method initialize(). What might ASBroadcaster.initialize() do?

Initializing an Event Source

Let's try ASBroadcaster.initialize() on a generic object, and see what happens.

obj = new Object();
ASBroadcaster.initialize (obj);

Did the makeup of the object change at all? We can list its properties with a for..in loop:

for (var i in obj) trace (i); // output: [nothing]

Hmm... it appears that obj has no properties. Or does it? Let's try our ASSetPropFlags() trick to unearth any properties that might be trying to hide:

ASSetPropFlags (obj, null, 8, 1);
for (var i in obj) trace (i);

We get this output:

_listeners
removeListener
addListener
broadcastMessage
__constructor__
constructor
__proto__

Those first four properties are exactly what we want to see:

  • _listeners
  • removeListener
  • addListener
  • broadcastMessage

Apparently, ASBroadcaster.initialize() has bestowed upon obj the four key characteristics of an event source. In a superhero movie, this would be the scene where an unsuspecting, ordinary guy is bitten by some sort of mutant/radioactive animal and gains that animal's powers.

In a similar way, we can "bite" objects with ASBroadcaster.initialize() to transform them from mild-mannered milquetoasts into powerful, event-radiating über-objects. It just takes one line of code:

ASBroadcaster.initialize (obj);

Now we can start adding and removing listeners, which we already know how to do. But what about sending the events--how does that work?

Broadcasting Events

An ActionScript event source uses its broadcastMessage() method (copied from ASBroadcaster) to notify its listeners of events. This the syntax for broadcastMessage():

obj.broadcastMessage (handlerName[, arg1, arg2, ..., argn]);

The handlerName parameter is a string that names the listener's event handler method, such as "onMouseDown" or "onKeyUp." The broadcastMessage() method loops through all all the listeners in the _listeners array, and calls the event handler for each. The other parameters arg1, arg2, etc. are optional arguments you can pass to the listener's event handler.

For example, suppose we have a mouth event source. It broadcasts a speak event, passing a words string as a parameter. The event would be sent like this:

mouth.broadcastMessage ("onSpeak", "hey you");

If we have an ear object listening for events from mouth, it would have an onSpeak() event handler:

ear.onSpeak = function (words) {
    trace (words); // output: hello
};

Here is the complete code for this small broadcasting scenario:

mouth = new Object();
ASBroadcaster.initialize (mouth);

ear = new Object();
ear.onSpeak = function (message) {
    trace (message);
};

mouth.addListener (ear);
mouth.broadcastMessage ("onSpeak", "hey you");

Here are the steps in the above code:

  1. create the event source object - mouth
  2. initialize the event source with ASBroadcaster.initialize()
  3. create a listener object - ear
  4. add an event handler - onSpeak()
  5. register the listener - mouth.addListener()
  6. broadcast the event - mouth.broadcastMessage()

These six steps comprise the basic process of creating an event source and listeners, and broadcasting events. In a future tutorial, we'll look at an example of a custom, object-oriented event source, built from a class and empowered by ASBroadcaster.

 

 

 
©2002 Ultrashock.com Inc. - All rights reserved