-- 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.LimitFunctions = {}; 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' or type(f) == 'nil' 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 i float interval 间隔时间,可选 ---@param ef fun(o:T):bool 是否要执行 tick, 可选 ---@param l float 时限,可选 ---@param lf fun(o:T) 是否要执行 tick,可选 function GlobalTickTool:AddTick(o, f, i, ef, l, lf) -- 说明当前存在了 if not self:CanAddTick(o, f, self.Functions) then return false; end if i == nil then i = 0; end if l ~= nil and l <= 0 then -- 立刻执行 lf(o) return nil; end local Handle = self:MakeHandle(o, f); self.Functions[Handle] = { o = o, -- 执行的是谁的 f = f, -- 执行函数 s = 0, -- 开始时间 c = i, -- 表示间隔时间 e = ef, -- 验证是否可以执行的函数 t = 0, -- 总计时 l = l, -- 时限 lf = lf, -- 时限结束执行函数 }; return Handle; end function GlobalTickTool:Delay(o, f, t) end function GlobalTickTool:RemoveTick(o, f) self.Functions[self:MakeHandle(o, f)] = nil; end function GlobalTickTool:RemoveTickByHandle(Handle) if Handle == nil then return ; end self.Functions[Handle] = nil; self.InternalTicks[Handle] = nil; end function GlobalTickTool:RemoveTickByOwner(InOwner) if InOwner == nil then return ; end local NeedRemoveTable = {}; local Name = tostring(InOwner) local NameLen = string.len(Name); for i, v in pairs(self.Functions) do if string.sub(i, 1, NameLen) == Name then table.insert(NeedRemoveTable, i); end end for i, v in pairs(NeedRemoveTable) do self.Functions[v] = nil; end 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 local Handle = self:MakeHandle(o, f); self.InternalTicks[Handle] = { o = o, f = f, s = 0, i = i, c = math.abs(c), inf = inf, l = lf, }; return Handle; end end function GlobalTickTool:UpdateInternalCount(o, f, c) local Handle = self:MakeHandle(o, f); if self.InternalTicks[Handle] then self.InternalTicks[self:MakeHandle(o, f)].c = c; else UGCLogSystem.Log("[GlobalTickTool:UpdateInternalCount] 不存在") end end function GlobalTickTool:UpdateInternalCountByHandle(Handle, c) self.InternalTicks[Handle].c = c; end function GlobalTickTool:GetInternalCount(o, f) return self.InternalTicks[self:MakeHandle(o, f)].c; end function GlobalTickTool:RemoveAll(o) local Ret = self:FindHandles(o) for i, v in pairs(Ret) do self.Functions[v] = nil; end end --- 调用所有注册的回调函数,此函数需要在gamestate的tick里调用一下 ---@param dt float ---@param st float function GlobalTickTool:ReceiveTick(dt, st) if st == nil then return ; end for o, t in pairs(self.Functions) do if t.o ~= nil then if t.e == nil or t.e(t.o) then t.s = t.s + dt; t.t = t.t + dt; if t.s >= t.c then t.s = t.s - t.c; if type(t.f) == 'function' then t.f(t.o, dt, st); end if t.l ~= nil and t.t >= t.l then t.l = nil; if type(t.lf) == 'function' then t.lf(t.o); t.lf = nil; t.l = nil; end self.Functions[o] = nil; -- 删除 end end end else self.Functions[o] = nil; end end for o, t in pairs(self.InternalTicks) do t.s = t.s + dt; if t.o ~= nil then if t.s >= t.i and t.c > 0 then t.s = t.s - t.i; t.c = t.c - 1; -- 次数 - 1 if type(t.f) == 'function' then t.f(t.o, dt, st, t.c); end 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 else self.InternalTicks[o] = nil; end end end return GlobalTickTool