[nostalgia] Split part of Core out into Foundation, add module system

This commit is contained in:
2023-02-03 00:41:24 -06:00
parent 83589287bc
commit 7868b0678f
50 changed files with 742 additions and 470 deletions
+99
View File
@@ -0,0 +1,99 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/std/defines.hpp>
#include <ox/claw/claw.hpp>
#include <ox/fs/fs.hpp>
#include <ox/model/metadata.hpp>
#include <nostalgia/foundation/context.hpp>
#include "typeconv.hpp"
namespace nostalgia::foundation {
struct PreloadPtr {
static constexpr auto TypeName = "net.drinkingtea.ox.PreloadPtr";
static constexpr auto TypeVersion = 1;
uint32_t preloadAddr = 0;
};
oxModelBegin(PreloadPtr)
oxModelField(preloadAddr)
oxModelEnd()
ox::Result<std::size_t> getPreloadAddr(foundation::Context *ctx, const ox::FileAddress &file) noexcept;
ox::Result<std::size_t> getPreloadAddr(foundation::Context *ctx, ox::CRStringView file) noexcept;
template<typename T>
ox::Result<foundation::AssetRef<T>> readObj([[maybe_unused]] foundation::Context *ctx, [[maybe_unused]] ox::CRStringView path,
[[maybe_unused]] bool forceLoad = false) noexcept {
#ifndef OX_BARE_METAL
const auto readConvert = [ctx](const ox::Buffer &buff) -> ox::Result<T> {
auto [obj, err] = ox::readClaw<T>(buff);
if (err) {
if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) {
return err;
}
oxReturnError(convert<T>(ctx, buff, &obj));
}
return std::move(obj);
};
if (forceLoad) {
oxRequire(buff, ctx->rom->read(path));
oxRequire(obj, readConvert(buff));
oxRequire(cached, ctx->assetManager.setAsset(path, obj));
return std::move(cached);
} else {
auto [cached, err] = ctx->assetManager.getAsset<T>(path);
if (err) {
oxRequire(buff, ctx->rom->read(path));
oxRequire(obj, readConvert(buff));
oxReturnError(ctx->assetManager.setAsset(path, obj).moveTo(&cached));
}
return std::move(cached);
}
#else
if constexpr(ox::preloadable<T>::value) {
oxRequire(addr, getPreloadAddr(ctx, path));
return foundation::AssetRef<T>(reinterpret_cast<const T*>(addr));
} else {
return OxError(1);
}
#endif
}
template<typename T>
ox::Result<foundation::AssetRef<T>> readObj(foundation::Context *ctx, const ox::FileAddress &file,
[[maybe_unused]] bool forceLoad = false) noexcept {
#ifndef OX_BARE_METAL
oxRequire(path, file.getPath());
return readObj<T>(ctx, ox::StringView(path), forceLoad);
#else
if constexpr(ox::preloadable<T>::value) {
oxRequire(addr, getPreloadAddr(ctx, file));
return foundation::AssetRef<T>(reinterpret_cast<const T*>(addr));
} else {
return OxError(1);
}
#endif
}
template<typename T>
ox::Error writeObj(foundation::Context *ctx, const ox::FileAddress &file, const T &obj,
ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept {
oxRequire(objBuff, ox::writeClaw(&obj, fmt));
return ctx->rom->write(file, objBuff.data(), objBuff.size());
}
ox::Result<ox::UniquePtr<ox::FileSystem>> loadRomFs(ox::CRStringView path) noexcept;
ox::Result<char*> loadRom(ox::CRStringView path = "") noexcept;
void unloadRom(char*) noexcept;
}