Blog Post With explination and source downloads: http://smurfmx.selfmedicatedandlivinginabucket.com/2006/05/watch-manager-beating-system.html
Source:
**Note:**You will have to change the import line to suit what ever your class path is. The Delegate class is also the MTASC compliant delegate class that is linked to in the blog post.
import org.flashdevelop.utils.Delegate;
class WatchManager
{
//public
//private
//static
static var watchers:Array = [];
//---Constructor---
public function WatchControl(Void){
//Not Used
}
//Public Method
//--Subscribe
/////////
/*Params:
* ---$obj: String representation of the object the prop to watch belongs to.
* ---$prop: String representation of the property to watch of $obj.
* ---$scope: The scope of the _object_ you're watching.
* ---$callBack: Function that's called when value of $obj[$prop] changes.
*
* Returns:
* --Object: Contains all the watch data, is used when unsubscribing the watch instance.
*/
public static function subscribe( $obj:String, $prop:String, $scope:Object, $callBack:Function):Object{
var wObj:Object = {obj:$obj, prop:$prop, scope:$scope, callback:$callBack, args:arguments.slice(4)};
if(!watchExists($prop)){
$scope[$obj].watch($prop, Delegate.create( WatchManager, manageCallback, $prop ));
}
watchers.push(wObj);
wObj.index = watchers.length-1;
return wObj;
}
//Public Method
//--Unsubscribe
////////////
/*Params:
* ---$wObj: A returned Object from the subscribe method
*/
public static function unsubscribe( $wObj:Object ):Void{
$wObj.obj.unwatch( $wObj.prop );
for( var i in watchers){
if(watchers* == $wObj){
//trace("Found, unsubscribing");
watchers.splice( $wObj.index, 1);
for(var a:Number = 0; a < watchers.length; a++){
watchers[a].index = a;
}
}
if(watchers*.prop == $wObj.prop){
if(!watchExists(watchers*.prop)){
//trace("Resubscribing other watches");
watchers*.scope[watchers*.obj].watch( watchers*.prop, Delegate.create( WatchManager, manageCallback ));
}
}
}
}
//Public Static Method
//--manageCallback
//-Handles callback for multiple watch instances
////////
public static function manageCallback(property, oldval, newval){
//trace("Callback Occured!");
for(var i in watchers){
if(watchers*.prop == property && watchers*.scope[watchers*.obj][watchers*.prop] == oldval){
//trace("Prop Found, callback activated");
var tObj:Object = watchers*;
unsubscribe( watchers* );
var setFunc:Function = function($s, $o, $p, $nv){
$s[$o][$p] = $nv;
return $s[$o][$p];
}
var func:Function = Delegate.create( tObj.scope, setFunc, tObj.scope, tObj.obj, property, newval);
func( tObj.scope, tObj.obj, property, newval );
func= Delegate.create( tObj.scope, tObj.callback, tObj.args );
func();
subscribe(tObj.obj, tObj.prop, tObj.scope, tObj.callback);
}
}
return newval;
}
//Public Static Method
//--watchExists
////////
/*Params:
* ---$prop: Property to check if a watch exists for
*
* Return:
* --Boolean: if prop exists in the watch array (true), or not (false)
*/
public static function watchExists($prop:String):Boolean{
for(var i in watchers){
if(watchers*.prop == $prop){
//trace("Exists, no watch added");
return true;
}
}
//trace("Doesn't Exist, watch added");
return false;
}
}