0

This is the overall flow of my setup:

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" is called once at the beginning of everything, then "play" is called anytime I want to execute a new lua script (that yields). "update" is executed every frame, and progresses the coroutine until it's finished, at which point it stops.

The problem: If I call "play" while the previous script coroutine has yielded but hasn't yet finished, I expect lua to discard the whole environment and create a new one, discard the old coroutine, parse the script again, create a brand new coroutine and start its execution from the beginning.

What I get instead is that the coroutine will STILL be running from the state of the previous script's coroutine (which should be completely discarded) and not from the very beginning.

How is this possible? Where exactly is the state of the coroutine stored? I tried wrapping the state with a thread, I tried calling lua.clear_stack but nothing made any difference in the fact that the new coroutine never starts from the beginning of the function when I re-parse the script and re-create the sol::coroutine object.

Any clarification is hugely appreciated.

Lake
  • 4,072
  • 26
  • 36

1 Answers1

0

Here was the solution: https://github.com/ThePhD/sol2/issues/1061

Apparently my attempt of wrapping the state with a thread was faulty, because that was exactly the thing to do.

So to solve this, here's what I did:

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);
}

One this that still blows my mind is that if I remove the second line (that reset the C-held reference to the lua coroutine), the result goes back to wrongly resuming the previous coroutine, despite that very same variable being set to a different value shortly after.. This baffles me deeply.

Lake
  • 4,072
  • 26
  • 36