AS3 TimerManager

之前的TimerManager好几个版都是使用别人写的;

自己写的没有备份过;

还是累积一下,并备份一下,再造一下轮子:


代码:

package org.ly.manager
{
	import flash.utils.getTimer;
	
	/**
	 * 时间器管理类
	 * @author Jave.Lin
	 * @date 2013-10-12
	 **/
	public class TimerManager
	{
		private static var _instance:TimerManager;
		public static function get instance():TimerManager
		{
			if (!_instance) _instance = new TimerManager();
			return _instance;
		}
		
		private var _elapsedTime:int = -1;
		private var _i:int;
		private var _cb:TimerCallback;
		
		private const _callbackArr:Vector.<TimerCallback> = new Vector.<TimerCallback>();
		
		public function TimerManager()
		{
			
		}
		/**
		 * 添加指定的定时回调,参数,执行时间间隔,执行次数(<=0时为无限次),并返回一个定时回调的id
		 */		
		public function addTimer(callback:Function, params:Array = null, interval:int = 1000, times:int = 0, interpolate:Boolean = false):int
		{
			var cb:TimerCallback = TimerCallback.timer_mgr_ns::getCB(callback, params, interval, times, interpolate);
			if (_callbackArr.indexOf(cb) == -1) _callbackArr.push(cb);
			return cb.id;
		}
		/**
		 * 删除指定id的定时回调
		 */		
		public function removeTimer(id:int):int
		{
			var idx:int = findCBIdx(id);
			if (idx != -1) removeTimerByIdx(idx);
			return idx;
		}
		/**
		 * 实时更新的一个方法,一般用在:enterframe中执行
		 */		
		public function update():void
		{
			if (_elapsedTime == -1) {
				_elapsedTime = getTimer();
				return;
			}
			for (_i =  0; _i < _callbackArr.length; _i++) {
				_cb = _callbackArr[_i];
				if (_cb.timer_mgr_ns::isOutTimes) {
					removeTimerByIdx(_i);
					_i--;
					continue;
				}
				_cb.timer_mgr_ns::update();
			}
			
			_elapsedTime = getTimer();
		}
		
		private function removeTimerByIdx(idx:int):void
		{
			var cb:TimerCallback = _callbackArr[idx];
			_callbackArr.splice(idx, 1);
			TimerCallback.timer_mgr_ns::pushCB(cb);
		}
		
		private function findCBIdx(id:int):int
		{
			var cb:TimerCallback;
			var i:int;
			var result:int = -1;
			for (i =  0; i < _callbackArr.length; i++) {
				cb = _callbackArr[i];
				if (cb.id == id) {
					result = i;
					break;
				}
			}
			return result;
		}
	}
}

namespace timer_mgr_ns;

import flash.utils.getTimer;

internal class TimerCallback
{
	private static var ID:int = 0;
	
	private static function getId():int
	{
		return ID++;
	}
	
	private static const _pool:Vector.<TimerCallback> = new Vector.<TimerCallback>();
	
	timer_mgr_ns static function getCB(callback:Function, params:Array = null, interval:int = 1000, times:int = 0, interpolate:Boolean = false):TimerCallback
	{
		var result:TimerCallback = _pool.length ? _pool.shift() : new TimerCallback();
		
		result.callback = callback;
		result.params = params;
		result.interval = interval;
		result.times = times;
		result.interpolate = interpolate;
		result.executedTime = 0;
		result.curTime = -1;
		result.eplasedTime = 0;
		
		return result;
	}
	
	timer_mgr_ns static function pushCB(cb:TimerCallback):void
	{
		cb.callback = null;
		cb.params = null;
		cb.interval = 0;
		cb.times = 0;
		cb.interpolate = false;
		cb.executedTime = 0;
		cb.curTime = -1;
		cb.eplasedTime = 0;
		
		_pool.push(cb);
	}
	
	internal var id:int; // 回调的id
	private var callback:Function = null; // 回调
	private var params:Array = null; // 回调参数
	private var interval:int = 0; // 间隔多少毫秒调一次
	private var curTime:int = -1;
	private var eplasedTime:int = 0;
	private var times:int = 0; // 回调次数,<=0 说明无限次
	private var executedTime:int = 0; // 记录当前已回调的次数
	private var interpolate:Boolean = false; // 是否补帧处理
	
	private var t:int;
	
	timer_mgr_ns function get isOutTimes():Boolean // 是否执行次数已达
	{
		return callback != null && times > 0 && executedTime >= times;
	}
	
	public function TimerCallback()
	{
		id = getId();
	}
	
	timer_mgr_ns function update():void
	{
		t = getTimer();
		(curTime == -1) && (curTime = t);
		eplasedTime += t - curTime;
		while (!timer_mgr_ns::isOutTimes && (eplasedTime >= interval)) {
			// 这里就不用 eplasedTime -= interval;的方法了当然,如果你想要TimerManager可兼容这种补帧逻辑
			//也可以在TimerManager上添加一个标识来区别这里的逻辑处理
			if (interpolate) {
				eplasedTime -= interval;
			} else {
				eplasedTime = 0;
			}
			if (!timer_mgr_ns::execute())
				break;
		}
		curTime = t;
	}
	
	timer_mgr_ns function execute():Boolean
	{
		if (callback == null) return false;
		callback.apply(null, params);
		executedTime += 1;
		return true;
	}
}



调用:

		stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		test1ID = TimerManager.instance.addTimer(testOnTimer, [1000, 0, "test1"]);
		trace("test1ID : " + test1ID);
		test2ID = TimerManager.instance.addTimer(testOnTimer, [2000, 3, "test22222"], 2000, 3);
		trace("test2ID : " + test2ID);
		
		private var test1times:int = 0;
		private var test1ID:int;
		private var test2ID:int;
		
		private function testOnTimer(a:int, b:int, c:String):void
		{
			if(c == "test1")
			{
				test1times += 1;
				if(test1times > 10)
				{
					TimerManager.instance.removeTimer(test1ID);
					trace("remove test1ID : " + test1ID);
					return;
				}
			}
			trace(" testOnTimer : interval:" + a + " times:" + b + " name:" + c);
		}
		
		private function onEnterFrame(e:Event):void
		{
			TimerManager.instance.update();
		}

输出结果:

test1ID : 0
test2ID : 1
 testOnTimer : interval:1000 times:0 name:test1
 testOnTimer : interval:1000 times:0 name:test1
 testOnTimer : interval:2000 times:3 name:test22222
 testOnTimer : interval:1000 times:0 name:test1
 testOnTimer : interval:1000 times:0 name:test1
 testOnTimer : interval:2000 times:3 name:test22222
 testOnTimer : interval:1000 times:0 name:test1
 testOnTimer : interval:1000 times:0 name:test1
 testOnTimer : interval:2000 times:3 name:test22222
 testOnTimer : interval:1000 times:0 name:test1
 testOnTimer : interval:1000 times:0 name:test1
 testOnTimer : interval:1000 times:0 name:test1
 testOnTimer : interval:1000 times:0 name:test1
remove test1ID : 0


你可能感兴趣的:(AS3 TimerManager)