1 local co_time_tbl = {} 2 setmetatable(co_time_tbl, { __len = function(o) 3 local count = 0 4 for k, v in pairs(o) do 5 count = count + 1 6 end 7 return count 8 end 9 }) 10 11 local function isWindows() 12 return package.config:sub(1, 1) == "\\" 13 end 14 15 local function sleep(n) 16 if isWindows() then 17 if n > 0 then 18 os.execute("ping -n " .. tonumber(n + 1) .. " localhost > NUL") 19 end 20 else 21 os.execute("sleep " .. tonumber(n)) 22 end 23 end 24 25 local function Update(deltaTime) 26 -- main loop 27 end 28 29 local function updateCoroutine() 30 local iTime = os.time() 31 for kco, vTime in pairs(co_time_tbl) do 32 if iTime >= vTime then 33 if coroutine.status(kco) == "suspended" or coroutine.status(kco) == "normal" then 34 coroutine.resume(kco) 35 elseif coroutine.status(kco) == "dead" then 36 co_time_tbl[kco] = nil 37 end 38 end 39 end 40 end 41 42 function coroutine.waitforSeconds(second) 43 assert(type(second) == "number" or second <= 0) 44 local iEndTime = os.time() + second 45 local co = coroutine.running() 46 if co then 47 co_time_tbl[co] = iEndTime 48 return coroutine.yield() 49 end 50 end 51 52 local function main() 53 local co1 = coroutine.wrap(function() 54 coroutine.waitforSeconds(5) 55 print("after 5 seconds") 56 end) 57 local co2 = coroutine.wrap(function() 58 coroutine.waitforSeconds(4) 59 print("after 4 seconds") 60 end) 61 local co3 = coroutine.wrap(function() 62 coroutine.waitforSeconds(3) 63 print("after 3 seconds") 64 end) 65 local count = 0 66 local co4 = coroutine.wrap(function() 67 while (true) do 68 coroutine.waitforSeconds(1) 69 count = count + 1 70 print("coroutine num: " .. #co_time_tbl .. " | second count:" .. count) 71 end 72 end) 73 co1() 74 co2() 75 co3() 76 co4() 77 while true do 78 sleep(0.033) 79 Update() 80 updateCoroutine() 81 end 82 end 83 84 main()
In fact, the idea is to maintain coroutine time to wait with a table, update timer after the main loop, according to coroutines wake-up time will hang on the line