diff --git a/blcrack/cracker/cracker.cpp b/blcrack/cracker/cracker.cpp index f23a87f5b..411b08346 100644 --- a/blcrack/cracker/cracker.cpp +++ b/blcrack/cracker/cracker.cpp @@ -59,34 +59,34 @@ static fnset_TimeScaleT get_Time_set_timeScale() { LuaStatePauser::LuaStatePauser(lua_State* L) : m_L(L) { thiz = this; - register_debug_hook(); + ensure_debug_hook(); } -void LuaStatePauser::set() { +void LuaStatePauser::do_when_paused(const std::function& func) { + auto _ = std::lock_guard(m_atomic_pause); + ensure_debug_hook(); + auto lk = std::mutex(); + + auto fn = std::function([&]() { + g_lua_state_operation.store(nullptr); + func(); + lk.unlock(); + }); + lk.lock(); + g_lua_state_operation.store(&fn); + lk.lock(); +} + +void LuaStatePauser::ensure_debug_hook() { if (lua_gethook(m_L) != LuaStatePauser::debug_hook) { register_debug_hook(); } - m_ready_flag = false; -} - -void LuaStatePauser::wait_paused() { - m_need_pause = true; - m_pause_flag.wait(false); -} - -void LuaStatePauser::ready() { - SPDLOG_INFO("lua operation ready"); - m_ready_flag = true; - m_ready_flag.notify_all(); -} - -void LuaStatePauser::release() { - m_need_pause = false; - m_pause_flag = false; } LuaStatePauser* LuaStatePauser::thiz = nullptr; +std::atomic*> LuaStatePauser::g_lua_state_operation = nullptr; + void LuaStatePauser::register_debug_hook() { SPDLOG_INFO("registering debug hook"); int ret = lua_sethook(m_L, LuaStatePauser::debug_hook, LUA_MASKCALL, 0); @@ -95,26 +95,6 @@ void LuaStatePauser::register_debug_hook() { } } -void LuaStatePauser::unregister_debug_hook() { - int ret = lua_sethook(m_L, nullptr, 0, 0); - if (ret != 1) { - SPDLOG_INFO("remove pause hook failed with code: {}", ret); - } -} - -void LuaStatePauser::paused() { - m_pause_flag = true; - m_pause_flag.notify_all(); -} - -void LuaStatePauser::wait_ready() { - m_ready_flag.wait(false); -} - -bool LuaStatePauser::need_pause() { - return m_need_pause.load(); -} - extern bool g_is_game_loaded; void LuaStatePauser::debug_hook(lua_State *L, lua_Debug *ar) { @@ -122,30 +102,15 @@ void LuaStatePauser::debug_hook(lua_State *L, lua_Debug *ar) { if (!thiz) { return; } - if (!thiz->need_pause()) { + auto callback = g_lua_state_operation.load(); + if (!callback) { return; } - SPDLOG_INFO("pause triggered, notify to operate lua state"); - thiz->paused(); - thiz->wait_ready(); + SPDLOG_INFO("pause triggered, operate lua state"); + (*callback)(); } } -LuaStatePauserGuard::LuaStatePauserGuard(LuaStatePauser* p) : m_p(p) { - m_p->set(); - m_p->wait_paused(); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); -} - -LuaStatePauserGuard::~LuaStatePauserGuard() { - m_p->ready(); - m_p->release(); -} - -#define LUA_STATUS_PAUSER_GUARD() \ - auto __pc = std::lock_guard(m_pauser_lock); \ - auto __pg = LuaStatePauserGuard(&m_lua_state_pauser); - Cracker::Cracker(bool need_pause) : m_state([]() -> lua_State* { auto new_tr = lua_newthread(Utils::get_lua_state()); @@ -644,9 +609,10 @@ void Cracker::fast_stage_move_set_duration(double duration) { } void Cracker::fast_stage_move_set_duration_with_pause(double duration) { - LUA_STATUS_PAUSER_GUARD(); - m_state["ChapterConst"]["ShipStepDuration"] = duration; - m_state["ChapterConst"]["ShipStepQuickPlayScale"] = duration; + m_lua_state_pauser.do_when_paused([&] () { + m_state["ChapterConst"]["ShipStepDuration"] = duration; + m_state["ChapterConst"]["ShipStepQuickPlayScale"] = duration; + }); } void Cracker::fast_stage_move_set_duration_without_pause(double duration) { @@ -663,8 +629,9 @@ void Cracker::skip_battle_celebrate_set_duration(double duration) { } void Cracker::skip_battle_celebrate_set_duration_with_pause(double duration) { - LUA_STATUS_PAUSER_GUARD(); - m_state["ys"]["Battle"]["BattleConfig"]["CelebrateDuration"] = duration; + m_lua_state_pauser.do_when_paused([&]() { + m_state["ys"]["Battle"]["BattleConfig"]["CelebrateDuration"] = duration; + }); } void Cracker::skip_battle_celebrate_set_duration_without_pause(double duration) { @@ -1528,9 +1495,10 @@ void Cracker::better_global_speedup_set_rate(double rate) { } void Cracker::better_global_speedup_set_rate_with_pause(double rate) { - LUA_STATUS_PAUSER_GUARD(); - m_state["ys"]["Battle"]["BattleConfig"]["BASIC_TIME_SCALE"] = rate; - m_state["Time"]["timeScale"] = rate; + m_lua_state_pauser.do_when_paused([&]() { + m_state["ys"]["Battle"]["BattleConfig"]["BASIC_TIME_SCALE"] = rate; + m_state["Time"]["timeScale"] = rate; + }); } void Cracker::better_global_speedup_set_rate_without_pause(double rate) { @@ -1737,11 +1705,12 @@ void Cracker::apply_config(Config& config) { } void Cracker::load_cracker_with_pause() { - SPDLOG_INFO("Load cracker with lua pause"); - LUA_STATUS_PAUSER_GUARD(); - load_lua_resources(); - hook_all_lua_functions(); - load_real_lua_func(); + m_lua_state_pauser.do_when_paused([&]() { + SPDLOG_INFO("Load cracker with lua pause"); + load_lua_resources(); + hook_all_lua_functions(); + load_real_lua_func(); + }); } void Cracker::load_cracker_without_pause() { diff --git a/blcrack/cracker/cracker.hpp b/blcrack/cracker/cracker.hpp index c2909e439..aaf90be16 100644 --- a/blcrack/cracker/cracker.hpp +++ b/blcrack/cracker/cracker.hpp @@ -25,34 +25,23 @@ class LuaStatePauser { public: LuaStatePauser(lua_State* L); + void do_when_paused(const std::function& func); + void set(); void wait_paused(); void ready(); void release(); private: + void ensure_debug_hook(); void register_debug_hook(); - void unregister_debug_hook(); - - void paused(); - void wait_ready(); - bool need_pause(); static LuaStatePauser* thiz; + static std::atomic*> g_lua_state_operation; static void debug_hook(lua_State *L, lua_Debug *ar); - std::atomic_bool m_pause_flag = ATOMIC_FLAG_INIT; - std::atomic_bool m_ready_flag = ATOMIC_FLAG_INIT; + std::mutex m_atomic_pause; lua_State* m_L; - std::atomic m_need_pause = false; -}; - -class LuaStatePauserGuard { -public: - LuaStatePauserGuard(LuaStatePauser* p); - ~LuaStatePauserGuard(); -private: - LuaStatePauser* m_p; }; class Cracker { @@ -453,7 +442,6 @@ private: std::atomic m_global_speedup_rate = 1.0; std::atomic m_better_global_speedup_rate = 1.0; LuaStatePauser m_lua_state_pauser; - std::mutex m_pauser_lock; std::atomic m_better_global_speedup_need_pause = false; std::atomic m_skip_battle_celebrate_need_pause = false; std::atomic m_fast_stage_move_need_pause = false;