--[[ -- added by wsh @ 2017-12-19 -- 协程模块:对Lua协程conroutine进行扩展,使其具有Unity侧协程的特性 -- 注意: -- 1、主线程使用coroutine.start启动协程,协程启动以后,首次挂起时主线程继续往下执行,这里和Unity侧表现是一致的 -- 2、协程里可以再次使用coroutine.start启动协程,和在Unity侧协程中使用StartCoroutine表现一致 -- 3、协程里启动子级协程并等待其执行完毕,在Unity侧是yield return StartCoroutine,但是在Lua不需要另外启动协程,直接调用函数即可 -- 4、如果lua侧协程不使用本脚本的扩展函数,则无法实现分帧;lua侧启动协程以后不管协程函数调用栈多深,不管使用多少次本脚本扩展函数,都运行在一个协程 -- 5、使用coroutine.waitforframes(1)来等待一帧,千万不要用coroutine.yield,否则整个协程将永远不被唤醒===>***很重要,除非你在其它地方手动唤醒它 -- 6、子级协同在lua侧等同于普通函数调用,和普通函数一样可在退出函数时带任意返回值,而Unity侧协同不能获取子级协同退出时的返回值 -- 7、理论上任何协同都可以用回调方式去做,但是对于异步操作,回调方式也需要每帧去检测异步操作是否完成,消耗相差不多,而使用协同可以简单很多,清晰很多 -- 8、协程所有等待时间的操作,如coroutine.waitforseconds误差由帧率决定,循环等待时有累积误差,所以最好只是用于分帧,或者等待异步操作 -- 9、yieldstart、yieldreturn、yieldbreak实际上是用lua不对称协程实现对称协同,使用方式和Unity侧协同类似,注意点看相关函数头说明 -- TODO: -- 1、CS侧做可视化调试器,方便单步查看各个协程运行状态 --]] -- 协程内部使用定时器实现,定时器是weak表,所以这里必须缓存Action,否则会被GC回收 local action_map = {} -- action缓存池 local action_pool = {} -- 用于子级协程yieldreturn时寻找父级协程 local yield_map = {} -- 协程数据缓存池 local yield_pool = {} -- 协程缓存池 local co_pool = {} -- 回收协程 local function __RecycleCoroutine(co) if not coroutine.status(co) == "suspended" then error("Try to recycle coroutine not suspended : "..coroutine.status(co)) end table.insert(co_pool, co) end -- 可复用协程 local function __Coroutine(func, ...) local args = SafePack(...) while func do local ret = SafePack(func(SafeUnpack(args))) __RecycleCoroutine(coroutine.running()) args = SafePack(coroutine.yield(SafeUnpack(ret))) func = args[1] table.remove(args, 1) end end -- 获取协程 local function __GetCoroutine() local co = nil if table.length(co_pool) > 0 then co = table.remove(co_pool) else co = coroutine.create(__Coroutine) end return co end -- 回收Action local function __RecycleAction(action) action.co = false action.timer = false action.func = false action.args = false action.result = false table.insert(action_pool, action) end -- 获取Action local function __GetAction(co, timer, func, args, result) local action = nil if table.length(action_pool) > 0 then action = table.remove(action_pool) else action = {false, false, false,
coroutine 携程与定时一起混用
最新推荐文章于 2022-12-29 18:16:27 发布
这段代码提供了一种在Lua中扩展协程(coroutine)的方法,使其具备Unity协程的特性。实现了协程的启动、等待一帧、等待固定时间、等待异步操作完成等功能,通过定时器实现。同时,代码中包含了一些特殊注意事项,如避免使用coroutine.yield,使用特定的waitforframes等待一帧等。
摘要由CSDN通过智能技术生成