-- Tick工具,可用于简化一些需要临时tick的逻辑 GlobalTickTool = GlobalTickTool or {}; ---@class GlobalTickItem ---@generic T ---@field o T 代表函数拥有者 ---@field f fun(o:T, dt: float, st: float) 代表函数拥有者 ---@field e fun(o:T): bool 支持执行的函数 ---@field s float 表示开始的时间 --- 要执行的函数 GlobalTickTool.Functions = {}; GlobalTickTool.InternalTicks = {}; function GlobalTickTool:MakeHandle(o, f, ...) return tostring(o) .. '#' .. tostring(f); end --- 找到有哪些 Handle function GlobalTickTool:FindHandles(o) local Ret = {}; local o_Name = tostring(o); for i, v in pairs(self.Functions) do local SplitNum = string.find(i, '#') if SplitNum ~= nil then local Name = string.sub(i, SplitNum); if Name == o_Name then table.insert(Ret, i); end end end return Ret; end --- 是否可以添加 Tick function GlobalTickTool:CanAddTick(o, f, t) if type(f) ~= 'function' then return false; end return t[self:MakeHandle(o, f)] == nil; end --- 注册tick回调函数 ---@generic T ---@param o T ---@param f fun(o:T, dt: float, st: float) tick 函数 ---@param f1 fun(o:T): bool 是否要执行 tick ---@param c float 间隔时间 function GlobalTickTool:AddTick(o, f, c, f1) -- 说明当前存在了 if not self:CanAddTick(o, f, GlobalTickTool.Functions) then return; end if c == nil then c = 0; end GlobalTickTool.Functions[self:MakeHandle(o, f)] = { o = o, -- 执行的是谁的 f = f, -- 执行函数 s = 0, -- 开始时间 c = 0, -- 表示间隔时间 e = f1, -- 验证是否可以执行的函数 }; end function GlobalTickTool:RemoveTick(o, f) GlobalTickTool.Functions[self:MakeHandle(o, f)] = nil; end --- 添加间隔执行,执行多少次的逻辑 ---@generic T ---@param o T ---@param f fun(o:T, dt: float, st: float, t:int32) tick 函数 t:倒计时 ---@param i float 每次间隔时间 ---@param c int32 执行次数 ---@param lf fun(o: T) 结束的时候执行的函数 ---@param inf fun(o:T):bool 打断函数 function GlobalTickTool:AddInternalCount(o, f, i, c, lf, inf) if not self:CanAddTick(o, f, self.InternalTicks) then return; end if i <= 0 then i = 0 end if c == 0 then lf(o); else self.InternalTicks[self:MakeHandle(o, f)] = { o = o, f = f, s = 0, i = i, c = math.abs(c), inf = inf, l = lf, } end end function GlobalTickTool:UpdateInternalCount(o, f, c) GlobalTickTool.InternalTicks[self:MakeHandle(o, f)].c = c; end function GlobalTickTool:GetInternalCount(o, f) return GlobalTickTool.InternalTicks[self:MakeHandle(o, f)].c; end function GlobalTickTool:RemoveAll(o) local Ret = self:FindHandles(o) for i, v in pairs(Ret) do GlobalTickTool.Functions[v] = nil; end end --- 调用所有注册的回调函数,此函数需要在gamestate的tick里调用一下 ---@param dt float ---@param ServerTime float function GlobalTickTool:ReceiveTick(dt, ServerTime) for o, t in pairs(self.Functions) do if t.e == nil or t.e(t.o) then t.s = t.s + dt; if t.s >= t.c then t.s = t.s - t.c; t.f(t.o, dt, ServerTime); end end end for o, t in pairs(self.InternalTicks) do t.s = t.s + dt; if t.s >= t.i and t.c > 0 then t.s = t.s - t.i; t.c = t.c - 1; -- 次数 - 1 t.f(t.o, dt, ServerTime, t.c); if (t.c == 0) or (t.inf ~= nil and t.inf(t.o)) then -- 移除 if t.l ~= nil then t.l(t.o); end self.InternalTicks[o] = nil; end end end end return GlobalTickTool