ここで、(Ret)には、Luaによってyieldに渡された値が含まれているはずです。
Luabindは単一の戻り値のみをサポートするため、に渡された最初の値のみを返しますcoroutine.yield
。
関数がyieldを呼び出すのではなく戻るとどうなりますか?resume_functionは関数の戻り値を返しますか?
はい、戻り値を取得します。
どの(またはいくつの)パラメーターが渡されて生成されるかが事前にわからない場合、この関数をどのように使用することになっていますか?たとえば、複数の可能な降伏関数がある場合、関数は呼び出すことができます。
それはあなた次第です; それらはあなたの機能です。降伏関数がパラメーターとして受け取るもの、およびコルーチンを再開する関数が提供するものについての規則を作成する必要があります。
複数の値がyieldに渡される場合、Retのタイプは何ですか?
あなたが望むものは何でも。これはテンプレートパラメータです。関数のパラメーターの数は、関数が提供する戻り値とは関係ありません。
注意:Lua関数は任意の数のパラメーターを取り、何でも返すことができます。Luabindが実行できるのは、指定したパラメーターを渡し、Lua関数からの戻り値を期待どおりの値に変換することだけです。もちろん、Luabindは戻り値の型チェックを行います。ただし、yielding/returning関数がユーザーがRetに提供するタイプに変換可能なものを返すことを確認するのはあなたの責任です。
loadImageは、画像を別のスレッドにロードするように要求してからlua_yieldを呼び出すC ++関数であり、しばらくすると、パラメーターとしてimgを使用してluabind::resume_functionが呼び出されます。
Luabindを使用している場合は、lua_yield
直接電話しないでください。Luabindでyieldを実行する適切な方法は、登録した関数に属性を追加することです。この属性は、関数から戻るたびに生成されます。構文は次のとおりです。
module(L)
[
def("do_thing_that_takes_time", &do_thing_that_takes_time, yield)
];
つまり、yieldを生成するC ++関数は、常にyieldでなければなりません。これはLuabindの制限であり、通常のLuaと同様に、適切と思われる場合に降伏するかどうかを選択できます。
また、Luaコルーチンは実際のスレッドと同じものではないことを忘れないでください。それらは先制的ではありません。それらは、withまたは同等のresume呼び出しを明示的に指示した場合にのみ実行されます。coroutine.resume
また、複数のC /C++スレッドから同じLuaインスタンスを実行しないでください。Luaは同じインスタンス内でスレッドセーフではありません(これは多かれ少なかれ同じlua_Stateオブジェクトを意味します)。
あなたがやりたいと思われるのは、LuaにC ++の関数を呼び出させ、それ自体がスレッドを生成してプロセスを実行し、そのスレッドが完了するまでLuaコードを待機させてから応答を受け取ることです。
そのためには、C++スレッドを表すオブジェクトをLuaスクリプトに与える必要があります。したがって、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
。