local watchdog = { m_ThreadsWaitOnTime = {}, -- [coroutine] = second m_ThreadsWaitOnSignal = {}, -- [signal] = {coroutines} m_Time = 0, Update = function(dog, dt) dog.m_Time = dog.m_Time + dt local threadsToWake = {} for co, wakeupTime in pairs(dog.m_ThreadsWaitOnTime) do if wakeupTime < dog.m_Time then dog.m_ThreadsWaitOnTime[co] = nil table.insert(threadsToWake, co) end end for _, co in pairs(threadsToWake) do coroutine.resume(co) end end , GetTime = function(dog) return dog.m_Time end , AddWaitOnTime = function(dog, co, sec) dog.m_ThreadsWaitOnTime[co] = sec end , AddWaitOnSignal = function(dog, co, cmd) dog.m_ThreadsWaitOnSignal[cmd] = dog.m_ThreadsWaitOnSignal[cmd] or {} table.insert(dog.m_ThreadsWaitOnSignal[cmd], co) end , Signal = function(dog, command) print("Signal " .. command) local thread = dog.m_ThreadsWaitOnSignal[command] if thread == nil then print("Invalid signal") return nil end dog.m_ThreadsWaitOnSignal[command] = nil for _, co in pairs(thread) do coroutine.resume(co) end end } local function wait(param) local co = coroutine.running() assert(co ~= nil, "the main coroutine cant wait") if type(param) == "number" then local wakeupTime = watchdog:GetTime() + param print("Wait " .. param .." Sec, until " .. string.format("%.2f", wakeupTime).. " Sec") watchdog:AddWaitOnTime(co, wakeupTime) return coroutine.yield() elseif type(param) == "string" then print("Wait Signal " .. param) watchdog:AddWaitOnSignal(co, param) return coroutine.yield() end end local function speaker() print("Speaker: Start") wait(2) --等2秒 print("Speaker: I'm speaker.") wait(2) --等2秒 print("Speaker: And I like game and programming.") wait(2) --等2秒 print("Speaker: Nice to meet you!") wait("kick") --等kick信号 print("Speaker: You hurt me!") wait("sorry") --等sorry信号 print("Speaker: That's ok.") end local signal = function(cmd) watchdog:Signal(cmd) end local command = "" local GetInput = function() if Kbhit() then local c = GetChar() if c == '\r' then signal(command) command = "" else print("Input: " .. c) command = command .. c end end end local function main() local pre = 0 local dt = 0 local co = coroutine.create(speaker) coroutine.resume(co) while true do local cur = GetTime() dt = cur - pre pre = cur local a = createObj() a = nil GetInput() watchdog:Update(dt) Sleep(0.016) end end xpcall(main, debug.traceback, 10)