const CallType = cc.Enum( { Once: 1, NextFrame: 2, Default: 3 }); let CTimerHelp = cc.Class({ statics: { instance: null }, ctor: function () { this.m_evtArray = []; this.m_timeIDLabor = 1; }, // 延迟执行一次 // cb : ( usrData?: any ) => void // return [TimerID] pushOnce : function ( timeDelay, cb, owner, usrData ) { let item = { ID : this.m_timeIDLabor++, Type : CallType.Once, TimeDelay : timeDelay, TimeLabor : 0, LateTouched : false, CallLabor : 0, CallBack : cb, Owner : owner, UsrData : usrData }; this.m_evtArray.push( item ); return item.ID; }, // 下一帧执行一次 // cb : ( usrData?: any ) => void // return [TimerID] pushNextFrame : function ( cb, owner, usrData ) { let item = { ID : this.m_timeIDLabor++, Type : CallType.NextFrame, LateTouched : false, CallBack : cb, Owner : owner, UsrData : usrData }; this.m_evtArray.push( item ); return item.ID; }, // 在timeTotal时间范围内,每帧都回调一次( -1 为永久,注意不用的时候需要手动关闭!!) // 函数参数说明:timeTotal 总时间(有效时长); callDelta 调用间隔,默认为0 // CallBack Params : ( timeElapsed:number, endCall:boolean, usrData?: any ) => void // Param0 Time Elapsed // Param1 endCall 是否最后一次调用 // Param2 UsrData // return [TimerID] push : function( timeTotal, callDelta, cb, owner, usrData ) { let item = { ID : this.m_timeIDLabor++, Type : CallType.Default, TimeTotal : timeTotal, TimeLabor : 0, CallDelta : callDelta, TimeLastCall : 0, LateTouched : false, CallLabor : 0, CallBack : cb, Owner : owner, UsrData : usrData }; this.m_evtArray.push( item ); return item.ID; }, // 提前结束一个事件 /** * @return {boolean} */ stop : function ( timerID ) { for ( let lCnt = 0; lCnt < this.m_evtArray.length; ++lCnt ) { if ( this.m_evtArray[ lCnt ].ID === timerID ) { this.m_evtArray[ lCnt ].CallBack = undefined; return true; } } return false; }, onUpdate : function( dt ) { for ( let lCnt = 0; lCnt < this.m_evtArray.length; ++lCnt ) { let item = this.m_evtArray[ lCnt ]; if ( item.LateTouched && item.CallBack ) { let ifDied = false; if ( CallType.NextFrame === item.Type ) { ifDied = true; item.CallBack.call( item.Owner, item.UsrData ); } else { item.TimeLabor += dt; if ( CallType.Once === item.Type ) { if ( item.TimeDelay <= item.TimeLabor && 0 === item.CallLabor ) { ifDied = true; item.CallLabor = 1; item.CallBack.call( item.Owner, item.UsrData ); } } else // Default { if ( 0 < item.TimeTotal && item.TimeTotal <= item.TimeLabor ) { ifDied = true; } item.TimeLastCall += dt; if ( item.CallDelta <= item.TimeLastCall || ifDied ) { item.TimeLastCall = 0; item.CallLabor += 1; item.CallBack.call( item.Owner, item.TimeLabor, ifDied, item.UsrData ); } } } if ( ifDied ) { item.CallBack = undefined; item.Owner = undefined; } } } }, onLateUpdate: function () { for ( let lCnt = 0; lCnt < this.m_evtArray.length; ) { let item = this.m_evtArray[ lCnt ]; if ( ! item || undefined === item.CallBack ) { item.Owner = undefined; item.UsrData = undefined; this.m_evtArray.splice( lCnt, 1 ); } else { if ( ! item.LateTouched ) { item.LateTouched = true; } ++lCnt; } } }, }); CTimerHelp.getInstance = function () { if (!CTimerHelp.instance) { CTimerHelp.instance = new CTimerHelp(); } return CTimerHelp.instance; } module.exports = CTimerHelp;