因爲剛把集合中的list實現,而後Timer中又用到了列表,因此,這模塊將會有重構.
函數
重構好了,明天再將timer如何實現來簡單介紹一下.this
--------------------------------------------code
終於有時間將百分之Timer系統的說一下了.對象
首先,百分之Timer提供了一個TimerManager單例對象,用來提供生成Timer的工廠,使用起來很簡單,代碼以下所示(局部代碼):
接口
var timer1:ITimer = TimerManager.instance.createTimer(1000 , onTimer1 , ["on timer 1"]); var timer2:ITimer = TimerManager.instance.createTimer(1000 , onTimer1 , ["on timer 2"]); var timer3:ITimer = TimerManager.instance.createTimer(2000 , onTimer1 , ["on timer 3"]); timer1.start(); timer2.start(); timer3.start()
private function onTimer1(message:String):void { trace(message); }
經過TimerManager提供的creatTimer方法,能夠很方便的生成一個ITimer對象,而後調用ITimer的start方法,onTimer1將會每隔一段時間,被執行一次.事件
關鍵處在於上面生成的三個ITimer對象,將會共享同一個Timer對象,這是如何實現的呢?不用着急,好菜立刻就要上了.rem
咱們先看一下TimerManager的createTimer方法須要傳入的參數,其參數定義以下:get
public function createTimer(delay:int , fn:Function , fnParams:Array = null):ITimer
delay(int) :延遲,以毫秒爲單位,表示每次回調函數被執行的時間間隔,與系統自帶的Timer的delay含義一致.回調函數
fn(Function):回調函數源碼
fnParams(Array):回調函數的參數列表
相信很多同窗在看到這裏的時候,已經能夠猜到百分之Timer的實現原理,在不繼續看下去的狀況下,也能本身實現了.不過,光看一個createTimer,顯然不是你們想要看到的結果.createTimer的源碼爲:
public function createTimer(delay:int , fn:Function , fnParams:Array = null):ITimer { var callback:FN = new FN(fn , fnParams); var timer:ITimer = new MyTimer(delay , callback); add(timer); return timer; }
代碼其實一目瞭然,重點在add方法,其源碼爲:
private function add(timer:ITimer):void { if(timer.delay < 0) return; //遍歷列表,找出其中是否存在與timer的delay成正比的執行者 var sets:ISet = _executers.getKeys(); for(var i:int = 0 ;i < sets.size ; i++) { if(timer.delay % sets.getValue(i) == 0) { (_executers.getValue(sets.getValue(i)) as ITimerExecuter).add(timer); break; } } // if(!timer.hasExecuter) { var executer:ITimerExecuter = new TimerExecuter(timer.delay); _executers.put(timer.delay , executer); executer.add(timer); } }
代碼也不復雜,只是稍微比createTimer多了幾行,一行行看過去,會發現,其實很簡單.
一開始我判斷了一下timer的delay是否大於0,若小於0,直接返回,這個是屬於容錯處理.
而後,我取得_executers的全部鍵值,咱們看下_executers是個什麼東西.
private var _executers:IMap; //執行列表
很是有必要將IMap貼出來看下,
public interface IMap { /** 插入一條數據*/ function put(key:* , value:*):void ; /** 刪除一條數據*/ function remove(key:*):void; /** 返回指定key是否存在*/ function hasKeys(key:*):Boolean; /** 返回指定value是否存在*/ function contains(value:*):Boolean; /** 根據指定的key取得數據*/ function getValue(key:*):*; /** 取得key的集*/ function getKeys():ISet; /** 取得數據列表*/ function getValues():IList; }
註釋的很明瞭,就很少說了.詳細有關IMap的介紹,能夠查看百分之集合,這個尚未寫出來,以後有時間會寫一下的.
回到add方法,在取出了_executers的鍵值集後,我採起了遍歷該無重複項的集合,讓其值與timer的delay值進行一個求餘的操做,若爲0,也就是恰好整除的狀況下,取得該ITimerExecuter,並將timer添加進該ITimerExecuter.若遍歷了全部鍵值還不存在一個符合條件的ITimerExecuter的話,便實例化一個以timer的delay值爲其delay值,並以delay爲鍵值,存儲在_executers中.add方法到此結束 .在這裏,有必要說明一下ITimerExecuter這個接口及其實現.
ITimerExecuter接口定義以下:
public interface ITimerExecuter { function add(timer:ITimer):void; function remove(timer:ITimer):void; function get isEmpty():Boolean; }
這個接口沒加註釋,由於它很簡單,光看名字就知道了.接下來,咱們來看一下它的實現類TimerExecuter,部分源碼以下:
成員變量:
private var _delay:int; private var _timers:IList; private var _timersCount:IList; private var _timer:Timer;
構造函數:
public function TimerExecuter(delay:int = 10) { _timers = new List(); _timersCount = new List(); _delay = delay; _timer = new Timer(delay); _timer.addEventListener(TimerEvent.TIMER , onTimer); _timer.start(); }
關於IList的說明,詳見百分之集合.在構造函數中,實例化了一個Timer對象,並監聽了TimerEvent.TIMER事件.其回調函數爲onTimer,咱們來看onTimer的實現:
protected function onTimer(event:TimerEvent):void { if(isEmpty) return; for(var i:int = 0 ;i < _timers.size ; i++) { var t:ITimer = _timers.getValue(i); if(t.isExecute) { if(_timersCount.getValue(i) <= 0) { t.callback.execute(); _timersCount.replace(i , getDelayCount(t)); } else { var count:int = _timersCount.getValue(i); count = count - 1; _timersCount.replace(i , count); } } } }
其實就是遍歷_timer列表,判斷每個timer是否可執行,若可執行,則判斷其timer對應的timerCount的值是否不大於0,如果,則執行timer的回調函數,並更新其對應的timerCount值.若不是,則將對應的timerCount減一.getDelayCount的實現以下:
private function getDelayCount(timer:ITimer):int { return timer.delay/delay - 1; }
so easy.很少說了.百分之Timer的核心實現已經介紹了一遍了.最基本重要的ITimer卻尚未說明,來看下其接口定義吧:
public interface ITimer { /** 執行間隔 */ function get delay():int; /** 回調函數 */ function get callback():FN; /** 設置 執行者 */ function set executer(value:ITimerExecuter):void; /** 取得執行者是否存在 */ function get hasExecuter():Boolean; /** 取得是否處於執行狀態中 */ function get isExecute():Boolean; /** 開始執行*/ function start():void; /** 中止執行 */ function stop():void; /** 回收 */ function recover():void; }
都有註釋,不須要多說了吧.其實現類MyTimer也很簡單.部分代碼以下:
成員變量:
private var _delay:int; private var _callback:FN; private var _isExecute:Boolean; private var _executer:ITimerExecuter;
start方法爲:
public function start():void { _isExecute = true; }
remove方法爲:
public function recover():void { _executer.remove(this); }
其它的都很簡單,一看start及remove方法就知道,其它的方法有多簡單了.
百分之Timer的介紹到此結束.期待你們的評論與留言.