2025-01-04 23:00:19 +08:00

106 lines
2.5 KiB
Lua

local TaskQueue = {};
---@class TaskQueueItem
---@field Time float 间隔时间会执行下一个
---@field InFunc fun(InOwner:table) 进入该状态函数
---@field TickFunc fun(InOwner:table, dt:float, st: float) 区间 Tick 函数
---@field OutFunc fun(InOwner:table) 离开区间函数
---@type TaskQueueItem[]
TaskQueue.Config = {};
TaskQueue.Owner = nil;
--- 默认不循环
TaskQueue.IsRecycle = false;
---@param Config TaskQueueItem[]
function TaskQueue:new(Config, Owner)
return setmetatable(
{
Config = Config,
Owner = Owner,
}, {
__index = self,
__metatable = self,
});
end
--- 启动
---@param IsCycle bool 是否循环
function TaskQueue:Start(IsCycle)
self.IsRecycle = IsCycle;
self:Reset();
end
TaskQueue.StartStopTime = 0;
--- 停止队列
function TaskQueue:Stop()
-- 暂停
self.StartStopTime = UE.GetServerTime();
GlobalTickTool:RemoveTickByOwner(self);
end
--- 暂停之后重新开始
function TaskQueue:Restart()
--- 如果没有开启过重置,那么就无法继续执行
if self.StartStopTime == 0 then return; end
local Time = UE.GetServerTime() - self.StartStopTime;
self.ExecEndTime = Time + self.ExecEndTime;
-- 开启 Tick
GlobalTickTool:AddTick(self, self.OnTick);
end
--- 重置
function TaskQueue:Reset()
self.CurrIndex = 1;
self:OneRound();
end
--- 当前正在执行的索引
TaskQueue.CurrIndex = 0;
--- 从开始的执行时间
TaskQueue.ExecStartTime = 0;
TaskQueue.ExecEndTime = 0;
--- 一次循环
function TaskQueue:OneRound()
local ConfigItem = self.Config[self.CurrIndex]
GlobalTickTool:RemoveTickByOwner(self);
self.ExecStartTime = UE.GetServerTime();
if ConfigItem == nil then return; end
-- 开始执行第一个函数
if ConfigItem.InFunc then
ConfigItem.InFunc(self.Owner);
end
-- 开启 Tick
GlobalTickTool:AddTick(self, self.OnTick);
self.ExecEndTime = self.ExecStartTime + ConfigItem.Time;
end
function TaskQueue:OnTick(dt, st)
local Item = self.Config[self.CurrIndex];
if Item == nil then return; end
if Item.TickFunc then
Item.TickFunc(self.Owner, dt, st);
end
if st >= self.ExecEndTime then
-- 直接结束
GlobalTickTool:RemoveTickByOwner(self);
if Item.OutFunc then
Item.OutFunc(self.Owner);
end
self.CurrIndex = self.CurrIndex + 1;
if self.Config[self.CurrIndex] == nil then
-- 这是最后一个了
self.CurrIndex = 1;
-- 如果循环,那么继续开启
if self.IsRecycle then
-- 下一轮回
self:OneRound();
end
end
end
end
return TaskQueue;