[keel] Add ability to log UUID duplication
All checks were successful
Build / build (push) Successful in 1m14s

This commit is contained in:
Gary Talent 2025-05-05 21:54:24 -05:00
parent 640ac85de4
commit 7cab133127
5 changed files with 96 additions and 27 deletions

View File

@ -15,7 +15,18 @@
namespace keel {
ox::Error init(
keel::Context &ctx,
Context &ctx,
ox::UPtr<ox::FileSystem> &&fs,
ox::StringViewCR appName,
DuplicateSet &duplicateSet) noexcept;
ox::Result<ox::UPtr<Context>> init(
ox::UPtr<ox::FileSystem> &&fs,
ox::StringViewCR appName,
DuplicateSet &duplicateSet) noexcept;
ox::Error init(
Context &ctx,
ox::UPtr<ox::FileSystem> &&fs,
ox::StringViewCR appName) noexcept;

View File

@ -29,13 +29,14 @@ OX_MODEL_BEGIN(PreloadPtr)
OX_MODEL_FIELD(preloadAddr)
OX_MODEL_END()
ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, ox::FileAddress const&addr) noexcept;
ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, ox::StringViewCR path) noexcept;
ox::Result<std::size_t> getPreloadAddr(Context &ctx, ox::FileAddress const&addr) noexcept;
ox::Result<std::size_t> getPreloadAddr(Context &ctx, ox::StringViewCR path) noexcept;
void createUuidMapping(Context &ctx, ox::StringViewCR filePath, ox::UUID const&uuid) noexcept;
ox::Error buildUuidMap(Context &ctx) noexcept;
// map of UUIDs to paths
using DuplicateSet = ox::HashMap<ox::UUID, ox::Vector<ox::String>>;
ox::Result<ox::UUID> pathToUuid(Context &ctx, ox::StringViewCR path) noexcept;
@ -87,8 +88,8 @@ constexpr auto makeLoader(Context &ctx) {
}
template<typename T>
ox::Result<keel::AssetRef<T>> readObjFile(
keel::Context &ctx,
ox::Result<AssetRef<T>> readObjFile(
Context &ctx,
ox::StringViewCR assetId,
bool const forceLoad) noexcept {
static constexpr auto load = [](
@ -135,11 +136,11 @@ ox::Result<keel::AssetRef<T>> readObjNoCache(
#endif
ox::Error reloadAsset(keel::Context &ctx, ox::StringViewCR assetId) noexcept;
ox::Error reloadAsset(Context &ctx, ox::StringViewCR assetId) noexcept;
template<typename T>
ox::Result<keel::AssetRef<T>> readObj(
keel::Context &ctx,
ox::Result<AssetRef<T>> readObj(
Context &ctx,
ox::StringViewCR assetId,
[[maybe_unused]] bool forceLoad = false) noexcept {
#ifndef OX_BARE_METAL
@ -150,8 +151,8 @@ ox::Result<keel::AssetRef<T>> readObj(
}
template<typename T>
ox::Result<keel::AssetRef<T>> readObj(
keel::Context &ctx,
ox::Result<AssetRef<T>> readObj(
Context &ctx,
ox::FileAddress const&file,
[[maybe_unused]] bool forceLoad = false) noexcept {
#ifndef OX_BARE_METAL
@ -169,7 +170,7 @@ ox::Result<keel::AssetRef<T>> readObj(
template<typename T>
ox::Error writeObj(
keel::Context &ctx,
Context &ctx,
ox::FileAddress const&file,
T const&obj,
ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept {
@ -177,6 +178,8 @@ ox::Error writeObj(
return ctx.rom->write(file, objBuff.data(), objBuff.size());
}
ox::Error setRomFs(Context &ctx, ox::UPtr<ox::FileSystem> &&fs, DuplicateSet &duplicateSet) noexcept;
ox::Error setRomFs(Context &ctx, ox::UPtr<ox::FileSystem> &&fs) noexcept;
ox::Result<ox::UPtr<ox::FileSystem>> loadRomFs(ox::StringViewCR path) noexcept;

View File

@ -6,21 +6,24 @@
namespace keel {
ox::Error init(
keel::Context &ctx,
static ox::Error init(
Context &ctx,
ox::UPtr<ox::FileSystem> &&fs,
ox::StringViewCR appName) noexcept {
ox::StringViewCR appName,
DuplicateSet *duplicateSet) noexcept {
ctx.appName = appName;
std::ignore = setRomFs(ctx, std::move(fs));
std::ignore = duplicateSet ?
setRomFs(ctx, std::move(fs), *duplicateSet) :
setRomFs(ctx, std::move(fs));
#ifndef OX_BARE_METAL
auto const&mods = modules();
for (auto &mod : mods) {
// register type converters
for (auto c : mod->converters()) {
for (auto const c : mod->converters()) {
ctx.converters.emplace_back(c);
}
// register pack transforms
for (auto c : mod->packTransforms()) {
for (auto const c : mod->packTransforms()) {
ctx.packTransforms.emplace_back(c);
}
}
@ -28,6 +31,30 @@ ox::Error init(
return {};
}
ox::Error init(
Context &ctx,
ox::UPtr<ox::FileSystem> &&fs,
ox::StringViewCR appName,
DuplicateSet &duplicateSet) noexcept {
return init(ctx, std::move(fs), appName, &duplicateSet);
}
ox::Result<ox::UPtr<Context>> init(
ox::UPtr<ox::FileSystem> &&fs,
ox::StringViewCR appName,
DuplicateSet &duplicateSet) noexcept {
auto ctx = ox::make_unique<Context>();
OX_RETURN_ERROR(keel::init(*ctx, std::move(fs), appName, &duplicateSet));
return ctx;
}
ox::Error init(
Context &ctx,
ox::UPtr<ox::FileSystem> &&fs,
ox::StringViewCR appName) noexcept {
return init(ctx, std::move(fs), appName, nullptr);
}
ox::Result<ox::UPtr<Context>> init(ox::UPtr<ox::FileSystem> &&fs, ox::StringViewCR appName) noexcept {
auto ctx = ox::make_unique<Context>();
OX_RETURN_ERROR(keel::init(*ctx, std::move(fs), appName));

View File

@ -47,7 +47,7 @@ void createUuidMapping(Context &ctx, ox::StringViewCR filePath, ox::UUID const&u
ctx.uuidToPath[uuid.toString()] = filePath;
}
static ox::Error buildUuidMap(Context &ctx, ox::StringViewCR path) noexcept {
static ox::Error buildUuidMap(Context &ctx, ox::StringViewCR path, DuplicateSet *duplicates) noexcept {
OX_REQUIRE(files, ctx.rom->ls(path));
for (auto const&f : files) {
OX_REQUIRE_M(filePath, ox::join("/", ox::Array<ox::StringView, 2>{path, f}));
@ -58,22 +58,31 @@ static ox::Error buildUuidMap(Context &ctx, ox::StringViewCR path) noexcept {
ctx.rom->read(filePath, 0, buff.size(), buff));
auto const [uuid, err] = readUuidHeader(buff);
if (!err) {
// check for duplication
if (duplicates && ctx.uuidToPath[uuid.toString()].len()) {
auto &dl = (*duplicates)[uuid];
if (dl.empty()) {
dl.emplace_back(ctx.uuidToPath[uuid.toString()]);
}
dl.emplace_back(filePath);
} else {
createUuidMapping(ctx, filePath, uuid);
}
}
} else if (stat.fileType == ox::FileType::Directory) {
if (!beginsWith(f, ".")) {
OX_RETURN_ERROR(buildUuidMap(ctx, filePath));
OX_RETURN_ERROR(buildUuidMap(ctx, filePath, duplicates));
}
}
}
return {};
}
ox::Error buildUuidMap(Context &ctx) noexcept {
static ox::Error buildUuidMap(Context &ctx, DuplicateSet *duplicates) noexcept {
if (!ctx.rom) {
return ox::Error(1, "No ROM FS");
return ox::Error{1, "No ROM FS"};
}
return buildUuidMap(ctx, "");
return buildUuidMap(ctx, "", duplicates);
}
ox::Result<ox::UUID> pathToUuid(Context &ctx, ox::StringViewCR path) noexcept {
@ -199,7 +208,7 @@ namespace keel {
static void clearUuidMap(Context&) noexcept {
}
ox::Error buildUuidMap(Context&) noexcept {
static ox::Error buildUuidMap(Context&, DuplicateSet*) noexcept {
return {};
}
@ -249,10 +258,16 @@ ox::Error reloadAsset(keel::Context&, ox::StringView) noexcept {
namespace keel {
ox::Error setRomFs(Context &ctx, ox::UPtr<ox::FileSystem> &&fs, DuplicateSet &duplicateSet) noexcept {
ctx.rom = std::move(fs);
clearUuidMap(ctx);
return buildUuidMap(ctx, &duplicateSet);
}
ox::Error setRomFs(Context &ctx, ox::UPtr<ox::FileSystem> &&fs) noexcept {
ctx.rom = std::move(fs);
clearUuidMap(ctx);
return buildUuidMap(ctx);
return buildUuidMap(ctx, nullptr);
}
ox::Result<ox::UPtr<ox::FileSystem>> loadRomFs(ox::StringViewCR path) noexcept {

View File

@ -55,7 +55,20 @@ static ox::Error pack(
ox::Buffer dstBuff(32 * ox::units::MB);
OX_RETURN_ERROR(ox::FileSystem32::format(dstBuff.data(), dstBuff.size()));
ox::FileSystem32 dst(dstBuff);
OX_REQUIRE(ctx, keel::init(ox::make_unique<ox::PassThroughFS>(argSrc), "keel-pack"));
keel::DuplicateSet duplicateSet;
OX_REQUIRE(ctx, keel::init(
ox::make_unique<ox::PassThroughFS>(argSrc), "keel-pack", duplicateSet));
if (duplicateSet.size()) {
oxErr("Multiple files have the same UUID:\n");
for (auto const &k : duplicateSet.keys()) {
oxErrf("\n\t{}:\n", k.toString());
for (auto const &v : duplicateSet[k]) {
oxErrf("\t\t{}\n", v);
}
}
oxErr("\n");
std::exit(1);
}
keel::TypeStore ts(*ctx->rom, ox::sfmt("{}/type_descriptors", projectDataDir));
OX_RETURN_ERROR(generateTypes(ts));
keel::Manifest manifest;