XClassEventListener, does it makes sens for you?

Hi,

I’ve done a class to be able to listen to the event for a CLASS not on an instance.


class net.webbymx.events.XClassEventListener {
	
/* *****************************************************************************
* PRIVATE STATIC VARIABLES
***************************************************************************** */
	private static var $instance:XClassEventListener = undefined;
	private static var _oListeners:Object;
	

/* *****************************************************************************
* CONSTRUCTOR
***************************************************************************** */
	private function XClassEventListener() {}

/* *****************************************************************************
* PUBLIC STATIC FUNCTIONS
***************************************************************************** */
	public static function initialize(obj:Object):Void {
		if ($instance == undefined) $instance = new XClassEventListener;
	//	obj.dispatchEvent = $instance.dispatchEvent;
	//	obj.eventListenerExists = $instance.eventListenerExists;
		obj.addEventListener = $instance.addEventListener;
		obj.removeEventListener = $instance.removeEventListener;
	//	obj.removeAllEventListeners = $instance.removeAllEventListeners;
	}

/* *****************************************************************************
* PRIVATE STATIC FUNCTIONS
***************************************************************************** */
	public static function dispatchEvent(eventObj:Object) {
	//	check if the object has the good properties
		if (eventObj.target == undefined || eventObj.clazz == undefined || typeof(eventObj.clazz) != "string" ||
			eventObj.type == undefined || typeof(eventObj.type) != "string") return;

	//	check is the class end event is registered
		if (_oListeners[eventObj.clazz] == undefined || _oListeners[eventObj.clazz][eventObj.type] == undefined) return;

	//	list object and call the function 
		for (var i:String in _oListeners[eventObj.clazz][eventObj.type]) {
			var o:Object = _oListeners[eventObj.clazz][eventObj.type]*.o;
			var oType:String = typeof(o);
			var f:String = _oListeners[eventObj.clazz][eventObj.type]*.f;
			if (oType == "object" || oType == "movieclip") {
				if (o.handleEvent != undefined && f == undefined) {
					o.handleEvent(eventObj);
				} else {
					if (f == undefined) f = eventObj.type;
					o[f](eventObj);
				}
			} else { // function
				//o.apply(p_dispatchObj,[eventObj]);
			}
		}
	}
	
//	internal function to locate listeners:
	private static function $indexOfListener(listeners:Array,obj:Object,func:String):Number {
		var l:Number = listeners.length;
		var i:Number = -1;
		while (++i < l) {
			var tmpObj:Object = listeners*;
			if (tmpObj.o ==obj && func == undefined) return i;
			else if (tmpObj.o ==obj && tmpObj.f == func) return i;
		}
		return -1;
	}
	

/* *****************************************************************************
* PRIVATE FUNCTIONS
***************************************************************************** */
/**
* Add a listener for an event, for a class
* @param	p_event: String
* @param	p_obj: Function (Class.prototype)
* @param	p_function: String
*/ 	// OK
	private function addEventListener(event:String, clazz:String, func:String):Void {
		if (_oListeners == undefined) { _oListeners = {}; /*_global.ASSetPropFlags(this,_oListeners,1);*/ }
		
	//	creating a new object for each class holding the events
		if (_oListeners[clazz] == undefined) _oListeners[clazz] = {};
		
	//	creating a array (same name as the function) holding the obj (ref, callbackfunction)
		if (_oListeners[clazz][event] == undefined) _oListeners[clazz][event] = [];

	//	check if the object is already in the array, if not pushing it
		if ($indexOfListener(_oListeners[clazz][event],this,func) == -1) _oListeners[clazz][event].push({o:this,f:func}); 
	}

	
/**
* Remove the listener for an event, for a class
* @param	p_event: String
* @param	p_obj: Function (Class.prototype)
* @param	p_function: String (optional)
*/
	private function removeEventListener(event:String, clazz:String):Void {
trace(_oListeners);
for (var i:String in _oListeners) {
	trace(i+": "+_oListeners*);
}
		var func:String = arguments[2];
		
	//	go out of the function if either the class is not registered nor the event for the class
		if (_oListeners == undefined || _oListeners[clazz] == undefined || _oListeners[clazz][event] == undefined) return;

	/*	find the index for the object. If the function is pass as the parameter we will delete just the instance holding this callback 
		function for this class, else we will delete all the instance */	
		var index:Number;
		if (arguments[2] != undefined) {
			index = $indexOfListener(_oListeners[clazz][event],this,func)
			if (index != -1) _oListeners[clazz][event].splice(index,1);
		}
		else {
			while ( (index = $indexOfListener(_oListeners[clazz][event],this)) != -1) {
				_oListeners[clazz][event].splice(index,1);
			}
		}

		if (index != -1) {
			if (_oListeners[clazz][event].length == 0) delete _oListeners[clazz][event];
			if (_oListeners[clazz].length == 0) delete _oListeners[clazz];
		}
	}

	private function removeAllEventListener(event:String, clazz:String):Void {
	//	go out of the function if either the class is not registered nor the event for the class
		if (_oListeners == undefined || _oListeners[clazz] == undefined || _oListeners[clazz][event] == undefined) return;
		delete _oListeners[clazz][event];
		if (_oListeners[clazz].length == 0) delete _oListeners[clazz];
		if (_oListeners.length == 0) delete _oListeners;
		
	}
	
	private function removeClassListener(clazz:String):Void {
	//	go out of the function if either the class is not registered nor the event for the class
		if (_oListeners == undefined || _oListeners[clazz] == undefined) return;
		delete _oListeners[clazz];
	}
}

Simple eg:


import net.webbymx.events.XClassEventListener;

[Event "test"]
class net.webbymx.test.DClass {
	function DClass(){
trace("DCLass instance created");
	};
	public function Dpatch() {
		var o:Object = new Object();
		o.target = this;
		o.type = "test";
		o.clazz = "net.webbymx.test.DClass";
		XClassEventListener.dispatchEvent(o);
	}
}

in the fla


import net.webbymx.events.XClassEventListener;
import net.webbymx.test.DClass;

XClassEventListener.initialize(this);
this.addEventListener("test", "net.webbymx.test.DClass", "atest");

var d1:DClass = new DClass();
var d2:DClass = new DClass();
var d3:DClass = new DClass();
var d4:DClass = new DClass();


// test dispatching
d1.Dpatch();

function atest(evtObj) {
	trace("callback done");
	trace(evtObj.clazz);
	this.removeEventListener("test", "net.webbymx.test.DClass");
}

why did I do this.
It cames with my rugby game.
I have player in two teams. When a player throw the ball I want the other teammate to act like “wait for ball” and the opponent like “seek for ball”. Plus I’m lazy (and I don’t want to register the listener for each instance of the player I’m creating). So this class is made to be able to handle as many instance of a class I want without adding a listener on each of them. I’m just creating a global listener on the class and then I will be able to receive dispatched event for any instance of this class .

so in my team I can do


XClassListener.initialize(this);
this.addEventListener("throw", "net.webbymx.game.Player", "wait");

and in my opponent team I can do


XClassListener.initialize(this);
this.addEventListener("throw", "net.webbymx.game.Player", "seek");

Does it makes sens for you ???
Any feedbacks/comments are welcome
Cheers

Such experiments should be posted in Source/Experiments section…

Thanks for sharing…

But I have a doubt

private static var $instance:[U]XClassEventListener[/U] = undefined;

How does this work? you are declaring a member variable of the type which is holding that member variable ?