这是我的设置的总体流程:
void ScriptPlayer::new_lua_state() {
lua = {};
lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::coroutine, sol::lib::math);
[...]
// Proceeds to initialize the state with usertype definitions and values
}
void ScriptPlayer::play(std::string path) {
main_coroutine = sol::nil;
script_env = sol::environment(lua, sol::create, lua.globals());
auto result = lua.load_file(path);
main_coroutine = sol::coroutine(result);
script_env.set_on(main_coroutine);
}
void ScriptPlayer::update() {
if (main_coroutine) {
main_coroutine();
}
}
"new_lua_state“在一切开始时都会被调用一次,然后"play”在我想要执行一个新的lua脚本(产生)时就被调用了。每个帧都执行"update“,并将协同线向前推进,直到它完成为止,然后停止。
问题:如果我调用"play“,而前面的脚本协同已经产生,但还没有完成,我希望lua放弃整个环境并创建一个新的环境,丢弃旧的协同,再次解析脚本,创建一个全新的协同,并从一开始就开始执行它。
相反,我得到的是,协同线仍然将运行在前一个脚本的协同线的状态(应该被完全丢弃),而不是从一开始。
这怎麽可能?协同线的状态究竟存储在哪里?我试着用线程包装状态,我试着调用lua.clear_stack,但是当我重新解析脚本并重新创建sol::coroutine对象时,新的coroutine从未从函数的开始就开始了。
任何澄清都是非常感谢的。
发布于 2022-01-12 13:14:56
解决方案如下:https://github.com/ThePhD/sol2/issues/1061
显然,我试图用线程包装状态是错误的,因为这正是我要做的事情。
为了解决这个问题,我所做的是:
void ScriptPlayer::play(std::string path) {
script_env = sol::nil;
main_coroutine = sol::nil;
script_thread = sol::thread::create(lua);
script_env = sol::environment(script_thread.state(), sol::create,
script_thread.state().globals());
auto result = script_thread.state().load_file(path);
main_coroutine = sol::coroutine(result);
script_env.set_on(main_coroutine);
}
其中一个令我震惊的是,如果我删除第二行(重新设置C持有的对lua协同线的引用),结果会回到错误地恢复以前的协同线,尽管这个变量在不久之后被设置为不同的值。这使我深感困惑。
https://stackoverflow.com/questions/70679013
复制相似问题