UGCProjects/InfFire/Script/Global/Tool/GlobalTickTool.lua

153 lines
3.9 KiB
Lua
Raw Permalink Normal View History

2025-01-04 23:00:19 +08:00
-- 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' 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 f1 fun(o:T):bool 是否要执行 tick 可选
---@param l float 时限,可选
---@param lf fun(o:T) 是否要执行 tick可选
function GlobalTickTool:AddTick(o, f, i, f1, l, lf, info)
-- 说明当前存在了
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 and lf ~= nil then
-- 立刻执行
lf(o)
return false;
end
self.Functions[self:MakeHandle(o, f)] = {
o = o, -- 执行的是谁的
f = f, -- 执行函数
s = 0, -- 开始时间
c = i, -- 表示间隔时间
e = f1, -- 验证是否可以执行的函数
t = 0, -- 总计时
l = l, -- 时限
lf = lf, -- 时限结束执行函数
info = info, -- 提示信息
};
return true;
end
function GlobalTickTool:RemoveTick(o, f)
self.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)
self.InternalTicks[self:MakeHandle(o, f)].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.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;
t.f(t.o, dt, st);
if t.l ~= nil and t.t >= t.l then
t.l = nil;
if type(t.lf) == 'function' then t.lf(t.o); end
self.Functions[o] = nil; -- 删除
end
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, st, 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