[keel] Add manifest to pack output
This commit is contained in:
parent
3b8eaef36b
commit
0cc6757c57
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,3 +20,4 @@ imgui.ini
|
|||||||
*.sav
|
*.sav
|
||||||
studio_state.json
|
studio_state.json
|
||||||
tags
|
tags
|
||||||
|
*-manifest.json
|
||||||
|
@ -28,8 +28,12 @@ project_name = sys.argv[2]
|
|||||||
bin = f'./build/{host_env}-{current_build}/bin/'
|
bin = f'./build/{host_env}-{current_build}/bin/'
|
||||||
project_bin = f'build/gba-release/bin/{project_name}.bin'
|
project_bin = f'build/gba-release/bin/{project_name}.bin'
|
||||||
project_gba = f'{project_name}.gba'
|
project_gba = f'{project_name}.gba'
|
||||||
|
project_manifest = f'{project_name}-manifest.json'
|
||||||
|
|
||||||
shutil.copyfile(project_bin, project_gba)
|
shutil.copyfile(project_bin, project_gba)
|
||||||
subprocess.run([
|
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])
|
subprocess.run(['gbafix', project_gba])
|
||||||
|
@ -57,8 +57,6 @@ ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::CRStringView uuid) noex
|
|||||||
|
|
||||||
ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept;
|
ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept;
|
||||||
|
|
||||||
ox::Error performPackTransforms(Context &ctx, ox::Buffer &clawData) noexcept;
|
|
||||||
|
|
||||||
#ifndef OX_BARE_METAL
|
#ifndef OX_BARE_METAL
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -12,6 +12,31 @@
|
|||||||
|
|
||||||
namespace keel {
|
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<ox::String, ManifestEntry> files;
|
||||||
|
};
|
||||||
|
|
||||||
|
oxModelBegin(Manifest)
|
||||||
|
oxModelField(files)
|
||||||
|
oxModelEnd()
|
||||||
|
|
||||||
|
|
||||||
class Context;
|
class Context;
|
||||||
|
|
||||||
struct GbaPlatSpec {
|
struct GbaPlatSpec {
|
||||||
@ -113,6 +138,7 @@ ox::Error preloadObj(
|
|||||||
// transformations need to be done after the copy to the new FS is complete
|
// transformations need to be done after the copy to the new FS is complete
|
||||||
template<typename PlatSpec>
|
template<typename PlatSpec>
|
||||||
ox::Error preloadDir(
|
ox::Error preloadDir(
|
||||||
|
Manifest &manifest,
|
||||||
ox::TypeStore &ts,
|
ox::TypeStore &ts,
|
||||||
ox::FileSystem &romFs,
|
ox::FileSystem &romFs,
|
||||||
ox::Preloader<PlatSpec> &pl,
|
ox::Preloader<PlatSpec> &pl,
|
||||||
@ -125,13 +151,14 @@ ox::Error preloadDir(
|
|||||||
oxRequire(stat, romFs.stat(filePath));
|
oxRequire(stat, romFs.stat(filePath));
|
||||||
if (stat.fileType == ox::FileType::Directory) {
|
if (stat.fileType == ox::FileType::Directory) {
|
||||||
auto const dir = ox::sfmt("{}{}/", path, name);
|
auto const dir = ox::sfmt("{}{}/", path, name);
|
||||||
oxReturnError(preloadDir(ts, romFs, pl, dir));
|
oxReturnError(preloadDir(manifest, ts, romFs, pl, dir));
|
||||||
} else {
|
} else {
|
||||||
auto const err = preloadObj(ts, romFs, pl, filePath);
|
auto const err = preloadObj(ts, romFs, pl, filePath);
|
||||||
if (err) {
|
if (err) {
|
||||||
oxErrf("\033[31;1;1mCould not preload {}:\n\t{}\n", filePath, toStr(err));
|
oxErrf("\033[31;1;1mCould not preload {}:\n\t{}\n", filePath, toStr(err));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
manifest.files[filePath].preloaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
@ -162,11 +189,15 @@ ox::Error appendBinary(ox::Buffer &binBuff, ox::SpanView<char> const&fsBuff, ox:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename PlatSpec>
|
template<typename PlatSpec>
|
||||||
ox::Error preload(ox::TypeStore &ts, ox::FileSystem &src, ox::Preloader<PlatSpec> &pl) noexcept {
|
ox::Error preload(
|
||||||
|
Manifest &manifest,
|
||||||
|
ox::TypeStore &ts,
|
||||||
|
ox::FileSystem &src,
|
||||||
|
ox::Preloader<PlatSpec> &pl) noexcept {
|
||||||
oxOut("Preloading\n");
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -154,18 +154,6 @@ ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::UUID const&uuid) noexce
|
|||||||
#endif
|
#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::Error reloadAsset(keel::Context &ctx, ox::StringView assetId) noexcept {
|
||||||
ox::UUIDStr uuidStr;
|
ox::UUIDStr uuidStr;
|
||||||
if (beginsWith(assetId, "uuid://")) {
|
if (beginsWith(assetId, "uuid://")) {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <ox/fs/fs.hpp>
|
#include <ox/fs/fs.hpp>
|
||||||
#include <ox/logconn/def.hpp>
|
#include <ox/logconn/def.hpp>
|
||||||
#include <ox/logconn/logconn.hpp>
|
#include <ox/logconn/logconn.hpp>
|
||||||
|
#include <ox/oc/write.hpp>
|
||||||
|
|
||||||
#include <keel/keel.hpp>
|
#include <keel/keel.hpp>
|
||||||
|
|
||||||
@ -48,16 +49,21 @@ static ox::Error generateTypes(ox::TypeStore &ts) noexcept {
|
|||||||
return {};
|
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);
|
ox::Buffer dstBuff(32 * ox::units::MB);
|
||||||
oxReturnError(ox::FileSystem32::format(dstBuff.data(), dstBuff.size()));
|
oxReturnError(ox::FileSystem32::format(dstBuff.data(), dstBuff.size()));
|
||||||
ox::FileSystem32 dst(dstBuff);
|
ox::FileSystem32 dst(dstBuff);
|
||||||
oxRequire(ctx, keel::init(ox::make_unique<ox::PassThroughFS>(argSrc), "keel-pack"));
|
oxRequire(ctx, keel::init(ox::make_unique<ox::PassThroughFS>(argSrc), "keel-pack"));
|
||||||
keel::TypeStore ts(*ctx->rom, ox::sfmt("{}/type_descriptors", projectDataDir));
|
keel::TypeStore ts(*ctx->rom, ox::sfmt("{}/type_descriptors", projectDataDir));
|
||||||
oxReturnError(generateTypes(ts));
|
oxReturnError(generateTypes(ts));
|
||||||
oxReturnError(keel::pack(*ctx, ts, dst));
|
keel::Manifest manifest;
|
||||||
|
oxReturnError(keel::pack(manifest, *ctx, ts, dst));
|
||||||
oxRequireM(pl, keel::GbaPreloader::make());
|
oxRequireM(pl, keel::GbaPreloader::make());
|
||||||
oxReturnError(preload(ts, dst, *pl));
|
oxReturnError(preload(manifest, ts, dst, *pl));
|
||||||
oxReturnError(dst.resize());
|
oxReturnError(dst.resize());
|
||||||
// resize buffer
|
// resize buffer
|
||||||
oxRequire(dstSize, dst.size());
|
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));
|
oxReturnError(appendBinary(romBuff, dstBuff, *pl));
|
||||||
oxOutf("Final ROM buff size: {} bytes\n", romBuff.size());
|
oxOutf("Final ROM buff size: {} bytes\n", romBuff.size());
|
||||||
oxReturnError(writeFileBuff(argRomBin, romBuff));
|
oxReturnError(writeFileBuff(argRomBin, romBuff));
|
||||||
|
oxRequire(manifestJson, ox::writeOC(manifest));
|
||||||
|
oxReturnError(writeFileBuff(argManifest, manifestJson));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +85,7 @@ static ox::Error run(int argc, char const**argv, ox::StringView projectDataDir)
|
|||||||
ox::ClArgs const args(argc, argv);
|
ox::ClArgs const args(argc, argv);
|
||||||
auto const argSrc = args.getString("src", "");
|
auto const argSrc = args.getString("src", "");
|
||||||
auto const argRomBin = args.getString("rom-bin", "");
|
auto const argRomBin = args.getString("rom-bin", "");
|
||||||
|
auto const argManifest = args.getString("manifest", "");
|
||||||
if (argSrc == "") {
|
if (argSrc == "") {
|
||||||
oxErr("\033[31;1;1merror:\033[0m must specify a source directory\n");
|
oxErr("\033[31;1;1merror:\033[0m must specify a source directory\n");
|
||||||
return OxError(1, "must specify a source directory");
|
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");
|
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 OxError(1, "must specify a path for preload file");
|
||||||
}
|
}
|
||||||
return pack(argSrc, argRomBin, projectDataDir);
|
return pack(argSrc, argRomBin, argManifest, projectDataDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace olympic {
|
namespace olympic {
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include <ox/model/modelvalue.hpp>
|
#include <ox/model/modelvalue.hpp>
|
||||||
|
|
||||||
#include <keel/media.hpp>
|
#include <keel/media.hpp>
|
||||||
|
|
||||||
#include <keel/pack.hpp>
|
#include <keel/pack.hpp>
|
||||||
|
|
||||||
namespace keel {
|
namespace keel {
|
||||||
@ -85,7 +84,21 @@ static ox::Error transformFileAddressesObj(
|
|||||||
return {};
|
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(
|
static ox::Error doTransformations(
|
||||||
|
Manifest &manifest,
|
||||||
keel::Context &ctx,
|
keel::Context &ctx,
|
||||||
ox::TypeStore &ts,
|
ox::TypeStore &ts,
|
||||||
ox::FileSystem &dest,
|
ox::FileSystem &dest,
|
||||||
@ -94,7 +107,7 @@ static ox::Error doTransformations(
|
|||||||
oxRequire(s, dest.stat(filePath));
|
oxRequire(s, dest.stat(filePath));
|
||||||
// do transformations
|
// do transformations
|
||||||
oxRequireM(buff, dest.read(s.inode));
|
oxRequireM(buff, dest.read(s.inode));
|
||||||
oxReturnError(keel::performPackTransforms(ctx, buff));
|
oxReturnError(keel::performPackTransforms(manifest.files[filePath], ctx, buff));
|
||||||
// transform FileAddresses
|
// transform FileAddresses
|
||||||
oxRequireM(obj, keel::readAsset(ts, buff));
|
oxRequireM(obj, keel::readAsset(ts, buff));
|
||||||
oxOutf("transforming {}\n", filePath);
|
oxOutf("transforming {}\n", filePath);
|
||||||
@ -108,6 +121,7 @@ static ox::Error doTransformations(
|
|||||||
// claw file transformations are broken out from copy because path to inode
|
// 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
|
// transformations need to be done after the copy to the new FS is complete
|
||||||
static ox::Error transformClaw(
|
static ox::Error transformClaw(
|
||||||
|
Manifest &manifest,
|
||||||
keel::Context &ctx,
|
keel::Context &ctx,
|
||||||
ox::TypeStore &ts,
|
ox::TypeStore &ts,
|
||||||
ox::FileSystem &dest,
|
ox::FileSystem &dest,
|
||||||
@ -120,9 +134,9 @@ static ox::Error transformClaw(
|
|||||||
oxRequire(stat, dest.stat(filePath));
|
oxRequire(stat, dest.stat(filePath));
|
||||||
if (stat.fileType == ox::FileType::Directory) {
|
if (stat.fileType == ox::FileType::Directory) {
|
||||||
auto const dir = ox::sfmt("{}{}/", path, name);
|
auto const dir = ox::sfmt("{}{}/", path, name);
|
||||||
oxReturnError(transformClaw(ctx, ts, dest, dir));
|
oxReturnError(transformClaw(manifest, ctx, ts, dest, dir));
|
||||||
} else {
|
} else {
|
||||||
auto const err = doTransformations(ctx, ts, dest, filePath);
|
auto const err = doTransformations(manifest, ctx, ts, dest, filePath);
|
||||||
if (err) {
|
if (err) {
|
||||||
oxErrf("\033[31;1;1mCould not do transformations for {}:\n\t{}\n", filePath, toStr(err));
|
oxErrf("\033[31;1;1mCould not do transformations for {}:\n\t{}\n", filePath, toStr(err));
|
||||||
return err;
|
return err;
|
||||||
@ -133,6 +147,7 @@ static ox::Error transformClaw(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ox::Error copy(
|
static ox::Error copy(
|
||||||
|
Manifest &manifest,
|
||||||
ox::FileSystem &src,
|
ox::FileSystem &src,
|
||||||
ox::FileSystem &dest,
|
ox::FileSystem &dest,
|
||||||
ox::CRStringView path,
|
ox::CRStringView path,
|
||||||
@ -149,7 +164,7 @@ static ox::Error copy(
|
|||||||
oxRequire(stat, src.stat(currentFile));
|
oxRequire(stat, src.stat(currentFile));
|
||||||
if (stat.fileType == ox::FileType::Directory) {
|
if (stat.fileType == ox::FileType::Directory) {
|
||||||
oxReturnError(dest.mkdir(currentFile, true));
|
oxReturnError(dest.mkdir(currentFile, true));
|
||||||
oxReturnError(copy(src, dest, currentFile + '/', childLogPrefix));
|
oxReturnError(copy(manifest, src, dest, currentFile + '/', childLogPrefix));
|
||||||
} else {
|
} else {
|
||||||
// load file
|
// load file
|
||||||
oxOutf("{}copying file: {}...", childLogPrefix, currentFile);
|
oxOutf("{}copying file: {}...", childLogPrefix, currentFile);
|
||||||
@ -161,15 +176,20 @@ static ox::Error copy(
|
|||||||
// write file to dest
|
// write file to dest
|
||||||
oxReturnError(dest.write(currentFile, buff));
|
oxReturnError(dest.write(currentFile, buff));
|
||||||
status = "OK";
|
status = "OK";
|
||||||
|
oxRequire(stat, dest.stat(currentFile));
|
||||||
|
manifest.files[currentFile] = {
|
||||||
|
.inode = stat.inode,
|
||||||
|
.type = ox::String{keel::readAssetTypeId(buff).or_value({})},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
oxReturnError(copy(*ctx.rom, dest, "/"));
|
oxReturnError(copy(manifest, *ctx.rom, dest, "/"));
|
||||||
oxOut("Doing transforms\n");
|
oxOut("Doing transforms\n");
|
||||||
oxReturnError(transformClaw(ctx, ts, dest, "/"));
|
oxReturnError(transformClaw(manifest, ctx, ts, dest, "/"));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user