From 511548a2ee54c5ceb2fd858919b278721cf5ba31 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 28 Sep 2024 23:44:24 -0500 Subject: [PATCH] Squashed 'deps/nostalgia/' changes from 5f10edd3..0daf938f 0daf938f [nostalgia/core/studio] Cleanup, make all number keys after num colors jump to last b90ab27a [nostalgia/core/studio] Fix Palette Color Name input to properly take focus c711f435 [nostalgia/core/studio] Fix PaletteEditor 0 key shortcut 84cb03d8 [nostalgia/core/studio] Cleanup 945a55f9 [studio] Fix Project to cut off correct end of OC data 2173b12c [nostalgia/core/studio] Give PaletteEditor keyboard shortcuts aa970b1f [keel,studio] Cleanup 6ad79b30 [ox] Cleanup a7cf2673 [studio] Remove null terminator from OC output 1a9f0d49 [ox] Rename CRString to StringCR a1b5b565 [olympic,nostalgia] Rename CRStringView to StringViewCR 256be6da [glutils] Rename CRStringView to StringViewCR cc10631b [ox] Rename CRStringView to StringViewCR 829dc029 [keel] Fix Linux build e8a1ff06 [ox/oc] Fix Linux build bdfb5e97 [nostalgia/core] Cleanup 396fecab [ox/oc] Add option for writeOC to return a string 5373b63c [keel,studio] Removing null terminator from JSON file output 8b655c40 [ox/std] Add HashMap::values 92d85d11 Merge commit '9f5f3e26efed6cd27f2a8ff0746f018d75986934' 118fef61 [buildcore] Remove python -m prefix from mypy command 8769305d [nostalgia] Allow disabling of BUILD_SHARED_LIBS c5999050 [nostalgia] Add support for partial tilesheet loading da23c930 [ox/std] Add oxModelFwdDecl macro for broken Apple Clang 3ae1d6c8 [ox/std] Make operator[] in Array and Vector nodiscard a7af6c66 [keel] Cleanup 0cc6757c [keel] Add manifest to pack output 3b8eaef3 [keel] Move vald and repair funcs to their own file, make conversion to validation b7990ed2 [keel] Make pack file copy logging nest for dir level 71313ed8 [ox/std] Cleanup 10531b6e [keel] Cleanup dfbc298d [keel] Add pack file copy status to logging 76760daf [ox/std] Cleanup Defer 5834b9c9 [ox/std] Cleanup logging output 2a584905 [ox/fs] More cleanup and bug fix from previous cleanup 702b166b [ox/fs] Cleanup 8dd837b3 [nostalgia/core] Add a valid function for CompactTileSheet 1d262597 [keel] Make default repair return a no repair error 712299fa [studio] Cleanup c45efa60 [ox/std] Make Result copyTo and moveTo able to convert git-subtree-dir: deps/nostalgia git-subtree-split: 0daf938f765b3a3ce8ba7fb292572a6a5a004634 --- .gitignore | 1 + CMakeLists.txt | 2 +- deps/buildcore/base.mk | 7 +- deps/glutils/src/glutils.cpp | 2 +- deps/ox/src/ox/clargs/clargs.cpp | 12 +- deps/ox/src/ox/clargs/clargs.hpp | 12 +- .../src/ox/fs/filestore/filestoretemplate.hpp | 6 +- deps/ox/src/ox/fs/filesystem/directory.hpp | 117 +++++++----------- deps/ox/src/ox/fs/filesystem/filelocation.cpp | 4 +- deps/ox/src/ox/fs/filesystem/filelocation.hpp | 4 +- deps/ox/src/ox/fs/filesystem/filesystem.cpp | 2 +- deps/ox/src/ox/fs/filesystem/filesystem.hpp | 87 +++++++------ .../ox/src/ox/fs/filesystem/passthroughfs.cpp | 17 ++- .../ox/src/ox/fs/filesystem/passthroughfs.hpp | 20 +-- deps/ox/src/ox/fs/filesystem/pathiterator.cpp | 49 ++------ deps/ox/src/ox/fs/filesystem/pathiterator.hpp | 24 +--- deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp | 2 +- deps/ox/src/ox/fs/ptrarith/ptr.hpp | 4 +- deps/ox/src/ox/fs/test/CMakeLists.txt | 1 - deps/ox/src/ox/fs/test/tests.cpp | 52 ++++---- deps/ox/src/ox/logconn/logconn.cpp | 2 +- deps/ox/src/ox/logconn/logconn.hpp | 2 +- deps/ox/src/ox/mc/test/tests.cpp | 4 +- deps/ox/src/ox/model/def.hpp | 4 +- deps/ox/src/ox/model/desctypes.hpp | 2 +- deps/ox/src/ox/model/descwrite.hpp | 42 +++---- deps/ox/src/ox/model/fieldcounter.hpp | 8 +- deps/ox/src/ox/model/modelvalue.hpp | 2 +- deps/ox/src/ox/model/typestore.hpp | 4 +- deps/ox/src/ox/oc/test/tests.cpp | 4 +- deps/ox/src/ox/oc/write.hpp | 24 +++- deps/ox/src/ox/preloader/alignmentcatcher.hpp | 6 +- deps/ox/src/ox/preloader/preloader.hpp | 36 +++--- deps/ox/src/ox/preloader/unionsizecatcher.hpp | 18 +-- deps/ox/src/ox/std/array.hpp | 4 +- deps/ox/src/ox/std/assert.hpp | 25 ++-- deps/ox/src/ox/std/defer.hpp | 9 +- deps/ox/src/ox/std/error.hpp | 9 +- deps/ox/src/ox/std/hashmap.hpp | 13 ++ deps/ox/src/ox/std/istring.hpp | 4 +- deps/ox/src/ox/std/stacktrace.cpp | 22 ++++ deps/ox/src/ox/std/stacktrace.hpp | 5 + deps/ox/src/ox/std/string.hpp | 20 +-- deps/ox/src/ox/std/stringview.hpp | 12 +- deps/ox/src/ox/std/strops.hpp | 18 +-- deps/ox/src/ox/std/tracehook.cpp | 37 +++--- deps/ox/src/ox/std/uuid.hpp | 4 +- deps/ox/src/ox/std/vector.hpp | 2 + scripts/pkg-gba.py | 6 +- .../core/include/nostalgia/core/gfx.hpp | 12 +- .../core/include/nostalgia/core/palette.hpp | 62 +++++----- .../core/include/nostalgia/core/tilesheet.hpp | 85 ++++++++++--- src/nostalgia/modules/core/src/gba/gfx.cpp | 41 ++++-- src/nostalgia/modules/core/src/gfx.cpp | 2 +- src/nostalgia/modules/core/src/opengl/gfx.cpp | 84 ++++++++++--- src/nostalgia/modules/core/src/opengl/gfx.hpp | 1 + .../paletteeditor/paletteeditor-imgui.cpp | 30 +++-- .../paletteeditor/paletteeditor-imgui.hpp | 2 + .../commands/cutpastecommand.hpp | 2 + .../commands/palettechangecommand.cpp | 2 +- .../commands/palettechangecommand.hpp | 2 +- .../tilesheeteditor/tilesheeteditor-imgui.cpp | 6 +- src/nostalgia/modules/core/src/tilesheet.cpp | 47 ++++++- .../modules/scene/src/studio/sceneeditor.cpp | 2 +- .../modules/scene/src/studio/sceneeditor.hpp | 2 +- .../keel/include/keel/assetmanager.hpp | 17 +-- src/olympic/keel/include/keel/keel.hpp | 4 +- src/olympic/keel/include/keel/media.hpp | 16 ++- src/olympic/keel/include/keel/module.hpp | 2 +- src/olympic/keel/include/keel/pack.hpp | 41 +++++- src/olympic/keel/include/keel/typeconv.hpp | 41 +++--- src/olympic/keel/include/keel/validation.hpp | 27 ++++ src/olympic/keel/src/keel.cpp | 4 +- src/olympic/keel/src/media.cpp | 26 ++-- src/olympic/keel/src/pack-applib.cpp | 17 ++- src/olympic/keel/src/pack.cpp | 69 ++++++++--- src/olympic/keel/src/typeconv.cpp | 15 ++- src/olympic/studio/applib/src/clawviewer.cpp | 10 +- src/olympic/studio/applib/src/clawviewer.hpp | 8 +- src/olympic/studio/applib/src/main.cpp | 8 +- .../studio/applib/src/projectexplorer.cpp | 2 +- .../studio/applib/src/projectexplorer.hpp | 2 +- src/olympic/studio/applib/src/studioapp.cpp | 34 +++-- src/olympic/studio/applib/src/studioapp.hpp | 8 +- .../studio/modlib/include/studio/configio.hpp | 8 +- .../modlib/include/studio/filedialog.hpp | 2 +- .../studio/modlib/include/studio/module.hpp | 4 +- .../studio/modlib/include/studio/project.hpp | 47 +++---- .../studio/modlib/src/filedialog_nfd.cpp | 2 +- src/olympic/studio/modlib/src/project.cpp | 26 ++-- .../turbine/include/turbine/clipboard.hpp | 2 +- src/olympic/turbine/include/turbine/gfx.hpp | 2 +- .../turbine/include/turbine/turbine.hpp | 2 +- src/olympic/turbine/src/gba/clipboard.cpp | 2 +- src/olympic/turbine/src/gba/gfx.cpp | 2 +- src/olympic/turbine/src/gba/turbine.cpp | 2 +- src/olympic/turbine/src/glfw/clipboard.cpp | 2 +- src/olympic/turbine/src/glfw/gfx.cpp | 2 +- src/olympic/turbine/src/glfw/turbine.cpp | 2 +- 99 files changed, 932 insertions(+), 681 deletions(-) create mode 100644 src/olympic/keel/include/keel/validation.hpp diff --git a/.gitignore b/.gitignore index 35f0222..3186e14 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ imgui.ini *.sav studio_state.json tags +*-manifest.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 9529a1e..289ffb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ set(CMAKE_CXX_STANDARD 23) if(APPLE) set(CMAKE_MACOSX_RPATH OFF) else() - if(UNIX) + if(UNIX AND NOT DEFINED BUILD_SHARED_LIBS) set(BUILD_SHARED_LIBS ON) endif() set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib") diff --git a/deps/buildcore/base.mk b/deps/buildcore/base.mk index 839510c..ff56f63 100644 --- a/deps/buildcore/base.mk +++ b/deps/buildcore/base.mk @@ -44,6 +44,9 @@ ifdef BC_VAR_USE_DOCKER_DEVENV exit 1 endif endif + ifndef BC_VAR_DEVENV_ROOT + BC_VAR_DEVENV_ROOT="." + endif else BC_CMD_PY3=${BC_CMD_HOST_PY3} endif @@ -90,7 +93,7 @@ purge: ${BC_CMD_RM_RF} compile_commands.json .PHONY: test test: build - ${BC_CMD_ENVRUN} ${BC_CMD_PY3} -m mypy ${BC_VAR_SCRIPTS} + ${BC_CMD_ENVRUN} mypy ${BC_VAR_SCRIPTS} ${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} test .PHONY: test-verbose test-verbose: build @@ -102,7 +105,7 @@ test-rerun-verbose: build ifdef BC_VAR_USE_DOCKER_DEVENV .PHONY: devenv-image devenv-image: - docker build . -t ${BC_VAR_DEVENV_IMAGE} + docker build ${BC_VAR_DEVENV_ROOT} -t ${BC_VAR_DEVENV_IMAGE} .PHONY: devenv-create devenv-create: docker run -d \ diff --git a/deps/glutils/src/glutils.cpp b/deps/glutils/src/glutils.cpp index d84f40b..c02f9f7 100644 --- a/deps/glutils/src/glutils.cpp +++ b/deps/glutils/src/glutils.cpp @@ -73,7 +73,7 @@ void bind(const FrameBuffer &fb) noexcept { static ox::Result buildShader( GLuint shaderType, const GLchar *src, - ox::CRStringView shaderName) noexcept { + ox::StringViewCR shaderName) noexcept { GLShader shader(glCreateShader(shaderType)); glShaderSource(shader, 1, &src, nullptr); glCompileShader(shader); diff --git a/deps/ox/src/ox/clargs/clargs.cpp b/deps/ox/src/ox/clargs/clargs.cpp index 41feed5..7cb8033 100644 --- a/deps/ox/src/ox/clargs/clargs.cpp +++ b/deps/ox/src/ox/clargs/clargs.cpp @@ -37,32 +37,32 @@ ClArgs::ClArgs(int argc, const char **args) noexcept { } } -bool ClArgs::getBool(ox::CRStringView arg, bool defaultValue) const noexcept { +bool ClArgs::getBool(ox::StringViewCR arg, bool defaultValue) const noexcept { auto [value, err] = m_ints.at(arg); return !err ? *value : defaultValue; } -String ClArgs::getString(ox::CRStringView arg, ox::StringView defaultValue) const noexcept { +String ClArgs::getString(ox::StringViewCR arg, ox::StringView defaultValue) const noexcept { auto [value, err] = m_strings.at(arg); return !err ? ox::String(*value) : ox::String(defaultValue); } -int ClArgs::getInt(ox::CRStringView arg, int defaultValue) const noexcept { +int ClArgs::getInt(ox::StringViewCR arg, int defaultValue) const noexcept { auto [value, err] = m_ints.at(arg); return !err ? *value : defaultValue; } -Result ClArgs::getBool(ox::CRStringView arg) const noexcept { +Result ClArgs::getBool(ox::StringViewCR arg) const noexcept { oxRequire(out, m_bools.at(arg)); return *out; } -Result ClArgs::getString(ox::CRStringView argName) const noexcept { +Result ClArgs::getString(ox::StringViewCR argName) const noexcept { oxRequire(out, m_strings.at(argName)); return *out; } -Result ClArgs::getInt(ox::CRStringView arg) const noexcept { +Result ClArgs::getInt(ox::StringViewCR arg) const noexcept { oxRequire(out, m_ints.at(arg)); return *out; } diff --git a/deps/ox/src/ox/clargs/clargs.hpp b/deps/ox/src/ox/clargs/clargs.hpp index ed51440..610d625 100644 --- a/deps/ox/src/ox/clargs/clargs.hpp +++ b/deps/ox/src/ox/clargs/clargs.hpp @@ -23,21 +23,21 @@ class ClArgs { ClArgs(int argc, const char **args) noexcept; [[nodiscard]] - bool getBool(ox::CRStringView arg, bool defaultValue) const noexcept; + bool getBool(ox::StringViewCR arg, bool defaultValue) const noexcept; [[nodiscard]] - String getString(ox::CRStringView argName, ox::StringView defaultValue) const noexcept; + String getString(ox::StringViewCR argName, ox::StringView defaultValue) const noexcept; [[nodiscard]] - int getInt(ox::CRStringView arg, int defaultValue) const noexcept; + int getInt(ox::StringViewCR arg, int defaultValue) const noexcept; [[nodiscard]] - Result getBool(ox::CRStringView arg) const noexcept; + Result getBool(ox::StringViewCR arg) const noexcept; [[nodiscard]] - Result getString(ox::CRStringView argName) const noexcept; + Result getString(ox::StringViewCR argName) const noexcept; - Result getInt(ox::CRStringView arg) const noexcept; + Result getInt(ox::StringViewCR arg) const noexcept; }; diff --git a/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp b/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp index 9241767..8d0505b 100644 --- a/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp +++ b/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp @@ -315,7 +315,7 @@ Error FileStoreTemplate::remove(uint64_t id) { template Error FileStoreTemplate::read(uint64_t id, void *out, FsSize_t outSize, FsSize_t *size) const { - oxTracef("ox.fs.FileStoreTemplate.read", "Attempting to read from inode {}", id); + oxTracef("ox.fs.FileStoreTemplate.read", "Attempting to read inode {}", id); auto src = find(static_cast(id)); // error check if (!src.valid()) { @@ -333,7 +333,7 @@ Error FileStoreTemplate::read(uint64_t id, void *out, FsSize_t outSize, oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id); oxTracef("ox.fs.FileStoreTemplate.read.fail", "Item data section size: {}, Expected size: {}", srcData.size(), outSize); - return OxError(1); + return OxError(1, "Invalid inode"); } ox::memcpy(out, srcData, srcData.size()); @@ -341,7 +341,7 @@ Error FileStoreTemplate::read(uint64_t id, void *out, FsSize_t outSize, *size = src.size(); } - return OxError(0); + return {}; } template diff --git a/deps/ox/src/ox/fs/filesystem/directory.hpp b/deps/ox/src/ox/fs/filesystem/directory.hpp index 5548fdd..5adff26 100644 --- a/deps/ox/src/ox/fs/filesystem/directory.hpp +++ b/deps/ox/src/ox/fs/filesystem/directory.hpp @@ -43,13 +43,15 @@ struct OX_PACKED DirectoryEntry { public: constexpr DirectoryEntry() noexcept = default; - Error init(InodeId_t inode, const char *name, InodeId_t bufferSize) noexcept { - m_bufferSize = bufferSize; + Error init(InodeId_t inode, ox::StringViewCR name, size_t bufferSize) noexcept { + oxTracef("ox.fs.DirectoryEntry.init", "inode: {}, name: {}, bufferSize: {}", inode, name, bufferSize); + m_bufferSize = static_cast(bufferSize); auto d = data(); if (d.valid()) { d->inode = inode; - ox::strncpy(d->name, name, ox::min(bufferSize, static_cast(MaxFileNameLength))); - return OxError(0); + auto const maxStrSz = bufferSize - 1 - sizeof(*this); + ox::strncpy(d->name, name.data(), ox::min(maxStrSz, name.len())); + return {}; } return OxError(1); } @@ -103,23 +105,23 @@ class Directory { */ Error init() noexcept; - Error mkdir(PathIterator path, bool parents, FileName *nameBuff = nullptr); + Error mkdir(PathIterator path, bool parents); /** * @param parents indicates the operation should create non-existent directories in the path, like mkdir -p */ - Error write(PathIterator path, uint64_t inode64, FileName *nameBuff = nullptr) noexcept; + Error write(PathIterator path, uint64_t inode64) noexcept; - Error remove(PathIterator path, FileName *nameBuff = nullptr) noexcept; + Error remove(PathIterator path) noexcept; template Error ls(F cb) noexcept; [[nodiscard]] - Result findEntry(const FileName &name) const noexcept; + Result findEntry(const StringView &name) const noexcept; [[nodiscard]] - Result find(PathIterator name, FileName *nameBuff = nullptr) const noexcept; + Result find(PathIterator path) const noexcept; }; @@ -145,22 +147,17 @@ Error Directory::init() noexcept { } new (buff) Buffer(Size); m_size = Size; - return OxError(0); + return {}; } template -Error Directory::mkdir(PathIterator path, bool parents, FileName *nameBuff) { +Error Directory::mkdir(PathIterator path, bool parents) { if (path.valid()) { oxTrace("ox.fs.Directory.mkdir", path.fullPath()); - // reuse nameBuff if it has already been allocated, as it is a rather large variable - if (nameBuff == nullptr) { - nameBuff = new (ox_alloca(sizeof(FileName))) FileName; - } - // determine if already exists - auto name = nameBuff; - oxReturnError(path.get(*name)); - auto childInode = find(PathIterator(*name)); + ox::StringView name; + oxReturnError(path.get(name)); + auto childInode = find(PathIterator(name)); if (!childInode.ok()) { // if this is not the last item in the path and parents is disabled, // return an error @@ -171,12 +168,10 @@ Error Directory::mkdir(PathIterator path, bool parents, Fi oxTracef("ox.fs.Directory.mkdir", "Generated Inode ID: {}", childInode.value); oxLogError(childInode.error); oxReturnError(childInode.error); - // initialize the directory Directory child(m_fs, childInode.value); oxReturnError(child.init()); - - auto err = write(PathIterator(*name), childInode.value); + auto err = write(PathIterator(name), childInode.value); if (err) { oxLogError(err); // could not index the directory, delete it @@ -184,46 +179,35 @@ Error Directory::mkdir(PathIterator path, bool parents, Fi return err; } } - Directory child(m_fs, childInode.value); if (path.hasNext()) { - oxReturnError(child.mkdir(path.next(), parents, nameBuff)); + oxReturnError(child.mkdir(path.next(), parents)); } } - return OxError(0); + return {}; } template -Error Directory::write(PathIterator path, uint64_t inode64, FileName *nameBuff) noexcept { +Error Directory::write(PathIterator path, uint64_t inode64) noexcept { const auto inode = static_cast(inode64); - // reuse nameBuff if it has already been allocated, as it is a rather large variable - if (nameBuff == nullptr) { - nameBuff = new (ox_alloca(sizeof(FileName))) FileName; - } - auto name = nameBuff; - + ox::StringView name; if (path.next().hasNext()) { // not yet at target directory, recurse to next one - oxReturnError(path.get(*name)); oxTracef("ox.fs.Directory.write", "Attempting to write to next sub-Directory: {} of {}", - *name, path.fullPath()); - oxRequire(nextChild, findEntry(*name)); - oxTracef("ox.fs.Directory.write", "{}: {}", *name, nextChild); + name, path.fullPath()); + oxReturnError(path.get(name)); + oxRequire(nextChild, findEntry(name)); + oxTracef("ox.fs.Directory.write", "{}: {}", name, nextChild); if (nextChild) { - // reuse name because it is a rather large variable and will not be used again - // be attentive that this remains true - name = nullptr; - return Directory(m_fs, nextChild).write(path.next(), inode, nameBuff); + return Directory(m_fs, nextChild).write(path.next(), inode); } else { - oxTracef("ox.fs.Directory.write", "{} not found and not allowed to create it.", *name); + oxTracef("ox.fs.Directory.write", "{} not found and not allowed to create it.", name); return OxError(1, "File not found and not allowed to create it."); } } else { oxTrace("ox.fs.Directory.write", path.fullPath()); + oxReturnError(path.next(name)); // insert the new entry on this directory - // get the name - oxReturnError(path.next(*name)); - // find existing version of directory oxTracef("ox.fs.Directory.write", "Searching for directory inode {}", m_inodeId); oxRequire(oldStat, m_fs.stat(m_inodeId)); @@ -233,8 +217,7 @@ Error Directory::write(PathIterator path, uint64_t inode64 oxTrace("ox.fs.Directory.write.fail", "Could not read existing version of Directory"); return OxError(1, "Could not read existing version of Directory"); } - - const auto pathSize = name->len() + 1; + const auto pathSize = name.len() + 1; const auto entryDataSize = DirectoryEntry::DirectoryEntryData::spaceNeeded(pathSize); const auto newSize = oldStat.size + Buffer::spaceNeeded(entryDataSize); auto cpy = ox_malloca(newSize, Buffer, *old, oldStat.size); @@ -242,29 +225,22 @@ Error Directory::write(PathIterator path, uint64_t inode64 oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for copy of Directory"); return OxError(1, "Could not allocate memory for copy of Directory"); } - oxReturnError(cpy->setSize(newSize)); auto val = cpy->malloc(entryDataSize).value; if (!val.valid()) { oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for new directory entry"); return OxError(1, "Could not allocate memory for new directory entry"); } - - oxTracef("ox.fs.Directory.write", "Attempting to write Directory entry: {}", name->data()); - oxReturnError(val->init(inode, name->data(), val.size())); + oxTracef("ox.fs.Directory.write", "Attempting to write Directory entry: {}", name); + oxReturnError(val->init(inode, name, val.size())); return m_fs.write(m_inodeId, cpy.get(), cpy->size(), static_cast(FileType::Directory)); } } template -Error Directory::remove(PathIterator path, FileName *nameBuff) noexcept { - // reuse nameBuff if it has already been allocated, as it is a rather large variable - if (nameBuff == nullptr) { - nameBuff = new (ox_alloca(sizeof(FileName))) FileName; - } - auto &name = *nameBuff; +Error Directory::remove(PathIterator path) noexcept { + ox::StringView name; oxReturnError(path.get(name)); - oxTrace("ox.fs.Directory.remove", name); auto buff = m_fs.read(m_inodeId).template to(); if (buff.valid()) { @@ -283,7 +259,7 @@ Error Directory::remove(PathIterator path, FileName *nameB oxTrace("ox.fs.Directory.remove.fail", "Could not find directory buffer"); return OxError(1, "Could not find directory buffer"); } - return OxError(0); + return {}; } template @@ -295,7 +271,6 @@ Error Directory::ls(F cb) noexcept { oxTrace("ox.fs.Directory.ls.fail", "Could not directory buffer"); return OxError(1, "Could not directory buffer"); } - oxTrace("ox.fs.Directory.ls", "Found directory buffer."); for (auto i = buff->iterator(); i.valid(); i.next()) { auto data = i->data(); @@ -305,12 +280,11 @@ Error Directory::ls(F cb) noexcept { oxTrace("ox.fs.Directory.ls", "INVALID DIRECTORY ENTRY"); } } - - return OxError(0); + return {}; } template -Result Directory::findEntry(const FileName &name) const noexcept { +Result Directory::findEntry(StringViewCR name) const noexcept { oxTrace("ox.fs.Directory.findEntry", name); auto buff = m_fs.read(m_inodeId).template to(); if (!buff.valid()) { @@ -327,7 +301,7 @@ Result Directory::findEntry return static_cast(data->inode); } } else { - oxTrace("ox.fs.Directory.findEntry") << "INVALID DIRECTORY ENTRY"; + oxTrace("ox.fs.Directory.findEntry", "INVALID DIRECTORY ENTRY"); } } oxTrace("ox.fs.Directory.findEntry.fail", "Entry not present"); @@ -335,22 +309,15 @@ Result Directory::findEntry } template -Result Directory::find(PathIterator path, FileName *nameBuff) const noexcept { - // reuse nameBuff if it has already been allocated, as it is a rather large variable - if (nameBuff == nullptr) { - nameBuff = new (ox_alloca(sizeof(FileName))) FileName; - } - +Result Directory::find(PathIterator path) const noexcept { // determine if already exists - auto name = nameBuff; - oxReturnError(path.get(*name)); - - oxRequire(v, findEntry(*name)); + ox::StringView name; + oxReturnError(path.get(name)); + oxRequire(v, findEntry(name)); // recurse if not at end of path if (auto p = path.next(); p.valid()) { Directory dir(m_fs, v); - name = nullptr; - return dir.find(p, nameBuff); + return dir.find(p); } return v; } diff --git a/deps/ox/src/ox/fs/filesystem/filelocation.cpp b/deps/ox/src/ox/fs/filesystem/filelocation.cpp index df5f8a1..51b9f2d 100644 --- a/deps/ox/src/ox/fs/filesystem/filelocation.cpp +++ b/deps/ox/src/ox/fs/filesystem/filelocation.cpp @@ -28,7 +28,7 @@ FileAddress::FileAddress(uint64_t inode) noexcept { m_type = FileAddressType::Inode; } -FileAddress::FileAddress(ox::CRStringView path) noexcept { +FileAddress::FileAddress(ox::StringViewCR path) noexcept { auto pathSize = path.bytes(); m_data.path = new char[pathSize + 1]; memcpy(m_data.path, path.data(), pathSize); @@ -114,7 +114,7 @@ bool FileAddress::operator==(FileAddress const&other) const noexcept { return true; } -bool FileAddress::operator==(CRStringView path) const noexcept { +bool FileAddress::operator==(StringViewCR path) const noexcept { auto [p, err] = getPath(); if (err) { return false; diff --git a/deps/ox/src/ox/fs/filesystem/filelocation.hpp b/deps/ox/src/ox/fs/filesystem/filelocation.hpp index 4ce349f..c8f6cfa 100644 --- a/deps/ox/src/ox/fs/filesystem/filelocation.hpp +++ b/deps/ox/src/ox/fs/filesystem/filelocation.hpp @@ -57,7 +57,7 @@ class FileAddress { FileAddress(uint64_t inode) noexcept; - explicit FileAddress(CRStringView path) noexcept; + explicit FileAddress(StringViewCR path) noexcept; constexpr FileAddress(ox::StringLiteral path) noexcept; @@ -69,7 +69,7 @@ class FileAddress { bool operator==(const FileAddress &other) const noexcept; - bool operator==(CRStringView path) const noexcept; + bool operator==(StringViewCR path) const noexcept; [[nodiscard]] constexpr FileAddressType type() const noexcept { diff --git a/deps/ox/src/ox/fs/filesystem/filesystem.cpp b/deps/ox/src/ox/fs/filesystem/filesystem.cpp index 16c28cb..5b9b771 100644 --- a/deps/ox/src/ox/fs/filesystem/filesystem.cpp +++ b/deps/ox/src/ox/fs/filesystem/filesystem.cpp @@ -44,7 +44,7 @@ Result FileSystem::read(const FileAddress &addr) noexcept { return buff; } -Result FileSystem::read(CRStringView path) noexcept { +Result FileSystem::read(StringViewCR path) noexcept { oxRequire(s, statPath(path)); Buffer buff(static_cast(s.size)); oxReturnError(readFilePath(path, buff.data(), buff.size())); diff --git a/deps/ox/src/ox/fs/filesystem/filesystem.hpp b/deps/ox/src/ox/fs/filesystem/filesystem.hpp index c39f556..a8c6110 100644 --- a/deps/ox/src/ox/fs/filesystem/filesystem.hpp +++ b/deps/ox/src/ox/fs/filesystem/filesystem.hpp @@ -30,22 +30,22 @@ class FileSystem { public: virtual ~FileSystem() noexcept = default; - virtual Error mkdir(CRStringView path, bool recursive) noexcept = 0; + virtual Error mkdir(StringViewCR path, bool recursive) noexcept = 0; /** * Moves an entry from one directory to another. * @param src the path to the file * @param dest the path of the destination directory */ - virtual Error move(CRStringView src, CRStringView dest) noexcept = 0; + virtual Error move(StringViewCR src, StringViewCR dest) noexcept = 0; Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept; Result read(const FileAddress &addr) noexcept; - Result read(CRStringView path) noexcept; + Result read(StringViewCR path) noexcept; - inline Error read(CRStringView path, void *buffer, std::size_t buffSize) noexcept { + inline Error read(StringViewCR path, void *buffer, std::size_t buffSize) noexcept { return readFilePath(path, buffer, buffSize); } @@ -55,19 +55,19 @@ class FileSystem { Error read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept; - virtual Result> ls(CRStringView dir) const noexcept = 0; + virtual Result> ls(StringViewCR dir) const noexcept = 0; - virtual Error remove(CRStringView path, bool recursive) noexcept = 0; + virtual Error remove(StringViewCR path, bool recursive) noexcept = 0; Error remove(const FileAddress &addr, bool recursive = false) noexcept; virtual Error resize(uint64_t size, void *buffer) noexcept = 0; - Error write(CRStringView path, const void *buffer, uint64_t size) noexcept { + Error write(StringViewCR path, const void *buffer, uint64_t size) noexcept { return writeFilePath(path, buffer, size, FileType::NormalFile); } - Error write(CRStringView path, ox::Span const&buff) noexcept { + Error write(StringViewCR path, ox::Span const&buff) noexcept { return write(path, buff.data(), buff.size(), FileType::NormalFile); } @@ -81,7 +81,7 @@ class FileSystem { Error write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType = FileType::NormalFile) noexcept; - inline Error write(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept { + inline Error write(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept { return writeFilePath(path, buffer, size, fileType); } @@ -93,7 +93,7 @@ class FileSystem { return statInode(inode); } - inline Result stat(CRStringView path) const noexcept { + inline Result stat(StringViewCR path) const noexcept { return statPath(path); } @@ -134,15 +134,15 @@ class FileSystem { protected: virtual Result statInode(uint64_t inode) const noexcept = 0; - virtual Result statPath(CRStringView path) const noexcept = 0; + virtual Result statPath(StringViewCR path) const noexcept = 0; - virtual Error readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept = 0; + virtual Error readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept = 0; virtual Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept = 0; virtual Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept = 0; - virtual Error writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept = 0; + virtual Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept = 0; virtual Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept = 0; @@ -152,7 +152,7 @@ class MemFS: public FileSystem { public: Result directAccess(const FileAddress &addr) const noexcept; - inline Result directAccess(CRStringView path) const noexcept { + inline Result directAccess(StringViewCR path) const noexcept { return directAccessPath(path); } @@ -161,7 +161,7 @@ class MemFS: public FileSystem { } protected: - virtual Result directAccessPath(CRStringView path) const noexcept = 0; + virtual Result directAccessPath(StringViewCR path) const noexcept = 0; virtual Result directAccessInode(uint64_t inode) const noexcept = 0; }; @@ -197,13 +197,13 @@ class FileSystemTemplate: public MemFS { static Error format(void *buff, uint64_t buffSize) noexcept; - Error mkdir(CRStringView path, bool recursive) noexcept override; + Error mkdir(StringViewCR path, bool recursive) noexcept override; - Error move(CRStringView src, CRStringView dest) noexcept override; + Error move(StringViewCR src, StringViewCR dest) noexcept override; - Error readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept override; + Error readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept override; - Result directAccessPath(CRStringView) const noexcept override; + Result directAccessPath(StringViewCR) const noexcept override; Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override; @@ -211,12 +211,12 @@ class FileSystemTemplate: public MemFS { Result directAccessInode(uint64_t) const noexcept override; - Result> ls(CRStringView dir) const noexcept override; + Result> ls(StringViewCR dir) const noexcept override; template - Error ls(CRStringView path, F cb) const; + Error ls(StringViewCR path, F cb) const; - Error remove(CRStringView path, bool recursive) noexcept override; + Error remove(StringViewCR path, bool recursive) noexcept override; /** * Resizes FileSystem to minimum possible size. @@ -225,13 +225,13 @@ class FileSystemTemplate: public MemFS { Error resize(uint64_t size, void *buffer) noexcept override; - Error writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept override; + Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept override; Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override; Result statInode(uint64_t inode) const noexcept override; - Result statPath(CRStringView path) const noexcept override; + Result statPath(StringViewCR path) const noexcept override; [[nodiscard]] uint64_t spaceNeeded(uint64_t size) const noexcept override; @@ -253,7 +253,7 @@ class FileSystemTemplate: public MemFS { /** * Finds the inode ID at the given path. */ - Result find(CRStringView path) const noexcept; + Result find(StringViewCR path) const noexcept; Result rootDir() const noexcept; @@ -305,14 +305,14 @@ Error FileSystemTemplate::format(void *buff, uint64_t buff } template -Error FileSystemTemplate::mkdir(CRStringView path, bool recursive) noexcept { +Error FileSystemTemplate::mkdir(StringViewCR path, bool recursive) noexcept { oxTracef("ox.fs.FileSystemTemplate.mkdir", "path: {}, recursive: {}", path, recursive); oxRequireM(rootDir, this->rootDir()); return rootDir.mkdir(path, recursive); } template -Error FileSystemTemplate::move(CRStringView src, CRStringView dest) noexcept { +Error FileSystemTemplate::move(StringViewCR src, StringViewCR dest) noexcept { oxRequire(fd, fileSystemData()); Directory rootDir(m_fs, fd.rootDirInode); oxRequireM(inode, rootDir.find(src)); @@ -322,7 +322,8 @@ Error FileSystemTemplate::move(CRStringView src, CRStringV } template -Error FileSystemTemplate::readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept { +Error FileSystemTemplate::readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept { + oxTrace("ox.fs.FileSystemTemplate.readFilePath", path); oxRequire(fd, fileSystemData()); Directory rootDir(m_fs, fd.rootDirInode); oxRequire(s, stat(path)); @@ -333,7 +334,7 @@ Error FileSystemTemplate::readFilePath(CRStringView path, } template -Result FileSystemTemplate::directAccessPath(CRStringView path) const noexcept { +Result FileSystemTemplate::directAccessPath(StringViewCR path) const noexcept { oxRequire(fd, fileSystemData()); Directory rootDir(m_fs, fd.rootDirInode); oxRequire(inode, rootDir.find(path)); @@ -342,6 +343,7 @@ Result FileSystemTemplate::directAccessPath(C template Error FileSystemTemplate::readFileInode(uint64_t inode, void *buffer, std::size_t buffSize) noexcept { + oxTracef("ox.fs.FileSystemTemplate.readFileInode", "{}", inode); oxRequire(s, stat(inode)); if (s.size > buffSize) { return OxError(1, "Buffer to small to load file"); @@ -364,9 +366,9 @@ Result FileSystemTemplate::directAccessInode( } template -Result> FileSystemTemplate::ls(CRStringView path) const noexcept { +Result> FileSystemTemplate::ls(StringViewCR path) const noexcept { Vector out; - oxReturnError(ls(path, [&out](CRStringView name, typename FileStore::InodeId_t) { + oxReturnError(ls(path, [&out](StringViewCR name, typename FileStore::InodeId_t) { out.emplace_back(name); return OxError(0); })); @@ -375,7 +377,7 @@ Result> FileSystemTemplate::ls(CRStringView template template -Error FileSystemTemplate::ls(CRStringView path, F cb) const { +Error FileSystemTemplate::ls(StringViewCR path, F cb) const { oxTracef("ox.fs.FileSystemTemplate.ls", "path: {}", path); oxRequire(s, stat(path)); Directory dir(m_fs, s.inode); @@ -383,7 +385,7 @@ Error FileSystemTemplate::ls(CRStringView path, F cb) cons } template -Error FileSystemTemplate::remove(CRStringView path, bool recursive) noexcept { +Error FileSystemTemplate::remove(StringViewCR path, bool recursive) noexcept { oxRequire(fd, fileSystemData()); Directory rootDir(m_fs, fd.rootDirInode); oxRequire(inode, rootDir.find(path)); @@ -409,24 +411,29 @@ Error FileSystemTemplate::resize() noexcept { template Error FileSystemTemplate::resize(uint64_t size, void *buffer) noexcept { oxReturnError(m_fs.resize(static_cast(size), buffer)); - return OxError(0); + return {}; } template -Error FileSystemTemplate::writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept { +Error FileSystemTemplate::writeFilePath( + StringViewCR path, + const void *buffer, + uint64_t size, + FileType fileType) noexcept { + oxTrace("ox.fs.FileSystemTemplate.writeFilePath", path); auto [inode, err] = find(path); if (err) { - oxRequire(generatedId, m_fs.generateInodeId()); - inode = generatedId; + oxReturnError(m_fs.generateInodeId().moveTo(inode)); oxRequireM(rootDir, this->rootDir()); oxReturnError(rootDir.write(path, inode)); } oxReturnError(writeFileInode(inode, buffer, size, fileType)); - return OxError(0); + return {}; } template Error FileSystemTemplate::writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept { + oxTrace("ox.fs.FileSystemTemplate.writeFileInode", ox::itoa(inode)); return m_fs.write(inode, buffer, static_cast(size), static_cast(fileType)); } @@ -442,7 +449,7 @@ Result FileSystemTemplate::statInode(uint64_t in } template -Result FileSystemTemplate::statPath(CRStringView path) const noexcept { +Result FileSystemTemplate::statPath(StringViewCR path) const noexcept { oxRequire(inode, find(path)); return stat(inode); } @@ -485,7 +492,7 @@ Result::FileSystemData> FileSy } template -Result FileSystemTemplate::find(CRStringView path) const noexcept { +Result FileSystemTemplate::find(StringViewCR path) const noexcept { oxRequire(fd, fileSystemData()); // return root as a special case if (path == "/") { diff --git a/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp b/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp index 57c0818..1fd7080 100644 --- a/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp +++ b/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp @@ -17,7 +17,7 @@ namespace ox { -PassThroughFS::PassThroughFS(CRStringView dirPath) { +PassThroughFS::PassThroughFS(StringViewCR dirPath) { m_path = std::string_view(dirPath.data(), dirPath.bytes()); } @@ -27,7 +27,7 @@ String PassThroughFS::basePath() const noexcept { return ox::String(m_path.string().c_str()); } -Error PassThroughFS::mkdir(CRStringView path, bool recursive) noexcept { +Error PassThroughFS::mkdir(StringViewCR path, bool recursive) noexcept { bool success = false; const auto p = m_path / stripSlash(path); const auto u8p = p.u8string(); @@ -54,7 +54,7 @@ Error PassThroughFS::mkdir(CRStringView path, bool recursive) noexcept { return OxError(success ? 0 : 1); } -Error PassThroughFS::move(CRStringView src, CRStringView dest) noexcept { +Error PassThroughFS::move(StringViewCR src, StringViewCR dest) noexcept { std::error_code ec; std::filesystem::rename(m_path / stripSlash(src), m_path / stripSlash(dest), ec); if (ec.value()) { @@ -63,7 +63,7 @@ Error PassThroughFS::move(CRStringView src, CRStringView dest) noexcept { return OxError(0); } -Result> PassThroughFS::ls(CRStringView dir) const noexcept { +Result> PassThroughFS::ls(StringViewCR dir) const noexcept { Vector out; std::error_code ec; const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec); @@ -75,7 +75,7 @@ Result> PassThroughFS::ls(CRStringView dir) const noexcept { return out; } -Error PassThroughFS::remove(CRStringView path, bool recursive) noexcept { +Error PassThroughFS::remove(StringViewCR path, bool recursive) noexcept { if (recursive) { return OxError(std::filesystem::remove_all(m_path / stripSlash(path)) != 0); } else { @@ -93,14 +93,13 @@ Result PassThroughFS::statInode(uint64_t) const noexcept { return OxError(1, "statInode(uint64_t) is not supported by PassThroughFS"); } -Result PassThroughFS::statPath(CRStringView path) const noexcept { +Result PassThroughFS::statPath(StringViewCR path) const noexcept { std::error_code ec; const auto p = m_path / stripSlash(path); const FileType type = std::filesystem::is_directory(p, ec) ? FileType::Directory : FileType::NormalFile; oxTracef("ox.fs.PassThroughFS.statInode", "{} {}", ec.message(), path); const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec); - oxTracef("ox.fs.PassThroughFS.statInode", "{} {}", ec.message(), path); oxTracef("ox.fs.PassThroughFS.statInode.size", "{} {}", path, size); oxReturnError(OxError(static_cast(ec.value()), "PassThroughFS: stat failed")); return FileStat{0, 0, size, type}; @@ -141,7 +140,7 @@ bool PassThroughFS::valid() const noexcept { return false; } -Error PassThroughFS::readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept { +Error PassThroughFS::readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept { try { std::ifstream file((m_path / stripSlash(path)), std::ios::binary | std::ios::ate); const std::size_t size = static_cast(file.tellg()); @@ -168,7 +167,7 @@ Error PassThroughFS::readFileInodeRange(uint64_t, std::size_t, std::size_t, void return OxError(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS"); } -Error PassThroughFS::writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType) noexcept { +Error PassThroughFS::writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType) noexcept { const auto p = (m_path / stripSlash(path)); try { std::ofstream f(p, std::ios::binary); diff --git a/deps/ox/src/ox/fs/filesystem/passthroughfs.hpp b/deps/ox/src/ox/fs/filesystem/passthroughfs.hpp index 22a8183..abe6dae 100644 --- a/deps/ox/src/ox/fs/filesystem/passthroughfs.hpp +++ b/deps/ox/src/ox/fs/filesystem/passthroughfs.hpp @@ -29,29 +29,29 @@ class PassThroughFS: public FileSystem { std::filesystem::path m_path; public: - explicit PassThroughFS(CRStringView dirPath); + explicit PassThroughFS(StringViewCR dirPath); ~PassThroughFS() noexcept override; [[nodiscard]] String basePath() const noexcept; - Error mkdir(CRStringView path, bool recursive) noexcept override; + Error mkdir(StringViewCR path, bool recursive) noexcept override; - Error move(CRStringView src, CRStringView dest) noexcept override; + Error move(StringViewCR src, StringViewCR dest) noexcept override; - Result> ls(CRStringView dir) const noexcept override; + Result> ls(StringViewCR dir) const noexcept override; template - Error ls(CRStringView dir, F cb) const noexcept; + Error ls(StringViewCR dir, F cb) const noexcept; - Error remove(CRStringView path, bool recursive) noexcept override; + Error remove(StringViewCR path, bool recursive) noexcept override; Error resize(uint64_t size, void *buffer) noexcept override; Result statInode(uint64_t inode) const noexcept override; - Result statPath(CRStringView path) const noexcept override; + Result statPath(StringViewCR path) const noexcept override; [[nodiscard]] uint64_t spaceNeeded(uint64_t size) const noexcept override; @@ -69,13 +69,13 @@ class PassThroughFS: public FileSystem { bool valid() const noexcept override; protected: - Error readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept override; + Error readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept override; Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override; Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override; - Error writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept override; + Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept override; Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override; @@ -89,7 +89,7 @@ class PassThroughFS: public FileSystem { }; template -Error PassThroughFS::ls(CRStringView dir, F cb) const noexcept { +Error PassThroughFS::ls(StringViewCR dir, F cb) const noexcept { std::error_code ec; const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec); oxReturnError(OxError(static_cast(ec.value()), "PassThroughFS: ls failed")); diff --git a/deps/ox/src/ox/fs/filesystem/pathiterator.cpp b/deps/ox/src/ox/fs/filesystem/pathiterator.cpp index 716d481..6f5af20 100644 --- a/deps/ox/src/ox/fs/filesystem/pathiterator.cpp +++ b/deps/ox/src/ox/fs/filesystem/pathiterator.cpp @@ -22,7 +22,7 @@ PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t it PathIterator::PathIterator(const char *path): PathIterator(path, ox::strlen(path)) { } -PathIterator::PathIterator(CRStringView path): PathIterator(path.data(), path.bytes()) { +PathIterator::PathIterator(StringViewCR path): PathIterator(path.data(), path.bytes()) { } /** @@ -40,30 +40,9 @@ Error PathIterator::dirPath(char *out, std::size_t outSize) { } } -/** - * @return 0 if no error - */ -Error PathIterator::fileName(char *out, std::size_t outSize) { - auto idx = ox::lastIndexOf(m_path, '/', m_maxSize); - if (idx >= 0) { - idx++; // pass up the preceding / - std::size_t fileNameSize = static_cast(ox::strlen(&m_path[idx])); - if (fileNameSize < outSize) { - ox::memcpy(out, &m_path[idx], fileNameSize); - out[fileNameSize] = 0; - return OxError(0); - } else { - return OxError(1); - } - } else { - return OxError(2); - } -} - // Gets the get item in the path -Error PathIterator::get(IString &fileName) { +Error PathIterator::get(StringView &fileName) { std::size_t size = 0; - std::ignore = fileName.resize(MaxFileNameLength); if (m_iterator >= m_maxSize) { oxTracef("ox.fs.PathIterator.get", "m_iterator ({}) >= m_maxSize ({})", m_iterator, m_maxSize); return OxError(1); @@ -88,22 +67,21 @@ Error PathIterator::get(IString &fileName) { if (size >= MaxFileNameLength || size == 0) { return OxError(1); } - ox::memcpy(fileName.data(), &m_path[start], size); + fileName = ox::substr(m_path, start, start + size); // truncate trailing / if (size && fileName[size - 1] == '/') { - size--; + fileName = ox::substr(m_path, start, start + size - 1); } - oxReturnError(fileName.resize(size)); + oxAssert(fileName[fileName.len()-1] != '/', "name ends in /"); return {}; } /** * @return 0 if no error */ -Error PathIterator::next(IString &fileName) { +Error PathIterator::next(StringView &fileName) { std::size_t size = 0; auto retval = OxError(1); - std::ignore = fileName.resize(MaxFileNameLength); if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) { retval = OxError(0); if (m_path[m_iterator] == '/') { @@ -122,15 +100,14 @@ Error PathIterator::next(IString &fileName) { if (size >= MaxFileNameLength) { return OxError(1); } - ox::memcpy(fileName.data(), &m_path[start], size); + fileName = ox::substr(m_path, start, start + size); + // truncate trailing / + while (fileName.len() && fileName[fileName.len() - 1] == '/') { + fileName = ox::substr(m_path, start, start + size); + } + m_iterator += size; + oxAssert(fileName.len() == 0 || fileName[fileName.len()-1] != '/', "name ends in /"); } - // truncate trailing / - if (size && fileName[size - 1] == '/') { - size--; - } - fileName[size] = 0; // end with null terminator - oxReturnError(fileName.resize(size)); - m_iterator += size; return retval; } diff --git a/deps/ox/src/ox/fs/filesystem/pathiterator.hpp b/deps/ox/src/ox/fs/filesystem/pathiterator.hpp index b3cbeda..33659ab 100644 --- a/deps/ox/src/ox/fs/filesystem/pathiterator.hpp +++ b/deps/ox/src/ox/fs/filesystem/pathiterator.hpp @@ -13,7 +13,6 @@ namespace ox { constexpr std::size_t MaxFileNameLength = 255; -using FileName = IString; class PathIterator { private: @@ -26,31 +25,14 @@ class PathIterator { PathIterator(const char *path); - PathIterator(CRStringView path); + PathIterator(StringViewCR path); - /** - * @return 0 if no error - */ Error dirPath(char *pathOut, std::size_t pathOutSize); - /** - * @return 0 if no error - */ - Error fileName(char *out, std::size_t outSize); + Error next(StringView &fileName); - /** - * @return 0 if no error - */ - Error next(FileName &fileName); + Error get(StringView &fileName); - /** - * @return 0 if no error - */ - Error get(FileName &fileName); - - /** - * @return 0 if no error - */ Result nextSize() const; [[nodiscard]] diff --git a/deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp b/deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp index b7d2f2d..e09f837 100644 --- a/deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp +++ b/deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp @@ -174,7 +174,7 @@ template NodeBuffer::NodeBuffer(std::size_t size) noexcept { m_header.size = static_cast(size); ox::memset(this + 1, 0, size - sizeof(*this)); - oxTracef("ox.NodeBuffer.constructor", "{}", m_header.firstItem.get()); + oxTracef("ox.ptrarith.NodeBuffer.constructor", "{}", m_header.firstItem.get()); } template diff --git a/deps/ox/src/ox/fs/ptrarith/ptr.hpp b/deps/ox/src/ox/fs/ptrarith/ptr.hpp index 31b0085..9994005 100644 --- a/deps/ox/src/ox/fs/ptrarith/ptr.hpp +++ b/deps/ox/src/ox/fs/ptrarith/ptr.hpp @@ -224,7 +224,7 @@ constexpr const Ptr Ptr::subPtr(s template template constexpr const Ptr Ptr::subPtr(size_t offset) const noexcept { - oxTracef("ox.fs.Ptr.subPtr", "{} {} {} {} {}", m_itemOffset, this->size(), offset, m_itemSize, (m_itemSize - offset)); + oxTracef("ox.ptrarith.Ptr.subPtr", "{} {} {} {} {}", m_itemOffset, this->size(), offset, m_itemSize, (m_itemSize - offset)); return subPtr(offset, m_itemSize - offset); } @@ -237,7 +237,7 @@ constexpr Ptr Ptr::subPtr(size_t template template constexpr Ptr Ptr::subPtr(size_t offset) noexcept { - oxTracef("ox.fs.Ptr.subPtr", "{} {} {} {} {}", m_itemOffset, this->size(), offset, m_itemSize, (m_itemSize - offset)); + oxTracef("ox.ptrarith.Ptr.subPtr", "{} {} {} {} {}", m_itemOffset, this->size(), offset, m_itemSize, (m_itemSize - offset)); return subPtr(offset, m_itemSize - offset); } diff --git a/deps/ox/src/ox/fs/test/CMakeLists.txt b/deps/ox/src/ox/fs/test/CMakeLists.txt index d2ecc00..44eaf77 100644 --- a/deps/ox/src/ox/fs/test/CMakeLists.txt +++ b/deps/ox/src/ox/fs/test/CMakeLists.txt @@ -19,7 +19,6 @@ add_test("[ox/fs] PathIterator::next5" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FSTests add_test("[ox/fs] PathIterator::hasNext" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FSTests PathIterator::hasNext) add_test("[ox/fs] PathIterator::dirPath" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FSTests PathIterator::dirPath) -add_test("[ox/fs] PathIterator::fileName" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FSTests PathIterator::fileName) add_test("[ox/fs] NodeBuffer::insert" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FSTests "NodeBuffer::insert") add_test("[ox/fs] FileStore::readWrite" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FSTests "FileStore::readWrite") diff --git a/deps/ox/src/ox/fs/test/tests.cpp b/deps/ox/src/ox/fs/test/tests.cpp index 25e5cb2..68199ea 100644 --- a/deps/ox/src/ox/fs/test/tests.cpp +++ b/deps/ox/src/ox/fs/test/tests.cpp @@ -58,9 +58,9 @@ const std::map> tests = { "PathIterator::next1", [](ox::StringView) { - auto const path = ox::String("/usr/share/charset.gbag"); + auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag"); ox::PathIterator it(path.c_str(), path.len()); - ox::FileName buff; + ox::StringView buff; oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next"); oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next"); oxAssert(it.next(buff) == 0 && buff == "charset.gbag", "PathIterator shows wrong next"); @@ -70,11 +70,13 @@ const std::map> tests = { "PathIterator::next2", [](ox::StringView) { - auto const path = ox::String("/usr/share/"); - ox::PathIterator it(path.c_str(), path.len()); - ox::FileName buff; - oxAssert(it.next(buff) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next"); - oxAssert(it.next(buff) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next"); + auto constexpr path = ox::StringView("/usr/share/"); + ox::PathIterator it(path); + ox::StringView buff; + oxAssert(it.next(buff), "PathIterator::next returned error"); + oxExpect(buff, "usr"); + oxAssert(it.next(buff), "PathIterator::next returned error"); + oxExpect(buff, "share"); return OxError(0); } }, @@ -83,20 +85,20 @@ const std::map> tests = [](ox::StringView) { auto const path = ox::String("/"); ox::PathIterator it(path.c_str(), path.len()); - ox::FileName buff; - oxAssert(it.next(buff) == 0 && ox::strcmp(buff, "\0") == 0, "PathIterator shows wrong next"); + ox::StringView buff; + oxAssert(it.next(buff) == 0 && buff == "\0", "PathIterator shows wrong next"); return OxError(0); } }, { "PathIterator::next4", [](ox::StringView) { - auto const path = ox::String("usr/share/charset.gbag"); - ox::PathIterator it(path.c_str(), path.len()); - ox::FileName buff; - oxAssert(it.next(buff) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next"); - oxAssert(it.next(buff) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next"); - oxAssert(it.next(buff) == 0 && ox::strcmp(buff, "charset.gbag") == 0, "PathIterator shows wrong next"); + auto constexpr path = ox::StringLiteral("usr/share/charset.gbag"); + ox::PathIterator it(path); + ox::StringView buff; + oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next"); + oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next"); + oxAssert(it.next(buff) == 0 && buff == "charset.gbag", "PathIterator shows wrong next"); return OxError(0); } }, @@ -105,32 +107,22 @@ const std::map> tests = [](ox::StringView) { auto const path = ox::String("usr/share/"); ox::PathIterator it(path.c_str(), path.len()); - ox::FileName buff; - oxAssert(it.next(buff) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next"); - oxAssert(it.next(buff) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next"); + ox::StringView buff; + oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next"); + oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next"); return OxError(0); } }, { "PathIterator::dirPath", [] (ox::StringView) { - auto const path = ox::String("/usr/share/charset.gbag"); + auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag"); ox::PathIterator it(path.c_str(), path.len()); auto buff = static_cast(ox_alloca(path.len() + 1)); oxAssert(it.dirPath(buff, path.len()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path"); return OxError(0); } }, - { - "PathIterator::fileName", - [](ox::StringView) { - auto const path = ox::String("/usr/share/charset.gbag"); - ox::PathIterator it(path.c_str(), path.len()); - auto buff = static_cast(ox_alloca(path.len() + 1)); - oxAssert(it.fileName(buff, path.len()) == 0 && ox::strcmp(buff, "charset.gbag") == 0, "PathIterator shows incorrect file name"); - return OxError(0); - } - }, { "PathIterator::hasNext", [](ox::StringView) { @@ -221,7 +213,6 @@ const std::map> tests = oxTrace("ox.fs.test.FileSystem") << "format"; oxAssert(ox::FileSystem32::format(fsBuff.data(), fsBuff.size()), "FileSystem format failed"); ox::FileSystem32 fs(ox::FileStore32(fsBuff.data(), fsBuff.size())); - oxTrace("ox.fs.test.FileSystem") << "mkdir"; oxAssert(fs.mkdir("/dir", true), "mkdir failed"); oxAssert(fs.stat("/dir").error, "mkdir failed"); @@ -229,7 +220,6 @@ const std::map> tests = oxAssert(fs.stat("/l1d1/l2d1/l3d1").error, "mkdir failed"); oxAssert(fs.mkdir("/l1d1/l2d2", true), "mkdir failed"); oxAssert(fs.stat("/l1d1/l2d2").error, "mkdir failed"); - return OxError(0); } }, diff --git a/deps/ox/src/ox/logconn/logconn.cpp b/deps/ox/src/ox/logconn/logconn.cpp index b5c5912..f5a398f 100644 --- a/deps/ox/src/ox/logconn/logconn.cpp +++ b/deps/ox/src/ox/logconn/logconn.cpp @@ -51,7 +51,7 @@ LoggerConn::~LoggerConn() noexcept { } } -ox::Error LoggerConn::initConn(ox::CRStringView appName) noexcept { +ox::Error LoggerConn::initConn(ox::StringViewCR appName) noexcept { sockaddr_in addr{}; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); diff --git a/deps/ox/src/ox/logconn/logconn.hpp b/deps/ox/src/ox/logconn/logconn.hpp index 2655de5..8a2b3ae 100644 --- a/deps/ox/src/ox/logconn/logconn.hpp +++ b/deps/ox/src/ox/logconn/logconn.hpp @@ -38,7 +38,7 @@ class LoggerConn: public trace::Logger { LoggerConn &operator=(const LoggerConn&) noexcept = delete; ox::Error send(const trace::TraceMsg&) noexcept final; ox::Error sendInit(const trace::InitTraceMsg&) noexcept final; - ox::Error initConn(ox::CRStringView appName) noexcept; + ox::Error initConn(ox::StringViewCR appName) noexcept; ox::Error send(const char *buff, std::size_t len) const noexcept; private: void msgSend() noexcept; diff --git a/deps/ox/src/ox/mc/test/tests.cpp b/deps/ox/src/ox/mc/test/tests.cpp index 1ff87d1..08c4a0f 100644 --- a/deps/ox/src/ox/mc/test/tests.cpp +++ b/deps/ox/src/ox/mc/test/tests.cpp @@ -316,7 +316,7 @@ std::map tests = { testIn.Union.Int = 93; oxAssert(ox::writeMC(dataBuff.data(), dataBuff.size(), testIn), "Data generation failed"); ox::TypeStore typeStore; - const auto [type, typeErr] = ox::buildTypeDef(&typeStore, &testIn); + const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn); oxAssert(typeErr, "Descriptor write failed"); ox::ModelObject testOut; oxReturnError(testOut.setType(type)); @@ -368,7 +368,7 @@ std::map tests = { testIn.Struct.IString = "Test String 2"; oxAssert(ox::writeMC(dataBuff, dataBuffLen, testIn), "Data generation failed"); ox::TypeStore typeStore; - const auto [type, typeErr] = ox::buildTypeDef(&typeStore, &testIn); + const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn); oxAssert(typeErr, "Descriptor write failed"); ox::BufferReader br({dataBuff, dataBuffLen}); oxReturnError(ox::walkModel(type, br, diff --git a/deps/ox/src/ox/model/def.hpp b/deps/ox/src/ox/model/def.hpp index 7e131e0..f4f042f 100644 --- a/deps/ox/src/ox/model/def.hpp +++ b/deps/ox/src/ox/model/def.hpp @@ -10,8 +10,10 @@ #include +// oxModelFwdDecl is necessary because Apple-Clang is broken... +#define oxModelFwdDecl(modelName) constexpr ox::Error model(auto *io, ox::CommonPtrWith auto *o) noexcept #define oxModelBegin(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith auto *o) noexcept { oxReturnError(io->template setTypeInfo()); #define oxModelEnd() return OxError(0); } #define oxModelField(fieldName) oxReturnError(io->field(#fieldName, &o->fieldName)); #define oxModelFieldRename(objFieldName, serFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName)); -#define oxModelFriend(modelName) friend constexpr ox::Error model(auto*, ox::CommonPtrWith auto*) noexcept +#define oxModelFriend(modelName) friend constexpr ox::Error model(auto *io, ox::CommonPtrWith auto *o) noexcept diff --git a/deps/ox/src/ox/model/desctypes.hpp b/deps/ox/src/ox/model/desctypes.hpp index 248c309..6a1bcc4 100644 --- a/deps/ox/src/ox/model/desctypes.hpp +++ b/deps/ox/src/ox/model/desctypes.hpp @@ -35,7 +35,7 @@ constexpr auto buildTypeId() noexcept { } static constexpr auto buildTypeId( - CRStringView name, int version, + StringViewCR name, int version, const TypeParamPack &typeParams = {}) noexcept { String tp; if (!typeParams.empty()) { diff --git a/deps/ox/src/ox/model/descwrite.hpp b/deps/ox/src/ox/model/descwrite.hpp index e0bf984..817bfc1 100644 --- a/deps/ox/src/ox/model/descwrite.hpp +++ b/deps/ox/src/ox/model/descwrite.hpp @@ -91,23 +91,23 @@ class TypeDescWriter { constexpr ~TypeDescWriter() noexcept = default; template - constexpr ox::Error setTypeInfo(CRStringView name = T::TypeName, - int version = T::TypeVersion, - const TypeParamPack &typeParams = {}, - std::size_t fields = ModelFieldCount_v) noexcept; + constexpr ox::Error setTypeInfo(StringViewCR name = T::TypeName, + int version = T::TypeVersion, + const TypeParamPack &typeParams = {}, + std::size_t fields = ModelFieldCount_v) noexcept; template - constexpr Error field(CRStringView name, const T *val, std::size_t valLen, + constexpr Error field(StringViewCR name, const T *val, std::size_t valLen, const SubscriptStack &subscriptStack = {}) noexcept; template - constexpr Error field(CRStringView name, UnionView val) noexcept; + constexpr Error field(StringViewCR name, UnionView val) noexcept; template - constexpr Error field(CRStringView name, const T *val) noexcept; + constexpr Error field(StringViewCR name, const T *val) noexcept; template - constexpr Error fieldCString(CRStringView name, Args&&...) noexcept; + constexpr Error fieldCString(StringViewCR name, Args&&...) noexcept; [[nodiscard]] constexpr DescriptorType *definition() noexcept { @@ -167,7 +167,7 @@ class TypeDescWriter { constexpr const DescriptorType *type(UnionView val) const noexcept; [[nodiscard]] - constexpr const DescriptorType *getType(CRStringView tn, int typeVersion, PrimitiveType t, int b, + constexpr const DescriptorType *getType(StringViewCR tn, int typeVersion, PrimitiveType t, int b, const TypeParamPack &typeParams = {}) const noexcept; }; @@ -176,8 +176,8 @@ constexpr TypeDescWriter::TypeDescWriter(TypeStore *typeStore) noexcept: m_typeS template constexpr ox::Error TypeDescWriter::setTypeInfo( - CRStringView typeName, int typeVersion, - const TypeParamPack &typeParams, std::size_t) noexcept { + StringViewCR typeName, int typeVersion, + const TypeParamPack &typeParams, std::size_t) noexcept { PrimitiveType pt; if constexpr(is_union_v) { pt = PrimitiveType::Union; @@ -193,7 +193,7 @@ constexpr ox::Error TypeDescWriter::setTypeInfo( // array handler template -constexpr Error TypeDescWriter::field(CRStringView name, const T*, std::size_t, const SubscriptStack &subscriptStack) noexcept { +constexpr Error TypeDescWriter::field(StringViewCR name, const T*, std::size_t, const SubscriptStack &subscriptStack) noexcept { if (m_type) { constexpr typename remove_pointer::type *p = nullptr; const auto t = type(p); @@ -205,7 +205,7 @@ constexpr Error TypeDescWriter::field(CRStringView name, const T*, std::size_t, } template -constexpr Error TypeDescWriter::field(CRStringView name, UnionView val) noexcept { +constexpr Error TypeDescWriter::field(StringViewCR name, UnionView val) noexcept { if (m_type) { const auto t = type(val); oxAssert(t != nullptr, "field(const char *name, T val): Type not found or generated"); @@ -216,7 +216,7 @@ constexpr Error TypeDescWriter::field(CRStringView name, UnionView val } template -constexpr Error TypeDescWriter::field(CRStringView name, const T *val) noexcept { +constexpr Error TypeDescWriter::field(StringViewCR name, const T *val) noexcept { if (m_type) { if constexpr(isVector_v || isArray_v) { typename T::value_type *data = nullptr; @@ -237,7 +237,7 @@ constexpr Error TypeDescWriter::field(CRStringView name, const T *val) noexcept } template -constexpr Error TypeDescWriter::fieldCString(CRStringView name, Args&&...) noexcept { +constexpr Error TypeDescWriter::fieldCString(StringViewCR name, Args&&...) noexcept { constexpr auto s = ""; const auto t = type(s); m_type->fieldList.emplace_back(t, String(name), 0, SubscriptStack{}, ox::String(t->typeName)); @@ -339,7 +339,7 @@ constexpr const DescriptorType *TypeDescWriter::type(const IString*) const n return getType(types::BString, 0, PT, 0); } -constexpr const DescriptorType *TypeDescWriter::getType(CRStringView tn, int typeVersion, PrimitiveType pt, int b, +constexpr const DescriptorType *TypeDescWriter::getType(StringViewCR tn, int typeVersion, PrimitiveType pt, int b, const TypeParamPack &typeParams) const noexcept { auto t = m_typeStore->get(tn, typeVersion, typeParams); if (!t.error) { @@ -357,8 +357,8 @@ constexpr const DescriptorType *TypeDescWriter::getType(CRStringView tn, int typ } template -constexpr Result buildTypeDef(TypeStore *typeStore) noexcept { - TypeDescWriter writer(typeStore); +constexpr Result buildTypeDef(TypeStore &typeStore) noexcept { + TypeDescWriter writer(&typeStore); ModelHandlerInterface handler(&writer); if (std::is_constant_evaluated()) { std::allocator a; @@ -373,10 +373,10 @@ constexpr Result buildTypeDef(TypeStore *typeStore) noexcept { } template -constexpr Result buildTypeDef(TypeStore *typeStore, T *val) noexcept { - TypeDescWriter writer(typeStore); +constexpr Result buildTypeDef(TypeStore &typeStore, T &val) noexcept { + TypeDescWriter writer(&typeStore); ModelHandlerInterface handler(&writer); - oxReturnError(model(&handler, val)); + oxReturnError(model(&handler, &val)); return writer.definition(); } diff --git a/deps/ox/src/ox/model/fieldcounter.hpp b/deps/ox/src/ox/model/fieldcounter.hpp index caebc41..55bd25f 100644 --- a/deps/ox/src/ox/model/fieldcounter.hpp +++ b/deps/ox/src/ox/model/fieldcounter.hpp @@ -24,24 +24,24 @@ class FieldCounter { std::size_t fields = 0; template - constexpr ox::Error setTypeInfo(CRStringView = "", int = 0, const Vector& = {}, std::size_t = 0) { + constexpr ox::Error setTypeInfo(StringViewCR = "", int = 0, const Vector& = {}, std::size_t = 0) { return {}; } template - constexpr ox::Error field(CRStringView, U) noexcept { + constexpr ox::Error field(StringViewCR, U) noexcept { ++fields; return OxError(0); } template - constexpr ox::Error field(CRStringView, U, std::size_t) noexcept { + constexpr ox::Error field(StringViewCR, U, std::size_t) noexcept { ++fields; return OxError(0); } template - constexpr Error field(CRStringView, Handler) { + constexpr Error field(StringViewCR, Handler) { ++fields; return OxError(0); } diff --git a/deps/ox/src/ox/model/modelvalue.hpp b/deps/ox/src/ox/model/modelvalue.hpp index 90088cf..7a62060 100644 --- a/deps/ox/src/ox/model/modelvalue.hpp +++ b/deps/ox/src/ox/model/modelvalue.hpp @@ -652,7 +652,7 @@ class ModelObject { } [[nodiscard]] - constexpr CRString typeName() const noexcept { + constexpr StringCR typeName() const noexcept { return m_type->typeName; } diff --git a/deps/ox/src/ox/model/typestore.hpp b/deps/ox/src/ox/model/typestore.hpp index 298a71d..4f39ea7 100644 --- a/deps/ox/src/ox/model/typestore.hpp +++ b/deps/ox/src/ox/model/typestore.hpp @@ -44,7 +44,7 @@ class TypeStore { return out->get(); } - constexpr DescriptorType *getInit(CRStringView typeName, int typeVersion, PrimitiveType pt, + constexpr DescriptorType *getInit(StringViewCR typeName, int typeVersion, PrimitiveType pt, const TypeParamPack &typeParams) noexcept { const auto typeId = buildTypeId(typeName, typeVersion, typeParams); auto &out = m_cache[typeId]; @@ -105,7 +105,7 @@ class TypeStore { return OxError(1); } - Result> loadDescriptor(ox::CRStringView name, int version, + Result> loadDescriptor(ox::StringViewCR name, int version, const ox::TypeParamPack &typeParams) noexcept { const auto typeId = buildTypeId(name, version, typeParams); return loadDescriptor(typeId); diff --git a/deps/ox/src/ox/oc/test/tests.cpp b/deps/ox/src/ox/oc/test/tests.cpp index e6597dc..13747d5 100644 --- a/deps/ox/src/ox/oc/test/tests.cpp +++ b/deps/ox/src/ox/oc/test/tests.cpp @@ -207,7 +207,7 @@ const std::map tests = { testIn.Union.Int = 93; oxAssert(ox::writeOC(testIn).moveTo(dataBuff), "Data generation failed"); ox::TypeStore typeStore; - auto type = ox::buildTypeDef(&typeStore, &testIn); + auto type = ox::buildTypeDef(typeStore, testIn); oxAssert(type.error, "Descriptor write failed"); ox::ModelObject testOut; oxReturnError(testOut.setType(type.value)); @@ -257,7 +257,7 @@ const std::map tests = { auto [oc, ocErr] = ox::writeOC(testIn); oxAssert(ocErr, "Data generation failed"); ox::TypeStore typeStore; - auto type = ox::buildTypeDef(&typeStore, &testIn); + auto type = ox::buildTypeDef(typeStore, testIn); oxAssert(type.error, "Descriptor write failed"); oxReturnError(ox::walkModel(type.value, oc.data(), oc.size(), [](const ox::Vector&, const ox::Vector&, const ox::DescriptorField &f, diff --git a/deps/ox/src/ox/oc/write.hpp b/deps/ox/src/ox/oc/write.hpp index 10489e3..006bfd6 100644 --- a/deps/ox/src/ox/oc/write.hpp +++ b/deps/ox/src/ox/oc/write.hpp @@ -24,7 +24,8 @@ namespace ox { class OrganicClawWriter { - friend Result writeOC(const auto &val) noexcept; + friend Result writeOC(const auto &val) noexcept; + friend Result writeOCString(const auto &val) noexcept; protected: Json::Value m_json{Json::Value(Json::objectValue)}; @@ -247,14 +248,27 @@ Error OrganicClawWriter::field(const char *key, UnionView val) noexcep return OxError(0); } -Result writeOC(const auto &val) noexcept { +Result writeOC(const auto &val) noexcept { OrganicClawWriter writer; ModelHandlerInterface handler(&writer); oxReturnError(model(&handler, &val)); - Json::StreamWriterBuilder jsonBuilder; + Json::StreamWriterBuilder const jsonBuilder; const auto str = Json::writeString(jsonBuilder, writer.m_json); - Buffer buff(str.size() + 1); - memcpy(buff.data(), str.c_str(), str.size() + 1); + Result buff; + buff.value.resize(str.size() + 1); + memcpy(buff.value.data(), str.data(), str.size() + 1); + return buff; +} + +Result writeOCString(const auto &val) noexcept { + OrganicClawWriter writer; + ModelHandlerInterface handler(&writer); + oxReturnError(model(&handler, &val)); + Json::StreamWriterBuilder const jsonBuilder; + const auto str = Json::writeString(jsonBuilder, writer.m_json); + Result buff; + buff.value.resize(str.size()); + memcpy(buff.value.data(), str.data(), str.size() + 1); return buff; } diff --git a/deps/ox/src/ox/preloader/alignmentcatcher.hpp b/deps/ox/src/ox/preloader/alignmentcatcher.hpp index 98ee847..07b2fbb 100644 --- a/deps/ox/src/ox/preloader/alignmentcatcher.hpp +++ b/deps/ox/src/ox/preloader/alignmentcatcher.hpp @@ -46,12 +46,12 @@ struct AlignmentCatcher: public ModelHandlerBase, OpT } template - constexpr ox::Error field(CRStringView name, const UnionView val) noexcept { + constexpr ox::Error field(StringViewCR name, const UnionView val) noexcept { return field(name, val.get()); } template - constexpr ox::Error field(CRStringView, const T *val) noexcept { + constexpr ox::Error field(StringViewCR, const T *val) noexcept { if constexpr(ox::is_pointer_v || ox::is_integer_v) { biggestAlignment = ox::max(biggestAlignment, PlatSpec::alignOf(*val)); } else { @@ -61,7 +61,7 @@ struct AlignmentCatcher: public ModelHandlerBase, OpT } template - constexpr ox::Error field(CRStringView, const T *val, std::size_t cnt) noexcept { + constexpr ox::Error field(StringViewCR, const T *val, std::size_t cnt) noexcept { for (std::size_t i = 0; i < cnt; ++i) { oxReturnError(field(nullptr, &val[i])); } diff --git a/deps/ox/src/ox/preloader/preloader.hpp b/deps/ox/src/ox/preloader/preloader.hpp index fd428bb..cf49d00 100644 --- a/deps/ox/src/ox/preloader/preloader.hpp +++ b/deps/ox/src/ox/preloader/preloader.hpp @@ -94,19 +94,19 @@ class Preloader: public ModelHandlerBase, OpType::Reflect> { } template - constexpr ox::Error field(CRStringView, ox::UnionView val) noexcept; + constexpr ox::Error field(StringViewCR, ox::UnionView val) noexcept; template - constexpr ox::Error field(CRStringView, const T *val) noexcept; + constexpr ox::Error field(StringViewCR, const T *val) noexcept; template - constexpr ox::Error field(CRStringView, const ox::BasicString *val) noexcept; + constexpr ox::Error field(StringViewCR, const ox::BasicString *val) noexcept; template - constexpr ox::Error field(CRStringView, const ox::Array *valArray) noexcept; + constexpr ox::Error field(StringViewCR, const ox::Array *valArray) noexcept; template - constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept; + constexpr ox::Error field(StringViewCR, const T **val, std::size_t cnt) noexcept; constexpr ox::Result startAlloc(size_t sz, size_t align) noexcept; @@ -125,14 +125,14 @@ class Preloader: public ModelHandlerBase, OpType::Reflect> { constexpr ox::Error pad(const T*) noexcept; private: - constexpr ox::Error fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept; + constexpr ox::Error fieldVector(StringViewCR name, const ox::ModelValueVector *val) noexcept; template - constexpr ox::Error fieldVector(CRStringView, const ox::Vector *val) noexcept; + constexpr ox::Error fieldVector(StringViewCR, const ox::Vector *val) noexcept; - constexpr ox::Error fieldVector(CRStringView, const auto *val, ox::VectorMemMap vecVal) noexcept; + constexpr ox::Error fieldVector(StringViewCR, const auto *val, ox::VectorMemMap vecVal) noexcept; - constexpr ox::Error fieldArray(CRStringView name, ox::ModelValueArray const*val) noexcept; + constexpr ox::Error fieldArray(StringViewCR name, ox::ModelValueArray const*val) noexcept; constexpr bool unionCheckAndIt() noexcept; @@ -158,7 +158,7 @@ Preloader::make(ox::ios_base::seekdir anchor, std::size_t sz) noexcept template template -constexpr ox::Error Preloader::field(CRStringView, const ox::UnionView val) noexcept { +constexpr ox::Error Preloader::field(StringViewCR, const ox::UnionView val) noexcept { if (!unionCheckAndIt()) { return {}; } @@ -171,7 +171,7 @@ constexpr ox::Error Preloader::field(CRStringView, const ox::UnionView template template -constexpr ox::Error Preloader::field(CRStringView name, const T *val) noexcept { +constexpr ox::Error Preloader::field(StringViewCR name, const T *val) noexcept { if (!unionCheckAndIt()) { return {}; } @@ -200,7 +200,7 @@ constexpr ox::Error Preloader::field(CRStringView name, const T *val) template template -constexpr ox::Error Preloader::field(CRStringView, const ox::BasicString *val) noexcept { +constexpr ox::Error Preloader::field(StringViewCR, const ox::BasicString *val) noexcept { if (!unionCheckAndIt()) { return {}; } @@ -230,7 +230,7 @@ constexpr ox::Error Preloader::field(CRStringView, const ox::BasicStri template template -constexpr ox::Error Preloader::field(CRStringView name, const ox::Array *val) noexcept { +constexpr ox::Error Preloader::field(StringViewCR name, const ox::Array *val) noexcept { if (!unionCheckAndIt()) { return {}; } @@ -248,7 +248,7 @@ constexpr ox::Error Preloader::field(CRStringView name, const ox::Arra template template -constexpr ox::Error Preloader::field(CRStringView, const T **val, std::size_t cnt) noexcept { +constexpr ox::Error Preloader::field(StringViewCR, const T **val, std::size_t cnt) noexcept { if (!unionCheckAndIt()) { return {}; } @@ -327,7 +327,7 @@ constexpr ox::Error Preloader::pad(const T *v) noexcept { template constexpr ox::Error Preloader::fieldVector( - CRStringView name, const ox::ModelValueVector *val) noexcept { + StringViewCR name, const ox::ModelValueVector *val) noexcept { // serialize the Vector ox::VectorMemMap vecVal{ .size = PlatSpec::correctEndianness(static_cast(val->size())), @@ -339,7 +339,7 @@ constexpr ox::Error Preloader::fieldVector( template template constexpr ox::Error Preloader::fieldVector( - CRStringView name, const ox::Vector *val) noexcept { + StringViewCR name, const ox::Vector *val) noexcept { // serialize the Vector ox::VectorMemMap vecVal{ .smallVecSize = SmallVectorSize * sizeOf(static_cast(nullptr)), @@ -353,7 +353,7 @@ constexpr ox::Error Preloader::fieldVector( template constexpr ox::Error Preloader::fieldVector( - CRStringView, const auto *val, ox::VectorMemMap vecVal) noexcept { + StringViewCR, const auto *val, ox::VectorMemMap vecVal) noexcept { oxReturnError(pad(&vecVal)); const auto vecValPt = m_writer.tellp(); // serialize the Vector elements @@ -383,7 +383,7 @@ constexpr ox::Error Preloader::fieldVector( } template -constexpr ox::Error Preloader::fieldArray(CRStringView, ox::ModelValueArray const*val) noexcept { +constexpr ox::Error Preloader::fieldArray(StringViewCR, ox::ModelValueArray const*val) noexcept { oxReturnError(pad(&(*val)[0])); for (auto const&v : *val) { oxReturnError(this->interface()->field({}, &v)); diff --git a/deps/ox/src/ox/preloader/unionsizecatcher.hpp b/deps/ox/src/ox/preloader/unionsizecatcher.hpp index 9e2d8c0..3468200 100644 --- a/deps/ox/src/ox/preloader/unionsizecatcher.hpp +++ b/deps/ox/src/ox/preloader/unionsizecatcher.hpp @@ -41,7 +41,7 @@ class UnionSizeCatcher: public ModelHandlerBase, OpTy } template - constexpr ox::Error field(CRStringView, const UnionView val) noexcept { + constexpr ox::Error field(StringViewCR, const UnionView val) noexcept { UnionSizeCatcher sc; oxReturnError(model(sc.interface(), val.get())); m_size += sc.size(); @@ -49,10 +49,10 @@ class UnionSizeCatcher: public ModelHandlerBase, OpTy } template - constexpr ox::Error field(CRStringView, const T *val) noexcept; + constexpr ox::Error field(StringViewCR, const T *val) noexcept; template - constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept; + constexpr ox::Error field(StringViewCR, const T **val, std::size_t cnt) noexcept; [[nodiscard]] constexpr auto size() const noexcept { @@ -61,24 +61,24 @@ class UnionSizeCatcher: public ModelHandlerBase, OpTy private: template - constexpr ox::Error fieldStr(CRStringView, const ox::BasicString *val) noexcept; + constexpr ox::Error fieldStr(StringViewCR, const ox::BasicString *val) noexcept; template - constexpr ox::Error fieldVector(CRStringView, const ox::Vector *val) noexcept; + constexpr ox::Error fieldVector(StringViewCR, const ox::Vector *val) noexcept; constexpr void setSize(std::size_t sz) noexcept; }; template template -constexpr ox::Error UnionSizeCatcher::field(CRStringView, const T *val) noexcept { +constexpr ox::Error UnionSizeCatcher::field(StringViewCR, const T *val) noexcept { setSize(sizeOf(val)); return {}; } template template -constexpr ox::Error UnionSizeCatcher::field(CRStringView, const T **val, std::size_t cnt) noexcept { +constexpr ox::Error UnionSizeCatcher::field(StringViewCR, const T **val, std::size_t cnt) noexcept { for (std::size_t i = 0; i < cnt; ++i) { oxReturnError(field("", &val[i])); } @@ -87,7 +87,7 @@ constexpr ox::Error UnionSizeCatcher::field(CRStringView, const T **va template template -constexpr ox::Error UnionSizeCatcher::fieldStr(CRStringView, const ox::BasicString*) noexcept { +constexpr ox::Error UnionSizeCatcher::fieldStr(StringViewCR, const ox::BasicString*) noexcept { ox::VectorMemMap v; setSize(sizeOf(v)); return {}; @@ -95,7 +95,7 @@ constexpr ox::Error UnionSizeCatcher::fieldStr(CRStringView, const ox: template template -constexpr ox::Error UnionSizeCatcher::fieldVector(CRStringView, const ox::Vector*) noexcept { +constexpr ox::Error UnionSizeCatcher::fieldVector(StringViewCR, const ox::Vector*) noexcept { ox::VectorMemMap v; setSize(sizeOf(v)); return {}; diff --git a/deps/ox/src/ox/std/array.hpp b/deps/ox/src/ox/std/array.hpp index 242010f..18926ec 100644 --- a/deps/ox/src/ox/std/array.hpp +++ b/deps/ox/src/ox/std/array.hpp @@ -41,7 +41,7 @@ class Array { constexpr Array(Array &&other) noexcept; - ~Array() = default; + constexpr ~Array() = default; constexpr iterator<> begin() noexcept { return iterator<>(&m_items[0], 0, ArraySize); @@ -81,8 +81,10 @@ class Array { constexpr Array &operator=(Array &&other) noexcept; + [[nodiscard]] constexpr T &operator[](std::size_t i) noexcept; + [[nodiscard]] constexpr const T &operator[](std::size_t i) const noexcept; [[nodiscard]] diff --git a/deps/ox/src/ox/std/assert.hpp b/deps/ox/src/ox/std/assert.hpp index 879f3b2..4ea28bf 100644 --- a/deps/ox/src/ox/std/assert.hpp +++ b/deps/ox/src/ox/std/assert.hpp @@ -22,9 +22,9 @@ namespace ox { -void panic(CRStringView file, int line, CRStringView panicMsg, const Error &err = OxError(0)) noexcept; +void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err = OxError(0)) noexcept; -constexpr void constexprPanic(CRStringView file, int line, CRStringView panicMsg, const Error &err = OxError(0)) noexcept { +constexpr void constexprPanic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err = OxError(0)) noexcept { if (!std::is_constant_evaluated()) { panic(file, line, panicMsg, err); } else { @@ -32,12 +32,12 @@ constexpr void constexprPanic(CRStringView file, int line, CRStringView panicMsg } } -constexpr void assertFunc(CRStringView file, int line, bool pass, [[maybe_unused]]CRStringView assertTxt, [[maybe_unused]]CRStringView msg) noexcept { +constexpr void assertFunc(StringViewCR file, int line, bool pass, [[maybe_unused]]StringViewCR assertTxt, [[maybe_unused]]StringViewCR msg) noexcept { if (!pass) { if (!std::is_constant_evaluated()) { #ifdef OX_USE_STDLIB - oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg); - printStackTrace(2); + auto output = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg); + output += genStackTrace(2); oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line); std::abort(); #else @@ -51,19 +51,20 @@ constexpr void assertFunc(CRStringView file, int line, bool pass, [[maybe_unused } } -constexpr void assertFunc(CRStringView file, int line, const Error &err, CRStringView, CRStringView assertMsg) noexcept { +constexpr void assertFunc(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept { if (err) { if (!std::is_constant_evaluated()) { #if defined(OX_USE_STDLIB) - oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg); + auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg); if (err.msg) { - oxErrf("\tError Message:\t{}\n", err.msg); + msg += sfmt("\tError Message:\t{}\n", err.msg); } - oxErrf("\tError Code:\t{}\n", static_cast(err)); + msg += sfmt("\tError Code:\t{}\n", static_cast(err)); if (err.file != nullptr) { - oxErrf("\tError Location:\t{}:{}\n", err.file, err.line); + msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line); } - printStackTrace(2); + msg += genStackTrace(2); + oxErr(msg); oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line); std::abort(); #else @@ -75,7 +76,7 @@ constexpr void assertFunc(CRStringView file, int line, const Error &err, CRStrin } } -constexpr void expect(CRStringView file, int line, const auto &actual, const auto &expected) noexcept { +constexpr void expect(StringViewCR file, int line, const auto &actual, const auto &expected) noexcept { if (actual != expected) { if (!std::is_constant_evaluated()) { #if defined(OX_USE_STDLIB) diff --git a/deps/ox/src/ox/std/defer.hpp b/deps/ox/src/ox/std/defer.hpp index 593cc57..390ffeb 100644 --- a/deps/ox/src/ox/std/defer.hpp +++ b/deps/ox/src/ox/std/defer.hpp @@ -8,8 +8,6 @@ #pragma once -#include "error.hpp" - namespace ox { template @@ -18,13 +16,12 @@ class Defer { T m_deferredFunc; public: - Defer(T deferredFunc) { - m_deferredFunc = deferredFunc; + constexpr Defer(T deferredFunc) noexcept: m_deferredFunc(deferredFunc) { } Defer(const Defer&) = delete; - ~Defer() { + constexpr ~Defer() { m_deferredFunc(); } @@ -34,4 +31,4 @@ class Defer { } -#define oxDefer ox::Defer oxConcat(oxDefer_, __LINE__) = [&] +#define oxDefer ox::Defer const oxConcat(oxDefer_, __LINE__) = diff --git a/deps/ox/src/ox/std/error.hpp b/deps/ox/src/ox/std/error.hpp index 6018971..45d217e 100644 --- a/deps/ox/src/ox/std/error.hpp +++ b/deps/ox/src/ox/std/error.hpp @@ -165,21 +165,24 @@ struct [[nodiscard]] Result { return error == 0; } - constexpr Error copyTo(type &val) const& noexcept { + template + constexpr Error copyTo(U &val) const& noexcept { if (!error) [[likely]] { val = value; } return error; } - constexpr Error copyTo(type &val) && noexcept { + template + constexpr Error copyTo(U &val) && noexcept { if (!error) [[likely]] { val = std::move(value); } return error; } - constexpr Error moveTo(type &val) noexcept { + template + constexpr Error moveTo(U &val) noexcept { if (!error) [[likely]] { val = std::move(value); } diff --git a/deps/ox/src/ox/std/hashmap.hpp b/deps/ox/src/ox/std/hashmap.hpp index d38e2c8..0133435 100644 --- a/deps/ox/src/ox/std/hashmap.hpp +++ b/deps/ox/src/ox/std/hashmap.hpp @@ -64,6 +64,9 @@ class HashMap { [[nodiscard]] constexpr Vector const&keys() const noexcept; + [[nodiscard]] + constexpr Vector values() const noexcept; + constexpr void clear(); private: @@ -198,6 +201,16 @@ constexpr Vector const&HashMap::keys() const noexcept { return m_keys; } +template +constexpr Vector HashMap::values() const noexcept { + Vector out; + out.reserve(m_pairs.size()); + for (auto const&p : m_pairs) { + out.emplace_back(p->value); + } + return out; +} + template constexpr void HashMap::clear() { for (std::size_t i = 0; i < m_pairs.size(); i++) { diff --git a/deps/ox/src/ox/std/istring.hpp b/deps/ox/src/ox/std/istring.hpp index 83dea25..118e6bd 100644 --- a/deps/ox/src/ox/std/istring.hpp +++ b/deps/ox/src/ox/std/istring.hpp @@ -35,7 +35,7 @@ class IString { constexpr IString(const char *str) noexcept; - constexpr IString &operator=(CRStringView str) noexcept; + constexpr IString &operator=(StringViewCR str) noexcept; constexpr IString &operator=(const char *str) noexcept; @@ -119,7 +119,7 @@ constexpr IString &IString::operator=(Integer_c auto i) noexcept { } template -constexpr IString &IString::operator=(ox::CRStringView str) noexcept { +constexpr IString &IString::operator=(ox::StringViewCR str) noexcept { std::size_t strLen = str.len(); if (cap() < strLen) { strLen = cap(); diff --git a/deps/ox/src/ox/std/stacktrace.cpp b/deps/ox/src/ox/std/stacktrace.cpp index acbfdb4..b4da271 100644 --- a/deps/ox/src/ox/std/stacktrace.cpp +++ b/deps/ox/src/ox/std/stacktrace.cpp @@ -57,6 +57,28 @@ static auto symbolicate([[maybe_unused]]void **frames, } #endif // defined(OX_USE_STDLIB) && __has_include() +ox::String genStackTrace([[maybe_unused]]unsigned shave) noexcept { + ox::String out; +#if defined(OX_USE_STDLIB) && __has_include() && __has_include() + constexpr auto FrameCnt = 100; + Vector frames(FrameCnt); +#ifdef OX_OS_FreeBSD + using FrameCnt_t = unsigned; +#else + using FrameCnt_t = signed; +#endif + frames.resize(static_cast(backtrace(frames.data(), static_cast(frames.size())))); + if (frames.size() - shave > 2) { + const auto symbolicatedStacktrace = symbolicate(frames.data() + shave, frames.size() - shave, "\t"); + out+= "Stacktrace:\n"; + for (const auto &s : symbolicatedStacktrace) { + out += sfmt("\t{}\n", s); + } + } +#endif + return out; +} + void printStackTrace([[maybe_unused]]unsigned shave) noexcept { #if defined(OX_USE_STDLIB) && __has_include() && __has_include() constexpr auto FrameCnt = 100; diff --git a/deps/ox/src/ox/std/stacktrace.hpp b/deps/ox/src/ox/std/stacktrace.hpp index 26555e5..0c462d0 100644 --- a/deps/ox/src/ox/std/stacktrace.hpp +++ b/deps/ox/src/ox/std/stacktrace.hpp @@ -8,8 +8,13 @@ #pragma once +#include "string.hpp" + namespace ox { +[[nodiscard]] +ox::String genStackTrace([[maybe_unused]]unsigned shave) noexcept; + /** * Prints a stack trace to stderr. * diff --git a/deps/ox/src/ox/std/string.hpp b/deps/ox/src/ox/std/string.hpp index 324e243..7d6a7ba 100644 --- a/deps/ox/src/ox/std/string.hpp +++ b/deps/ox/src/ox/std/string.hpp @@ -46,7 +46,7 @@ class BasicString { constexpr explicit BasicString(StringLiteral const&str) noexcept; - constexpr explicit BasicString(CRStringView str) noexcept; + constexpr explicit BasicString(StringViewCR str) noexcept; constexpr explicit BasicString(BasicString const&) noexcept; @@ -126,7 +126,7 @@ class BasicString { constexpr BasicString &operator=(BasicString &&src) noexcept; - constexpr BasicString &operator=(CRStringView src) noexcept; + constexpr BasicString &operator=(StringViewCR src) noexcept; constexpr BasicString &operator+=(const char *str) noexcept; @@ -148,7 +148,7 @@ class BasicString { constexpr BasicString operator+(Integer_c auto i) const noexcept; - constexpr BasicString operator+(CRStringView src) const noexcept; + constexpr BasicString operator+(StringViewCR src) const noexcept; constexpr BasicString operator+(BasicString const&src) const noexcept; @@ -243,7 +243,7 @@ class BasicString { constexpr std::size_t bytes() const noexcept; private: - constexpr void set(CRStringView str) noexcept; + constexpr void set(StringViewCR str) noexcept; constexpr void set(const char8_t *str) noexcept; }; @@ -278,7 +278,7 @@ constexpr BasicString::BasicString(StringLiteral const&str) n } template -constexpr BasicString::BasicString(CRStringView str) noexcept { +constexpr BasicString::BasicString(StringViewCR str) noexcept { set(str); } @@ -343,7 +343,7 @@ constexpr BasicString &BasicString::operat } template -constexpr BasicString &BasicString::operator=(CRStringView src) noexcept { +constexpr BasicString &BasicString::operator=(StringViewCR src) noexcept { set(src); return *this; } @@ -416,7 +416,7 @@ constexpr BasicString BasicString::operato } template -constexpr BasicString BasicString::operator+(CRStringView src) const noexcept { +constexpr BasicString BasicString::operator+(StringViewCR src) const noexcept { const std::size_t strLen = src.len(); const auto currentLen = len(); BasicString cpy(currentLen + strLen); @@ -521,7 +521,7 @@ constexpr std::size_t BasicString::len() const noexcept { } template -constexpr void BasicString::set(CRStringView str) noexcept { +constexpr void BasicString::set(StringViewCR str) noexcept { std::size_t const strBytes = str.bytes(); m_buff.resize(strBytes + 1); copy_n(str.data(), strBytes, m_buff.data()); @@ -539,11 +539,11 @@ constexpr void BasicString::set(const char8_t *str) noexcept extern template class BasicString<8>; using String = BasicString<8>; -using CRString = String const&; +using StringCR = String const&; [[nodiscard]] -constexpr ox::String toString(ox::CRStringView sv) noexcept { +constexpr ox::String toString(ox::StringViewCR sv) noexcept { return ox::String(sv); } diff --git a/deps/ox/src/ox/std/stringview.hpp b/deps/ox/src/ox/std/stringview.hpp index 63f57a9..c9c6af7 100644 --- a/deps/ox/src/ox/std/stringview.hpp +++ b/deps/ox/src/ox/std/stringview.hpp @@ -58,16 +58,16 @@ class StringView: public detail::BaseStringView { }; -using CRStringView = const StringView&; +using StringViewCR = const StringView&; -constexpr auto operator==(CRStringView s1, CRStringView s2) noexcept { +constexpr auto operator==(StringViewCR s1, StringViewCR s2) noexcept { if (s2.len() != s1.len()) { return false; } return ox::strncmp(s1.data(), s2.data(), s1.len()) == 0; } -constexpr auto operator<=>(CRStringView s1, CRStringView s2) noexcept { +constexpr auto operator<=>(StringViewCR s1, StringViewCR s2) noexcept { const auto maxLen = ox::min(s1.len(), s2.len()); const auto a = &s1.front(); const auto b = &s2.front(); @@ -87,18 +87,18 @@ constexpr auto operator<=>(CRStringView s1, CRStringView s2) noexcept { } } -constexpr auto write(Writer_c auto &writer, ox::CRStringView sv) noexcept { +constexpr auto write(Writer_c auto &writer, ox::StringViewCR sv) noexcept { return writer.write(sv.data(), sv.bytes()); } #ifdef OX_USE_STDLIB -constexpr auto toStdStringView(CRStringView sv) noexcept { +constexpr auto toStdStringView(StringViewCR sv) noexcept { return std::string_view(sv.data(), sv.bytes()); } #endif -constexpr ox::Result atoi(ox::CRStringView str) noexcept { +constexpr ox::Result atoi(ox::StringViewCR str) noexcept { int total = 0; int multiplier = 1; for (auto i = static_cast(str.len()) - 1; i != -1; --i) { diff --git a/deps/ox/src/ox/std/strops.hpp b/deps/ox/src/ox/std/strops.hpp index ef0dfa2..260ec83 100644 --- a/deps/ox/src/ox/std/strops.hpp +++ b/deps/ox/src/ox/std/strops.hpp @@ -34,19 +34,19 @@ constexpr ox::StringView substr(ox::StringView const&str, std::size_t start, std } [[nodiscard]] -constexpr bool beginsWith(CRStringView base, CRStringView beginning) noexcept { +constexpr bool beginsWith(StringViewCR base, StringViewCR beginning) noexcept { const auto beginningLen = ox::min(beginning.len(), base.len()); return base.len() >= beginning.len() && ox::strncmp(base.data(), beginning, beginningLen) == 0; } [[nodiscard]] -constexpr bool endsWith(CRStringView base, CRStringView ending) noexcept { +constexpr bool endsWith(StringViewCR base, StringViewCR ending) noexcept { const auto endingLen = ending.len(); return base.len() >= endingLen && ox::strcmp(base.data() + (base.len() - endingLen), ending) == 0; } [[nodiscard]] -constexpr std::size_t find(CRStringView str, char search) noexcept { +constexpr std::size_t find(StringViewCR str, char search) noexcept { std::size_t i = 0; for (; i < str.len(); ++i) { if (str[i] == search) { @@ -57,7 +57,7 @@ constexpr std::size_t find(CRStringView str, char search) noexcept { } [[nodiscard]] -constexpr std::size_t find(CRStringView str, CRStringView search) noexcept { +constexpr std::size_t find(StringViewCR str, StringViewCR search) noexcept { std::size_t i = 0; for (; i < str.len(); ++i) { if (beginsWith(substr(str, i), search)) { @@ -69,9 +69,9 @@ constexpr std::size_t find(CRStringView str, CRStringView search) noexcept { template [[nodiscard]] -constexpr ox::Vector split(CRStringView str, char del) noexcept { +constexpr ox::Vector split(StringViewCR str, char del) noexcept { ox::Vector out; - constexpr auto nextSeg = [](CRStringView current, char del) { + constexpr auto nextSeg = [](StringViewCR current, char del) { return substr(current, find(current, del) + 1); }; for (auto current = str; current.len(); current = nextSeg(current, del)) { @@ -86,9 +86,9 @@ constexpr ox::Vector split(CRStringView str, char del) template [[nodiscard]] -constexpr ox::Vector split(CRStringView str, CRStringView del) noexcept { +constexpr ox::Vector split(StringViewCR str, StringViewCR del) noexcept { ox::Vector out; - constexpr auto nextSeg = [](CRStringView current, CRStringView del) { + constexpr auto nextSeg = [](StringViewCR current, StringViewCR del) { return substr(current, find(current, del) + del.len()); }; for (auto current = str; current.len(); current = nextSeg(current, del)) { @@ -102,7 +102,7 @@ constexpr ox::Vector split(CRStringView str, CRStringVi } [[nodiscard]] -constexpr ox::Result lastIndexOf(ox::CRStringView str, int character) noexcept { +constexpr ox::Result lastIndexOf(ox::StringViewCR str, int character) noexcept { ox::Result retval = OxError(1, "Character not found"); for (auto i = static_cast(str.bytes() - 1); i >= 0; --i) { if (str[static_cast(i)] == character) { diff --git a/deps/ox/src/ox/std/tracehook.cpp b/deps/ox/src/ox/std/tracehook.cpp index 90743ec..fd194b4 100644 --- a/deps/ox/src/ox/std/tracehook.cpp +++ b/deps/ox/src/ox/std/tracehook.cpp @@ -24,10 +24,10 @@ static const auto OxPrintTrace = std::getenv("OXTRACE") != nullptr; #define REG_MGBA_DEBUG_FLAGS *reinterpret_cast(0x4FFF700) #define REG_MGBA_DEBUG_STRING (reinterpret_cast(0x4FFF600)) -inline void nullLog(ox::CRStringView) {} -inline void (*infoLog)(ox::CRStringView) = nullLog; -inline void (*debugLog)(ox::CRStringView) = nullLog; -inline void (*errorLog)(ox::CRStringView) = nullLog; +inline void nullLog(ox::StringViewCR) {} +inline void (*infoLog)(ox::StringViewCR) = nullLog; +inline void (*debugLog)(ox::StringViewCR) = nullLog; +inline void (*errorLog)(ox::StringViewCR) = nullLog; namespace mgba { @@ -40,7 +40,7 @@ enum LogChan { }; template -static void log(ox::CRStringView str) { +static void log(ox::StringViewCR str) { const auto sz = ox::min(0x100, str.bytes()); ox::strncpy(REG_MGBA_DEBUG_STRING, str.data(), sz); REG_MGBA_DEBUG_FLAGS = chan | 0x100; @@ -65,23 +65,28 @@ void oxTraceInitHook() { void oxTraceHook([[maybe_unused]] const char *file, [[maybe_unused]] int line, [[maybe_unused]] const char *ch, [[maybe_unused]] const char *msg) { #if defined(OX_USE_STDLIB) + auto const chv = ox::StringView{ch}; if (OxPrintTrace) { + auto m = std::string_view{msg}; + if (m.ends_with('\n')) { + m = std::string_view{msg, m.size() - 1}; + } std::cout << std::setw(53) << std::left << ch << "| "; - std::cout << std::setw(65) << std::left << msg << '|'; + std::cout << std::setw(65) << std::left << m << '|'; std::cout << " " << file << ':' << line << "\n"; - } else if (ox::strcmp(ch, "debug") == 0 || ox::strcmp(ch, "info") == 0) { + } else if (chv == "debug" || chv == "info") { printf("%s\n", msg); - fflush(stdout); - } else if (ox::strcmp(ch, "stdout") == 0) { + std::ignore = fflush(stdout); + } else if (chv == "stdout") { printf("%s", msg); - fflush(stdout); - } else if (ox::strcmp(ch, "stderr") == 0) { - printf("%s", msg); - fflush(stdout); - } else if (ox::strcmp(ch, "error") == 0) { + std::ignore = fflush(stdout); + } else if (chv == "stderr") { + std::ignore = fprintf(stderr, "%s", msg); + std::ignore = fflush(stderr); + } else if (chv == "error") { //std::cerr << "\033[31;1;1mERROR:\033[0m (" << file << ':' << line << "): " << msg << '\n'; - fprintf(stderr, "\033[31;1;1mERROR:\033[0m (%s:%d): %s\n", file, line, msg); - fflush(stderr); + std::ignore = fprintf(stderr, "\033[31;1;1mERROR:\033[0m (%s:%d): %s\n", file, line, msg); + std::ignore = fflush(stderr); } #else if (ox::strcmp(ch, "info") == 0) { diff --git a/deps/ox/src/ox/std/uuid.hpp b/deps/ox/src/ox/std/uuid.hpp index 80b66f1..5e55925 100644 --- a/deps/ox/src/ox/std/uuid.hpp +++ b/deps/ox/src/ox/std/uuid.hpp @@ -31,7 +31,7 @@ constexpr auto isHexChar(char c) noexcept { || (c >= 'A' && c <= 'F'); } -constexpr ox::Result fromHex(ox::CRStringView v) noexcept { +constexpr ox::Result fromHex(ox::StringViewCR v) noexcept { constexpr auto valMap = [] { ox::Array out; out['A'] = out['a'] = 10; @@ -125,7 +125,7 @@ class UUID { } } - static constexpr ox::Result fromString(ox::CRStringView s) noexcept { + static constexpr ox::Result fromString(ox::StringViewCR s) noexcept { if (s.len() < 36) { return OxError(1, "Insufficient data to contain a complete UUID"); } diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index a3f763d..8035dfb 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -222,8 +222,10 @@ class Vector: detail::VectorAllocator { constexpr Vector &operator=(Vector &&other) noexcept; + [[nodiscard]] constexpr T &operator[](std::size_t i) noexcept; + [[nodiscard]] constexpr const T &operator[](std::size_t i) const noexcept; [[nodiscard]] diff --git a/scripts/pkg-gba.py b/scripts/pkg-gba.py index f47c70f..e3ee369 100755 --- a/scripts/pkg-gba.py +++ b/scripts/pkg-gba.py @@ -28,8 +28,12 @@ project_name = sys.argv[2] bin = f'./build/{host_env}-{current_build}/bin/' project_bin = f'build/gba-release/bin/{project_name}.bin' project_gba = f'{project_name}.gba' +project_manifest = f'{project_name}-manifest.json' shutil.copyfile(project_bin, project_gba) subprocess.run([ - f'{bin}/{project_name}-pack', '-src', project_dir, '-rom-bin', project_gba]) + f'{bin}/{project_name}-pack', + '-src', project_dir, + '-rom-bin', project_gba, + '-manifest', project_manifest]) subprocess.run(['gbafix', project_gba]) diff --git a/src/nostalgia/modules/core/include/nostalgia/core/gfx.hpp b/src/nostalgia/modules/core/include/nostalgia/core/gfx.hpp index 0e104b2..e15a97d 100644 --- a/src/nostalgia/modules/core/include/nostalgia/core/gfx.hpp +++ b/src/nostalgia/modules/core/include/nostalgia/core/gfx.hpp @@ -139,7 +139,15 @@ ox::Error loadBgTileSheet( Context &ctx, unsigned cbb, CompactTileSheet const&ts, - ox::Optional const&paletteBank) noexcept; + size_t dstTileIdx, + size_t srcTileIdx, + size_t tileCnt) noexcept; + +ox::Error loadBgTileSheet( + Context &ctx, + unsigned cbb, + CompactTileSheet const&ts, + ox::Optional const&paletteBank = {}) noexcept; ox::Error loadBgTileSheet( Context &ctx, @@ -192,7 +200,7 @@ uint_t spriteCount(Context &ctx) noexcept; ox::Error initConsole(Context &ctx) noexcept; -void puts(Context &ctx, int column, int row, ox::CRStringView str) noexcept; +void puts(Context &ctx, int column, int row, ox::StringViewCR str) noexcept; } diff --git a/src/nostalgia/modules/core/include/nostalgia/core/palette.hpp b/src/nostalgia/modules/core/include/nostalgia/core/palette.hpp index 6a2c914..2550ba3 100644 --- a/src/nostalgia/modules/core/include/nostalgia/core/palette.hpp +++ b/src/nostalgia/modules/core/include/nostalgia/core/palette.hpp @@ -67,12 +67,22 @@ struct NostalgiaPalette { ox::Vector colors = {}; }; +oxModelBegin(NostalgiaPalette) + oxModelField(colors) +oxModelEnd() + + struct PaletteV1 { static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette"; static constexpr auto TypeVersion = 1; ox::Vector colors; }; +oxModelBegin(PaletteV1) + oxModelField(colors) +oxModelEnd() + + struct PaletteV2 { static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette"; static constexpr auto TypeVersion = 2; @@ -80,6 +90,10 @@ struct PaletteV2 { ox::Vector> pages; }; +oxModelBegin(PaletteV2) + oxModelField(pages) +oxModelEnd() + struct PaletteV3 { static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Palette"; @@ -96,6 +110,15 @@ struct PaletteV3 { ox::Vector> pages; }; +oxModelBegin(PaletteV3::ColorInfo) + oxModelField(name) +oxModelEnd() + +oxModelBegin(PaletteV3) + oxModelField(colorInfo) + oxModelField(pages) +oxModelEnd() + [[nodiscard]] constexpr bool valid(PaletteV3 const&p) noexcept { auto const colors = p.colorInfo.size(); @@ -121,6 +144,11 @@ struct PaletteV4 { ox::Vector pages; }; +oxModelBegin(PaletteV4) + oxModelField(colorNames) + oxModelField(pages) +oxModelEnd() + [[nodiscard]] constexpr bool valid(PaletteV4 const&p) noexcept { auto const colors = p.colorNames.size(); @@ -148,6 +176,10 @@ struct CompactPaletteV1 { ox::Vector> pages{}; }; +oxModelBegin(CompactPaletteV1) + oxModelField(pages) +oxModelEnd() + [[nodiscard]] constexpr bool valid(CompactPaletteV1 const&p) noexcept { size_t colors{}; @@ -254,34 +286,4 @@ constexpr size_t largestPage(CompactPalette const&pal) noexcept { return out; } -oxModelBegin(NostalgiaPalette) - oxModelField(colors) -oxModelEnd() - -oxModelBegin(PaletteV1) - oxModelField(colors) -oxModelEnd() - -oxModelBegin(PaletteV2) - oxModelField(pages) -oxModelEnd() - -oxModelBegin(PaletteV3::ColorInfo) - oxModelField(name) -oxModelEnd() - -oxModelBegin(PaletteV3) - oxModelField(colorInfo) - oxModelField(pages) -oxModelEnd() - -oxModelBegin(PaletteV4) - oxModelField(colorNames) - oxModelField(pages) -oxModelEnd() - -oxModelBegin(CompactPaletteV1) - oxModelField(pages) -oxModelEnd() - } diff --git a/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp b/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp index a1012dc..dfbe030 100644 --- a/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp +++ b/src/nostalgia/modules/core/include/nostalgia/core/tilesheet.hpp @@ -31,6 +31,12 @@ struct TileSheetV1 { ox::Vector pixels = {}; }; +[[nodiscard]] +constexpr bool valid(TileSheetV1 const&ts) noexcept { + return ts.bpp == 4 || ts.bpp == 8; +} + + struct TileSheetV2 { using SubSheetIdx = ox::Vector; @@ -43,8 +49,8 @@ struct TileSheetV2 { ox::Vector subsheets; ox::Vector pixels; constexpr SubSheet() noexcept = default; - constexpr SubSheet(ox::CRStringView pName, int pColumns, int pRows, int bpp) noexcept: - name(pName), + constexpr SubSheet(ox::StringParam pName, int pColumns, int pRows, int bpp) noexcept: + name(std::move(pName)), columns(pColumns), rows(pRows), pixels(static_cast(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) { @@ -59,6 +65,12 @@ struct TileSheetV2 { }; +[[nodiscard]] +constexpr bool valid(TileSheetV2 const&ts) noexcept { + return ts.bpp == 4 || ts.bpp == 8; +} + + using SubSheetId = int32_t; struct TileSheetV3 { @@ -74,14 +86,14 @@ struct TileSheetV3 { ox::Vector subsheets; ox::Vector pixels; constexpr SubSheet() noexcept = default; - inline SubSheet( + SubSheet( SubSheetId pId, - ox::CRStringView pName, + ox::StringParam pName, int pColumns, int pRows, int bpp) noexcept: id(pId), - name(pName), + name(std::move(pName)), columns(pColumns), rows(pRows), pixels(static_cast(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) { @@ -98,7 +110,13 @@ struct TileSheetV3 { }; -struct TileSheet { +[[nodiscard]] +constexpr bool valid(TileSheetV3 const&ts) noexcept { + return ts.bpp == 4 || ts.bpp == 8; +} + + +struct TileSheetV4 { using SubSheetIdx = ox::Vector; struct SubSheet { @@ -112,26 +130,26 @@ struct TileSheet { ox::Vector pixels; constexpr SubSheet() noexcept = default; - inline SubSheet( + SubSheet( SubSheetId pId, - ox::CRStringView pName, + ox::StringParam pName, int pColumns, int pRows, int bpp) noexcept: id(pId), - name(pName), + name(std::move(pName)), columns(pColumns), rows(pRows), pixels(static_cast(columns * rows * PixelsPerTile) / (bpp == 4 ? 2u : 1u)) { } - inline SubSheet( + SubSheet( SubSheetId pId, - ox::CRStringView pName, + ox::StringParam pName, int pColumns, int pRows, ox::Vector pPixels) noexcept: id(pId), - name(pName), + name(std::move(pName)), columns(pColumns), rows(pRows), pixels(std::move(pPixels)) { @@ -151,10 +169,18 @@ struct TileSheet { ox::FileAddress defaultPalette; SubSheet subsheet{0, "Root", 1, 1, bpp}; - constexpr TileSheet() noexcept = default; + constexpr TileSheetV4() noexcept = default; }; +[[nodiscard]] +constexpr bool valid(TileSheetV4 const&ts) noexcept { + return ts.bpp == 4 || ts.bpp == 8; +} + + +using TileSheet = TileSheetV4; + [[nodiscard]] std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; @@ -280,18 +306,17 @@ uint8_t getPixel8Bpp( ox::Point const&pt, TileSheet::SubSheetIdx const&subsheetIdx) noexcept; -ox::Result getIdFor(TileSheet const&ts, ox::CRStringView path) noexcept; +ox::Result getIdFor(TileSheet const&ts, ox::StringViewCR path) noexcept; -ox::Result getTileOffset(TileSheet const&ts, ox::CRStringView pNamePath) noexcept; +ox::Result getTileOffset(TileSheet const&ts, ox::StringViewCR pNamePath) noexcept; ox::Result getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept; -ox::Result getNameFor(TileSheet const&ss, SubSheetId pId) noexcept; +ox::Result getNameFor(TileSheet const&ts, SubSheetId pId) noexcept; [[nodiscard]] ox::Vector pixels(TileSheet &ts) noexcept; -using TileSheetV4 = TileSheet; struct CompactTileSheetV1 { static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.CompactTileSheet"; @@ -302,8 +327,34 @@ struct CompactTileSheetV1 { ox::Vector pixels; }; +[[nodiscard]] +constexpr bool valid(CompactTileSheetV1 const&ts) noexcept { + return ts.bpp == 4 || ts.bpp == 8; +} + + using CompactTileSheet = CompactTileSheetV1; +[[nodiscard]] +uint8_t getPixel4Bpp( + CompactTileSheet const&ts, + size_t idx) noexcept; + +[[nodiscard]] +uint8_t getPixel8Bpp( + CompactTileSheet const&ts, + size_t idx) noexcept; + +[[nodiscard]] +ox::Pair get2Pixels4Bpp( + CompactTileSheet const&ts, + size_t idx) noexcept; + +[[nodiscard]] +ox::Pair get2Pixels8Bpp( + CompactTileSheet const&ts, + size_t idx) noexcept; + oxModelBegin(TileSheetV1) oxModelField(bpp) oxModelField(rows) diff --git a/src/nostalgia/modules/core/src/gba/gfx.cpp b/src/nostalgia/modules/core/src/gba/gfx.cpp index 7255f55..8b87084 100644 --- a/src/nostalgia/modules/core/src/gba/gfx.cpp +++ b/src/nostalgia/modules/core/src/gba/gfx.cpp @@ -3,7 +3,6 @@ */ #include -#include #include #include @@ -11,9 +10,7 @@ #include #include -#include -#include #include #include #include @@ -22,7 +19,7 @@ namespace nostalgia::core { -constexpr auto SpriteCount = 128; +static constexpr auto SpriteCount = 128; ox::Error initGfx(Context&, InitParams const&) noexcept { for (auto bgCtl = ®_BG0CTL; bgCtl <= ®_BG3CTL; bgCtl += 2) { @@ -81,7 +78,7 @@ ox::Error loadSpritePalette( static ox::Error loadTileSheetSet( Context &ctx, - uint16_t *tileMapTargetMem, + ox::Span tileMapTargetMem, TileSheetSet const&set) noexcept { size_t tileWriteIdx = 0; size_t const bppMod = set.bpp == 4; @@ -106,6 +103,34 @@ static ox::Error loadTileSheetSet( return {}; } +ox::Error loadBgTileSheet( + Context &ctx, + unsigned const cbb, + CompactTileSheet const&ts, + size_t const dstTileIdx, + size_t const srcTileIdx, + size_t const tileCnt) noexcept { + size_t const bppMod = ts.bpp == 4; + size_t const bytesPerTile = PixelsPerTile >> bppMod; + auto const pixCnt = tileCnt * bytesPerTile; + auto const srcPxIdx = srcTileIdx * bytesPerTile; + auto const dstPxIdx = (dstTileIdx * bytesPerTile) / 2; + for (size_t i = 0; i < pixCnt; ++i) { + auto const srcIdx = srcPxIdx + i * 2; + auto const p1 = static_cast(ts.pixels[srcIdx]); + auto const p2 = static_cast(ts.pixels[srcIdx + 1]); + MEM_BG_TILES[cbb][dstPxIdx + i] = static_cast(p1 | (p2 << 8)); + } + // update bpp of all bgs with the updated cbb + auto const bpp = ctx.cbbData[cbb].bpp; + teagba::iterateBgCtl([bpp, cbb](volatile BgCtl &bgCtl) { + if (teagba::bgCbb(bgCtl) == cbb) { + teagba::bgSetBpp(bgCtl, bpp); + } + }); + return {}; +} + ox::Error loadBgTileSheet( Context &ctx, unsigned cbb, @@ -142,10 +167,10 @@ ox::Error loadBgTileSheet( ox::Error loadBgTileSheet( Context &ctx, - unsigned cbb, + unsigned const cbb, TileSheetSet const&set) noexcept { auto const bpp = static_cast(set.bpp); - oxReturnError(loadTileSheetSet(ctx, MEM_BG_TILES[cbb].data(), set)); + oxReturnError(loadTileSheetSet(ctx, MEM_BG_TILES[cbb], set)); // update bpp of all bgs with the updated cbb ctx.cbbData[cbb].bpp = bpp; teagba::iterateBgCtl([bpp, cbb](volatile BgCtl &bgCtl) { @@ -193,7 +218,7 @@ ox::Error loadSpriteTileSheet( Context &ctx, TileSheetSet const&set) noexcept { auto const bpp = static_cast(set.bpp); - oxReturnError(loadTileSheetSet(ctx, MEM_SPRITE_TILES, set)); + oxReturnError(loadTileSheetSet(ctx, {MEM_SPRITE_TILES, 32 * ox::units::KB}, set)); setSpritesBpp(bpp); return {}; } diff --git a/src/nostalgia/modules/core/src/gfx.cpp b/src/nostalgia/modules/core/src/gfx.cpp index 3c941f8..85f6400 100644 --- a/src/nostalgia/modules/core/src/gfx.cpp +++ b/src/nostalgia/modules/core/src/gfx.cpp @@ -168,7 +168,7 @@ void puts( Context &ctx, int const column, int const row, - ox::CRStringView str) noexcept { + ox::StringViewCR str) noexcept { auto const col = static_cast(column); for (auto i = 0u; i < str.bytes(); ++i) { setBgTile( diff --git a/src/nostalgia/modules/core/src/opengl/gfx.cpp b/src/nostalgia/modules/core/src/opengl/gfx.cpp index e5dee25..a86dde8 100644 --- a/src/nostalgia/modules/core/src/opengl/gfx.cpp +++ b/src/nostalgia/modules/core/src/opengl/gfx.cpp @@ -22,8 +22,8 @@ namespace nostalgia::core { namespace renderer { -constexpr auto Scale = 1; -constexpr auto PriorityScale = 0.01f; +static constexpr auto Scale = 1; +static constexpr auto PriorityScale = 0.01f; Drawer::Drawer(Context &ctx) noexcept: m_ctx(ctx) {} @@ -31,7 +31,7 @@ void Drawer::draw(turbine::Context &tctx) noexcept { core::gl::draw(m_ctx, turbine::getScreenSize(tctx)); } -constexpr ox::CStringView bgvshadTmpl = R"glsl( +static constexpr ox::CStringView bgvshadTmpl = R"glsl( {} in vec2 vTexCoord; in vec3 vPosition; @@ -55,7 +55,7 @@ constexpr ox::CStringView bgvshadTmpl = R"glsl( fPalOffset = vPalOffset; })glsl"; -constexpr ox::CStringView bgfshadTmpl = R"glsl( +static constexpr ox::CStringView bgfshadTmpl = R"glsl( {} out vec4 outColor; in float fPalOffset; @@ -71,7 +71,7 @@ constexpr ox::CStringView bgfshadTmpl = R"glsl( } })glsl"; -constexpr ox::CStringView spritevshadTmpl = R"glsl( +static constexpr ox::CStringView spritevshadTmpl = R"glsl( {} in float vEnabled; in vec3 vPosition; @@ -90,7 +90,7 @@ constexpr ox::CStringView spritevshadTmpl = R"glsl( fTexCoord = vTexCoord * vec2(1, vTileHeight); })glsl"; -constexpr ox::CStringView spritefshadTmpl = R"glsl( +static constexpr ox::CStringView spritefshadTmpl = R"glsl( {} out vec4 outColor; in vec2 fTexCoord; @@ -279,7 +279,7 @@ static void initBackgroundBufferset( static glutils::GLTexture createTexture( GLsizei w, GLsizei h, - const void *pixels) noexcept { + void const*pixels) noexcept { GLuint texId = 0; glGenTextures(1, &texId); glutils::GLTexture tex(texId); @@ -492,22 +492,22 @@ struct TileSheetData { }; static ox::Result normalizeTileSheet( - CompactTileSheet const&tilesheet) noexcept { - const uint_t bytesPerTile = tilesheet.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2; - const auto tiles = tilesheet.pixels.size() / bytesPerTile; + CompactTileSheet const&ts) noexcept { + const uint_t bytesPerTile = ts.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2; + const auto tiles = ts.pixels.size() / bytesPerTile; constexpr int width = 8; const int height = 8 * static_cast(tiles); ox::Vector pixels; if (bytesPerTile == 64) { // 8 BPP - pixels.resize(tilesheet.pixels.size()); - for (std::size_t i = 0; i < tilesheet.pixels.size(); ++i) { - pixels[i] = tilesheet.pixels[i]; + pixels.resize(ts.pixels.size()); + for (std::size_t i = 0; i < ts.pixels.size(); ++i) { + pixels[i] = ts.pixels[i]; } } else { // 4 BPP - pixels.resize(tilesheet.pixels.size() * 2); - for (std::size_t i = 0; i < tilesheet.pixels.size(); ++i) { - pixels[i * 2 + 0] = tilesheet.pixels[i] & 0xF; - pixels[i * 2 + 1] = tilesheet.pixels[i] >> 4; + pixels.resize(ts.pixels.size() * 2); + for (std::size_t i = 0; i < ts.pixels.size(); ++i) { + pixels[i * 2 + 0] = ts.pixels[i] & 0xF; + pixels[i * 2 + 1] = ts.pixels[i] >> 4; } } return TileSheetData{std::move(pixels), width, height}; @@ -572,14 +572,58 @@ static ox::Result buildSetTsd( return setTsd; } +static void copyPixels( + CompactTileSheet const&ts, + uint32_t *dst, + size_t const srcPxIdx, + size_t pxlCnt) noexcept { + if (ts.bpp == 4) { + for (size_t i = 0; i < pxlCnt; i += 2) { + auto const [a, b] = get2Pixels4Bpp(ts, i + srcPxIdx); + *(dst++) = a; + *(dst++) = b; + } + } else if (ts.bpp == 8) { + for (size_t i = 0; i < pxlCnt; i += 2) { + auto const [a, b] = get2Pixels8Bpp(ts, i + srcPxIdx); + *(dst++) = a; + *(dst++) = b; + } + } +} + +ox::Error loadBgTileSheet( + Context &ctx, + unsigned const cbb, + CompactTileSheet const&ts, + size_t const dstTileIdx, + size_t const srcTileIdx, + size_t const tileCnt) noexcept { + auto &cbbPxls = ctx.cbbs[cbb].pixels; + auto const bytesPerTile = static_cast(PixelsPerTile / (1 + (ts.bpp == 4))); + auto const pxlCnt = tileCnt * PixelsPerTile; + auto const srcPxIdx = srcTileIdx * PixelsPerTile; + auto const dstPxIdx = dstTileIdx * PixelsPerTile; + if (dstPxIdx + pxlCnt >= cbbPxls.size()) { + return OxError(1, "video mem dst overflow"); + } + auto const dst = &cbbPxls[dstPxIdx]; + copyPixels(ts, dst, srcPxIdx, pxlCnt); + auto const cbbTiles = cbbPxls.size() / bytesPerTile; + int constexpr cbbWidth = 8; + int const cbbHeight = 8 * static_cast(cbbTiles); + ctx.cbbs[cbb].tex = renderer::createTexture(cbbWidth, cbbHeight, cbbPxls.data()); + return {}; +} + ox::Error loadBgTileSheet( Context &ctx, uint_t cbb, CompactTileSheet const&ts, ox::Optional const&paletteBank) noexcept { - oxRequire(tsd, normalizeTileSheet(ts)); - oxTracef("nostalgia.core.gfx.gl", "loadBgTexture: { cbbIdx: {}, w: {}, h: {} }", cbb, tsd.width, tsd.height); - ctx.cbbs[cbb].tex = renderer::createTexture(tsd.width, tsd.height, tsd.pixels.data()); + auto const bytesPerTile = static_cast(PixelsPerTile / (1 + (ts.bpp == 4))); + auto const tiles = ts.pixels.size() / bytesPerTile; + oxReturnError(loadBgTileSheet(ctx, cbb, ts, 0, 0, tiles)); if (paletteBank.has_value() && ts.defaultPalette) { oxReturnError(loadBgPalette(ctx, *paletteBank, ts.defaultPalette)); } diff --git a/src/nostalgia/modules/core/src/opengl/gfx.hpp b/src/nostalgia/modules/core/src/opengl/gfx.hpp index 0fefa6f..81200d7 100644 --- a/src/nostalgia/modules/core/src/opengl/gfx.hpp +++ b/src/nostalgia/modules/core/src/opengl/gfx.hpp @@ -28,6 +28,7 @@ constexpr uint64_t SpriteVertexEboLength = 6; struct CBB: public glutils::BufferSet { bool updated = false; + ox::Array pixels; constexpr CBB() noexcept { vertices.resize(TileCount * BgVertexVboLength); elements.resize(TileCount * BgVertexEboLength); diff --git a/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.cpp b/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.cpp index f197f1c..ebf079a 100644 --- a/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.cpp +++ b/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.cpp @@ -41,7 +41,7 @@ PaletteEditorImGui::PaletteEditorImGui(studio::StudioContext &sctx, ox::StringPa m_sctx(sctx), m_tctx(sctx.tctx), m_pal(*keel::readObj(keelCtx(m_tctx), itemPath()).unwrapThrow()) { - if (!valid(m_pal)) { + if (keel::ensureValid(m_pal).errCode) { throw OxException(1, "PaletteEditorImGui: invalid Palette object"); } undoStack()->changeTriggered.connect(this, &PaletteEditorImGui::handleCommand); @@ -98,6 +98,12 @@ void PaletteEditorImGui::drawColumn(ox::CStringView txt) noexcept { ImGui::Text("%s", txt.c_str()); } +void PaletteEditorImGui::colorInput(ox::CStringView label, int &v, bool &inputFocused) noexcept { + ImGui::InputInt(label.c_str(), &v, 1, 5); + inputFocused = inputFocused || ImGui::IsItemFocused(); + v = ox::max(v, 0); +} + void PaletteEditorImGui::drawColorsEditor() noexcept { constexpr auto tableFlags = ImGuiTableFlags_RowBg; auto const colorsSz = ImGui::GetContentRegionAvail(); @@ -238,17 +244,27 @@ void PaletteEditorImGui::drawColorEditor() noexcept { ox::IString<50> name; name = currentName; ImGui::InputText("Name", name.data(), name.cap() + 1); + bool inputFocused = ImGui::IsItemFocused(); ImGui::Separator(); - ImGui::InputInt("Red", &r, 1, 5); - ImGui::InputInt("Green", &g, 1, 5); - ImGui::InputInt("Blue", &b, 1, 5); + colorInput("Red", r, inputFocused); + colorInput("Green", g, inputFocused); + colorInput("Blue", b, inputFocused); if (ig::PushButton("Apply to all pages", {-1, ig::BtnSz.y})) { std::ignore = pushCommand( m_pal, m_page, m_selectedColorRow); } - r = ox::max(r, 0); - g = ox::max(g, 0); - b = ox::max(b, 0); + if (!inputFocused) { + auto const lastColor = largestPage(m_pal) - 1; + if (ImGui::IsKeyPressed(ImGuiKey_0, false)) { + m_selectedColorRow = ox::min(9, lastColor); + } else for (auto i = 9u; i < 10; --i) { + auto const key = static_cast(ImGuiKey_1 + i); + if (ImGui::IsKeyPressed(key, false)) { + m_selectedColorRow = ox::min(i, lastColor); + break; + } + } + } auto const newColor = color16(r, g, b, a); if (c != newColor) { std::ignore = pushCommand(m_pal, m_page, m_selectedColorRow, newColor); diff --git a/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.hpp b/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.hpp index feefa08..d11d614 100644 --- a/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.hpp +++ b/src/nostalgia/modules/core/src/studio/paletteeditor/paletteeditor-imgui.hpp @@ -56,6 +56,8 @@ class PaletteEditorImGui: public studio::Editor { drawColumn(ox::itoa(i)); } + static void colorInput(ox::CStringView label, int &v, bool &inputFocused) noexcept; + void drawColorsEditor() noexcept; void drawPagesEditor() noexcept; diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/cutpastecommand.hpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/cutpastecommand.hpp index 0129337..5dece14 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/cutpastecommand.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/cutpastecommand.hpp @@ -10,6 +10,8 @@ namespace nostalgia::core { +oxModelFwdDecl(class TileSheetClipboard); + class TileSheetClipboard: public turbine::ClipboardObject { public: static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.TileSheetClipboard"; diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/palettechangecommand.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/palettechangecommand.cpp index 2138c85..6166ce8 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/palettechangecommand.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/palettechangecommand.cpp @@ -9,7 +9,7 @@ namespace nostalgia::core { core::PaletteChangeCommand::PaletteChangeCommand( TileSheet::SubSheetIdx idx, TileSheet &img, - ox::CRStringView newPalette) noexcept: + ox::StringViewCR newPalette) noexcept: m_img(img), m_idx(std::move(idx)), m_oldPalette(m_img.defaultPalette), diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/palettechangecommand.hpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/palettechangecommand.hpp index 8561099..c4540b7 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/palettechangecommand.hpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/commands/palettechangecommand.hpp @@ -19,7 +19,7 @@ class PaletteChangeCommand: public TileSheetCommand { PaletteChangeCommand( TileSheet::SubSheetIdx idx, TileSheet &img, - ox::CRStringView newPalette) noexcept; + ox::StringViewCR newPalette) noexcept; ox::Error redo() noexcept final; diff --git a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp index d8df5f5..8274521 100644 --- a/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp +++ b/src/nostalgia/modules/core/src/studio/tilesheeteditor/tilesheeteditor-imgui.cpp @@ -312,9 +312,8 @@ void TileSheetEditorImGui::drawSubsheetSelector( for (auto i = 0ul; auto &child : subsheet.subsheets) { path.push_back(i); ImGui::PushID(static_cast(i)); - ImGui::Indent(-indentReduce); + ig::IndentStackItem const indentStackItem{-indentReduce}; drawSubsheetSelector(child, path); - ImGui::Indent(indentReduce); ImGui::PopID(); path.pop_back(); ++i; @@ -440,7 +439,7 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept { } auto const pages = m_model.pal().pages.size(); if (pages > 1) { - ImGui::Indent(20); + ig::IndentStackItem const indentStackItem{20}; using Str = ox::IString<55>; auto numStr = ox::sfmt( "{} - {}", m_model.palettePage() + 1, m_model.pal().pages[m_model.palettePage()].name); @@ -458,7 +457,6 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept { } ImGui::EndCombo(); } - ImGui::Indent(-20); } // header if (ImGui::BeginTable( diff --git a/src/nostalgia/modules/core/src/tilesheet.cpp b/src/nostalgia/modules/core/src/tilesheet.cpp index fb336f7..99428aa 100644 --- a/src/nostalgia/modules/core/src/tilesheet.cpp +++ b/src/nostalgia/modules/core/src/tilesheet.cpp @@ -280,7 +280,7 @@ uint8_t getPixel4Bpp( TileSheet::SubSheetIdx const&subsheetIdx) noexcept { oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); auto &s = getSubSheet(ts, subsheetIdx); - const auto idx = ptToIdx(pt, s.columns); + auto const idx = ptToIdx(pt, s.columns); return getPixel4Bpp(s, idx); } @@ -290,10 +290,49 @@ uint8_t getPixel8Bpp( TileSheet::SubSheetIdx const&subsheetIdx) noexcept { oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); auto &s = getSubSheet(ts, subsheetIdx); - const auto idx = ptToIdx(pt, s.columns); + auto const idx = ptToIdx(pt, s.columns); return getPixel8Bpp(s, idx); } +uint8_t getPixel4Bpp( + CompactTileSheet const&ts, + size_t const idx) noexcept { + oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); + if (idx & 1) { + return ts.pixels[idx / 2] >> 4; + } else { + return ts.pixels[idx / 2] & 0b0000'1111; + } +} + +uint8_t getPixel8Bpp( + CompactTileSheet const&ts, + size_t const idx) noexcept { + oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); + return ts.pixels[idx]; +} + +ox::Pair get2Pixels4Bpp( + CompactTileSheet const&ts, + size_t const idx) noexcept { + oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); + auto const out = ts.pixels[idx / 2]; + return { + static_cast(out & 0x0f), + static_cast(out >> 4), + }; +} + +ox::Pair get2Pixels8Bpp( + CompactTileSheet const&ts, + size_t const idx) noexcept { + oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); + return { + static_cast(ts.pixels[idx]), + static_cast(ts.pixels[idx + 1]), + }; +} + static ox::Result getIdFor( TileSheet::SubSheet const&ss, ox::SpanView const&pNamePath, @@ -309,7 +348,7 @@ static ox::Result getIdFor( return OxError(1, "SubSheet not found"); } -ox::Result getIdFor(TileSheet const&ts, ox::CRStringView path) noexcept { +ox::Result getIdFor(TileSheet const&ts, ox::StringViewCR path) noexcept { return getIdFor(ts.subsheet, ox::split<8>(path, '.')); } @@ -340,7 +379,7 @@ static ox::Result getTileOffset( return OxError(1, "SubSheet not found"); } -ox::Result getTileOffset(TileSheet const&ts, ox::CRStringView pNamePath) noexcept { +ox::Result getTileOffset(TileSheet const&ts, ox::StringViewCR pNamePath) noexcept { return core::getTileOffset(ts.subsheet, ox::split<8>(pNamePath, '.'), ts.bpp); } diff --git a/src/nostalgia/modules/scene/src/studio/sceneeditor.cpp b/src/nostalgia/modules/scene/src/studio/sceneeditor.cpp index 6b15bb9..50788ab 100644 --- a/src/nostalgia/modules/scene/src/studio/sceneeditor.cpp +++ b/src/nostalgia/modules/scene/src/studio/sceneeditor.cpp @@ -8,7 +8,7 @@ namespace nostalgia::scene { -SceneEditor::SceneEditor(turbine::Context &ctx, ox::CRStringView path): +SceneEditor::SceneEditor(turbine::Context &ctx, ox::StringViewCR path): m_ctx(ctx), m_scene(*keel::readObj(keelCtx(m_ctx), path).unwrapThrow()) { } diff --git a/src/nostalgia/modules/scene/src/studio/sceneeditor.hpp b/src/nostalgia/modules/scene/src/studio/sceneeditor.hpp index 3843893..6891d23 100644 --- a/src/nostalgia/modules/scene/src/studio/sceneeditor.hpp +++ b/src/nostalgia/modules/scene/src/studio/sceneeditor.hpp @@ -19,7 +19,7 @@ class SceneEditor { SceneStatic m_scene; public: - SceneEditor(turbine::Context &ctx, ox::CRStringView path); + SceneEditor(turbine::Context &ctx, ox::StringViewCR path); [[nodiscard]] SceneStatic const&scene() const noexcept { diff --git a/src/olympic/keel/include/keel/assetmanager.hpp b/src/olympic/keel/include/keel/assetmanager.hpp index b17d2cf..ca6e6cf 100644 --- a/src/olympic/keel/include/keel/assetmanager.hpp +++ b/src/olympic/keel/include/keel/assetmanager.hpp @@ -14,6 +14,8 @@ #include #include +#include "validation.hpp" + namespace keel { class AssetManager; @@ -21,17 +23,6 @@ class AssetManager; template class AssetRef; - -[[nodiscard]] -constexpr bool valid(auto const&) noexcept { - return true; -} - -[[nodiscard]] -constexpr ox::Error repair(auto const&) noexcept { - return {}; -} - #ifndef OX_BARE_METAL template class AssetContainer { @@ -226,9 +217,7 @@ class AssetManager { ox::Result> loadAsset(ox::StringView const assetId) noexcept { auto &p = m_cache[assetId]; oxRequireM(obj, m_loader(assetId)); - if (!valid(obj) && repair(obj)) { - return OxError(1, "asset is invalid state and could not be repaired"); - } + oxReturnError(ensureValid(obj)); if (!p) { p = ox::make_unique>(std::move(obj)); } else { diff --git a/src/olympic/keel/include/keel/keel.hpp b/src/olympic/keel/include/keel/keel.hpp index ec0b558..203bb15 100644 --- a/src/olympic/keel/include/keel/keel.hpp +++ b/src/olympic/keel/include/keel/keel.hpp @@ -17,10 +17,10 @@ namespace keel { ox::Error init( keel::Context &ctx, ox::UPtr &&fs, - ox::CRStringView appName) noexcept; + ox::StringViewCR appName) noexcept; ox::Result> init( ox::UPtr &&fs, - ox::CRStringView appName) noexcept; + ox::StringViewCR appName) noexcept; } diff --git a/src/olympic/keel/include/keel/media.hpp b/src/olympic/keel/include/keel/media.hpp index 1af4e49..7132e7a 100644 --- a/src/olympic/keel/include/keel/media.hpp +++ b/src/olympic/keel/include/keel/media.hpp @@ -30,14 +30,14 @@ oxModelBegin(PreloadPtr) oxModelEnd() ox::Result getPreloadAddr(keel::Context &ctx, ox::FileAddress const&file) noexcept; -ox::Result getPreloadAddr(keel::Context &ctx, ox::CRStringView file) noexcept; +ox::Result getPreloadAddr(keel::Context &ctx, ox::StringViewCR file) noexcept; void createUuidMapping(Context &ctx, ox::StringView filePath, ox::UUID const&uuid) noexcept; ox::Error buildUuidMap(Context &ctx) noexcept; -ox::Result pathToUuid(Context &ctx, ox::CRStringView path) noexcept; +ox::Result pathToUuid(Context &ctx, ox::StringViewCR path) noexcept; ox::Result getUuid(Context &ctx, ox::FileAddress const&fileAddr) noexcept; @@ -53,12 +53,10 @@ constexpr ox::Result uuidUrlToUuid(ox::StringView uuidUrl) noexcept { ox::Result uuidUrlToPath(Context &ctx, ox::StringView uuid) noexcept; -ox::Result uuidToPath(Context &ctx, ox::CRStringView uuid) noexcept; +ox::Result uuidToPath(Context &ctx, ox::StringViewCR uuid) noexcept; ox::Result uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept; -ox::Error performPackTransforms(Context &ctx, ox::Buffer &clawData) noexcept; - #ifndef OX_BARE_METAL namespace detail { @@ -116,7 +114,7 @@ ox::Result> readObjFile( template ox::Result> readObjNoCache( keel::Context &ctx, - ox::CRStringView assetId) noexcept { + ox::StringViewCR assetId) noexcept { if constexpr(ox::preloadable::value) { oxRequire(addr, getPreloadAddr(ctx, assetId)); return keel::AssetRef(std::bit_cast(uintptr_t{addr})); @@ -132,7 +130,7 @@ ox::Error reloadAsset(keel::Context &ctx, ox::StringView assetId) noexcept; template ox::Result> readObj( keel::Context &ctx, - ox::CRStringView assetId, + ox::StringViewCR assetId, [[maybe_unused]] bool forceLoad = false) noexcept { #ifndef OX_BARE_METAL return readObjFile(ctx, assetId, forceLoad); @@ -171,9 +169,9 @@ ox::Error writeObj( ox::Error setRomFs(Context &ctx, ox::UPtr &&fs) noexcept; -ox::Result> loadRomFs(ox::CRStringView path) noexcept; +ox::Result> loadRomFs(ox::StringViewCR path) noexcept; -ox::Result loadRom(ox::CRStringView path = "") noexcept; +ox::Result loadRom(ox::StringViewCR path = "") noexcept; void unloadRom(char*) noexcept; diff --git a/src/olympic/keel/include/keel/module.hpp b/src/olympic/keel/include/keel/module.hpp index 13de7f1..6d17a1b 100644 --- a/src/olympic/keel/include/keel/module.hpp +++ b/src/olympic/keel/include/keel/module.hpp @@ -15,7 +15,7 @@ using TypeDescGenerator = ox::Error(*)(ox::TypeStore&); template ox::Error generateTypeDesc(ox::TypeStore &ts) noexcept { - return ox::buildTypeDef(&ts).error; + return ox::buildTypeDef(ts).error; } class Module { diff --git a/src/olympic/keel/include/keel/pack.hpp b/src/olympic/keel/include/keel/pack.hpp index 635fc8a..532b4ef 100644 --- a/src/olympic/keel/include/keel/pack.hpp +++ b/src/olympic/keel/include/keel/pack.hpp @@ -12,6 +12,31 @@ namespace keel { +struct ManifestEntry { + static constexpr auto TypeName = "net.drinkingtea.keel.ManifestEntry"; + static constexpr auto TypeVersion = 1; + uint64_t inode{}; + bool preloaded{}; + ox::String type; +}; + +oxModelBegin(ManifestEntry) + oxModelField(inode) + oxModelField(preloaded) + oxModelField(type) +oxModelEnd() + +struct Manifest { + static constexpr auto TypeName = "net.drinkingtea.keel.Manifest"; + static constexpr auto TypeVersion = 1; + ox::HashMap files; +}; + +oxModelBegin(Manifest) + oxModelField(files) +oxModelEnd() + + class Context; struct GbaPlatSpec { @@ -113,10 +138,11 @@ ox::Error preloadObj( // transformations need to be done after the copy to the new FS is complete template ox::Error preloadDir( + Manifest &manifest, ox::TypeStore &ts, ox::FileSystem &romFs, ox::Preloader &pl, - ox::CRStringView path) noexcept { + ox::StringViewCR path) noexcept { // copy oxTracef("pack.preload", "path: {}", path); oxRequire(fileList, romFs.ls(path)); @@ -125,13 +151,14 @@ ox::Error preloadDir( oxRequire(stat, romFs.stat(filePath)); if (stat.fileType == ox::FileType::Directory) { auto const dir = ox::sfmt("{}{}/", path, name); - oxReturnError(preloadDir(ts, romFs, pl, dir)); + oxReturnError(preloadDir(manifest, ts, romFs, pl, dir)); } else { auto const err = preloadObj(ts, romFs, pl, filePath); if (err) { oxErrf("\033[31;1;1mCould not preload {}:\n\t{}\n", filePath, toStr(err)); return err; } + manifest.files[filePath].preloaded = true; } } return {}; @@ -162,11 +189,15 @@ ox::Error appendBinary(ox::Buffer &binBuff, ox::SpanView const&fsBuff, ox: } template -ox::Error preload(ox::TypeStore &ts, ox::FileSystem &src, ox::Preloader &pl) noexcept { +ox::Error preload( + Manifest &manifest, + ox::TypeStore &ts, + ox::FileSystem &src, + ox::Preloader &pl) noexcept { oxOut("Preloading\n"); - return detail::preloadDir(ts, src, pl, "/"); + return detail::preloadDir(manifest, ts, src, pl, "/"); } -ox::Error pack(keel::Context &ctx, ox::TypeStore &ts, ox::FileSystem &dest) noexcept; +ox::Error pack(Manifest &manifest, keel::Context &ctx, ox::TypeStore &ts, ox::FileSystem &dest) noexcept; } diff --git a/src/olympic/keel/include/keel/typeconv.hpp b/src/olympic/keel/include/keel/typeconv.hpp index b2c51a6..94ac91e 100644 --- a/src/olympic/keel/include/keel/typeconv.hpp +++ b/src/olympic/keel/include/keel/typeconv.hpp @@ -51,29 +51,29 @@ constexpr T &wrapCast(Wrap &ptr) noexcept { class BaseConverter { public: - virtual ~BaseConverter() noexcept = default; + constexpr virtual ~BaseConverter() noexcept = default; [[nodiscard]] - virtual ox::StringView srcTypeName() const noexcept = 0; + constexpr virtual ox::StringView srcTypeName() const noexcept = 0; [[nodiscard]] - virtual int srcTypeVersion() const noexcept = 0; + constexpr virtual int srcTypeVersion() const noexcept = 0; [[nodiscard]] - virtual bool srcMatches(ox::CRStringView pSrcTypeName, int pSrcTypeVersion) const noexcept = 0; + constexpr virtual bool srcMatches(ox::StringViewCR pSrcTypeName, int pSrcTypeVersion) const noexcept = 0; [[nodiscard]] - virtual bool dstMatches(ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept = 0; + constexpr virtual bool dstMatches(ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept = 0; virtual ox::Result> convertPtrToPtr(keel::Context &ctx, Wrap &src) const noexcept = 0; virtual ox::Result> convertBuffToPtr( - keel::Context &ctx, ox::Buffer const&srcBuff) const noexcept = 0; + keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept = 0; [[nodiscard]] - inline bool matches( - ox::CRStringView srcTypeName, int srcTypeVersion, - ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept { + constexpr bool matches( + ox::StringViewCR srcTypeName, int srcTypeVersion, + ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept { return srcMatches(srcTypeName, srcTypeVersion) && dstMatches(dstTypeName, dstTypeVersion); } @@ -84,17 +84,17 @@ template class Converter: public BaseConverter { public: [[nodiscard]] - ox::StringView srcTypeName() const noexcept final { + constexpr ox::StringView srcTypeName() const noexcept final { return ox::ModelTypeName_v; } [[nodiscard]] - int srcTypeVersion() const noexcept final { + constexpr int srcTypeVersion() const noexcept final { return ox::ModelTypeVersion_v; } [[nodiscard]] - bool srcMatches(ox::CRStringView pSrcTypeName, int pSrcTypeVersion) const noexcept final { + constexpr bool srcMatches(ox::StringViewCR pSrcTypeName, int pSrcTypeVersion) const noexcept final { constexpr auto SrcTypeName = ox::requireModelTypeName(); constexpr auto SrcTypeVersion = ox::requireModelTypeVersion(); return pSrcTypeName == SrcTypeName @@ -102,8 +102,8 @@ class Converter: public BaseConverter { } [[nodiscard]] - bool dstMatches(ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept final { - constexpr auto DstTypeName = ox::StringView(ox::requireModelTypeName()); + constexpr bool dstMatches(ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept final { + constexpr auto DstTypeName = ox::StringView{ox::requireModelTypeName()}; constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); return dstTypeName == DstTypeName && dstTypeVersion == DstTypeVersion; @@ -117,8 +117,9 @@ class Converter: public BaseConverter { } ox::Result> convertBuffToPtr( - keel::Context &ctx, ox::Buffer const&srcBuff) const noexcept final { + keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept final { oxRequireM(src, readAsset(srcBuff)); + oxReturnError(ensureValid(src)); auto dst = makeWrap(); oxReturnError(convert(ctx, src, wrapCast(*dst))); return {std::move(dst)}; @@ -131,12 +132,12 @@ class Converter: public BaseConverter { ox::Result> convert( keel::Context &ctx, - ox::Buffer const&srcBuffer, - ox::CRStringView dstTypeName, + ox::BufferView const&srcBuffer, + ox::StringViewCR dstTypeName, int dstTypeVersion) noexcept; template -ox::Result convert(keel::Context &ctx, ox::Buffer const&srcBuffer) noexcept { +ox::Result convert(keel::Context &ctx, ox::BufferView const&srcBuffer) noexcept { static constexpr auto DstTypeName = ox::requireModelTypeName(); static constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); oxRequire(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion)); @@ -144,7 +145,7 @@ ox::Result convert(keel::Context &ctx, ox::Buffer const&srcBuffer) noex } template -ox::Error convert(keel::Context &ctx, ox::Buffer const&buff, DstType *outObj) noexcept { +ox::Error convert(keel::Context &ctx, ox::BufferView const&buff, DstType *outObj) noexcept { static constexpr auto DstTypeName = ox::requireModelTypeName(); static constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); oxRequire(outPtr, convert(ctx, buff, DstTypeName, DstTypeVersion)); @@ -154,7 +155,7 @@ ox::Error convert(keel::Context &ctx, ox::Buffer const&buff, DstType *outObj) no template ox::Result convertBuffToBuff( - keel::Context &ctx, ox::Buffer const&srcBuffer, ox::ClawFormat fmt) noexcept { + keel::Context &ctx, ox::BufferView const&srcBuffer, ox::ClawFormat fmt) noexcept { static constexpr auto DstTypeName = ox::requireModelTypeName(); static constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); oxRequire(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion)); diff --git a/src/olympic/keel/include/keel/validation.hpp b/src/olympic/keel/include/keel/validation.hpp new file mode 100644 index 0000000..7f86b0f --- /dev/null +++ b/src/olympic/keel/include/keel/validation.hpp @@ -0,0 +1,27 @@ +/* + * Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#pragma once + +#include + +namespace keel { + +[[nodiscard]] +constexpr bool valid(auto const&) noexcept { + return true; +} + +constexpr ox::Error repair(auto const&) noexcept { + return OxError(1, "No repair function for this type"); +} + +constexpr ox::Error ensureValid(auto &o) noexcept { + if (!valid(o)) { + return repair(o); + } + return {}; +} + +} diff --git a/src/olympic/keel/src/keel.cpp b/src/olympic/keel/src/keel.cpp index 894069f..39f78e9 100644 --- a/src/olympic/keel/src/keel.cpp +++ b/src/olympic/keel/src/keel.cpp @@ -9,7 +9,7 @@ namespace keel { ox::Error init( keel::Context &ctx, ox::UPtr &&fs, - ox::CRStringView appName) noexcept { + ox::StringViewCR appName) noexcept { ctx.appName = appName; std::ignore = setRomFs(ctx, std::move(fs)); #ifndef OX_BARE_METAL @@ -28,7 +28,7 @@ ox::Error init( return {}; } -ox::Result> init(ox::UPtr &&fs, ox::CRStringView appName) noexcept { +ox::Result> init(ox::UPtr &&fs, ox::StringViewCR appName) noexcept { auto ctx = ox::make_unique(); oxReturnError(keel::init(*ctx, std::move(fs), appName)); return ctx; diff --git a/src/olympic/keel/src/media.cpp b/src/olympic/keel/src/media.cpp index ca3c857..7f2b7cb 100644 --- a/src/olympic/keel/src/media.cpp +++ b/src/olympic/keel/src/media.cpp @@ -12,7 +12,7 @@ namespace keel { -ox::Result loadRom(ox::CRStringView path) noexcept { +ox::Result loadRom(ox::StringViewCR path) noexcept { std::ifstream file(std::string(toStdStringView(path)), std::ios::binary | std::ios::ate); if (!file.good()) { oxErrorf("Could not find ROM file: {}", path); @@ -47,7 +47,7 @@ void createUuidMapping(Context &ctx, ox::StringView filePath, ox::UUID const&uui ctx.uuidToPath[uuid.toString()] = filePath; } -static ox::Error buildUuidMap(Context &ctx, ox::CRStringView path) noexcept { +static ox::Error buildUuidMap(Context &ctx, ox::StringViewCR path) noexcept { oxRequire(files, ctx.rom->ls(path)); for (auto const&f : files) { oxRequireM(filePath, ox::join("/", ox::Array{path, f})); @@ -74,7 +74,7 @@ ox::Error buildUuidMap(Context &ctx) noexcept { return buildUuidMap(ctx, ""); } -ox::Result pathToUuid(Context &ctx, ox::CRStringView path) noexcept { +ox::Result pathToUuid(Context &ctx, ox::StringViewCR path) noexcept { #ifndef OX_BARE_METAL oxRequire(out, ctx.pathToUuid.at(path)); return *out; @@ -136,7 +136,7 @@ ox::Result uuidUrlToPath(Context &ctx, ox::StringView uuid) noe #endif } -ox::Result uuidToPath(Context &ctx, ox::CRStringView uuid) noexcept { +ox::Result uuidToPath(Context &ctx, ox::StringViewCR uuid) noexcept { #ifndef OX_BARE_METAL oxRequireM(out, ctx.uuidToPath.at(uuid)); return ox::CStringView(*out); @@ -154,18 +154,6 @@ ox::Result uuidToPath(Context &ctx, ox::UUID const&uuid) noexce #endif } -ox::Error performPackTransforms(Context &ctx, ox::Buffer &clawData) noexcept { - oxRequireM(typeId, readAssetTypeId(clawData)); - for (auto const tr : packTransforms(ctx)) { - bool changed{}; - oxReturnError(tr(ctx, clawData, typeId).moveTo(changed)); - if (changed) { - oxReturnError(readAssetTypeId(clawData).moveTo(typeId)); - } - } - return {}; -} - ox::Error reloadAsset(keel::Context &ctx, ox::StringView assetId) noexcept { ox::UUIDStr uuidStr; if (beginsWith(assetId, "uuid://")) { @@ -198,7 +186,7 @@ ox::Error buildUuidMap(Context&) noexcept { return {}; } -ox::Result loadRom(ox::CRStringView) noexcept { +ox::Result loadRom(ox::StringViewCR) noexcept { // put the header in the wrong order to prevent mistaking this code for the // media section constexpr auto headerP2 = "R_______________"; @@ -218,7 +206,7 @@ ox::Result loadRom(ox::CRStringView) noexcept { void unloadRom(char*) noexcept { } -ox::Result getPreloadAddr(keel::Context &ctx, ox::CRStringView path) noexcept { +ox::Result getPreloadAddr(keel::Context &ctx, ox::StringViewCR path) noexcept { oxRequire(stat, ctx.rom->stat(path)); oxRequire(buff, static_cast(ctx.rom.get())->directAccess(path)); PreloadPtr p; @@ -250,7 +238,7 @@ ox::Error setRomFs(Context &ctx, ox::UPtr &&fs) noexcept { return buildUuidMap(ctx); } -ox::Result> loadRomFs(ox::CRStringView path) noexcept { +ox::Result> loadRomFs(ox::StringViewCR path) noexcept { auto const lastDot = ox::lastIndexOf(path, '.'); if (!lastDot.error && substr(path, lastDot.value) == ".oxfs") { oxRequire(rom, loadRom(path)); diff --git a/src/olympic/keel/src/pack-applib.cpp b/src/olympic/keel/src/pack-applib.cpp index a830e98..820a2a4 100644 --- a/src/olympic/keel/src/pack-applib.cpp +++ b/src/olympic/keel/src/pack-applib.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -48,16 +49,21 @@ static ox::Error generateTypes(ox::TypeStore &ts) noexcept { return {}; } -static ox::Error pack(ox::StringView argSrc, ox::StringView argRomBin, ox::StringView projectDataDir) noexcept { +static ox::Error pack( + ox::StringView argSrc, + ox::StringView argRomBin, + ox::StringView argManifest, + ox::StringView projectDataDir) noexcept { ox::Buffer dstBuff(32 * ox::units::MB); oxReturnError(ox::FileSystem32::format(dstBuff.data(), dstBuff.size())); ox::FileSystem32 dst(dstBuff); oxRequire(ctx, keel::init(ox::make_unique(argSrc), "keel-pack")); keel::TypeStore ts(*ctx->rom, ox::sfmt("{}/type_descriptors", projectDataDir)); oxReturnError(generateTypes(ts)); - oxReturnError(keel::pack(*ctx, ts, dst)); + keel::Manifest manifest; + oxReturnError(keel::pack(manifest, *ctx, ts, dst)); oxRequireM(pl, keel::GbaPreloader::make()); - oxReturnError(preload(ts, dst, *pl)); + oxReturnError(preload(manifest, ts, dst, *pl)); oxReturnError(dst.resize()); // resize buffer oxRequire(dstSize, dst.size()); @@ -70,6 +76,8 @@ static ox::Error pack(ox::StringView argSrc, ox::StringView argRomBin, ox::Strin oxReturnError(appendBinary(romBuff, dstBuff, *pl)); oxOutf("Final ROM buff size: {} bytes\n", romBuff.size()); oxReturnError(writeFileBuff(argRomBin, romBuff)); + oxRequire(manifestJson, ox::writeOCString(manifest)); + oxReturnError(writeFileBuff(argManifest, {manifestJson.data(), manifestJson.len()})); return {}; } @@ -77,6 +85,7 @@ static ox::Error run(int argc, char const**argv, ox::StringView projectDataDir) ox::ClArgs const args(argc, argv); auto const argSrc = args.getString("src", ""); auto const argRomBin = args.getString("rom-bin", ""); + auto const argManifest = args.getString("manifest", ""); if (argSrc == "") { oxErr("\033[31;1;1merror:\033[0m must specify a source directory\n"); return OxError(1, "must specify a source directory"); @@ -85,7 +94,7 @@ static ox::Error run(int argc, char const**argv, ox::StringView projectDataDir) oxErr("\033[31;1;1merror:\033[0m must specify a path for ROM file\n"); return OxError(1, "must specify a path for preload file"); } - return pack(argSrc, argRomBin, projectDataDir); + return pack(argSrc, argRomBin, argManifest, projectDataDir); } namespace olympic { diff --git a/src/olympic/keel/src/pack.cpp b/src/olympic/keel/src/pack.cpp index 09bda0e..1f18eb6 100644 --- a/src/olympic/keel/src/pack.cpp +++ b/src/olympic/keel/src/pack.cpp @@ -6,13 +6,14 @@ #include #include - #include namespace keel { static ox::Error pathToInode( - keel::Context &ctx, ox::FileSystem &dest, ox::ModelObject &obj) noexcept { + keel::Context &ctx, + ox::FileSystem &dest, + ox::ModelObject &obj) noexcept { auto &o = obj; auto type = static_cast(o.at("type").unwrap()->get()); auto &data = o.at("data").unwrap()->get(); @@ -85,16 +86,33 @@ static ox::Error transformFileAddressesObj( return {}; } +static ox::Error performPackTransforms( + ManifestEntry &entry, + Context &ctx, + ox::Buffer &clawData) noexcept { + oxRequireM(typeId, readAssetTypeId(clawData)); + for (auto const tr : packTransforms(ctx)) { + bool changed{}; + oxReturnError(tr(ctx, clawData, typeId).moveTo(changed)); + if (changed) { + oxReturnError(readAssetTypeId(clawData).moveTo(typeId)); + } + } + entry.type = ox::String{typeId}; + return {}; +} + static ox::Error doTransformations( + Manifest &manifest, keel::Context &ctx, ox::TypeStore &ts, ox::FileSystem &dest, - ox::CRStringView filePath) noexcept { + ox::StringViewCR filePath) noexcept { // load file oxRequire(s, dest.stat(filePath)); // do transformations oxRequireM(buff, dest.read(s.inode)); - oxReturnError(keel::performPackTransforms(ctx, buff)); + oxReturnError(keel::performPackTransforms(manifest.files[filePath], ctx, buff)); // transform FileAddresses oxRequireM(obj, keel::readAsset(ts, buff)); oxOutf("transforming {}\n", filePath); @@ -108,10 +126,11 @@ static ox::Error doTransformations( // claw file transformations are broken out from copy because path to inode // transformations need to be done after the copy to the new FS is complete static ox::Error transformClaw( + Manifest &manifest, keel::Context &ctx, ox::TypeStore &ts, ox::FileSystem &dest, - ox::CRStringView path) noexcept { + ox::StringViewCR path) noexcept { // copy oxTracef("pack.transformClaw", "path: {}", path); oxRequire(fileList, dest.ls(path)); @@ -120,9 +139,9 @@ static ox::Error transformClaw( oxRequire(stat, dest.stat(filePath)); if (stat.fileType == ox::FileType::Directory) { auto const dir = ox::sfmt("{}{}/", path, name); - oxReturnError(transformClaw(ctx, ts, dest, dir)); + oxReturnError(transformClaw(manifest, ctx, ts, dest, dir)); } else { - auto const err = doTransformations(ctx, ts, dest, filePath); + auto const err = doTransformations(manifest, ctx, ts, dest, filePath); if (err) { oxErrf("\033[31;1;1mCould not do transformations for {}:\n\t{}\n", filePath, toStr(err)); return err; @@ -133,10 +152,13 @@ static ox::Error transformClaw( } static ox::Error copy( + Manifest &manifest, ox::FileSystem &src, ox::FileSystem &dest, - ox::CRStringView path) noexcept { - oxOutf("copying directory: {}\n", path); + ox::StringViewCR path, + ox::StringViewCR logPrefix = "") noexcept { + oxOutf("{}copying directory: {}\n", logPrefix, path); + auto const childLogPrefix = ox::sfmt("{}\t", logPrefix); // copy oxRequire(fileList, src.ls(path)); for (auto const&name : fileList) { @@ -147,27 +169,36 @@ static ox::Error copy( oxRequire(stat, src.stat(currentFile)); if (stat.fileType == ox::FileType::Directory) { oxReturnError(dest.mkdir(currentFile, true)); - oxReturnError(copy(src, dest, currentFile + '/')); + oxReturnError(copy(manifest, src, dest, currentFile + '/', childLogPrefix)); } else { // load file - oxOutf("copying file: {}\n", currentFile); + oxOutf("{}copying file: {}...", childLogPrefix, currentFile); + ox::StringView status = "failed"; + oxDefer [&status] { + oxOutf(" {}\n", status); + }; oxRequireM(buff, src.read(currentFile)); // write file to dest oxReturnError(dest.write(currentFile, buff)); + status = "OK"; + oxRequire(stat, dest.stat(currentFile)); + manifest.files[currentFile] = { + .inode = stat.inode, + .type = ox::String{keel::readAssetTypeId(buff).or_value({})}, + }; } } return {}; } -static ox::Error copyFS(ox::FileSystem &src, ox::FileSystem &dest) noexcept { - oxReturnError(copy(src, dest, "/")); - return {}; -} - -ox::Error pack(keel::Context &ctx, ox::TypeStore &ts, ox::FileSystem &dest) noexcept { - oxReturnError(copyFS(*ctx.rom, dest)); +ox::Error pack( + Manifest &manifest, + keel::Context &ctx, + ox::TypeStore &ts, + ox::FileSystem &dest) noexcept { + oxReturnError(copy(manifest, *ctx.rom, dest, "/")); oxOut("Doing transforms\n"); - oxReturnError(transformClaw(ctx, ts, dest, "/")); + oxReturnError(transformClaw(manifest, ctx, ts, dest, "/")); return {}; } diff --git a/src/olympic/keel/src/typeconv.cpp b/src/olympic/keel/src/typeconv.cpp index bb82179..909ac10 100644 --- a/src/olympic/keel/src/typeconv.cpp +++ b/src/olympic/keel/src/typeconv.cpp @@ -9,12 +9,11 @@ namespace keel { -[[nodiscard]] static ox::Result findConverter( ox::SpanView const&converters, - ox::CRStringView srcTypeName, + ox::StringViewCR srcTypeName, int srcTypeVersion, - ox::CRStringView dstTypeName, + ox::StringViewCR dstTypeName, int dstTypeVersion) noexcept { for (auto const&c : converters) { if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) { @@ -27,10 +26,10 @@ static ox::Result findConverter( static ox::Result> convert( keel::Context &ctx, ox::SpanView const&converters, - ox::Buffer const&srcBuffer, - ox::CRStringView srcTypeName, + ox::BufferView const&srcBuffer, + ox::StringViewCR srcTypeName, int srcTypeVersion, - ox::CRStringView dstTypeName, + ox::StringViewCR dstTypeName, int dstTypeVersion) noexcept { // look for direct converter auto [c, err] = findConverter( @@ -55,8 +54,8 @@ static ox::Result> convert( ox::Result> convert( keel::Context &ctx, - ox::Buffer const&srcBuffer, - ox::CRStringView dstTypeName, + ox::BufferView const&srcBuffer, + ox::StringViewCR dstTypeName, int dstTypeVersion) noexcept { oxRequire(hdr, readAssetHeader(srcBuffer)); return convert( diff --git a/src/olympic/studio/applib/src/clawviewer.cpp b/src/olympic/studio/applib/src/clawviewer.cpp index 861a04b..ad8466e 100644 --- a/src/olympic/studio/applib/src/clawviewer.cpp +++ b/src/olympic/studio/applib/src/clawviewer.cpp @@ -8,12 +8,12 @@ namespace studio { -ClawEditor::ClawEditor(ox::CRStringView path, ox::ModelObject obj) noexcept: - Editor(path), - m_obj(std::move(obj)) { +ClawEditor::ClawEditor(StudioContext &sctx, ox::StringParam path): + Editor(std::move(path)), + m_obj(sctx.project->loadObj(itemPath()).unwrapThrow()) { } -void ClawEditor::draw(studio::StudioContext&) noexcept { +void ClawEditor::draw(StudioContext&) noexcept { ImGui::BeginChild("PaletteEditor"); static constexpr auto flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody; if (ImGui::BeginTable("ObjTree", 3, flags)) { @@ -93,7 +93,7 @@ void ClawEditor::drawRow(ox::ModelValue const&value) noexcept { ImGui::Text("%s", val.c_str()); } -void ClawEditor::drawVar(ObjPath &path, ox::CRStringView name, ox::ModelValue const&value) noexcept { +void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const&value) noexcept { using Str = ox::BasicString<100>; path.push_back(name); if (value.type() == ox::ModelValue::Type::Object) { diff --git a/src/olympic/studio/applib/src/clawviewer.hpp b/src/olympic/studio/applib/src/clawviewer.hpp index 5441ac3..3be1f96 100644 --- a/src/olympic/studio/applib/src/clawviewer.hpp +++ b/src/olympic/studio/applib/src/clawviewer.hpp @@ -11,19 +11,19 @@ namespace studio { -class ClawEditor: public studio::Editor { +class ClawEditor: public Editor { private: using ObjPath = ox::Vector; ox::ModelObject m_obj; public: - ClawEditor(ox::CRStringView path, ox::ModelObject obj) noexcept; + ClawEditor(StudioContext &sctx, ox::StringParam path); - void draw(studio::StudioContext&) noexcept final; + void draw(StudioContext&) noexcept final; private: static void drawRow(ox::ModelValue const&value) noexcept; - void drawVar(ObjPath &path, ox::CRStringView name, ox::ModelValue const&value) noexcept; + void drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const&value) noexcept; void drawTree(ObjPath &path, ox::ModelObject const&obj) noexcept; }; diff --git a/src/olympic/studio/applib/src/main.cpp b/src/olympic/studio/applib/src/main.cpp index 324cebc..e1cf5cf 100644 --- a/src/olympic/studio/applib/src/main.cpp +++ b/src/olympic/studio/applib/src/main.cpp @@ -34,8 +34,8 @@ static void keyEventHandler(turbine::Context &ctx, turbine::Key key, bool down) } static ox::Error runApp( - ox::CRStringView appName, - ox::CRStringView projectDataDir, + ox::StringViewCR appName, + ox::StringViewCR projectDataDir, ox::UPtr &&fs) noexcept { oxRequireM(ctx, turbine::init(std::move(fs), appName)); turbine::setWindowTitle(*ctx, keelCtx(*ctx).appName); @@ -50,8 +50,8 @@ static ox::Error runApp( } static ox::Error run( - ox::CRStringView appName, - ox::CRStringView projectDataDir, + ox::StringViewCR appName, + ox::StringViewCR projectDataDir, int, char const**) { // seed UUID generator diff --git a/src/olympic/studio/applib/src/projectexplorer.cpp b/src/olympic/studio/applib/src/projectexplorer.cpp index 8961c4c..56b1d2b 100644 --- a/src/olympic/studio/applib/src/projectexplorer.cpp +++ b/src/olympic/studio/applib/src/projectexplorer.cpp @@ -51,7 +51,7 @@ void ProjectExplorer::setModel(ox::UPtr &&model) noexcept { m_treeModel = std::move(model); } -ox::Error ProjectExplorer::refreshProjectTreeModel(ox::CRStringView) noexcept { +ox::Error ProjectExplorer::refreshProjectTreeModel(ox::StringViewCR) noexcept { oxRequireM(model, buildProjectTreeModel(*this, "Project", "/", nullptr)); setModel(std::move(model)); return OxError(0); diff --git a/src/olympic/studio/applib/src/projectexplorer.hpp b/src/olympic/studio/applib/src/projectexplorer.hpp index b7c15a4..1e3cc73 100644 --- a/src/olympic/studio/applib/src/projectexplorer.hpp +++ b/src/olympic/studio/applib/src/projectexplorer.hpp @@ -23,7 +23,7 @@ class ProjectExplorer: public studio::Widget { void setModel(ox::UPtr &&model) noexcept; - ox::Error refreshProjectTreeModel(ox::CRStringView = {}) noexcept; + ox::Error refreshProjectTreeModel(ox::StringViewCR = {}) noexcept; [[nodiscard]] inline ox::FileSystem *romFs() noexcept { diff --git a/src/olympic/studio/applib/src/studioapp.cpp b/src/olympic/studio/applib/src/studioapp.cpp index db84e5a..2dfada0 100644 --- a/src/olympic/studio/applib/src/studioapp.cpp +++ b/src/olympic/studio/applib/src/studioapp.cpp @@ -318,7 +318,7 @@ void StudioUI::handleKeyInput() noexcept { } } -ox::Error StudioUI::createOpenProject(ox::CRStringView path) noexcept { +ox::Error StudioUI::createOpenProject(ox::StringViewCR path) noexcept { std::error_code ec; std::filesystem::create_directories(toStdStringView(path), ec); oxReturnError(OxError(ec.value() != 0, "Could not create project directory")); @@ -346,11 +346,11 @@ ox::Error StudioUI::openProjectPath(ox::StringParam path) noexcept { return m_projectExplorer.refreshProjectTreeModel(); } -ox::Error StudioUI::openFile(ox::CRStringView path) noexcept { +ox::Error StudioUI::openFile(ox::StringViewCR path) noexcept { return openFileActiveTab(path, true); } -ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab) noexcept { +ox::Error StudioUI::openFileActiveTab(ox::StringViewCR path, bool makeActiveTab) noexcept { if (!m_project) { return OxError(1, "No project open to open a file from"); } @@ -366,23 +366,17 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab) } oxRequire(ext, studio::fileExt(path)); // create Editor - studio::BaseEditor *editor = nullptr; - if (!m_editorMakers.contains(ext)) { - auto [obj, err] = m_project->loadObj(path); - if (err) { - return OxError(1, "There is no editor for this file extension"); - } - editor = ox::make(path, std::move(obj)); - } else { - auto const err = m_editorMakers[ext](path).moveTo(editor); - if (err) { - if constexpr(!ox::defines::Debug) { - oxErrf("Could not open Editor: {}\n", toStr(err)); - } else { - oxErrf("Could not open Editor: {} ({}:{})\n", err.errCode, err.file, err.line); - } - return err; + BaseEditor *editor = nullptr; + auto const err = m_editorMakers.contains(ext) ? + m_editorMakers[ext](path).moveTo(editor) : + ox::makeCatch(m_sctx, path).moveTo(editor); + if (err) { + if constexpr(!ox::defines::Debug) { + oxErrf("Could not open Editor: {}\n", toStr(err)); + } else { + oxErrf("Could not open Editor: {} ({}:{})\n", err.errCode, err.file, err.line); } + return err; } editor->closed.connect(this, &StudioUI::closeFile); m_editors.emplace_back(editor); @@ -400,7 +394,7 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab) return {}; } -ox::Error StudioUI::closeFile(ox::CRStringView path) noexcept { +ox::Error StudioUI::closeFile(ox::StringViewCR path) noexcept { if (!m_openFiles.contains(path)) { return {}; } diff --git a/src/olympic/studio/applib/src/studioapp.hpp b/src/olympic/studio/applib/src/studioapp.hpp index 059c9f7..efd374c 100644 --- a/src/olympic/studio/applib/src/studioapp.hpp +++ b/src/olympic/studio/applib/src/studioapp.hpp @@ -83,15 +83,15 @@ class StudioUI: public ox::SignalHandler { void handleKeyInput() noexcept; - ox::Error createOpenProject(ox::CRStringView path) noexcept; + ox::Error createOpenProject(ox::StringViewCR path) noexcept; ox::Error openProjectPath(ox::StringParam path) noexcept; - ox::Error openFile(ox::CRStringView path) noexcept; + ox::Error openFile(ox::StringViewCR path) noexcept; - ox::Error openFileActiveTab(ox::CRStringView path, bool makeActiveTab) noexcept; + ox::Error openFileActiveTab(ox::StringViewCR path, bool makeActiveTab) noexcept; - ox::Error closeFile(ox::CRStringView path) noexcept; + ox::Error closeFile(ox::StringViewCR path) noexcept; }; } diff --git a/src/olympic/studio/modlib/include/studio/configio.hpp b/src/olympic/studio/modlib/include/studio/configio.hpp index 69b4443..711bbcb 100644 --- a/src/olympic/studio/modlib/include/studio/configio.hpp +++ b/src/olympic/studio/modlib/include/studio/configio.hpp @@ -33,7 +33,7 @@ inline ox::String slashesToPct(ox::StringView str) noexcept { ox::String configPath(keel::Context const&ctx) noexcept; template -ox::Result readConfig(keel::Context &ctx, ox::CRStringView name) noexcept { +ox::Result readConfig(keel::Context &ctx, ox::StringViewCR name) noexcept { oxAssert(name != "", "Config type has no TypeName"); auto const path = ox::sfmt("/{}.json", detail::slashesToPct(name)); ox::PassThroughFS fs(configPath(ctx)); @@ -52,7 +52,7 @@ ox::Result readConfig(keel::Context &ctx) noexcept { } template -ox::Error writeConfig(keel::Context &ctx, ox::CRStringView name, T const&data) noexcept { +ox::Error writeConfig(keel::Context &ctx, ox::StringViewCR name, T const&data) noexcept { oxAssert(name != "", "Config type has no TypeName"); auto const path = ox::sfmt("/{}.json", detail::slashesToPct(name)); ox::PassThroughFS fs(configPath(ctx)); @@ -76,7 +76,7 @@ ox::Error writeConfig(keel::Context &ctx, T const&data) noexcept { } template -void openConfig(keel::Context &ctx, ox::CRStringView name, Func f) noexcept { +void openConfig(keel::Context &ctx, ox::StringViewCR name, Func f) noexcept { oxAssert(name != "", "Config type has no TypeName"); auto const [c, err] = readConfig(ctx, name); oxLogError(err); @@ -90,7 +90,7 @@ void openConfig(keel::Context &ctx, Func f) noexcept { } template -void editConfig(keel::Context &ctx, ox::CRStringView name, Func f) noexcept { +void editConfig(keel::Context &ctx, ox::StringViewCR name, Func f) noexcept { oxAssert(name != "", "Config type has no TypeName"); auto [c, err] = readConfig(ctx, name); oxLogError(err); diff --git a/src/olympic/studio/modlib/include/studio/filedialog.hpp b/src/olympic/studio/modlib/include/studio/filedialog.hpp index 40c13c8..e8415f0 100644 --- a/src/olympic/studio/modlib/include/studio/filedialog.hpp +++ b/src/olympic/studio/modlib/include/studio/filedialog.hpp @@ -17,7 +17,7 @@ struct FDFilterItem { String name{}; String spec{}; constexpr FDFilterItem() noexcept = default; - FDFilterItem(ox::CRStringView pName, ox::CRStringView pSpec) noexcept; + FDFilterItem(ox::StringViewCR pName, ox::StringViewCR pSpec) noexcept; }; ox::Result saveFile(ox::Vector const&exts) noexcept; diff --git a/src/olympic/studio/modlib/include/studio/module.hpp b/src/olympic/studio/modlib/include/studio/module.hpp index a8fac91..78fcd82 100644 --- a/src/olympic/studio/modlib/include/studio/module.hpp +++ b/src/olympic/studio/modlib/include/studio/module.hpp @@ -18,7 +18,7 @@ namespace studio { class ItemMaker; struct EditorMaker { - using Func = std::function(ox::CRStringView)>; + using Func = std::function(ox::StringViewCR)>; ox::Vector fileTypes; Func make; }; @@ -38,7 +38,7 @@ template studio::EditorMaker editorMaker(studio::StudioContext &ctx, ox::StringParam ext) noexcept { return { {std::move(ext)}, - [&ctx](ox::CRStringView path) -> ox::Result { + [&ctx](ox::StringViewCR path) -> ox::Result { return ox::makeCatch(ctx, path); } }; diff --git a/src/olympic/studio/modlib/include/studio/project.hpp b/src/olympic/studio/modlib/include/studio/project.hpp index 223fc09..203cf1d 100644 --- a/src/olympic/studio/modlib/include/studio/project.hpp +++ b/src/olympic/studio/modlib/include/studio/project.hpp @@ -28,7 +28,7 @@ enum class ProjectEvent { }; [[nodiscard]] -constexpr ox::Result fileExt(ox::CRStringView path) noexcept { +constexpr ox::Result fileExt(ox::StringViewCR path) noexcept { auto const extStart = ox::find(path.crbegin(), path.crend(), '.').offset(); if (!extStart) { return OxError(1, "file path does not have valid extension"); @@ -57,7 +57,7 @@ class Project { ox::HashMap> m_fileExtFileMap; public: - explicit Project(keel::Context &ctx, ox::String path, ox::CRStringView projectDataDir); + explicit Project(keel::Context &ctx, ox::String path, ox::StringViewCR projectDataDir); ox::Error create() noexcept; @@ -67,14 +67,14 @@ class Project { [[nodiscard]] ox::FileSystem &romFs() noexcept; - ox::Error mkdir(ox::CRStringView path) const noexcept; + ox::Error mkdir(ox::StringViewCR path) const noexcept; /** * Writes a MetalClaw object to the project at the given path. */ template ox::Error writeObj( - ox::CRStringView path, + ox::StringViewCR path, T const&obj, ox::ClawFormat fmt) noexcept; @@ -83,60 +83,63 @@ class Project { */ template ox::Error writeObj( - ox::CRStringView path, + ox::StringViewCR path, T const&obj) noexcept; template - ox::Result loadObj(ox::CRStringView path) const noexcept; + ox::Result loadObj(ox::StringViewCR path) const noexcept; - ox::Result stat(ox::CRStringView path) const noexcept; + ox::Result stat(ox::StringViewCR path) const noexcept; [[nodiscard]] - bool exists(ox::CRStringView path) const noexcept; + bool exists(ox::StringViewCR path) const noexcept; template ox::Error subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&slot) const noexcept; [[nodiscard]] - ox::Vector const&fileList(ox::CRStringView ext) noexcept; + ox::Vector const&fileList(ox::StringViewCR ext) noexcept; ox::Error writeTypeStore() noexcept; private: void buildFileIndex() noexcept; - void indexFile(ox::CRStringView path) noexcept; + void indexFile(ox::StringViewCR path) noexcept; - ox::Error writeBuff(ox::CRStringView path, ox::Buffer const&buff) noexcept; + ox::Error writeBuff(ox::StringViewCR path, ox::BufferView const&buff) noexcept; - ox::Result loadBuff(ox::CRStringView path) const noexcept; + ox::Result loadBuff(ox::StringViewCR path) const noexcept; - ox::Error lsProcDir(ox::Vector *paths, ox::CRStringView path) const noexcept; + ox::Error lsProcDir(ox::Vector *paths, ox::StringViewCR path) const noexcept; - ox::Result> listFiles(ox::CRStringView path = "") const noexcept; + ox::Result> listFiles(ox::StringViewCR path = "") const noexcept; // signals public: - ox::Signal fileEvent; - ox::Signal fileAdded; + ox::Signal fileEvent; + ox::Signal fileAdded; // FileRecognized is triggered for all matching files upon a new // subscription to a section of the project and upon the addition of a // file. - ox::Signal fileRecognized; - ox::Signal fileDeleted; + ox::Signal fileRecognized; + ox::Signal fileDeleted; ox::Signal fileUpdated; }; template -ox::Error Project::writeObj(ox::CRStringView path, T const&obj, ox::ClawFormat fmt) noexcept { +ox::Error Project::writeObj(ox::StringViewCR path, T const&obj, ox::ClawFormat fmt) noexcept { oxRequireM(buff, ox::writeClaw(obj, fmt)); + if (fmt == ox::ClawFormat::Organic) { + buff.pop_back(); + } // write to FS oxReturnError(mkdir(parentDir(path))); oxReturnError(writeBuff(path, buff)); // write type descriptor if (m_typeStore.get().error) { - oxReturnError(ox::buildTypeDef(&m_typeStore, &obj)); + oxReturnError(ox::buildTypeDef(m_typeStore, obj)); } oxRequire(desc, m_typeStore.get()); auto const descPath = ox::sfmt("{}/{}", m_typeDescPath, buildTypeId(*desc)); @@ -151,14 +154,14 @@ ox::Error Project::writeObj(ox::CRStringView path, T const&obj, ox::ClawFormat f } template -ox::Error Project::writeObj(ox::CRStringView path, T const&obj) noexcept { +ox::Error Project::writeObj(ox::StringViewCR path, T const&obj) noexcept { oxRequire(ext, fileExt(path)); auto const fmt = m_typeFmt[ext].or_value(ox::ClawFormat::Metal); return writeObj(path, obj, fmt); } template -ox::Result Project::loadObj(ox::CRStringView path) const noexcept { +ox::Result Project::loadObj(ox::StringViewCR path) const noexcept { oxRequire(buff, loadBuff(path)); if constexpr(ox::is_same_v) { return keel::readAsset(m_typeStore, buff); diff --git a/src/olympic/studio/modlib/src/filedialog_nfd.cpp b/src/olympic/studio/modlib/src/filedialog_nfd.cpp index e010259..9420f31 100644 --- a/src/olympic/studio/modlib/src/filedialog_nfd.cpp +++ b/src/olympic/studio/modlib/src/filedialog_nfd.cpp @@ -11,7 +11,7 @@ namespace studio { -FDFilterItem::FDFilterItem(ox::CRStringView pName, ox::CRStringView pSpec) noexcept { +FDFilterItem::FDFilterItem(ox::StringViewCR pName, ox::StringViewCR pSpec) noexcept { name.resize(pName.len() + 1); ox::strncpy(name.data(), pName.data(), pName.len()); spec.resize(pSpec.len() + 1); diff --git a/src/olympic/studio/modlib/src/project.cpp b/src/olympic/studio/modlib/src/project.cpp index 9b9843a..2975dbb 100644 --- a/src/olympic/studio/modlib/src/project.cpp +++ b/src/olympic/studio/modlib/src/project.cpp @@ -26,7 +26,7 @@ static void generateTypes(ox::TypeStore &ts) noexcept { } } -Project::Project(keel::Context &ctx, ox::String path, ox::CRStringView projectDataDir): +Project::Project(keel::Context &ctx, ox::String path, ox::StringViewCR projectDataDir): m_ctx(ctx), m_path(std::move(path)), m_projectDataDir(projectDataDir), @@ -55,7 +55,7 @@ ox::FileSystem &Project::romFs() noexcept { return m_fs; } -ox::Error Project::mkdir(ox::CRStringView path) const noexcept { +ox::Error Project::mkdir(ox::StringViewCR path) const noexcept { auto const [stat, err] = m_fs.stat(path); if (err) { oxReturnError(m_fs.mkdir(path, true)); @@ -65,15 +65,15 @@ ox::Error Project::mkdir(ox::CRStringView path) const noexcept { ox::Error{} : OxError(1, "path exists as normal file"); } -ox::Result Project::stat(ox::CRStringView path) const noexcept { +ox::Result Project::stat(ox::StringViewCR path) const noexcept { return m_fs.stat(path); } -bool Project::exists(ox::CRStringView path) const noexcept { +bool Project::exists(ox::StringViewCR path) const noexcept { return m_fs.stat(path).error == 0; } -ox::Vector const&Project::fileList(ox::CRStringView ext) noexcept { +ox::Vector const&Project::fileList(ox::StringViewCR ext) noexcept { return m_fileExtFileMap[ext]; } @@ -81,12 +81,10 @@ ox::Error Project::writeTypeStore() noexcept { // write all descriptors because we don't know which types T depends on oxReturnError(mkdir(m_typeDescPath)); for (auto const &t: m_typeStore.typeList()) { - oxRequireM(typeOut, ox::writeClaw(*t, ox::ClawFormat::Organic)); - // replace garbage last character with new line - *typeOut.back().value = '\n'; + oxRequire(typeOut, ox::writeClaw(*t, ox::ClawFormat::Organic)); // write to FS auto const typePath = ox::sfmt("{}/{}", m_typeDescPath, buildTypeId(*t)); - oxReturnError(writeBuff(typePath, typeOut)); + oxReturnError(writeBuff(typePath, {typeOut.data(), typeOut.size() - 1})); } return {}; } @@ -106,7 +104,7 @@ void Project::buildFileIndex() noexcept { } } -void Project::indexFile(ox::CRStringView path) noexcept { +void Project::indexFile(ox::StringViewCR path) noexcept { auto const [ext, err] = fileExt(path); if (err) { return; @@ -114,7 +112,7 @@ void Project::indexFile(ox::CRStringView path) noexcept { m_fileExtFileMap[ext].emplace_back(path); } -ox::Error Project::writeBuff(ox::CRStringView path, ox::Buffer const&buff) noexcept { +ox::Error Project::writeBuff(ox::StringViewCR path, ox::BufferView const&buff) noexcept { constexpr auto HdrSz = 40; ox::Buffer outBuff; outBuff.reserve(buff.size() + HdrSz); @@ -135,11 +133,11 @@ ox::Error Project::writeBuff(ox::CRStringView path, ox::Buffer const&buff) noexc return {}; } -ox::Result Project::loadBuff(ox::CRStringView path) const noexcept { +ox::Result Project::loadBuff(ox::StringViewCR path) const noexcept { return m_fs.read(path); } -ox::Error Project::lsProcDir(ox::Vector *paths, ox::CRStringView path) const noexcept { +ox::Error Project::lsProcDir(ox::Vector *paths, ox::StringViewCR path) const noexcept { oxRequire(files, m_fs.ls(path)); for (auto const&name : files) { auto fullPath = ox::sfmt("{}/{}", path, name); @@ -158,7 +156,7 @@ ox::Error Project::lsProcDir(ox::Vector *paths, ox::CRStringView pat return {}; } -ox::Result> Project::listFiles(ox::CRStringView path) const noexcept { +ox::Result> Project::listFiles(ox::StringViewCR path) const noexcept { ox::Vector paths; oxReturnError(lsProcDir(&paths, path)); return paths; diff --git a/src/olympic/turbine/include/turbine/clipboard.hpp b/src/olympic/turbine/include/turbine/clipboard.hpp index 83de726..2044515 100644 --- a/src/olympic/turbine/include/turbine/clipboard.hpp +++ b/src/olympic/turbine/include/turbine/clipboard.hpp @@ -30,7 +30,7 @@ class ClipboardObject: public BaseClipboardObject { ox::String getClipboardText(Context &ctx) noexcept; -void setClipboardText(Context &ctx, ox::CRStringView text) noexcept; +void setClipboardText(Context &ctx, ox::StringViewCR text) noexcept; void setClipboardObject(Context &ctx, ox::UPtr &&obj) noexcept; diff --git a/src/olympic/turbine/include/turbine/gfx.hpp b/src/olympic/turbine/include/turbine/gfx.hpp index 7e863cb..5ff11ba 100644 --- a/src/olympic/turbine/include/turbine/gfx.hpp +++ b/src/olympic/turbine/include/turbine/gfx.hpp @@ -26,7 +26,7 @@ void removeDrawer(Context &ctx, Drawer *cd) noexcept; ox::Error initGfx(Context &ctx) noexcept; -void setWindowTitle(Context &ctx, ox::CRStringView title) noexcept; +void setWindowTitle(Context &ctx, ox::StringViewCR title) noexcept; void focusWindow(Context &ctx) noexcept; diff --git a/src/olympic/turbine/include/turbine/turbine.hpp b/src/olympic/turbine/include/turbine/turbine.hpp index d24897b..e27341d 100644 --- a/src/olympic/turbine/include/turbine/turbine.hpp +++ b/src/olympic/turbine/include/turbine/turbine.hpp @@ -16,7 +16,7 @@ namespace turbine { using TimeMs = uint64_t; -ox::Result init(ox::UPtr &&fs, ox::CRStringView appName) noexcept; +ox::Result init(ox::UPtr &&fs, ox::StringViewCR appName) noexcept; ox::Error run(Context &ctx) noexcept; diff --git a/src/olympic/turbine/src/gba/clipboard.cpp b/src/olympic/turbine/src/gba/clipboard.cpp index eae5fbe..03a74ae 100644 --- a/src/olympic/turbine/src/gba/clipboard.cpp +++ b/src/olympic/turbine/src/gba/clipboard.cpp @@ -12,7 +12,7 @@ ox::String getClipboardText(Context&) noexcept { return {}; } -void setClipboardText(Context&, ox::CRStringView) noexcept { +void setClipboardText(Context&, ox::StringViewCR) noexcept { } } diff --git a/src/olympic/turbine/src/gba/gfx.cpp b/src/olympic/turbine/src/gba/gfx.cpp index e244e3c..a777074 100644 --- a/src/olympic/turbine/src/gba/gfx.cpp +++ b/src/olympic/turbine/src/gba/gfx.cpp @@ -24,7 +24,7 @@ ox::Error initGfx(Context&) noexcept { return {}; } -void setWindowTitle(Context&, ox::CRStringView) noexcept { +void setWindowTitle(Context&, ox::StringViewCR) noexcept { } int getScreenWidth(Context&) noexcept { diff --git a/src/olympic/turbine/src/gba/turbine.cpp b/src/olympic/turbine/src/gba/turbine.cpp index 96432a2..9840912 100644 --- a/src/olympic/turbine/src/gba/turbine.cpp +++ b/src/olympic/turbine/src/gba/turbine.cpp @@ -57,7 +57,7 @@ static ox::Result findPreloadSection() noexcept { } ox::Result init( - ox::UPtr &&fs, ox::CRStringView appName) noexcept { + ox::UPtr &&fs, ox::StringViewCR appName) noexcept { auto ctx = ox::make_unique(); oxReturnError(keel::init(ctx->keelCtx, std::move(fs), appName)); #ifdef OX_BARE_METAL diff --git a/src/olympic/turbine/src/glfw/clipboard.cpp b/src/olympic/turbine/src/glfw/clipboard.cpp index 2fd824b..fa9a6a0 100644 --- a/src/olympic/turbine/src/glfw/clipboard.cpp +++ b/src/olympic/turbine/src/glfw/clipboard.cpp @@ -16,7 +16,7 @@ ox::String getClipboardText(Context &ctx) noexcept { return ox::String(glfwGetClipboardString(ctx.window)); } -void setClipboardText(Context &ctx, ox::CRStringView text) noexcept { +void setClipboardText(Context &ctx, ox::StringViewCR text) noexcept { auto cstr = ox_malloca(text.bytes() + 1, char); ox::strncpy(cstr.get(), text.data(), text.bytes()); glfwSetClipboardString(ctx.window, cstr.get()); diff --git a/src/olympic/turbine/src/glfw/gfx.cpp b/src/olympic/turbine/src/glfw/gfx.cpp index 9eeef90..7507b5e 100644 --- a/src/olympic/turbine/src/glfw/gfx.cpp +++ b/src/olympic/turbine/src/glfw/gfx.cpp @@ -219,7 +219,7 @@ ox::Error initGfx(Context &ctx) noexcept { return {}; } -void setWindowTitle(Context &ctx, ox::CRStringView title) noexcept { +void setWindowTitle(Context &ctx, ox::StringViewCR title) noexcept { auto cstr = ox_malloca(title.bytes() + 1, char); ox::strncpy(cstr.get(), title.data(), title.bytes()); glfwSetWindowTitle(ctx.window, cstr.get()); diff --git a/src/olympic/turbine/src/glfw/turbine.cpp b/src/olympic/turbine/src/glfw/turbine.cpp index fb307e6..d844606 100644 --- a/src/olympic/turbine/src/glfw/turbine.cpp +++ b/src/olympic/turbine/src/glfw/turbine.cpp @@ -41,7 +41,7 @@ static void draw(GLFWwindow *window, int, int) noexcept { } ox::Result init( - ox::UPtr &&fs, ox::CRStringView appName) noexcept { + ox::UPtr &&fs, ox::StringViewCR appName) noexcept { auto ctx = ox::make_unique(); oxReturnError(keel::init(ctx->keelCtx, std::move(fs), appName)); using namespace std::chrono;