Где (Ret) должен содержать значения, передаваемые Lua для передачи.
Luabind поддерживает только одиночные возвращаемые значения, поэтому он вернет только первое значение, переданное coroutine.yield
.
Что произойдет, если функция вернет, а не вызовет yield?Функция resume_function возвращает возвращаемое значение функции?
Да, вы получаете его возвращаемое значение.
Как вы должны использовать эту функцию, если не знаете заранеевремя, которое (или сколько) параметров будет передано для получения?Например, если существует несколько возможных функций выдачи, функция может вызвать эту функцию.
Это зависит от вас;это твои функции.Вы должны разработать соглашения о том, что приносящая функция (и) получает в качестве параметров, и что обеспечивает функция, возобновляющая сопрограмму.
Каков тип Ret, если несколько значений передаются в yield?
Что бы вы ни хотели.Это параметр шаблона.Количество параметров функции не имеет отношения к возвращаемым значениям, которые предоставляет функция.
Помните: функции Lua принимают любое количество параметров и могут возвращать что угодно.Все, что может сделать Luabind, - это передать заданные вами параметры и преобразовать возвращаемое значение из функций Lua в ожидаемое вами возвращаемое значение.Конечно же, Luabind выполнит проверку типа возвращаемого значения.Но вы несете ответственность за то, чтобы функции, возвращающие / возвращающие функции, возвращали что-то, что можно преобразовать в тип, предоставленный пользователем для Ret.
loadImage была бы функцией C ++, которая запрашивает изображение длязагружается в другой поток, а затем вызывает lua_yield, а через некоторое время luabind :: resume_function вызывается с параметром img.
Если вы используете Luabind, никогда не вызывайте lua_yield
напрямую.Правильный способ выхода в Luabind - это добавить в зарегистрированную вами функцию атрибут, который будет возвращаться всякий раз, когда вы возвращаетесь из функции.Синтаксис следующий:
module(L)
[
def("do_thing_that_takes_time", &do_thing_that_takes_time, yield)
];
То есть функция C ++, которая выдает, должна всегда давать.Это ограничение Luabind, так как с обычным Lua вы можете выбирать, уступать или нет, как считаете нужным.
Кроме того, не забывайте, что сопрограммы Lua - это не то же самое, что реальные потоки.Они не являются преимущественными;они будут только исполняться, когда вы явно скажете им с помощью coroutine.resume
или эквивалентного вызова возобновления.
Кроме того, вы никогда не должны запускать один и тот же экземпляр Lua из несколькихC / C ++ темы;Lua не является потокобезопасным в одном и том же экземпляре (что более или менее означает тот же объект lua_State).
То, что вы хотите сделать, это заставить Lua вызывать некоторую функцию в C ++, которая сама порождает поток для выполнениянекоторый процесс, затем заставьте код Lua дождаться завершения потока и затем получить ответ.
Чтобы сделать это, вам нужно предоставить сценарию Lua объект, представляющий поток C ++.Таким образом, ваша loadImage
функция не должна использовать логику сопрограммы;он должен вернуть объект, который представляет поток C ++.Скрипт Lua может спросить объект, завершен ли он, и если он есть, он может запросить данные из него.
Место, где сопрограммы могут вступить в игру, - это если вы не хотите, чтобы скрипт Luaподождите, пока это не закончится.То есть вы вызываете скрипт Lua очень часто, но если поток C ++ не завершен, он должен просто вернуться.В этом случае вы можете сделать что-то вроде этого:
function loadImageAsCoroutine(imageFilename)
local cppThread = cpp.loadImage(imageFilename);
local function threadFunc(cppThread)
if(cppThread:isFinished()) then
local data = cppThread:GetImage();
return data;
else
coroutine.yield();
end
end
local thread = coroutine.create(threadFunc);
local errors, data = assert(coroutine.resume(thread, cppThread));
if(coroutine.status(thread) == "dead") then
return data;
else
return thread;
end
end
Эта функция возвращает сопрограмму или сами данные изображения.Вызывающий эту функцию должен проверить тип;если тип "поток", то поток C ++ еще не закончен.В противном случае это данные изображения.
Вызывающий эту функцию может качать сопрограмму сколько угодно, с некоторым эквивалентом coroutine.resume
(будь то luabind :: resume_function или что-то еще). Каждый раз проверяйте возвращаемое значение. Это будет nil
, если поток C ++ еще не завершен, и не nil
в противном случае.