因为刚把集合中的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的介绍到此结束.期待你们的评论与留言.