diff --git a/src/mods/ScriptRunner.cpp b/src/mods/ScriptRunner.cpp index 87afdf638..261987eda 100644 --- a/src/mods/ScriptRunner.cpp +++ b/src/mods/ScriptRunner.cpp @@ -13,6 +13,7 @@ #include "sdk/SF6Utility.hpp" #include "utility/String.hpp" +#include #include "Mods.hpp" @@ -63,16 +64,16 @@ uint32_t get_id() { return std::this_thread::get_id()._Get_underlying_id(); } -sol::object get_hook_storage(sol::this_state s, size_t hash) { +sol::object get_hook_storage(sol::this_state s) { auto sol_state = sol::state_view{s}; auto state = sol_state.registry()["state"].get(); - auto result = state->get_hook_storage(get_hash()); + auto result = state->get_hook_storage(); - if (!result.has_value()) { + if (!result.valid()) { return sol::make_object(s, sol::lua_nil); } - return sol::make_object(s, result.value()); + return sol::make_object(s, result); } } @@ -667,9 +668,13 @@ void ScriptState::install_hooks() { return; } + const auto thash = std::hash{}(std::this_thread::get_id()); + utility::ScopeGuard sg{[state, thash] { state->pop_hook_storage(thash); }}; + try { + state->m_current_hook_storage = state->get_hook_storage_internal(thash); + if (post_cb.is()) { - state->pop_hook_storage(std::hash{}(std::this_thread::get_id())); return; } @@ -680,7 +685,6 @@ void ScriptState::install_hooks() { } ret_val = (uintptr_t)script_result.get(); - state->pop_hook_storage(std::hash{}(std::this_thread::get_id())); } catch (const std::exception& e) { ScriptRunner::get()->spew_error(e.what()); } catch (...) { diff --git a/src/mods/ScriptRunner.hpp b/src/mods/ScriptRunner.hpp index 719022056..68cfeff3e 100644 --- a/src/mods/ScriptRunner.hpp +++ b/src/mods/ScriptRunner.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -166,33 +167,42 @@ class ScriptState { void push_hook_storage(size_t thread_hash) { auto it = m_hook_storage.find(thread_hash); if (it == m_hook_storage.end()) { - it = m_hook_storage.emplace(thread_hash, std::stack{}).first; + it = m_hook_storage.emplace(thread_hash, std::deque{}).first; } - it->second.push(m_lua.create_table()); + it->second.push_back(m_lua.create_table()); + m_current_hook_storage = it->second.back(); } void pop_hook_storage(size_t thread_hash) { auto it = m_hook_storage.find(thread_hash); if (it != m_hook_storage.end()) { if (!it->second.empty()) { - it->second.pop(); + it->second.pop_front(); } } + + m_current_hook_storage = sol::nil; + } + + sol::reference get_hook_storage() { + return m_current_hook_storage; } - std::optional get_hook_storage(size_t thread_hash) { +private: + sol::reference get_hook_storage_internal(size_t thread_hash) { + //return m_current_hook_storage; + auto it = m_hook_storage.find(thread_hash); if (it != m_hook_storage.end()) { if (!it->second.empty()) { - return it->second.top(); + return it->second.front(); } } - return std::nullopt; + return sol::nil; } -private: sol::state m_lua{}; GarbageCollectionData m_gc_data{}; @@ -221,7 +231,8 @@ class ScriptState { std::deque m_hooks_to_add{}; std::unordered_map> m_hooks{}; - std::unordered_map> m_hook_storage{}; + std::unordered_map> m_hook_storage{}; + sol::reference m_current_hook_storage{}; }; class ScriptRunner : public Mod {