miduo_client/Assets/ManagedResources/~Lua/System/coroutine.lua

155 lines
3.1 KiB
Lua

--------------------------------------------------------------------------------
-- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com
-- All rights reserved.
-- Use, modification and distribution are subject to the "MIT License"
--------------------------------------------------------------------------------
local create = coroutine.create
local running = coroutine.running
local resume = coroutine.resume
local yield = coroutine.yield
local error = error
local unpack = unpack
local debug = debug
local FrameTimer = FrameTimer
local CoTimer = CoTimer
local comap = {}
local pool = {}
setmetatable(comap, {__mode = "kv"})
function coroutine.start(f, ...)
local co = create(f)
if running() == nil then
local flag, msg = resume(co, ...)
if not flag then
error(debug.traceback(co, msg))
end
else
local args = {...}
local timer = nil
local action = function()
comap[co] = nil
timer.func = nil
local flag, msg = resume(co, unpack(args, 1, table.maxn(args)))
table.insert(pool, timer)
if not flag then
timer:Stop()
error(debug.traceback(co, msg))
end
end
if #pool > 0 then
timer = table.remove(pool)
timer:Reset(action, 0, 1)
else
timer = FrameTimer.New(action, 0, 1)
end
comap[co] = timer
timer:Start()
end
return co
end
function coroutine.wait(t, co, ...)
local args = {...}
co = co or running()
local timer = nil
local action = function()
comap[co] = nil
timer.func = nil
local flag, msg = resume(co, unpack(args, 1, table.maxn(args)))
if not flag then
timer:Stop()
error(debug.traceback(co, msg))
return
end
end
timer = CoTimer.New(action, t, 1)
comap[co] = timer
timer:Start()
return yield()
end
function coroutine.step(t, co, ...)
local args = {...}
co = co or running()
local timer = nil
local action = function()
comap[co] = nil
timer.func = nil
local flag, msg = resume(co, unpack(args, 1, table.maxn(args)))
table.insert(pool, timer)
if not flag then
timer:Stop()
error(debug.traceback(co, msg))
return
end
end
if #pool > 0 then
timer = table.remove(pool)
timer:Reset(action, t or 1, 1)
else
timer = FrameTimer.New(action, t or 1, 1)
end
comap[co] = timer
timer:Start()
return yield()
end
function coroutine.www(www, co)
co = co or running()
local timer = nil
local action = function()
if www.error then
LogError("www.error:"..www.error)
elseif not www.isDone then
return
end
comap[co] = nil
timer:Stop()
timer.func = nil
local flag, msg = resume(co)
table.insert(pool, timer)
if not flag then
error(debug.traceback(co, msg))
return
end
end
if #pool > 0 then
timer = table.remove(pool)
timer:Reset(action, 1, -1)
else
timer = FrameTimer.New(action, 1, -1)
end
comap[co] = timer
timer:Start()
return yield()
end
function coroutine.stop(co)
local timer = comap[co]
if timer ~= nil then
comap[co] = nil
timer:Stop()
timer.func = nil
end
end