---@class MsgLoop local MsgLoop = {} MsgLoop.__cname = "MsgLoop" MsgLoop.__index = MsgLoop function MsgLoop.new(maxRunSec) local inst = {} setmetatable(inst, MsgLoop) inst:ctor(maxRunSec) return inst end function MsgLoop:ctor(maxRunSec) self.m_MsgQueue = {} self.m_MaxRunSec = maxRunSec or 0 end ---@param callback fun(data:any) ---@param dur number ---@param data any function MsgLoop:PostRun(callback, dur, data) local now = os.time() local msg = { startTime = now, endTime = now + dur, cb = callback, data = data, } table.insert(self.m_MsgQueue, msg) end ---開始訊息迴圈, 執行後, 執行緒將阻塞 function MsgLoop:StartLoop() local startTime = os.time() while true do local now = os.time() if self.m_MaxRunSec > 0 and now - startTime >= self.m_MaxRunSec then break end local cnt = #self.m_MsgQueue local i = 1 while i <= cnt do local loopItem = self.m_MsgQueue[i] local leftTime = loopItem.endTime - now if leftTime <= 0 then loopItem.cb(loopItem.data) table.remove(self.m_MsgQueue, i) cnt = cnt - 1 else i = i + 1 end end os.execute("ping -n 2 localhost > NUL") --Windows下sleep暫停 --os.execute("sleep 0.1") -- Unix或Linux中sleep暫停 end print("Msg Loop Exit!", os.time() - startTime) end return MsgLoop
使用程式碼
---@type MsgLoop local MsgLoop = require("MsgLoop") local _MsgLoop = MsgLoop.new(60) _MsgLoop:PostRun(function(data) --2s後執行 end, 2, "TestData") --其他邏輯,都要放在StartLoop前,StartLoop啟動後,當前執行緒就在那裡阻塞了 _MsgLoop:StartLoop()