Я использую сопрограммы 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
. Можете ли вы упростить свой код, чтобы показать взаимодействие с остальной частью вашего приложения? - person Paul Kulchenko   schedule 20.01.2013