[nostalgia/core] Add ability to chain converters
This commit is contained in:
parent
1ceb76ee6d
commit
713f5c4bce
@ -61,8 +61,8 @@ struct TileSheet {
|
|||||||
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet.SubSheet";
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheet.SubSheet";
|
||||||
static constexpr auto TypeVersion = 1;
|
static constexpr auto TypeVersion = 1;
|
||||||
ox::BString<32> name;
|
ox::BString<32> name;
|
||||||
std::size_t begin = 0;
|
uint64_t begin = 0;
|
||||||
std::size_t size = 0;
|
uint64_t size = 0;
|
||||||
int rows = 1;
|
int rows = 1;
|
||||||
int columns = 1;
|
int columns = 1;
|
||||||
ox::Vector<SubSheet> subsheets;
|
ox::Vector<SubSheet> subsheets;
|
||||||
|
@ -23,7 +23,7 @@ ox::Result<AssetRef<T>> readObj(Context *ctx, const ox::FileAddress &file, bool
|
|||||||
if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) {
|
if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
oxReturnError(convert(buff, T::TypeName, T::TypeVersion, &obj));
|
oxReturnError(convert<T>(buff, &obj));
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
@ -30,9 +30,8 @@ struct NostalgiaPaletteToPaletteConverter: public Converter<NostalgiaPalette, Pa
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Src>
|
struct TileSheetToCompactTileSheetConverter: public Converter<TileSheet, CompactTileSheet> {
|
||||||
struct ToCompactTileSheetConverter: public Converter<Src, CompactTileSheet> {
|
ox::Error convert(TileSheet *src, CompactTileSheet *dst) noexcept final {
|
||||||
ox::Error convert(Src *src, CompactTileSheet *dst) noexcept final {
|
|
||||||
dst->bpp = src->bpp;
|
dst->bpp = src->bpp;
|
||||||
dst->defaultPalette = std::move(src->defaultPalette);
|
dst->defaultPalette = std::move(src->defaultPalette);
|
||||||
dst->pixels = std::move(src->pixels);
|
dst->pixels = std::move(src->pixels);
|
||||||
@ -42,11 +41,10 @@ struct ToCompactTileSheetConverter: public Converter<Src, CompactTileSheet> {
|
|||||||
|
|
||||||
#ifndef OX_BARE_METAL
|
#ifndef OX_BARE_METAL
|
||||||
static const auto converters = [] {
|
static const auto converters = [] {
|
||||||
ox::Vector<ox::UniquePtr<BaseConverter>, 4> converters;
|
ox::Vector<ox::UniquePtr<BaseConverter>, 3> converters;
|
||||||
converters.emplace_back(new NostalgiaGraphicToTileSheetConverter());
|
converters.emplace_back(new NostalgiaGraphicToTileSheetConverter());
|
||||||
converters.emplace_back(new NostalgiaPaletteToPaletteConverter());
|
converters.emplace_back(new NostalgiaPaletteToPaletteConverter());
|
||||||
converters.emplace_back(new ToCompactTileSheetConverter<NostalgiaGraphic>());
|
converters.emplace_back(new TileSheetToCompactTileSheetConverter());
|
||||||
converters.emplace_back(new ToCompactTileSheetConverter<TileSheet>());
|
|
||||||
return converters;
|
return converters;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
@ -59,11 +57,25 @@ static auto findConverter(const ox::String &srcTypeName, int srcTypeVersion, con
|
|||||||
return OxError(1, "Could not find converter");
|
return OxError(1, "Could not find converter");
|
||||||
};
|
};
|
||||||
|
|
||||||
ox::Error convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion, void *dstObj) noexcept {
|
ox::Result<ox::Buffer> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion, ox::ClawFormat fmt) noexcept {
|
||||||
oxRequire(hdr, ox::readClawHeader(srcBuffer));
|
oxRequire(hdr, ox::readClawHeader(srcBuffer));
|
||||||
oxRequire(c, findConverter(hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion));
|
auto [c, err] = findConverter(hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion);
|
||||||
return c->convertRaw(srcBuffer, dstObj);
|
if (!err) { // try to chain multiple converters
|
||||||
|
return c->convertBuffToBuff(srcBuffer);
|
||||||
|
}
|
||||||
|
for (const auto &subConverter : converters) {
|
||||||
|
if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto [intermediateBuff, chainErr] =
|
||||||
|
convert(srcBuffer, subConverter->srcTypeName(), subConverter->srcTypeVersion(), fmt);
|
||||||
|
if (!chainErr) {
|
||||||
|
return subConverter->convertBuffToBuff(intermediateBuff, fmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OxError(1, "Could not convert between types");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,42 @@ namespace nostalgia::core {
|
|||||||
struct BaseConverter {
|
struct BaseConverter {
|
||||||
virtual ~BaseConverter() noexcept = default;
|
virtual ~BaseConverter() noexcept = default;
|
||||||
|
|
||||||
|
virtual ox::String srcTypeName() noexcept = 0;
|
||||||
|
|
||||||
|
virtual int srcTypeVersion() noexcept = 0;
|
||||||
|
|
||||||
|
virtual bool srcMatches(const ox::String &srcTypeName, int srcTypeVersion) noexcept = 0;
|
||||||
|
|
||||||
|
virtual bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0;
|
||||||
|
|
||||||
virtual bool matches(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0;
|
virtual bool matches(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0;
|
||||||
|
|
||||||
virtual ox::Error convertRaw(const ox::Buffer &pV1Buff, void *pV2) noexcept = 0;
|
virtual ox::Error convertRaw(const ox::Buffer &pV1Buff, void *pV2) noexcept = 0;
|
||||||
|
|
||||||
|
virtual ox::Result<ox::Buffer> convertBuffToBuff(const ox::Buffer &srcBuff, ox::ClawFormat dstFmt = ox::ClawFormat::Metal) noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename SrcType, typename DstType>
|
template<typename SrcType, typename DstType>
|
||||||
struct Converter: public BaseConverter{
|
struct Converter: public BaseConverter{
|
||||||
bool matches(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept override {
|
ox::String srcTypeName() noexcept final {
|
||||||
|
return SrcType::TypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srcTypeVersion() noexcept final {
|
||||||
|
return SrcType::TypeVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool srcMatches(const ox::String &srcTypeName, int srcTypeVersion) noexcept final {
|
||||||
|
return srcTypeName == DstType::TypeName
|
||||||
|
&& srcTypeVersion == DstType::TypeVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept final {
|
||||||
|
return dstTypeName == DstType::TypeName
|
||||||
|
&& dstTypeVersion == DstType::TypeVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matches(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept final {
|
||||||
return srcTypeName == SrcType::TypeName
|
return srcTypeName == SrcType::TypeName
|
||||||
&& dstTypeName == DstType::TypeName
|
&& dstTypeName == DstType::TypeName
|
||||||
&& srcTypeVersion == SrcType::TypeVersion
|
&& srcTypeVersion == SrcType::TypeVersion
|
||||||
@ -40,26 +68,26 @@ struct Converter: public BaseConverter{
|
|||||||
auto dst = static_cast<DstType*>(pV2);
|
auto dst = static_cast<DstType*>(pV2);
|
||||||
return convert(&src, dst);
|
return convert(&src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Result<ox::Buffer> convertBuffToBuff(const ox::Buffer &srcBuff, ox::ClawFormat dstFmt) noexcept final {
|
||||||
|
DstType dst;
|
||||||
|
oxReturnError(convertRaw(srcBuff, &dst));
|
||||||
|
oxRequireM(out, ox::writeClaw(&dst, dstFmt));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ox::Error convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion, void *dstObj) noexcept;
|
ox::Result<ox::Buffer> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion, ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
ox::Error convert(const ox::Buffer &srcBuffer, T *dstObj) noexcept {
|
|
||||||
return convert((srcBuffer, T::TypeName, T::TypeVersion, &dstObj));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Result<ox::Buffer> convert(const ox::Buffer &srcBuffer, ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept {
|
ox::Result<ox::Buffer> convert(const ox::Buffer &srcBuffer, ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept {
|
||||||
T dstObj;
|
return convert(srcBuffer, T::TypeName, T::TypeVersion, fmt);
|
||||||
oxReturnError(convert(srcBuffer, T::TypeName, T::TypeVersion, &dstObj));
|
|
||||||
return ox::writeClaw(&dstObj, fmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Error convert(ox::Buffer *buff) noexcept {
|
ox::Error convert(const ox::Buffer &buff, T *outObj) noexcept {
|
||||||
return convert<T>(*buff).moveTo(buff);
|
oxRequireM(outBuff, convert<T>(buff));
|
||||||
|
return ox::readClaw<T>(outBuff).moveTo(outObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ static ox::Error doTransformations(ox::FileSystem *dest, const ox::String &fileP
|
|||||||
// load file
|
// load file
|
||||||
oxRequireM(buff, dest->read(filePath.c_str()));
|
oxRequireM(buff, dest->read(filePath.c_str()));
|
||||||
if (filePath.endsWith(".ng")) {
|
if (filePath.endsWith(".ng")) {
|
||||||
oxReturnError(core::convert<core::CompactTileSheet>(&buff));
|
oxReturnError(core::convert<core::CompactTileSheet>(buff).moveTo(&buff));
|
||||||
}
|
}
|
||||||
// do transformations
|
// do transformations
|
||||||
oxReturnError(pathToInode(buff).moveTo(&buff));
|
oxReturnError(pathToInode(buff).moveTo(&buff));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user