local TimerStatus = require("GameCore.Timer.TimerStatus") local TimerResetType = require("GameCore.Timer.TimerResetType") local TimerScaleType = require("GameCore.Timer.TimerScaleType") local Time = CS.UnityEngine.Time local Timer = class("Timer") function Timer:ctor(mapParam) if mapParam.bAutoRun == true or mapParam.bAutoRun == nil then self._status = TimerStatus.Running else self._status = TimerStatus.ReadyToGo end self._nCreateTS = mapParam.nTs self._nTS = mapParam.nTs self._nPauseTS = 0 self._bDestroyWhenComplete = mapParam.bDestroyWhenComplete self._nCurCount = 0 self._nTargetCount = mapParam.nTargetCount self._nElapsed = 0 self._nInterval = mapParam.nInterval self._nScaleType = mapParam.nScaleType self._data = mapParam.data self._listener = mapParam.listener self._callback = mapParam.callback self._nDelCountLimit = 10 self._nRate = 1 self._nRange = 0 self._bDebugWatch = false end function Timer:_Run(nCurTS) if type(self._nInterval) ~= "number" or self._nInterval <= 0 or self._callback == nil then self:Cancel(false) return end if self._status ~= TimerStatus.Running then return end self._nElapsed = self._nElapsed + (nCurTS - self._nTS) self._nTS = nCurTS local nInterval = self._nInterval / self._nRate if nInterval > self._nElapsed then local nRemain = nInterval - self._nElapsed if 60 < nRemain then self._nRange = 2 elseif 1 < nRemain then self._nRange = 1 else self._nRange = 0 end return end local nDelCount = math.floor(self._nElapsed / nInterval) self._nElapsed = self._nElapsed - nDelCount * nInterval if 0 >= self._nTargetCount then self:_DoCallback() else if self._nCurCount + nDelCount >= self._nTargetCount then nDelCount = self._nTargetCount - self._nCurCount self._nCurCount = self._nTargetCount self:_Stop() self._nElapsed = 0 else self._nCurCount = self._nCurCount + nDelCount end if nDelCount >= self._nDelCountLimit then nDelCount = 1 end for i = 1, nDelCount do self:_DoCallback() end end end function Timer:_Stop() if self._bDestroyWhenComplete == true then self._status = TimerStatus.Destroy else self._status = TimerStatus.Complete end end function Timer:_ResetTimeStamp(bIsPauseTS) local TimerManager = require("GameCore.Timer.TimerManager") if bIsPauseTS == true then if self._nScaleType == TimerScaleType.None then self._nPauseTS = Time.time elseif self._nScaleType == TimerScaleType.Unscaled then self._nPauseTS = TimerManager.GetUnscaledTime() elseif self._nScaleType == TimerScaleType.RealTime then self._nPauseTS = Time.realtimeSinceStartup end else if self._nScaleType == TimerScaleType.None then self._nTS = Time.time elseif self._nScaleType == TimerScaleType.Unscaled then self._nTS = TimerManager.GetUnscaledTime() elseif self._nScaleType == TimerScaleType.RealTime then self._nTS = Time.realtimeSinceStartup end self._nCreateTS = self._nTS end end function Timer:_DoCallback() if self._listener == nil then self._callback(self, self._data) else self._callback(self._listener, self, self._data) end end function Timer:Pause(bSetPause) self._nRange = 0 if type(bSetPause) ~= "boolean" then bSetPause = true end if bSetPause == true and self._status == TimerStatus.Running then self:_ResetTimeStamp(true) self._status = TimerStatus.Pause elseif bSetPause == false then if self._status == TimerStatus.Pause then local TimerManager = require("GameCore.Timer.TimerManager") if self._nScaleType == TimerScaleType.None then self._nTS = self._nTS + (Time.time - self._nPauseTS) elseif self._nScaleType == TimerScaleType.Unscaled then self._nTS = self._nTS + (TimerManager.GetUnscaledTime() - self._nPauseTS) elseif self._nScaleType == TimerScaleType.RealTime then self._nTS = self._nTS + (Time.realtimeSinceStartup - self._nPauseTS) end self._nPauseTS = 0 self._status = TimerStatus.Running elseif self._status == TimerStatus.ReadyToGo then self:_ResetTimeStamp(false) self._status = TimerStatus.Running end end end function Timer:Cancel(bInvokeCallback) self._status = TimerStatus.Destroy if bInvokeCallback == true and self._listener ~= nil and self._callback ~= nil then self:_DoCallback() end end function Timer:Reset(nResetType, nNewInterval) self._nRange = 0 if self._status == TimerStatus.Destroy then return end if nResetType == nil then nResetType = TimerResetType.ResetAll end if nResetType == TimerResetType.ResetAll then self._status = TimerStatus.Running self._nCurCount = 0 self._nElapsed = 0 self._nPauseTS = 0 self:_ResetTimeStamp(false) elseif nResetType == TimerResetType.ResetCount then self._nCurCount = 0 elseif nResetType == TimerResetType.ResetElapsed then self._nElapsed = 0 self._nPauseTS = 0 self:_ResetTimeStamp(false) end if type(nNewInterval) == "number" then self._nInterval = nNewInterval end end function Timer:GetRemainInterval() if self._status == TimerStatus.Running then local TimerManager = require("GameCore.Timer.TimerManager") if self._nScaleType == TimerScaleType.None then return self._nInterval - (self._nElapsed + Time.time - self._nTS) elseif self._nScaleType == TimerScaleType.Unscaled then return self._nInterval - (self._nElapsed + TimerManager.GetUnscaledTime() - self._nTS) elseif self._nScaleType == TimerScaleType.RealTime then return self._nInterval - (self._nElapsed + Time.realtimeSinceStartup - self._nTS) end elseif self._status == TimerStatus.Pause then return self._nInterval - (self._nElapsed + self._nPauseTS - self._nTS) else return 0 end end function Timer:GetRenmainTime() local nTotalTime = self._nTargetCount * self._nInterval local nPassedTime = self._nInterval * self._nCurCount + self._nElapsed if self._status == TimerStatus.Running then local TimerManager = require("GameCore.Timer.TimerManager") if self._nScaleType == TimerScaleType.None then nPassedTime = nPassedTime + (Time.time - self._nTS) elseif self._nScaleType == TimerScaleType.Unscaled then nPassedTime = nPassedTime + (TimerManager.GetUnscaledTime() - self._nTS) elseif self._nScaleType == TimerScaleType.RealTime then nPassedTime = nPassedTime + (Time.realtimeSinceStartup - self._nTS) end return nTotalTime - nPassedTime elseif self._status == TimerStatus.Pause then nPassedTime = nPassedTime + (self._nPauseTS - self._nTS) return nTotalTime - nPassedTime else return 0 end end function Timer:GetDelTS() return self._nTS - self._nCreateTS end function Timer:GetCreateTS() return self._nCreateTS end function Timer:GetCurTS() return self._nTS end function Timer:GetCurCount() return self._nCurCount end function Timer:SetSpeed(rate) if rate <= 0 then return end self._nRate = rate self._nRange = 0 end function Timer:IsUnused() return self._status == TimerStatus.Destroy end function Timer:PrintSelf() local tb = { ["状态"] = self._status, ["创建时间"] = self._nCreateTS, ["时间戳"] = self._nTS, ["暂停时间戳"] = self._nPauseTS, ["完成时销毁"] = self._bDestroyWhenComplete, ["已触发次数"] = self._nCurCount, ["目标触发次数"] = self._nTargetCount, ["已流逝"] = self._nElapsed, ["触发间隔"] = self._nInterval, ["缩放类型"] = self._nScaleType, ["一帧里触发极限次数"] = self._nDelCountLimit, ["速率"] = self._nRate, ["精度"] = self._nRange, ["监视"] = self._bDebugWatch } printTable(tb) end return Timer