mirror of
https://github.com/0O0o0oOoO00/Alas.git
synced 2026-05-14 13:39:25 +08:00
fix: call lua operation at lua state pause thread
This commit is contained in:
@@ -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<void()>& func) {
|
||||
auto _ = std::lock_guard<std::mutex>(m_atomic_pause);
|
||||
ensure_debug_hook();
|
||||
auto lk = std::mutex();
|
||||
|
||||
auto fn = std::function<void()>([&]() {
|
||||
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<std::function<void()>*> 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<std::mutex>(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() {
|
||||
|
||||
@@ -25,34 +25,23 @@ class LuaStatePauser {
|
||||
public:
|
||||
LuaStatePauser(lua_State* L);
|
||||
|
||||
void do_when_paused(const std::function<void()>& 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<std::function<void()>*> 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<bool> m_need_pause = false;
|
||||
};
|
||||
|
||||
class LuaStatePauserGuard {
|
||||
public:
|
||||
LuaStatePauserGuard(LuaStatePauser* p);
|
||||
~LuaStatePauserGuard();
|
||||
private:
|
||||
LuaStatePauser* m_p;
|
||||
};
|
||||
|
||||
class Cracker {
|
||||
@@ -453,7 +442,6 @@ private:
|
||||
std::atomic<float> m_global_speedup_rate = 1.0;
|
||||
std::atomic<double> m_better_global_speedup_rate = 1.0;
|
||||
LuaStatePauser m_lua_state_pauser;
|
||||
std::mutex m_pauser_lock;
|
||||
std::atomic<bool> m_better_global_speedup_need_pause = false;
|
||||
std::atomic<bool> m_skip_battle_celebrate_need_pause = false;
|
||||
std::atomic<bool> m_fast_stage_move_need_pause = false;
|
||||
|
||||
Reference in New Issue
Block a user