diff --git a/binding/binding-mri.cpp b/binding/binding-mri.cpp index a9565fb..35289bc 100644 --- a/binding/binding-mri.cpp +++ b/binding/binding-mri.cpp @@ -531,7 +531,7 @@ RB_METHOD(mkxpSystemMemory) { RB_METHOD(mkxpReloadPathCache) { RB_UNUSED_PARAM; - shState->fileSystem().reloadPathCache(); + GUARD_EXC(shState->fileSystem().reloadPathCache();); return Qnil; } @@ -968,7 +968,11 @@ static void runRMXPScripts(BacktraceData &btData) { /* Execute preloaded scripts */ for (std::vector::const_iterator i = conf.preloadScripts.begin(); i != conf.preloadScripts.end(); ++i) + { + if (shState->rtData().rqTerm) + break; runCustomScript(*i); + } VALUE exc = rb_gv_get("$!"); if (exc != Qnil) @@ -976,6 +980,9 @@ static void runRMXPScripts(BacktraceData &btData) { while (true) { for (long i = 0; i < scriptCount; ++i) { + if (shState->rtData().rqTerm) + break; + VALUE script = rb_ary_entry(scriptArray, i); VALUE scriptDecoded = rb_ary_entry(script, 3); VALUE string = diff --git a/src/filesystem/filesystem.cpp b/src/filesystem/filesystem.cpp index d5abc27..67c9be0 100644 --- a/src/filesystem/filesystem.cpp +++ b/src/filesystem/filesystem.cpp @@ -396,6 +396,9 @@ struct CacheEnumData { static PHYSFS_EnumerateCallbackResult cacheEnumCB(void *d, const char *origdir, const char *fname) { + if (shState && shState->rtData().rqTerm) + throw Exception(Exception::MKXPError, "Game close requested. Aborting path cache enumeration."); + CacheEnumData &data = *static_cast(d); char fullPath[512]; diff --git a/src/sharedstate.cpp b/src/sharedstate.cpp index f11153e..83af953 100644 --- a/src/sharedstate.cpp +++ b/src/sharedstate.cpp @@ -115,6 +115,9 @@ struct SharedStatePrivate _glState(threadData->config), fontState(threadData->config), stampCounter(0) + {} + + void init(RGSSThreadData *threadData) { startupTime = std::chrono::steady_clock::now(); @@ -380,7 +383,24 @@ unsigned int SharedState::genTimeStamp() SharedState::SharedState(RGSSThreadData *threadData) { p = new SharedStatePrivate(threadData); - p->screen = p->graphics.getScreen(); + SharedState::instance = this; + try + { + p->init(threadData); + p->screen = p->graphics.getScreen(); + } + catch (const Exception &exc) + { + // If the "error" was the user quitting the game before the path cache finished building, + // then just return + if (rtData().rqTerm) + return; + + delete p; + SharedState::instance = 0; + + throw exc; + } } SharedState::~SharedState()