備忘録

プログラムやゲーム関連に関すること

【Lua】C++環境からコルーチンを実行する

test.cpp

#include <iostream>
#include <lua.hpp>

void testCoroutine()
{
	// Luaステートを生成する
	auto L = luaL_newstate();

	// Luaステートに全てのライブラリを使用可能にする
	// 個別でライブラリを使用可能にするには luaL_requiref 関数を参照
	luaL_openlibs(L);

	// Luaファイルをロードして実行することで
	// Luaステートに関数をスタック可能にする
	if (luaL_dofile(L, "coroutine.lua"))
	{
		std::cout << lua_tostring(L, lua_gettop(L)) << std::endl;
		lua_close(L);
		return;
	}

	// Luaステートのスレッドを生成する
	// 生成されたスレッドはグローバル環境(変数・関数)を元のスレッドと
	// 共有するが、独立した実行スタックを持つ(重要)
	// 生成したスレッドはガベージコレクションの対象なので
	// 明示的に破棄する必要はない(破棄する関数はない)
	auto T = lua_newthread(L);

	// スレッドに関数をスタックする
	lua_getglobal(T, "func");

	// コルーチンを実行して戻り値を表示する
	// lua_resumeの第2引数は第1引数の処理を再開させる側のコルーチンを表す
	while (lua_resume(T, nullptr, 0))
	{
		std::cout << lua_tostring(T, lua_gettop(T)) << std::endl;
		getchar(); // 入力待ち用
	}

	// Luaステートを破棄する
	lua_close(L);
}

int main(int argc, char* argv[])
{
	testCoroutine(); // 入力ごとに、A, B, C と表示される

	return 0;
}

coroutine.lua

function func()
	coroutine.yield("A")
	coroutine.yield("B")
	coroutine.yield("C")
end