fix(lua): waitingThreads was not reset causing crash on re-play
This commit is contained in:
parent
9ca0bb0cec
commit
5fdc745259
1 changed files with 8 additions and 33 deletions
|
@ -16,38 +16,27 @@ SignalConnection::SignalConnection(std::weak_ptr<Signal> parent) : parentSignal(
|
||||||
SignalConnection::~SignalConnection() = default;
|
SignalConnection::~SignalConnection() = default;
|
||||||
|
|
||||||
// Only used for its address
|
// Only used for its address
|
||||||
int __savedCallbacks = 0;
|
|
||||||
LuaSignalConnection::LuaSignalConnection(lua_State* L, std::weak_ptr<Signal> parent) : SignalConnection(parent) {
|
LuaSignalConnection::LuaSignalConnection(lua_State* L, std::weak_ptr<Signal> parent) : SignalConnection(parent) {
|
||||||
state = L;
|
state = L;
|
||||||
|
|
||||||
// https://stackoverflow.com/a/31952046/16255372
|
// https://stackoverflow.com/a/31952046/16255372
|
||||||
// Create the table
|
|
||||||
if (__savedCallbacks == 0) {
|
|
||||||
lua_newtable(L);
|
|
||||||
__savedCallbacks = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save function so it doesn't get GC'd
|
// Save function so it doesn't get GC'd
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, __savedCallbacks);
|
function = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
lua_pushvalue(L, -2);
|
lua_pop(L, 1);
|
||||||
function = luaL_ref(L, -2);
|
|
||||||
lua_pop(L, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaSignalConnection::~LuaSignalConnection() {
|
LuaSignalConnection::~LuaSignalConnection() {
|
||||||
// Remove LuaSignalConnectionthread so that it can get properly GC'd
|
// Remove LuaSignalConnectionthread so that it can get properly GC'd
|
||||||
lua_rawgeti(state, LUA_REGISTRYINDEX, __savedCallbacks);
|
luaL_unref(state, LUA_REGISTRYINDEX, function);
|
||||||
luaL_unref(state, -1, function);
|
|
||||||
lua_pop(state, 1); // Pop __savedCallbacks
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaSignalConnection::Call(std::vector<Data::Variant> args) {
|
void LuaSignalConnection::Call(std::vector<Data::Variant> args) {
|
||||||
lua_State* thread = lua_newthread(state);
|
lua_State* thread = lua_newthread(state);
|
||||||
|
|
||||||
// Push function
|
// Push function
|
||||||
lua_rawgeti(thread, LUA_REGISTRYINDEX, __savedCallbacks);
|
lua_rawgeti(thread, LUA_REGISTRYINDEX, function);
|
||||||
lua_rawgeti(thread, -1, function);
|
luaL_unref(thread, LUA_REGISTRYINDEX, function);
|
||||||
lua_remove(thread, -2);
|
|
||||||
|
|
||||||
for (Data::Variant arg : args) {
|
for (Data::Variant arg : args) {
|
||||||
arg.PushLuaValue(thread);
|
arg.PushLuaValue(thread);
|
||||||
|
@ -111,19 +100,9 @@ SignalConnectionRef Signal::Once(lua_State* state) {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
int __waitingThreads = 0;
|
|
||||||
int Signal::Wait(lua_State* thread) {
|
int Signal::Wait(lua_State* thread) {
|
||||||
// If the table hasn't been constructed yet, make it
|
|
||||||
if (__waitingThreads == 0) {
|
|
||||||
lua_newtable(thread);
|
|
||||||
__waitingThreads = luaL_ref(thread, LUA_REGISTRYINDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get waitingThreads table
|
|
||||||
lua_rawgeti(thread, LUA_REGISTRYINDEX, __waitingThreads);
|
|
||||||
lua_pushthread(thread);
|
lua_pushthread(thread);
|
||||||
int threadId = luaL_ref(thread, -2);
|
int threadId = luaL_ref(thread, LUA_REGISTRYINDEX);
|
||||||
lua_pop(thread, -1); // pop __waitingThreads
|
|
||||||
waitingThreads.push_back(std::make_pair(threadId, thread));
|
waitingThreads.push_back(std::make_pair(threadId, thread));
|
||||||
|
|
||||||
// Yield and return results
|
// Yield and return results
|
||||||
|
@ -157,9 +136,7 @@ void Signal::Fire(std::vector<Data::Variant> args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove thread from registry
|
// Remove thread from registry
|
||||||
lua_rawgeti(thread, LUA_REGISTRYINDEX, __waitingThreads);
|
luaL_unref(thread, LUA_REGISTRYINDEX, threadId);
|
||||||
luaL_unref(thread, -1, threadId);
|
|
||||||
lua_pop(thread, 1); // pop __waitingThreads
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -180,9 +157,7 @@ void Signal::DisconnectAll() {
|
||||||
onceConnections.clear();
|
onceConnections.clear();
|
||||||
|
|
||||||
for (auto& [threadId, thread] : waitingThreads) {
|
for (auto& [threadId, thread] : waitingThreads) {
|
||||||
lua_rawgeti(thread, LUA_REGISTRYINDEX, __waitingThreads);
|
luaL_unref(thread, -1, LUA_REGISTRYINDEX);
|
||||||
luaL_unref(thread, -1, threadId);
|
|
||||||
lua_pop(thread, 1);
|
|
||||||
}
|
}
|
||||||
waitingThreads.clear();
|
waitingThreads.clear();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue