【发布时间】:2013-01-03 12:07:49
【问题描述】:
我正在使用 lua 协程 (lua 5.1) 为应用程序创建插件系统。我希望使用协程,以便插件可以像一个单独的应用程序一样运行,每个处理帧产生一次。插件程序通常遵循如下公式:
function Program(P)
-- setup --
NewDrawer(function()
-- this gets rendered in a window for this plugin program --
drawstuff(howeveryouwant)
end)
-- loop --
local continue = true
while continue do
-- frame by frame stuff excluding rendering (handled by NewDrawer) --
P = coroutine.yield()
end
end
每个插件在应用程序的主循环中每帧恢复一次。然后,当开始绘图时,每个插件都有一个单独的窗口,它会在其中执行传递给 NewDrawer 的函数。
类似这样的:
while MainContinue do
-- other stuff left out --
ExecutePluginFrames() -- all plugin coroutines resumed once
BeginRendering()
-- other stuff left out --
RenderPluginWindows() -- functions passed to NewDrawer called.
EndRendering()
end
但是我发现,每当渲染中发生错误时,这突然开始表现得很奇怪,并弄乱了我原本强大的错误处理系统。我花了一点时间来理解正在发生的事情,但似乎我期望在主线程的调用堆栈中的对 WIN:Draw() 的调用(因为它由主应用程序处理)实际上是导致隐式跳转到协程的调用堆栈。
最初的问题是程序突然关闭,没有有用的错误输出。然后在查看插件程序中定义的渲染函数的堆栈回溯后,我发现从主线程到窗口的 Draw 的所有内容都不存在,并且该 yield 在调用堆栈中。
似乎因为窗口是在线程和绘图函数中创建的,所以它们正在由该线程的调用堆栈处理,这是一个问题,因为这意味着它们在主线程中设置的 pcall 之外。
这会发生吗?它是 C 源代码中的错误/快捷方式的结果吗?我做错了什么或至少做得不够正确?有没有办法干净利落地处理?
【问题讨论】:
-
很难回答你的问题,因为你没有展示你如何打电话/恢复
Program。您能否简化代码以显示与应用程序其余部分的交互? -
添加了编辑,它在 RenderPluginWindows() 中似乎正在发生调用堆栈的隐式变化。
标签: error-handling lua callstack implicit coroutine