From 84a4d16aedee60ed4d6d2c5229c3b0ae50162029 Mon Sep 17 00:00:00 2001 From: elasota Date: Mon, 19 Apr 2021 01:02:10 -0400 Subject: [PATCH] Web file system implementation + fixes --- Aerofoil/GpFileStream_Win32.h | 6 +- AerofoilWeb/GpFileSystem_Web.cpp | 250 +++++++++++++++++++++---- AerofoilWeb/GpFileSystem_Web.h | 8 +- AerofoilWeb/GpMain_SDL_Web.cpp | 15 +- AerofoilWeb/Link.bat | 3 +- Common/CoreDefs.h | 4 + GenerateFonts/GenerateFonts.cpp | 2 +- GpApp/HouseIO.cpp | 3 +- GpApp/HouseLegal.cpp | 14 ++ GpApp/Marquee.cpp | 8 +- GpApp/RoomInfo.cpp | 4 +- GpCommon/GpIOStream.h | 7 +- GpCommon/IGpFileSystem.h | 3 +- PortabilityLayer/CFileStream.cpp | 2 +- PortabilityLayer/CFileStream.h | 2 +- PortabilityLayer/FileBrowserUI.cpp | 8 +- PortabilityLayer/FileManager.cpp | 44 ++++- PortabilityLayer/FileManager.h | 12 +- PortabilityLayer/FileSectionStream.cpp | 4 +- PortabilityLayer/InflateStream.cpp | 4 +- PortabilityLayer/MemReaderStream.cpp | 4 +- PortabilityLayer/MemReaderStream.h | 4 +- PortabilityLayer/MenuManager.cpp | 16 +- PortabilityLayer/MenuManager.h | 2 +- PortabilityLayer/PLCore.cpp | 6 + PortabilityLayer/PLCore.h | 1 + PortabilityLayer/PLResourceManager.cpp | 9 +- PortabilityLayer/PLSysCalls.cpp | 5 +- PortabilityLayer/PLSysCalls.h | 2 +- PortabilityLayer/ResourceManager.h | 2 +- 30 files changed, 373 insertions(+), 81 deletions(-) diff --git a/Aerofoil/GpFileStream_Win32.h b/Aerofoil/GpFileStream_Win32.h index fdedf17..9a2767b 100644 --- a/Aerofoil/GpFileStream_Win32.h +++ b/Aerofoil/GpFileStream_Win32.h @@ -19,9 +19,13 @@ public: bool SeekEnd(GpUFilePos_t loc) override; GpUFilePos_t Size() const override; GpUFilePos_t Tell() const override; - void Close() override; + void GP_ASYNCIFY_PARANOID_NAMED(Close)() override; void Flush() override; +#if GP_ASYNCIFY_PARANOID + void Close(); +#endif + private: HANDLE m_handle; bool m_readable; diff --git a/AerofoilWeb/GpFileSystem_Web.cpp b/AerofoilWeb/GpFileSystem_Web.cpp index b55453a..a5da4b6 100644 --- a/AerofoilWeb/GpFileSystem_Web.cpp +++ b/AerofoilWeb/GpFileSystem_Web.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "UTF8.h" @@ -29,6 +30,111 @@ typedef off_t off64_t; #define stat64 stat #endif +EM_JS(void, FlushFileSystem, (), { + Asyncify.handleSleep(wakeUp => { + FS.syncfs(false, function (err) { + assert(!err); + wakeUp(); + }); + }); +}); + + +class GpDirectoryCursor_Web final : public IGpDirectoryCursor +{ +public: + explicit GpDirectoryCursor_Web(DIR *dir, const std::string &prefix); + ~GpDirectoryCursor_Web(); + + bool GetNext(const char *&outFileName) override; + void Destroy() override; + +private: + DIR *m_dir; + std::string m_prefix; + std::string m_decodedFileName; +}; + +GpDirectoryCursor_Web::GpDirectoryCursor_Web(DIR *dir, const std::string &prefix) + : m_dir(dir) + , m_prefix(prefix) +{ +} + +GpDirectoryCursor_Web::~GpDirectoryCursor_Web() +{ + closedir(m_dir); +} + +bool GpDirectoryCursor_Web::GetNext(const char *&outFileName) +{ + const size_t prefixLength = m_prefix.size(); + + for (;;) + { + struct dirent *dir = readdir(m_dir); + if (!dir) + return false; + + const char *fname = dir->d_name; + + const size_t fnameLen = strlen(fname); + if (fnameLen > prefixLength && (prefixLength == 0 || !memcmp(&m_prefix[0], fname, prefixLength))) + { + const char *encodedResult = fname + prefixLength; + + m_decodedFileName.clear(); + for (size_t i = 0; encodedResult[i] != 0; i++) + { + char c = encodedResult[i]; + if (c == '%') + { + char highNibble = encodedResult[i + 1]; + if ((highNibble >= '0' && highNibble <= '9') || (highNibble >= 'a' && highNibble <= 'f') || (highNibble >= 'A' && highNibble <= 'F')) + { + char lowNibble = encodedResult[i + 2]; + + if ((lowNibble >= '0' && lowNibble <= '9') || (lowNibble >= 'a' && lowNibble <= 'f') || (lowNibble >= 'A' && lowNibble <= 'F')) + { + bool failedNibble = false; + char nibbles[2] = { highNibble, lowNibble }; + int decNibbles[2]; + for (int ni = 0; ni < 2; ni++) + { + char nc = nibbles[ni]; + if (nc >= '0' && nc <= '9') + decNibbles[ni] = nc - '0'; + else if (nc >= 'a' && nc <= 'f') + decNibbles[ni] = 0xa + (nc - 'a'); + else if (nc >= 'A' && nc <= 'F') + decNibbles[ni] = 0xa + (nc - 'A'); + else + failedNibble = true; + } + + if (!failedNibble) + { + c = static_cast((decNibbles[0] << 4) + decNibbles[1]); + i += 2; + } + } + } + } + + m_decodedFileName += c; + } + + outFileName = m_decodedFileName.c_str(); + return true; + } + } + return true; +} + +void GpDirectoryCursor_Web::Destroy() +{ + delete this; +} class GpFileStream_Web_StaticMemFile final : public GpIOStream { @@ -46,7 +152,7 @@ public: bool SeekEnd(GpUFilePos_t loc) override; GpUFilePos_t Size() const override; GpUFilePos_t Tell() const override; - void Close() override; + void GP_ASYNCIFY_PARANOID_NAMED(Close)() override; void Flush() override; private: @@ -136,7 +242,7 @@ GpUFilePos_t GpFileStream_Web_StaticMemFile::Tell() const return m_offset; } -void GpFileStream_Web_StaticMemFile::Close() +void GpFileStream_Web_StaticMemFile::GP_ASYNCIFY_PARANOID_NAMED(Close)() { delete this; } @@ -149,7 +255,7 @@ void GpFileStream_Web_StaticMemFile::Flush() class GpFileStream_Web_File final : public GpIOStream { public: - GpFileStream_Web_File(FILE *f, bool readOnly, bool writeOnly); + GpFileStream_Web_File(FILE *f, bool readOnly, bool writeOnly, bool synchronizeOnClose); ~GpFileStream_Web_File(); size_t Read(void *bytesOut, size_t size) override; @@ -162,7 +268,7 @@ public: bool SeekEnd(GpUFilePos_t loc) override; GpUFilePos_t Size() const override; GpUFilePos_t Tell() const override; - void Close() override; + void GP_ASYNCIFY_PARANOID_NAMED(Close)() override; void Flush() override; private: @@ -170,13 +276,15 @@ private: bool m_seekable; bool m_isReadOnly; bool m_isWriteOnly; + bool m_synchronizeOnClose; }; -GpFileStream_Web_File::GpFileStream_Web_File(FILE *f, bool readOnly, bool writeOnly) +GpFileStream_Web_File::GpFileStream_Web_File(FILE *f, bool readOnly, bool writeOnly, bool synchronizeOnClose) : m_f(f) , m_isReadOnly(readOnly) , m_isWriteOnly(writeOnly) + , m_synchronizeOnClose(synchronizeOnClose) { m_seekable = (fseek(m_f, 0, SEEK_CUR) == 0); } @@ -184,6 +292,9 @@ GpFileStream_Web_File::GpFileStream_Web_File(FILE *f, bool readOnly, bool writeO GpFileStream_Web_File::~GpFileStream_Web_File() { fclose(m_f); + + if (m_synchronizeOnClose) + GpFileSystem_Web::MarkFSStateDirty(); } size_t GpFileStream_Web_File::Read(void *bytesOut, size_t size) @@ -258,7 +369,7 @@ GpUFilePos_t GpFileStream_Web_File::Tell() const return static_cast(ftell(m_f)); } -void GpFileStream_Web_File::Close() +void GpFileStream_Web_File::GP_ASYNCIFY_PARANOID_NAMED(Close)() { this->~GpFileStream_Web_File(); free(this); @@ -269,20 +380,25 @@ void GpFileStream_Web_File::Flush() fflush(m_f); } -bool GpFileSystem_Web::ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution) + +bool GpFileSystem_Web::ms_fsStateDirty; + + +bool GpFileSystem_Web::ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, bool trailingSlash, std::string &resolution) { const char *prefsAppend = nullptr; + std::string unsanitized; switch (virtualDirectory) { case PortabilityLayer::VirtualDirectories::kApplicationData: - resolution = std::string("Packaged"); + unsanitized = std::string("Packaged"); break; case PortabilityLayer::VirtualDirectories::kGameData: - resolution = std::string("Packaged/Houses"); + unsanitized = std::string("Packaged/Houses"); break; case PortabilityLayer::VirtualDirectories::kFonts: - resolution = std::string("Resources"); + unsanitized = std::string("Resources"); break; case PortabilityLayer::VirtualDirectories::kHighScores: prefsAppend = "HighScores"; @@ -301,14 +417,50 @@ bool GpFileSystem_Web::ResolvePath(PortabilityLayer::VirtualDirectory_t virtualD }; if (prefsAppend) - resolution = m_prefsPath + prefsAppend; - else - resolution = m_basePath + resolution; - - for (size_t i = 0; i < numPaths; i++) { - resolution += "/"; - resolution += paths[i]; + unsanitized = prefsAppend; + + for (size_t i = 0; i < numPaths; i++) + { + unsanitized += "/"; + unsanitized += paths[i]; + } + + if (trailingSlash) + unsanitized += "/"; + + std::string sanitized; + for (size_t i = 0; i < unsanitized.size(); i++) + { + char c = unsanitized[i]; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') + sanitized += c; + else + { + const char *nibbles = "0123456789abcdef"; + char subPath[4]; + subPath[0] = '%'; + subPath[1] = nibbles[(c >> 4) & 0xf]; + subPath[2] = nibbles[c & 0xf]; + subPath[3] = 0; + + sanitized += subPath; + } + } + + resolution = m_prefsPath + "/" + sanitized; + } + else + { + std::string sanitized = m_basePath + unsanitized; + + for (size_t i = 0; i < numPaths; i++) + { + sanitized += "/"; + sanitized += paths[i]; + } + + resolution = sanitized; } return true; @@ -325,8 +477,7 @@ GpFileSystem_Web::~GpFileSystem_Web() void GpFileSystem_Web::Init() { - char *prefsDir = SDL_GetPrefPath("aerofoil", "aerofoil"); - m_prefsPath = prefsDir; + m_prefsPath = "/aerofoil"; char *baseDir = SDL_GetBasePath(); m_basePath = baseDir; @@ -335,14 +486,6 @@ void GpFileSystem_Web::Init() char baseDirSeparator = m_basePath[m_basePath.size() - 1]; if (m_basePath.size() >= 4 && m_basePath.substr(m_basePath.size() - 4, 3) == "bin") m_basePath = m_basePath.substr(0, m_basePath.size() - 4) + "lib" + baseDirSeparator + "aerofoil" + baseDirSeparator; - - const char *extensions[] = { "HighScores", "Houses", "SavedGames", "Prefs", "FontCache" }; - for (size_t i = 0; i < sizeof(extensions) / sizeof(extensions[0]); i++) - { - std::string prefsPath = std::string(prefsDir) + extensions[i]; - int created = mkdir(prefsPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - } - SDL_free(prefsDir); } bool GpFileSystem_Web::FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path) @@ -360,7 +503,7 @@ bool GpFileSystem_Web::FileExists(PortabilityLayer::VirtualDirectory_t virtualDi } std::string resolvedPath; - if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath)) + if (!ResolvePath(virtualDirectory, &path, 1, false, resolvedPath)) return false; struct stat s; @@ -386,7 +529,7 @@ bool GpFileSystem_Web::FileLocked(PortabilityLayer::VirtualDirectory_t virtualDi } std::string resolvedPath; - if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath)) + if (!ResolvePath(virtualDirectory, &path, 1, false, resolvedPath)) { if (exists) exists = false; @@ -445,7 +588,7 @@ GpIOStream *GpFileSystem_Web::OpenFileNested(PortabilityLayer::VirtualDirectory_ return nullptr; std::string resolvedPath; - if (!ResolvePath(virtualDirectory, subPaths, numSubPaths, resolvedPath)) + if (!ResolvePath(virtualDirectory, subPaths, numSubPaths, false, resolvedPath)) return nullptr; void *objStorage = malloc(sizeof(GpFileStream_Web_File)); @@ -472,7 +615,7 @@ GpIOStream *GpFileSystem_Web::OpenFileNested(PortabilityLayer::VirtualDirectory_ } } - return new (objStorage) GpFileStream_Web_File(f, !writeAccess, false); + return new (objStorage) GpFileStream_Web_File(f, !writeAccess, false, writeAccess); } bool GpFileSystem_Web::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) @@ -481,7 +624,7 @@ bool GpFileSystem_Web::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDi return false; std::string resolvedPath; - if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath)) + if (!ResolvePath(virtualDirectory, &path, 1, false, resolvedPath)) { existed = false; return false; @@ -490,6 +633,9 @@ bool GpFileSystem_Web::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDi if (unlink(resolvedPath.c_str()) < 0) { existed = (errno != ENOENT); + if (existed) + FlushFileSystem(); + return false; } existed = true; @@ -596,7 +742,17 @@ IGpDirectoryCursor *GpFileSystem_Web::ScanDirectoryNested(PortabilityLayer::Virt if (const GpFileSystem_Web_Resources::FileCatalog *catalog = GetCatalogForVirtualDirectory(virtualDirectory)) return ScanCatalog(*catalog); - return nullptr; + std::string resolvedPrefix; + if (!ResolvePath(virtualDirectory, paths, numPaths, true, resolvedPrefix)) + return nullptr; + + std::string trimmedPrefix = resolvedPrefix.substr(m_prefsPath.size() + 1); + + DIR *d = opendir(m_prefsPath.c_str()); + if (!d) + return nullptr; + + return new GpDirectoryCursor_Web(d, trimmedPrefix); } const GpFileSystem_Web_Resources::FileCatalog *GpFileSystem_Web::GetCatalogForVirtualDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory) @@ -619,5 +775,33 @@ IGpDirectoryCursor *GpFileSystem_Web::ScanCatalog(const GpFileSystem_Web_Resourc return new GpDirectoryCursor_StringList(paths); } +void GpFileSystem_Web::MarkFSStateDirty() +{ + ms_fsStateDirty = true; +} + +void GpFileSystem_Web::FlushFS() +{ + if (ms_fsStateDirty) + { + ms_fsStateDirty = false; + FlushFileSystem(); + } +} + + +#if GP_ASYNCIFY_PARANOID +void GpIOStream::Close() +{ + this->GP_ASYNCIFY_PARANOID_NAMED(Close)(); + GpFileSystem_Web::FlushFS(); +} + +bool IGpFileSystem::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) +{ + return static_cast(this)->DeleteFile(virtualDirectory, path, existed); +} + +#endif GpFileSystem_Web GpFileSystem_Web::ms_instance; diff --git a/AerofoilWeb/GpFileSystem_Web.h b/AerofoilWeb/GpFileSystem_Web.h index 236a10a..3eb7b81 100644 --- a/AerofoilWeb/GpFileSystem_Web.h +++ b/AerofoilWeb/GpFileSystem_Web.h @@ -21,7 +21,7 @@ public: bool FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path) override; bool FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &exists) override; GpIOStream *OpenFileNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* subPaths, size_t numSubPaths, bool writeAccess, GpFileCreationDisposition_t createDisposition) override; - bool DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) override; + bool DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) GP_ASYNCIFY_PARANOID_OVERRIDE; IGpDirectoryCursor *ScanDirectoryNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths) override; bool ValidateFilePath(const char *path, size_t pathLen) const override; @@ -29,6 +29,9 @@ public: void SetDelayCallback(DelayCallback_t delayCallback) override; + static void MarkFSStateDirty(); + static void FlushFS(); + static GpFileSystem_Web *GetInstance(); private: @@ -51,12 +54,13 @@ private: static IGpDirectoryCursor *ScanCatalog(const GpFileSystem_Web_Resources::FileCatalog &catalog); - bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution); + bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, bool trailingSlash, std::string &resolution); DelayCallback_t m_delayCallback; std::string m_prefsPath; std::string m_basePath; + static bool ms_fsStateDirty; static GpFileSystem_Web ms_instance; }; diff --git a/AerofoilWeb/GpMain_SDL_Web.cpp b/AerofoilWeb/GpMain_SDL_Web.cpp index a424a87..6ca001c 100644 --- a/AerofoilWeb/GpMain_SDL_Web.cpp +++ b/AerofoilWeb/GpMain_SDL_Web.cpp @@ -19,18 +19,29 @@ #include "IGpVOSEventQueue.h" #include +#include GpXGlobals g_gpXGlobals; -extern "C" IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties); - IGpDisplayDriver *GpDriver_CreateDisplayDriver_SDL_GL2(const GpDisplayDriverProperties &properties); IGpAudioDriver *GpDriver_CreateAudioDriver_SDL(const GpAudioDriverProperties &properties); IGpInputDriver *GpDriver_CreateInputDriver_SDL2_Gamepad(const GpInputDriverProperties &properties); +EM_JS(void, InitFileSystem, (), { + Asyncify.handleSleep(wakeUp => { + FS.mkdir('/aerofoil'); + FS.mount(IDBFS, {}, '/aerofoil'); + FS.syncfs(true, function (err) { + assert(!err); + wakeUp(); + }); + }); +}); int main(int argc, char* argv[]) { + InitFileSystem(); + GpLogDriver_Web::Init(); IGpLogDriver *logger = GpLogDriver_Web::GetInstance(); diff --git a/AerofoilWeb/Link.bat b/AerofoilWeb/Link.bat index 9950709..fe20388 100644 --- a/AerofoilWeb/Link.bat +++ b/AerofoilWeb/Link.bat @@ -1,5 +1,4 @@ set INPUT_DIR=. set OUTPUT_DIR=bin -set FLAGS=-flto -O3 -s USE_SDL=2 -s USE_ZLIB=1 -s ASYNCIFY -s ASYNCIFY_IGNORE_INDIRECT -s INITIAL_MEMORY=33554432 -s ASYNCIFY_ADVISE - +set FLAGS=-flto -O3 -s USE_SDL=2 -s USE_ZLIB=1 -s ASYNCIFY -s ASYNCIFY_IGNORE_INDIRECT -s INITIAL_MEMORY=33554432 -s ASYNCIFY_ADVISE -lidbfs.js -s ASYNCIFY_IMPORTS=['InitFileSystem','FlushFileSystem'] emcc obj/AerofoilWeb_Combined.o obj/AerofoilWeb_Resources.o obj/GpShell_Combined.o obj/AerofoilSDL_Combined.o obj/GpApp_Combined.o obj/PortabilityLayer_Combined.o obj/MacRomanConversion.o -o %OUTPUT_DIR%/aerofoil.html %FLAGS% diff --git a/Common/CoreDefs.h b/Common/CoreDefs.h index 55fa0c4..8e597ed 100644 --- a/Common/CoreDefs.h +++ b/Common/CoreDefs.h @@ -60,12 +60,16 @@ static const size_t GP_SYSTEM_MEMORY_ALIGNMENT = 16; #define GP_ASYNCIFY_PARANOID 0 #endif +#define GP_ASYNCIFY_PARANOID_VALIDATION 0 + #if GP_ASYNCIFY_PARANOID #define GP_ASYNCIFY_PARANOID_VIRTUAL #define GP_ASYNCIFY_PARANOID_PURE #define GP_ASYNCIFY_PARANOID_OVERRIDE +#define GP_ASYNCIFY_PARANOID_NAMED(n) GpAsyncifyParanoid##n #else #define GP_ASYNCIFY_PARANOID_VIRTUAL virtual #define GP_ASYNCIFY_PARANOID_PURE = 0 #define GP_ASYNCIFY_PARANOID_OVERRIDE override +#define GP_ASYNCIFY_PARANOID_NAMED(n) n #endif diff --git a/GenerateFonts/GenerateFonts.cpp b/GenerateFonts/GenerateFonts.cpp index 38bf049..e5e6bbb 100644 --- a/GenerateFonts/GenerateFonts.cpp +++ b/GenerateFonts/GenerateFonts.cpp @@ -31,7 +31,7 @@ public: bool SeekEnd(GpUFilePos_t loc) override; GpUFilePos_t Size() const override; GpUFilePos_t Tell() const override; - void Close() override; + void GP_ASYNCIFY_PARANOID_NAMED(Close)() override; void Flush() override; const uint8_t *GetBytes() const; diff --git a/GpApp/HouseIO.cpp b/GpApp/HouseIO.cpp index 16a433a..9466ab3 100644 --- a/GpApp/HouseIO.cpp +++ b/GpApp/HouseIO.cpp @@ -602,6 +602,7 @@ Boolean ReadHouse (GpIOStream *houseStream) ByteSwapHouse(*thisHouse, static_cast(byteCount), false); numberRooms = (*thisHouse)->nRooms; + #ifdef COMPILEDEMO if (numberRooms != 45) return (false); @@ -685,7 +686,7 @@ Boolean WriteHouse (Boolean checkIt) } GpIOStream *houseStream = nil; - theErr = houseCFile->OpenData(PortabilityLayer::EFilePermission_Write, GpFileCreationDispositions::kCreateOrOpen, houseStream); + theErr = houseCFile->OpenData(PortabilityLayer::EFilePermission_Write, GpFileCreationDispositions::kCreateOrOverwrite, houseStream); if (theErr != PLErrors::kNone) return (false); diff --git a/GpApp/HouseLegal.cpp b/GpApp/HouseLegal.cpp index 94e328c..dded8df 100644 --- a/GpApp/HouseLegal.cpp +++ b/GpApp/HouseLegal.cpp @@ -9,6 +9,7 @@ #include "PLNumberFormatting.h" #include "PLStringCompare.h" #include "PLStandardColors.h" +#include "PLSysCalls.h" #include "Externs.h" #include "ObjectEdit.h" #include "PLStandardColors.h" @@ -874,6 +875,7 @@ void KeepAllObjectsLegal (void) GetLocalizedString(19, message); SetMessageWindowMessage(message, StdColors::Red()); houseErrors++; + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); } } @@ -908,6 +910,7 @@ void CheckForStaircasePairs (void) { GetLocalizedString(20, message); SetMessageWindowMessage(message, StdColors::Red()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); } else @@ -923,6 +926,7 @@ void CheckForStaircasePairs (void) { GetLocalizedString(21, message); SetMessageWindowMessage(message, StdColors::Red()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); } } @@ -935,6 +939,7 @@ void CheckForStaircasePairs (void) { GetLocalizedString(22, message); SetMessageWindowMessage(message, StdColors::Red()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); } else @@ -950,6 +955,7 @@ void CheckForStaircasePairs (void) { GetLocalizedString(23, message); SetMessageWindowMessage(message, StdColors::Red()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); } } @@ -992,6 +998,7 @@ void CheckHouseForProblems (void) { GetLocalizedString(27, message); SetMessageWindowMessage(message, StdColors::Black()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); houseErrors = 0; } @@ -1008,6 +1015,7 @@ void CheckHouseForProblems (void) GetLocalizedString(28, message2); PasStringConcat(message, message2); SetMessageWindowMessage(message, StdColors::Red()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(45); } } @@ -1027,6 +1035,7 @@ void CheckHouseForProblems (void) GetLocalizedString(29, message2); PasStringConcat(message, message2); SetMessageWindowMessage(message, StdColors::Red()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); } } @@ -1042,6 +1051,7 @@ void CheckHouseForProblems (void) GetLocalizedString(30, message2); PasStringConcat(message, message2); SetMessageWindowMessage(message, StdColors::Blue()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(45); } } @@ -1057,6 +1067,7 @@ void CheckHouseForProblems (void) GetLocalizedString(31, message2); PasStringConcat(message, message2); SetMessageWindowMessage(message, StdColors::Blue()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(45); } } @@ -1072,6 +1083,7 @@ void CheckHouseForProblems (void) GetLocalizedString(32, message2); PasStringConcat(message, message2); SetMessageWindowMessage(message, StdColors::Red()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); } } @@ -1089,6 +1101,7 @@ void CheckHouseForProblems (void) GetLocalizedString(34, message2); PasStringConcat(message, message2); SetMessageWindowMessage(message, StdColors::Red()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); } } @@ -1107,6 +1120,7 @@ void CheckHouseForProblems (void) { GetLocalizedString(35, message); SetMessageWindowMessage(message, StdColors::Red()); + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); DelayTicks(60); } } diff --git a/GpApp/Marquee.cpp b/GpApp/Marquee.cpp index cd74b41..6405c64 100644 --- a/GpApp/Marquee.cpp +++ b/GpApp/Marquee.cpp @@ -208,7 +208,7 @@ void DragOutMarqueeRect (Window *window, Point start, Rect *theRect) surface->InvertFrameRect(*theRect, pattern); wasPt = start; - while (WaitMouseUp()) + while (WaitMouseUp_DisarmAsyncify()) { GetMouse(window, &newPt); if (wasPt != newPt) @@ -238,7 +238,7 @@ void DragMarqueeRect (Window *window, DrawSurface *surface, Point start, Rect *t surface->InvertFrameRect(theMarquee.bounds, pattern); wasPt = start; - while (WaitMouseUp()) + while (WaitMouseUp_DisarmAsyncify()) { GetMouse(window, &newPt); if (wasPt != newPt) @@ -283,7 +283,7 @@ void DragMarqueeHandle (Window *window, DrawSurface *surface, Point start, short surface->InvertFillRect(theMarquee.handle, pattern); wasPt = start; - while (WaitMouseUp()) + while (WaitMouseUp_DisarmAsyncify()) { GetMouse(window, &newPt); if (wasPt != newPt) @@ -365,7 +365,7 @@ void DragMarqueeCorner (Window *window, DrawSurface *surface, Point start, short surface->InvertFillRect(theMarquee.handle, pattern); wasPt = start; - while (WaitMouseUp()) + while (WaitMouseUp_DisarmAsyncify()) { GetMouse(window, &newPt); if (wasPt != newPt) diff --git a/GpApp/RoomInfo.cpp b/GpApp/RoomInfo.cpp index 122ecec..d66dca3 100644 --- a/GpApp/RoomInfo.cpp +++ b/GpApp/RoomInfo.cpp @@ -153,9 +153,9 @@ void DragMiniTile (Window *window, DrawSurface *surface, Point mouseIs, short *n surface->InvertFrameRect(dragRect, pattern); mouseWas = mouseIs; - while (WaitMouseUp()) // loop until mouse button let up + while (WaitMouseUp_DisarmAsyncify()) // loop until mouse button let up { - GetMouse(window, &mouseIs); // get mouse coords + GetMouse(window, &mouseIs); // get mouse coords if (mouseWas != mouseIs) // the mouse has moved { surface->InvertFrameRect(dragRect, pattern); diff --git a/GpCommon/GpIOStream.h b/GpCommon/GpIOStream.h index 302a3a5..e246e1f 100644 --- a/GpCommon/GpIOStream.h +++ b/GpCommon/GpIOStream.h @@ -3,6 +3,7 @@ #include #include "GpFilePos.h" +#include "CoreDefs.h" class GpIOStream { @@ -17,11 +18,15 @@ public: virtual bool SeekEnd(GpUFilePos_t loc) = 0; virtual GpUFilePos_t Size() const = 0; virtual GpUFilePos_t Tell() const = 0; - virtual void Close() = 0; + virtual void GP_ASYNCIFY_PARANOID_NAMED(Close)() = 0; virtual void Flush() = 0; bool ReadExact(void *bytesOut, size_t size); bool WriteExact(const void *bytesOut, size_t size); + +#if GP_ASYNCIFY_PARANOID + void Close(); +#endif }; inline bool GpIOStream::ReadExact(void *bytesOut, size_t size) diff --git a/GpCommon/IGpFileSystem.h b/GpCommon/IGpFileSystem.h index 72ad02a..f3ea479 100644 --- a/GpCommon/IGpFileSystem.h +++ b/GpCommon/IGpFileSystem.h @@ -1,6 +1,7 @@ #pragma once #include "GpFileCreationDisposition.h" +#include "CoreDefs.h" #include "VirtualDirectory.h" #include @@ -17,7 +18,7 @@ public: virtual bool FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path) = 0; virtual bool FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &exists) = 0; virtual GpIOStream *OpenFileNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* subPaths, size_t numSubPaths, bool writeAccess, GpFileCreationDisposition_t createDisposition) = 0; - virtual bool DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) = 0; + GP_ASYNCIFY_PARANOID_VIRTUAL bool DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) GP_ASYNCIFY_PARANOID_PURE; virtual IGpDirectoryCursor *ScanDirectoryNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths) = 0; virtual bool ValidateFilePath(const char *path, size_t pathLen) const = 0; diff --git a/PortabilityLayer/CFileStream.cpp b/PortabilityLayer/CFileStream.cpp index f013edc..da7ee46 100644 --- a/PortabilityLayer/CFileStream.cpp +++ b/PortabilityLayer/CFileStream.cpp @@ -81,7 +81,7 @@ namespace PortabilityLayer return static_cast(ftell(m_file)); } - void CFileStream::Close() + void CFileStream::GP_ASYNCIFY_PARANOID_NAMED(Close)() { if (m_file) { diff --git a/PortabilityLayer/CFileStream.h b/PortabilityLayer/CFileStream.h index 5bb0a6c..aefe406 100644 --- a/PortabilityLayer/CFileStream.h +++ b/PortabilityLayer/CFileStream.h @@ -23,7 +23,7 @@ namespace PortabilityLayer bool SeekEnd(GpUFilePos_t loc) override; GpUFilePos_t Size() const override; GpUFilePos_t Tell() const override; - void Close() override; + void GP_ASYNCIFY_PARANOID_NAMED(Close)() override; void Flush() override; private: diff --git a/PortabilityLayer/FileBrowserUI.cpp b/PortabilityLayer/FileBrowserUI.cpp index 24d9531..4735d03 100644 --- a/PortabilityLayer/FileBrowserUI.cpp +++ b/PortabilityLayer/FileBrowserUI.cpp @@ -459,7 +459,13 @@ namespace PortabilityLayer break; } - if (WaitForEvent(&evtHolder, 1)) + bool haveEvent = false; + { + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); + haveEvent = WaitForEvent(&evtHolder, 1); + } + + if (haveEvent) rcvEvt = &evtHolder; else rcvEvt = nullptr; diff --git a/PortabilityLayer/FileManager.cpp b/PortabilityLayer/FileManager.cpp index e1ccccd..aae4990 100644 --- a/PortabilityLayer/FileManager.cpp +++ b/PortabilityLayer/FileManager.cpp @@ -39,17 +39,17 @@ namespace PortabilityLayer bool CompositeFileExists(VirtualDirectory_t dirID, const PLPasStr &filename) override; bool NonCompositeFileExists(VirtualDirectory_t dirID, const PLPasStr &filename, const char *extension) override; - bool DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext) override; - bool DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename) override; + bool DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext) GP_ASYNCIFY_PARANOID_OVERRIDE; + bool DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename) GP_ASYNCIFY_PARANOID_OVERRIDE; - PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) override; - PLError_t CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType) override; + PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) GP_ASYNCIFY_PARANOID_OVERRIDE; + PLError_t CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType) GP_ASYNCIFY_PARANOID_OVERRIDE; PLError_t RawOpenFileData(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t creationDisposition, GpIOStream *&outStream) override; PLError_t RawOpenFileResources(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t creationDisposition, GpIOStream *&outStream) override; - bool PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) override; - bool PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) override; + bool PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) GP_ASYNCIFY_PARANOID_OVERRIDE; + bool PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) GP_ASYNCIFY_PARANOID_OVERRIDE; static FileManagerImpl *GetInstance(); @@ -506,4 +506,36 @@ namespace PortabilityLayer if (m_stream) m_stream->Close(); } + +#if GP_ASYNCIFY_PARANOID + bool FileManager::PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) + { + return static_cast(this)->PromptSaveFile(dirID, extension, path, outPathLength, pathCapacity, initialFileName, promptText, composites, callbackAPI); + } + + bool FileManager::PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) + { + return static_cast(this)->PromptOpenFile(dirID, extension, path, outPathLength, pathCapacity, promptText, composites, callbackAPI); + } + + PLError_t FileManager::CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) + { + return static_cast(this)->CreateFile(dirID, filename, mfp); + } + + PLError_t FileManager::CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType) + { + return static_cast(this)->CreateFileAtCurrentTime(dirID, filename, fileCreator, fileType); + } + + bool FileManager::DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext) + { + return static_cast(this)->DeleteNonCompositeFile(dirID, filename, ext); + } + + bool FileManager::DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename) + { + return static_cast(this)->DeleteCompositeFile(dirID, filename); + } +#endif } diff --git a/PortabilityLayer/FileManager.h b/PortabilityLayer/FileManager.h index 93f8045..a2f8482 100644 --- a/PortabilityLayer/FileManager.h +++ b/PortabilityLayer/FileManager.h @@ -46,17 +46,17 @@ namespace PortabilityLayer virtual bool CompositeFileExists(VirtualDirectory_t dirID, const PLPasStr &filename) = 0; virtual bool NonCompositeFileExists(VirtualDirectory_t dirID, const PLPasStr &filename, const char *extension) = 0; - virtual bool DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext) = 0; - virtual bool DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename) = 0; + GP_ASYNCIFY_PARANOID_VIRTUAL bool DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext) GP_ASYNCIFY_PARANOID_PURE; + GP_ASYNCIFY_PARANOID_VIRTUAL bool DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename) GP_ASYNCIFY_PARANOID_PURE; - virtual PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) = 0; - virtual PLError_t CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType) = 0; + GP_ASYNCIFY_PARANOID_VIRTUAL PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) GP_ASYNCIFY_PARANOID_PURE; + GP_ASYNCIFY_PARANOID_VIRTUAL PLError_t CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType) GP_ASYNCIFY_PARANOID_PURE; virtual PLError_t RawOpenFileData(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t createDisposition, GpIOStream *&outStream) = 0; virtual PLError_t RawOpenFileResources(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t createDisposition, GpIOStream *&outStream) = 0; - virtual bool PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) = 0; - virtual bool PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) = 0; + GP_ASYNCIFY_PARANOID_VIRTUAL bool PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) GP_ASYNCIFY_PARANOID_PURE; + GP_ASYNCIFY_PARANOID_VIRTUAL bool PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) GP_ASYNCIFY_PARANOID_PURE; static FileManager *GetInstance(); }; diff --git a/PortabilityLayer/FileSectionStream.cpp b/PortabilityLayer/FileSectionStream.cpp index cdc2c16..ac5ce70 100644 --- a/PortabilityLayer/FileSectionStream.cpp +++ b/PortabilityLayer/FileSectionStream.cpp @@ -21,7 +21,7 @@ namespace PortabilityLayer bool SeekEnd(GpUFilePos_t loc) override; GpUFilePos_t Size() const override; GpUFilePos_t Tell() const override; - void Close() override; + void GP_ASYNCIFY_PARANOID_NAMED(Close)() override; void Flush() override; private: @@ -148,7 +148,7 @@ namespace PortabilityLayer return m_expectedPosition - m_start; } - void FileSectionStreamImpl::Close() + void FileSectionStreamImpl::GP_ASYNCIFY_PARANOID_NAMED(Close)() { this->~FileSectionStreamImpl(); free(this); diff --git a/PortabilityLayer/InflateStream.cpp b/PortabilityLayer/InflateStream.cpp index a05d653..3328b59 100644 --- a/PortabilityLayer/InflateStream.cpp +++ b/PortabilityLayer/InflateStream.cpp @@ -22,7 +22,7 @@ namespace PortabilityLayer bool SeekEnd(GpUFilePos_t loc) override; GpUFilePos_t Size() const override; GpUFilePos_t Tell() const override; - void Close() override; + void GP_ASYNCIFY_PARANOID_NAMED(Close)() override; void Flush() override; private: @@ -222,7 +222,7 @@ namespace PortabilityLayer return m_decompressedPos; } - void InflateStreamImpl::Close() + void InflateStreamImpl::GP_ASYNCIFY_PARANOID_NAMED(Close)() { this->~InflateStreamImpl(); free(this); diff --git a/PortabilityLayer/MemReaderStream.cpp b/PortabilityLayer/MemReaderStream.cpp index cf051b6..9d5aad8 100644 --- a/PortabilityLayer/MemReaderStream.cpp +++ b/PortabilityLayer/MemReaderStream.cpp @@ -104,7 +104,7 @@ namespace PortabilityLayer return static_cast(m_loc); } - void MemReaderStream::Close() + void MemReaderStream::GP_ASYNCIFY_PARANOID_NAMED(Close)() { } @@ -128,7 +128,7 @@ namespace PortabilityLayer return new (storage) MemBufferReaderStream(buffer, size); } - void MemBufferReaderStream::Close() + void MemBufferReaderStream::GP_ASYNCIFY_PARANOID_NAMED(Close)() { this->~MemBufferReaderStream(); MemoryManager::GetInstance()->Release(this); diff --git a/PortabilityLayer/MemReaderStream.h b/PortabilityLayer/MemReaderStream.h index b73dc9b..35f0dc7 100644 --- a/PortabilityLayer/MemReaderStream.h +++ b/PortabilityLayer/MemReaderStream.h @@ -23,7 +23,7 @@ namespace PortabilityLayer bool SeekEnd(GpUFilePos_t loc) override; GpUFilePos_t Size() const override; GpUFilePos_t Tell() const override; - void Close() override; + void GP_ASYNCIFY_PARANOID_NAMED(Close)() override; void Flush() override; private: @@ -41,7 +41,7 @@ namespace PortabilityLayer static MemBufferReaderStream *Create(void *buffer, size_t size); - void Close() override; + void GP_ASYNCIFY_PARANOID_NAMED(Close)() override; private: MemBufferReaderStream() GP_DELETED; diff --git a/PortabilityLayer/MenuManager.cpp b/PortabilityLayer/MenuManager.cpp index a2b565e..f2f07c9 100644 --- a/PortabilityLayer/MenuManager.cpp +++ b/PortabilityLayer/MenuManager.cpp @@ -155,7 +155,7 @@ namespace PortabilityLayer bool FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar) override; void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) GP_ASYNCIFY_PARANOID_OVERRIDE; - void PopupMenuSelect(const THandle &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem) override; + void PopupMenuSelect(const THandle &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem) GP_ASYNCIFY_PARANOID_OVERRIDE; void DrawMenuBar() override; void SetMenuVisible(bool isVisible) override; @@ -776,7 +776,14 @@ namespace PortabilityLayer bool canDismiss = false; while (!canDismiss) { - if (WaitForEvent(&evt, 1)) + bool haveEvent = false; + + { + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); + haveEvent = WaitForEvent(&evt, 1); + } + + if (haveEvent) { if (evt.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput) { @@ -1589,5 +1596,10 @@ namespace PortabilityLayer { static_cast(this)->MenuSelect(initialPoint, outMenu, outItem); } + + void MenuManager::PopupMenuSelect(const THandle &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem) + { + static_cast(this)->PopupMenuSelect(menu, popupMenuPos, initialPoint, initialItem, outItem); + } #endif } diff --git a/PortabilityLayer/MenuManager.h b/PortabilityLayer/MenuManager.h index cf66c6d..638cc34 100644 --- a/PortabilityLayer/MenuManager.h +++ b/PortabilityLayer/MenuManager.h @@ -50,7 +50,7 @@ namespace PortabilityLayer virtual bool FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar) = 0; GP_ASYNCIFY_PARANOID_VIRTUAL void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) GP_ASYNCIFY_PARANOID_PURE; - virtual void PopupMenuSelect(const THandle &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem) = 0; + GP_ASYNCIFY_PARANOID_VIRTUAL void PopupMenuSelect(const THandle &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem) GP_ASYNCIFY_PARANOID_PURE; virtual void DrawMenuBar() = 0; virtual void SetMenuVisible(bool isVisible) = 0; diff --git a/PortabilityLayer/PLCore.cpp b/PortabilityLayer/PLCore.cpp index 29d203e..88772f6 100644 --- a/PortabilityLayer/PLCore.cpp +++ b/PortabilityLayer/PLCore.cpp @@ -515,6 +515,12 @@ Boolean WaitMouseUp() return isDown; } +Boolean WaitMouseUp_DisarmAsyncify() +{ + PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE(); + return WaitMouseUp(); +} + short Random() { // Should return with range -32767..32767 diff --git a/PortabilityLayer/PLCore.h b/PortabilityLayer/PLCore.h index 5d95872..50e2af2 100644 --- a/PortabilityLayer/PLCore.h +++ b/PortabilityLayer/PLCore.h @@ -249,6 +249,7 @@ void DisposeDirectoryFiles(DirectoryFileListEntry *firstDFL); void GetMouse(Window *window, Point *point); Boolean StillDown(); Boolean WaitMouseUp(); +Boolean WaitMouseUp_DisarmAsyncify(); short Random(); void GetTime(DateTimeRec *dateTime); diff --git a/PortabilityLayer/PLResourceManager.cpp b/PortabilityLayer/PLResourceManager.cpp index 5443f00..5b2bd19 100644 --- a/PortabilityLayer/PLResourceManager.cpp +++ b/PortabilityLayer/PLResourceManager.cpp @@ -116,7 +116,7 @@ namespace PortabilityLayer IResourceArchive *GetAppResourceArchive() const override; IResourceArchive *LoadResFile(CompositeFile *file) const override; - PLError_t CreateBlankResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) override; + PLError_t CreateBlankResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) GP_ASYNCIFY_PARANOID_OVERRIDE; void DissociateHandle(MMHandleBlock *hdl) const override; const ResourceArchiveRef *ResourceForHandle(MMHandleBlock *hdl) const override; @@ -524,4 +524,11 @@ namespace PortabilityLayer if (m_stream) m_stream->Close(); } + +#if GP_ASYNCIFY_PARANOID + PLError_t ResourceManager::CreateBlankResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) + { + return static_cast(this)->CreateBlankResFile(virtualDir, filename); + } +#endif } diff --git a/PortabilityLayer/PLSysCalls.cpp b/PortabilityLayer/PLSysCalls.cpp index b59a10d..54621ef 100644 --- a/PortabilityLayer/PLSysCalls.cpp +++ b/PortabilityLayer/PLSysCalls.cpp @@ -19,6 +19,7 @@ #include #include +#include static void TranslateMouseInputEvent(const GpVOSEvent &vosEventBase, uint32_t timestamp, PortabilityLayer::EventQueue *queue) { @@ -176,7 +177,7 @@ namespace PLSysCalls { // Asyncify disarm checks are for manually checking that a stack has no indirect calls. // They should not be nested! -#if GP_DEBUG_CONFIG && GP_ASYNCIFY_PARANOID +#if GP_DEBUG_CONFIG && GP_ASYNCIFY_PARANOID_VALIDATION static bool g_asyncifyParanoidDisarmed = false; void AsyncifyParanoidSetDisarmed(bool state) @@ -198,7 +199,7 @@ namespace PLSysCalls void Sleep(uint32_t ticks) { -#if GP_DEBUG_CONFIG && GP_ASYNCIFY_PARANOID +#if GP_DEBUG_CONFIG && GP_ASYNCIFY_PARANOID_VALIDATION assert(g_asyncifyParanoidDisarmed); #endif if (ticks > 0) diff --git a/PortabilityLayer/PLSysCalls.h b/PortabilityLayer/PLSysCalls.h index 0bd77a8..4d4f8ba 100644 --- a/PortabilityLayer/PLSysCalls.h +++ b/PortabilityLayer/PLSysCalls.h @@ -10,7 +10,7 @@ namespace PLSysCalls void Sleep(uint32_t ticks); void Exit(int exitCode); -#if GP_DEBUG_CONFIG && GP_ASYNCIFY_PARANOID +#if GP_DEBUG_CONFIG && GP_ASYNCIFY_PARANOID_VALIDATION class AsyncifyDisarmScope { public: diff --git a/PortabilityLayer/ResourceManager.h b/PortabilityLayer/ResourceManager.h index ea49208..95f0546 100644 --- a/PortabilityLayer/ResourceManager.h +++ b/PortabilityLayer/ResourceManager.h @@ -78,7 +78,7 @@ namespace PortabilityLayer virtual IResourceArchive *GetAppResourceArchive() const = 0; virtual IResourceArchive *LoadResFile(CompositeFile *file) const = 0; - virtual PLError_t CreateBlankResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) = 0; + GP_ASYNCIFY_PARANOID_VIRTUAL PLError_t CreateBlankResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) GP_ASYNCIFY_PARANOID_PURE; virtual void DissociateHandle(MMHandleBlock *hdl) const = 0; virtual const ResourceArchiveRef *ResourceForHandle(MMHandleBlock *hdl) const = 0;