mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-12-13 19:49:36 +00:00
Web file system implementation + fixes
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <emscripten.h>
|
||||
|
||||
#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<char>((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<GpUFilePos_t>(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<GpFileSystem_Web*>(this)->DeleteFile(virtualDirectory, path, existed);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
GpFileSystem_Web GpFileSystem_Web::ms_instance;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -19,18 +19,29 @@
|
||||
#include "IGpVOSEventQueue.h"
|
||||
|
||||
#include <string>
|
||||
#include <emscripten.h>
|
||||
|
||||
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();
|
||||
|
||||
|
||||
@@ -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%
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -602,6 +602,7 @@ Boolean ReadHouse (GpIOStream *houseStream)
|
||||
ByteSwapHouse(*thisHouse, static_cast<size_t>(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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#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)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "GpFileCreationDisposition.h"
|
||||
#include "CoreDefs.h"
|
||||
#include "VirtualDirectory.h"
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -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;
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace PortabilityLayer
|
||||
return static_cast<GpUFilePos_t>(ftell(m_file));
|
||||
}
|
||||
|
||||
void CFileStream::Close()
|
||||
void CFileStream::GP_ASYNCIFY_PARANOID_NAMED(Close)()
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<FileManagerImpl*>(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<FileManagerImpl*>(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<FileManagerImpl*>(this)->CreateFile(dirID, filename, mfp);
|
||||
}
|
||||
|
||||
PLError_t FileManager::CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType)
|
||||
{
|
||||
return static_cast<FileManagerImpl*>(this)->CreateFileAtCurrentTime(dirID, filename, fileCreator, fileType);
|
||||
}
|
||||
|
||||
bool FileManager::DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext)
|
||||
{
|
||||
return static_cast<FileManagerImpl*>(this)->DeleteNonCompositeFile(dirID, filename, ext);
|
||||
}
|
||||
|
||||
bool FileManager::DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename)
|
||||
{
|
||||
return static_cast<FileManagerImpl*>(this)->DeleteCompositeFile(dirID, filename);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace PortabilityLayer
|
||||
return static_cast<GpUFilePos_t>(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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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> &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem) override;
|
||||
void PopupMenuSelect(const THandle<Menu> &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<MenuManagerImpl*>(this)->MenuSelect(initialPoint, outMenu, outItem);
|
||||
}
|
||||
|
||||
void MenuManager::PopupMenuSelect(const THandle<Menu> &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem)
|
||||
{
|
||||
static_cast<MenuManagerImpl*>(this)->PopupMenuSelect(menu, popupMenuPos, initialPoint, initialItem, outItem);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -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> &menu, const Vec2i &popupMenuPos, const Vec2i &initialPoint, size_t initialItem, uint16_t *outItem) = 0;
|
||||
GP_ASYNCIFY_PARANOID_VIRTUAL void PopupMenuSelect(const THandle<Menu> &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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<ResourceManagerImpl*>(this)->CreateBlankResFile(virtualDir, filename);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user