https://code.google.com/p/actionscript-3-advanced-object/
AdvancedObject
bfc_bfs_x
bfs_x old=0 new=10
afc_bfs_x
10
bfc_bfc_addChild [object Sprite]
bfc_addChild [object Sprite]
afc_bfc_addChild [object Sprite]
afc_addChild [object Sprite]
1
bfc_bfs_x
bfs_x old=0 new=100
afc_bfs_x
100
bfc_bfc_addChild [object Sprite]
bfc_addChild [object Sprite]
afc_bfc_addChild [object Sprite]
afc_addChild [object Sprite]
1
目前AdvancedObject已經實現了目標中的Proxy功能。
接下來要做EventListener的部份,
這個部份有比較大的問題,在於沒辦法知道superObj內到底會發出那些Event,
和一個Event會同時觸發多個function。
AdvancedObject
package tw.right929
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
use namespace flash_proxy
/**
* 每一個屬性都有bfs_XXX(before set XXX)和afs_XXX(after set XXX)的function,
* 代表在這個屬性被設定前和設定後,會呼叫的方法,這是可以累加的方法,
* 比如,若存在bfs_bfs_XXX會在呼叫bfs_XXX之前被呼叫。
*
* 若該屬性是function則還會有bfc_XXX(before call XXX)和afc_XXX(after call XXX)的function,
* 代表這個方法在被呼叫前和呼叫後,會呼叫的方法,這也是可以累加的方法。
*
* 上述的四個方法,是會混合的,
* 比如bfc_bfs_XXX這是會在bfs_XXX這個function被呼叫前呼叫的function。
*
* 依然遵守繼承鏈的關係。
*/
public dynamic class AdvancedObject extends Proxy
{
/**
* 統一改變這個屬於這個類別物件的missFunction
*/
public static var missFunction:Function = function (name:*, rest:Array):* {return undefined};
/**
* 統一改變這個屬於這個類別物件的missProperty
*/
public static var missProperty:Function = function (name:*):* {return undefined};
private var _obj:Object = new Object();
private var _properties:Array = new Array();
private var _variables:Array = new Array();
private var _functions:Array = new Array();
private var _needUpdateProperties:Boolean = false;
private var _superObj:Object;
private var _missFunction:Function;
private var _missProperty:Function;
public function AdvancedObject()
{
super();
}
/**
* 先看自已有沒有這個屬性,若沒有找superObj的,若superObj也沒有,幫自已新增這個屬性。
*/
override flash_proxy function setProperty(name:*, value:*):void
{
if(this[name] == value)
return;
_needUpdateProperties = true;
var old:* = this[name];
if(_hasProperty(name))
{
_beforeSet(name , value , old);
_obj[name] = value;
_afterSet(name , value , old);
}
else if(_superObj && _superObj.hasOwnProperty(name))
{
_beforeSet(name , value , old);
_superObj[name] = value;
_afterSet(name , value , old);
}
else
{
_beforeSet(name , value , old);
_obj[name] = value;
_afterSet(name , value , old);
}
}
private function _beforeSet(name:* , newValue:* , oldValue:*):void
{
if(_hasProperty("bfs_"+name))
{
_callProperty("bfs_"+name , [oldValue , newValue]);
}
}
private function _afterSet(name:* , newValue:* , oldValue:*):void
{
if(_hasProperty("afs_"+name))
{
_callProperty("afs_"+name , [oldValue , newValue]);
}
}
/**
* 這個方法應該要只能刪掉自已的,不能刪掉繼承鏈上的屬性。
*/
override flash_proxy function deleteProperty(name:*):Boolean
{
_needUpdateProperties = true;
return delete _obj[name];
}
/**
* 先看自已有沒有這個方法,若沒有呼叫superObj的,若superObj也沒有,統一呼叫這個物件的missFunction。
*/
override flash_proxy function callProperty(name:*, ... rest):*
{
return _callProperty(name , rest);
}
flash_proxy function _callProperty(name:* , rest:Array):*
{
var result:*;
if(_hasProperty(name))
{
_beforeCall(name , rest);
result = _obj[name].apply(this , rest);
_afterCall(name , rest);
}
else if(_superObj && _superObj.hasOwnProperty(name))
{
_beforeCall(name , rest);
if(_superObj is AdvancedObject)
{
result = _superObj._callProperty(name , rest);
}
else
{
result = _superObj[name].apply(this , rest);
}
_afterCall(name , rest);
}
else
{
result = missFunction(name , rest);
}
return result;
}
private function _beforeCall(name:* , parameters:Array):void
{
if(_hasProperty("bfc_"+name))
{
_callProperty("bfc_"+name , parameters);
}
}
private function _afterCall(name:* , parameters:Array):void
{
if(_hasProperty("afc_"+name))
{
_callProperty("afc_"+name , parameters);
}
}
/**
* 先看自已有沒有這個屬性,若沒有找superObj的,若superObj也沒有,統一呼叫這個物件的missProperty。
*/
override flash_proxy function getProperty(name:*):*
{
if(_hasProperty(name))
return _obj[name];
else if(_superObj && _superObj.hasOwnProperty(name))
return _superObj[name];
else
return missProperty(name);
}
override flash_proxy function nextName(index:int):String
{
updateProperties();
return _properties[index-1].toString();
}
override flash_proxy function nextNameIndex(index:int):int
{
updateProperties()
if (index < _properties.length)
return index + 1;
else
return 0;
}
override flash_proxy function nextValue(index:int):*
{
updateProperties();
return _obj[_properties[index-1]];
}
override flash_proxy function isAttribute(name:*):Boolean
{
return true;
}
override flash_proxy function getDescendants(name:*):*
{
return _obj[name];
}
/**
* 尋找是否有這個屬性,包含superObj。
*/
override flash_proxy function hasProperty(name:*):Boolean
{
updateProperties();
if(_hasProperty(name))
return true;
else if(_superObj && _superObj.hasOwnProperty(name))
return true;
else
return false;
}
/**
* 尋找是否有這個屬性,不包含superObj。
*/
private function _hasProperty(name:*):Boolean
{
if(name is QName)
name = name.localName;
return(name in _obj);
}
/**
* 設定父物件。
*/
public final function set superObj(v:Object):void
{
_superObj = v;
}
public final function get superObj():Object
{
return _superObj;
}
/**
* 若呼叫了不存在的方法,則會呼叫這個方法,預設值是傳回undefined。
*/
public final function set missFunction(v:Function):void
{
_missFunction = v;
}
public final function get missFunction():Function
{
if(_missFunction)
return _missFunction;
return getDefinitionByName(getQualifiedClassName(this))["missFunction"] as Function;
}
/**
* 若想取得不存在的屬性,則會呼叫這個方法,預設值是傳回undefined。
*/
public final function set missProperty(v:Function):void
{
_missProperty = v;
}
public final function get missProperty():Function
{
if(_missProperty)
return _missProperty;
return getDefinitionByName(getQualifiedClassName(this))["missProperty"] as Function;
}
/**
* 重整自已的屬性清單。
*/
private function updateProperties():void
{
if(checkNeedUpdate())
{
_properties = new Array();
_variables = new Array();
_functions = new Array();
for (var p:String in _obj)
{
_properties.push(p);
if(_obj[p] is Function)
_functions.push(p);
else
_variables.push(p);
}
_needUpdateProperties = false;
}
}
/**
* 確定自已的屬性是否有變化而需要更新。
*/
private function checkNeedUpdate():Boolean
{
if(_needUpdateProperties)
return true;
if(!_superObj)
return false;
if(!(_superObj is AdvancedObject))
return true;
return false;
}
}
}
測試檔<?xml version="1.0" encoding="utf-8"?>
<s:Application creationComplete="init()" xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">
<fx:Script>
<![CDATA[
import tw.right929.AdvancedObject;
private function init():void
{
var s:Sprite = new Sprite();
trace(s.hasOwnProperty("x"));
var a:AdvancedObject = new AdvancedObject();
a.superObj = s;
a.bfs_x = function (oldV:* , newV:*):void
{
trace("bfs_x old="+oldV+" new="+newV);
};
a.bfc_bfs_x = function (oldV:* , newV:*):void
{
trace("bfc_bfs_x");
};
a.afc_bfs_x = function (oldV:* , newV:*):void
{
trace("afc_bfs_x");
};
a._afs_x = function (oldV:* , newV:*):void
{
trace("afs_x old="+oldV+" new="+newV);
};
a.x = 10;
trace(s.x);
var s2:Sprite = new Sprite();
a.bfc_addChild = function (child:DisplayObject):void
{
trace("bfc_addChild "+child);
};
a.bfc_bfc_addChild = function (child:DisplayObject):void
{
trace("bfc_bfc_addChild "+child);
};
a.afc_bfc_addChild = function (child:DisplayObject):void
{
trace("afc_bfc_addChild "+child);
};
a.afc_addChild = function (child:DisplayObject):void
{
trace("afc_addChild "+child);
}
a.addChild(s2);
trace(s.numChildren);
var mc:MovieClip = new MovieClip();
a.superObj = mc;
a.x = 100;
trace(mc.x);
a.addChild(s);
trace(mc.numChildren);
a.x = 100;
}
]]>
</fx:Script>
</s:Application>
輸出結果bfc_bfs_x
bfs_x old=0 new=10
afc_bfs_x
10
bfc_bfc_addChild [object Sprite]
bfc_addChild [object Sprite]
afc_bfc_addChild [object Sprite]
afc_addChild [object Sprite]
1
bfc_bfs_x
bfs_x old=0 new=100
afc_bfs_x
100
bfc_bfc_addChild [object Sprite]
bfc_addChild [object Sprite]
afc_bfc_addChild [object Sprite]
afc_addChild [object Sprite]
1
目前AdvancedObject已經實現了目標中的Proxy功能。
接下來要做EventListener的部份,
這個部份有比較大的問題,在於沒辦法知道superObj內到底會發出那些Event,
和一個Event會同時觸發多個function。
沒有留言:
張貼留言