私はluaコルーチン(lua 5.1)を使用して、アプリケーションのプラグインシステムを作成しています。プラグインが処理フレームごとに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
各プラグインは、フレームごとに1回、アプリケーションのメインループで再開されます。次に、描画が開始されると、各プラグインには、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()の呼び出し(メインアプリケーションによって処理されるため)が実際に原因であったようですコルーチンのコールスタックへの暗黙のジャンプ。
最初の問題は、プログラムが突然終了し、有用なエラー出力がないことでした。次に、プラグインプログラムで定義されたレンダリング関数のスタックトレースバックを調べた後、メインスレッドからウィンドウの描画に至るまでのすべてがそこになく、そのyieldが呼び出しスタックにあることがわかりました。
ウィンドウはスレッドと描画関数で作成されたため、そのスレッドの呼び出しスタックによって処理されているようです。これは、メインスレッドで設定されたpcallの外部にあることを意味するため問題です。
これは起こると思いますか?それはCソースのバグ/ショートカットの結果ですか?私は何か間違ったことをしているのですか、それとも少なくとも正しくは不十分ですか?これをきれいに処理する方法はありますか?