A couple of questions on the Dictionary class in Actionscript 3:
What's the best way to check for an unused key? I'm doing dictionary[key] == undefined
right now. Is that the fastest and cleanest way?
Do I have to loop through and delete dictionary[key]
or can I just let the dictionary go out of scope?
Is there a better solution for mapping message listeners to a broadcasting class? I do something like this:
addListener(function : Function, messageType : Type)
{
if(dictionary[messageType] == undefined)
dictionary[messageType] = new Vector<Function>();
dictionary[messageType].push(function);
}
broadcast(message : Message, messageType : Type)
{
if(dictionary[messageType] != undefined)
{
for each(var function : Function in dictionary[messageType])
function(message);
}
}
I just typed that out now, so it may not be 100% accurate. Good idea to use a routing system with a dictionary like that?
1 -- You have two valid options: compare with undefined
or compare with null
. The difference is like this:
undefined
: a value does not exist at allnull
: a value exists, but contains nullSo, you choose what's appropriate in your case. See examples.
import flash.utils.Dictionary;
var test:Dictionary = new Dictionary();
trace(test[1] == null); // true, because null is internally converted to undefined
trace(test[1] === null); // false, because of strictly typed comparison
trace(test[1] == undefined); // true
trace(test[1] === undefined); // true
2 -- I always do loops through dictionaries to clean them up when I have references there (and not just ptimitive types like numbers or strings). Well, it shouldn't be necessary, but this way I help garbage collector a little bit, which is generally a good idea.
3 -- This one gets me puzzled. Why do you need broadcasting this way? It looks much like what we had days ago with AsBroadcaster class in AS1-2, that non-natively provided us with broadcasting capabilities. AS3 has a native event dispatching system, which you can upgrade to suit your needs (for instance, if you need to maintain a list of listeners for each event type).
These links might be usefull:
you could also write if (!dictionary[key]) ...
you can nullify a dictionary object instead of looping thru to delete all keys: dictionary = null;
i wrote a broadcaster class and you're absolutely welcome to use it if you'd like! it works quite well for global communication between non display objects. however, if you want to allow global communicating between display objects, you can add and dispatch custom event via the stage instead - assuming they are added to the stage, of course.
Broadcast.as
package com.mattie.events.broadcaster
{
//Class
public class Broadcast
{
//Variables
public var name:String;
public var data:Object;
//Constructor
public function Broadcast(name:String, data:Object)
{
this.name = name;
this.data = data;
}
}
}
Broadcaster.as
package com.mattie.events.broadcaster
{
//Imports
import flash.utils.Dictionary;
//Class
public final class Broadcaster
{
//Properties
private static var singleton:Broadcaster;
private var publicationsProperty:Dictionary;
private var subscriptionsProperty:Array;
//Constructor
public function Broadcaster()
{
if (singleton)
throw new Error("Broadcaster is a singleton that cannot be publically instantiated and is only accessible thru the \"broadcaster\" public property.");
publicationsProperty = new Dictionary(true);
subscriptionsProperty = new Array();
}
//Publish Data
public function publish(name:String, data:Object = null):void
{
publicationsProperty[name] = data;
for (var i:uint = 0; i < subscriptionsProperty.length; i++)
if (subscriptionsProperty[i].name == name)
{
var handler:Function = subscriptionsProperty[i].handler;
handler(new Broadcast(name, data));
}
}
//Subscribe Handler
public function subscribe(name:String, handler:Function):void
{
if (publicationsProperty[name])
handler(new Broadcast(name, publicationsProperty[name]));
for (var i:uint = 0; i < subscriptionsProperty.length; i++)
if (subscriptionsProperty[i].name == name && subscriptionsProperty[i].handler == handler)
return;
subscriptionsProperty.push({name: name, handler: handler});
}
//Unpublish Data
public function unpublish(name:String):void
{
delete publicationsProperty[name];
}
//Unsubscribe Handler
public function unsubscribe(name:String, handler:Function):void
{
for (var i:uint = 0; i < subscriptionsProperty.length; i++)
if (subscriptionsProperty[i].name == name && subscriptionsProperty[i].handler == handler)
{
subscriptionsProperty.splice(i, 1);
return;
}
}
//Publications Getter
public function get publications():Dictionary
{
return publicationsProperty;
}
//Subscriptions Getter
public function get subscriptions():Array
{
return subscriptionsProperty;
}
//Singleton Getter
public static function get broadcaster():Broadcaster
{
if (!singleton)
singleton = new Broadcaster();
return singleton;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With