用Lua的协程实现类似Unity协程的语句块
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()
思路其实就是用一张表维护协程要等待的时间,在主循环之后更新计时器,根据时间将挂起的协程唤醒就行