並在從達成變未達成時,也會觸發特定的方法。
Trigger
package tw.right929.proxy
{
import flash.utils.*;
use namespace flash_proxy
/**
* <p>
* 達成條件時,發動函式whenInDo.call(thisObjectForIn),<br/>
* 從達成條件變成未達成時,發動函式whenOutDo.call(thisObjectForOut)。
* </p>
*/
public dynamic class Trigger extends Proxy
{
private var _propertyMap:Object = new Object();
private var _triggerCount:int = 0;
private var _map:Dictionary = new Dictionary();
public function Trigger()
{
super();
}
/**
* 新增一個條件觸發式。
* 若加入時,Trigger已是滿足條件的狀態,會直接發動函式whenInDo.call(thisObjectForIn)。
*/
public function $addTrigger(conditions:* , whenInDo:Function , whenOutDo:Function , thisObjectForIn:*=null , thisObjectForOut:*=null):*
{
_triggerCount++;
_map[_triggerCount] = new $ConditionInfo(conditions , whenInDo , whenOutDo , thisObjectForIn , thisObjectForOut);
_map[_triggerCount].testConditions(_propertyMap , _propertyMap);
return _triggerCount;
}
/**
* 移除一個條件觸發式。
*/
public function $removeTrigger(triggerID:*):void
{
_map[triggerID].die();
delete _map[triggerID];
}
/**
* 一次修改許多絛件式。
*/
public function $setConditions(conditions:*):void
{
for(var p:String in conditions)
_propertyMap[p] = conditions[p];
_update(conditions);
}
/**
* 把物件清空,方便回收。
*/
public function die():void
{
for(var triggerID:* in _map)
$removeTrigger(triggerID);
for(var p:* in _propertyMap)
delete _propertyMap[p];
_propertyMap = null;
_map = null;
}
/**
* conditions為改變的條件。
* 檢查所有觸發式,若有符合,則發動。
*/
private function _update(conditions:*):void
{
for each(var conditionInfo:$ConditionInfo in _map)
{
conditionInfo.testConditions(_propertyMap , conditions);
}
}
override flash_proxy function setProperty(name:*, value:*):void
{
if(this[name] == value)
return;
_propertyMap[name] = value;
var conditions:Object = new Object();
conditions[name] = value;
_update(conditions);
}
override flash_proxy function deleteProperty(name:*):Boolean
{
return delete _propertyMap[name];
var conditions:Object = new Object();
conditions[name] = false;
_update(conditions);
}
override flash_proxy function getProperty(name:*):*
{
return _propertyMap[name];
}
override flash_proxy function hasProperty(name:*):Boolean
{
return name in _propertyMap;
}
}
}
class $ConditionInfo
{
public var conditions:*;
public var whenInDo:Function;
public var whenOutDo:Function;
public var thisObjectForIn:*;
public var thisObjectForOut:*;
private var _inConditions:Boolean = false;
public function $ConditionInfo(conditions:* , whenInDo:Function , whenOutDo:Function , thisObjectForIn:*=null , thisObjectForOut:*=null)
{
this.conditions = conditions;
this.whenInDo = whenInDo;
this.whenOutDo = whenOutDo;
this.thisObjectForIn = thisObjectForIn;
this.thisObjectForOut = thisObjectForOut;
}
public function testConditions(conditionsMap:Object , change:*):void
{
if(checkChange(change))
{
if(_inConditions)
{
_inConditions = false;
if(whenOutDo != null)
whenOutDo.call(thisObjectForOut);
}
else
{
for(var p:String in conditions)
{
if(conditionsMap[p] == undefined)
return;
if(conditionsMap[p] != conditions[p])
return;
}
_inConditions = true;
if(whenInDo != null)
whenInDo.call(thisObjectForIn);
}
}
}
public function die():void
{
conditions = null;
whenInDo = null;
whenOutDo = null;
thisObjectForIn = null;
thisObjectForOut = null;
}
private function checkChange(change:*):Boolean
{
for(var p:String in change)
{
if(p in conditions)
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.proxy.Trigger;
private function init():void
{
var trigger:Trigger = new Trigger();
trigger.$addTrigger({A:true} , onInA , null , this);
trigger.$addTrigger({B:true} , onInB , onOutB , this);
trigger.$addTrigger({C:true , D:true} , null , onOutCD , null , this);
trigger.$addTrigger({E:10} , onInE , null , this);
trigger.A = true; //onInA
trigger.B = true; //onInB
trigger.C = true;
trigger.D = true;
trigger.A = false;
trigger.B = false; //onOutB
trigger.C = false; //onOutCD
trigger.D = false;
trigger.E = 0;
trigger.E = 10; //onInE
trigger.die();
}
private function onInA():void
{
trace("onInA");
}
private function onInB():void
{
trace("onInB");
}
private function onOutB():void
{
trace("onOutB");
}
public function onOutCD():void
{
trace("onOutCD");
}
public function onInE():void
{
trace("onInE");
}
]]>
</fx:Script>
</s:Application>
沒有留言:
張貼留言