UGCProjects/InfFire/Script/Global/Tool/GlobalTickTool.lua
2025-01-04 23:00:19 +08:00

153 lines
3.9 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 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