Merge commit 'ec6cf92c4763be5933ee6debbf97bce25b9fcfc9'

This commit is contained in:
Gary Talent 2025-04-17 20:12:48 -05:00
commit ac29f7a0f2
11 changed files with 129 additions and 131 deletions

View File

@ -14,19 +14,6 @@
namespace nostalgia::gfx { namespace nostalgia::gfx {
static class: public keel::Module { static class: public keel::Module {
private:
NostalgiaPaletteToPaletteV1Converter m_nostalgiaPaletteToPaletteV1Converter;
PaletteV1ToPaletteV2Converter m_paletteV1ToPaletteV2Converter;
PaletteV2ToPaletteV3Converter m_paletteV2ToPaletteV3Converter;
PaletteV3ToPaletteV4Converter m_paletteV3ToPaletteV4Converter;
PaletteV4ToPaletteV5Converter m_paletteV4ToPaletteV5Converter;
PaletteToCompactPaletteConverter m_paletteToCompactPaletteConverter;
TileSheetV1ToTileSheetV2Converter m_tileSheetV1ToTileSheetV2Converter;
TileSheetV2ToTileSheetV3Converter m_tileSheetV2ToTileSheetV3Converter;
TileSheetV3ToTileSheetV4Converter m_tileSheetV3ToTileSheetV4Converter;
TileSheetV4ToTileSheetV5Converter m_tileSheetV4ToTileSheetV5Converter;
TileSheetToCompactTileSheetConverter m_tileSheetToCompactTileSheetConverter;
public: public:
[[nodiscard]] [[nodiscard]]
ox::String id() const noexcept override { ox::String id() const noexcept override {
@ -52,19 +39,19 @@ static class: public keel::Module {
} }
[[nodiscard]] [[nodiscard]]
ox::Vector<keel::BaseConverter const*> converters() const noexcept final { ox::Vector<keel::Converter> converters() const noexcept final {
return { return {
&m_nostalgiaPaletteToPaletteV1Converter, keel::Converter::make<convertNostalgiaPaletteToPaletteV1>(),
&m_paletteV1ToPaletteV2Converter, keel::Converter::make<convertPaletteV1ToPaletteV2>(),
&m_paletteV2ToPaletteV3Converter, keel::Converter::make<convertPaletteV2ToPaletteV3>(),
&m_paletteV3ToPaletteV4Converter, keel::Converter::make<convertPaletteV3ToPaletteV4>(),
&m_paletteV4ToPaletteV5Converter, keel::Converter::make<convertPaletteV4ToPaletteV5>(),
&m_paletteToCompactPaletteConverter, keel::Converter::make<convertPaletteToCompactPalette>(),
&m_tileSheetV1ToTileSheetV2Converter, keel::Converter::make<convertTileSheetV1ToTileSheetV2>(),
&m_tileSheetV2ToTileSheetV3Converter, keel::Converter::make<convertTileSheetV2ToTileSheetV3>(),
&m_tileSheetV3ToTileSheetV4Converter, keel::Converter::make<convertTileSheetV3ToTileSheetV4>(),
&m_tileSheetV4ToTileSheetV5Converter, keel::Converter::make<convertTileSheetV4ToTileSheetV5>(),
&m_tileSheetToCompactTileSheetConverter, keel::Converter::make<convertTileSheetToCompactTileSheet>(),
}; };
} }

View File

@ -6,26 +6,26 @@
namespace nostalgia::gfx { namespace nostalgia::gfx {
ox::Error NostalgiaPaletteToPaletteV1Converter::convert( ox::Error convertNostalgiaPaletteToPaletteV1(
keel::Context&, keel::Context&,
NostalgiaPalette &src, NostalgiaPalette &src,
PaletteV1 &dst) const noexcept { PaletteV1 &dst) noexcept {
dst.colors = std::move(src.colors); dst.colors = std::move(src.colors);
return {}; return {};
} }
ox::Error PaletteV1ToPaletteV2Converter::convert( ox::Error convertPaletteV1ToPaletteV2(
keel::Context&, keel::Context&,
PaletteV1 &src, PaletteV1 &src,
PaletteV2 &dst) const noexcept { PaletteV2 &dst) noexcept {
dst.pages.emplace_back(std::move(src.colors)); dst.pages.emplace_back(std::move(src.colors));
return {}; return {};
} }
ox::Error PaletteV2ToPaletteV3Converter::convert( ox::Error convertPaletteV2ToPaletteV3(
keel::Context&, keel::Context&,
PaletteV2 &src, PaletteV2 &src,
PaletteV3 &dst) const noexcept { PaletteV3 &dst) noexcept {
dst.pages = std::move(src.pages); dst.pages = std::move(src.pages);
if (!dst.pages.empty()) { if (!dst.pages.empty()) {
dst.colorInfo.reserve(dst.pages[0].size()); dst.colorInfo.reserve(dst.pages[0].size());
@ -36,10 +36,10 @@ ox::Error PaletteV2ToPaletteV3Converter::convert(
return {}; return {};
} }
ox::Error PaletteV3ToPaletteV4Converter::convert( ox::Error convertPaletteV3ToPaletteV4(
keel::Context&, keel::Context&,
PaletteV3 &src, PaletteV3 &src,
PaletteV4 &dst) const noexcept { PaletteV4 &dst) noexcept {
dst.pages.reserve(src.pages.size()); dst.pages.reserve(src.pages.size());
for (auto i = 1; auto &page : src.pages) { for (auto i = 1; auto &page : src.pages) {
dst.pages.emplace_back(ox::sfmt("Page {}", i), std::move(page)); dst.pages.emplace_back(ox::sfmt("Page {}", i), std::move(page));
@ -52,10 +52,10 @@ ox::Error PaletteV3ToPaletteV4Converter::convert(
return {}; return {};
} }
ox::Error PaletteV4ToPaletteV5Converter::convert( ox::Error convertPaletteV4ToPaletteV5(
keel::Context&, keel::Context&,
PaletteV4 &src, PaletteV4 &src,
PaletteV5 &dst) const noexcept { PaletteV5 &dst) noexcept {
dst.colorNames = std::move(src.colorNames); dst.colorNames = std::move(src.colorNames);
dst.pages.reserve(src.pages.size()); dst.pages.reserve(src.pages.size());
for (auto &s : src.pages) { for (auto &s : src.pages) {
@ -72,10 +72,10 @@ ox::Error PaletteV4ToPaletteV5Converter::convert(
return {}; return {};
} }
ox::Error PaletteToCompactPaletteConverter::convert( ox::Error convertPaletteToCompactPalette(
keel::Context&, keel::Context&,
Palette &src, Palette &src,
CompactPalette &dst) const noexcept { CompactPalette &dst) noexcept {
dst.pages.reserve(src.pages.size()); dst.pages.reserve(src.pages.size());
for (auto &page : src.pages) { for (auto &page : src.pages) {
auto &p = dst.pages.emplace_back(); auto &p = dst.pages.emplace_back();
@ -86,10 +86,10 @@ ox::Error PaletteToCompactPaletteConverter::convert(
return {}; return {};
} }
ox::Error TileSheetV1ToTileSheetV2Converter::convert( ox::Error convertTileSheetV1ToTileSheetV2(
keel::Context&, keel::Context&,
TileSheetV1 &src, TileSheetV1 &src,
TileSheetV2 &dst) const noexcept { TileSheetV2 &dst) noexcept {
dst.bpp = src.bpp; dst.bpp = src.bpp;
dst.defaultPalette = std::move(src.defaultPalette); dst.defaultPalette = std::move(src.defaultPalette);
dst.subsheet.name = "Root"; dst.subsheet.name = "Root";
@ -99,7 +99,7 @@ ox::Error TileSheetV1ToTileSheetV2Converter::convert(
return {}; return {};
} }
void TileSheetV2ToTileSheetV3Converter::convertSubsheet( static void convertSubsheet(
TileSheetV2::SubSheet &src, TileSheetV2::SubSheet &src,
TileSheetV3::SubSheet &dst, TileSheetV3::SubSheet &dst,
SubSheetId &idIt) noexcept { SubSheetId &idIt) noexcept {
@ -115,10 +115,10 @@ void TileSheetV2ToTileSheetV3Converter::convertSubsheet(
} }
} }
ox::Error TileSheetV2ToTileSheetV3Converter::convert( ox::Error convertTileSheetV2ToTileSheetV3(
keel::Context&, keel::Context&,
TileSheetV2 &src, TileSheetV2 &src,
TileSheetV3 &dst) const noexcept { TileSheetV3 &dst) noexcept {
dst.bpp = src.bpp; dst.bpp = src.bpp;
dst.defaultPalette = std::move(src.defaultPalette); dst.defaultPalette = std::move(src.defaultPalette);
convertSubsheet(src.subsheet, dst.subsheet, dst.idIt); convertSubsheet(src.subsheet, dst.subsheet, dst.idIt);
@ -126,7 +126,7 @@ ox::Error TileSheetV2ToTileSheetV3Converter::convert(
} }
void TileSheetV3ToTileSheetV4Converter::convertSubsheet( static void convertSubsheet(
TileSheetV3::SubSheet &src, TileSheetV3::SubSheet &src,
TileSheetV4::SubSheet &dst, TileSheetV4::SubSheet &dst,
SubSheetId &idIt) noexcept { SubSheetId &idIt) noexcept {
@ -142,10 +142,10 @@ void TileSheetV3ToTileSheetV4Converter::convertSubsheet(
} }
} }
ox::Error TileSheetV3ToTileSheetV4Converter::convert( ox::Error convertTileSheetV3ToTileSheetV4(
keel::Context&, keel::Context&,
TileSheetV3 &src, TileSheetV3 &src,
TileSheetV4 &dst) const noexcept { TileSheetV4 &dst) noexcept {
dst.bpp = src.bpp; dst.bpp = src.bpp;
dst.idIt = src.idIt; dst.idIt = src.idIt;
dst.defaultPalette = std::move(src.defaultPalette); dst.defaultPalette = std::move(src.defaultPalette);
@ -154,7 +154,7 @@ ox::Error TileSheetV3ToTileSheetV4Converter::convert(
} }
void TileSheetV4ToTileSheetV5Converter::convertSubsheet( static void convertSubsheet(
int const bpp, int const bpp,
TileSheetV4::SubSheet &src, TileSheetV4::SubSheet &src,
TileSheetV5::SubSheet &dst) noexcept { TileSheetV5::SubSheet &dst) noexcept {
@ -179,10 +179,10 @@ void TileSheetV4ToTileSheetV5Converter::convertSubsheet(
} }
} }
ox::Error TileSheetV4ToTileSheetV5Converter::convert( ox::Error convertTileSheetV4ToTileSheetV5(
keel::Context&, keel::Context&,
TileSheetV4 &src, TileSheetV4 &src,
TileSheetV5 &dst) const noexcept { TileSheetV5 &dst) noexcept {
dst.bpp = src.bpp; dst.bpp = src.bpp;
dst.idIt = src.idIt; dst.idIt = src.idIt;
OX_RETURN_ERROR(src.defaultPalette.getPath().moveTo(dst.defaultPalette)); OX_RETURN_ERROR(src.defaultPalette.getPath().moveTo(dst.defaultPalette));
@ -191,10 +191,10 @@ ox::Error TileSheetV4ToTileSheetV5Converter::convert(
} }
ox::Error TileSheetToCompactTileSheetConverter::convert( ox::Error convertTileSheetToCompactTileSheet(
keel::Context&, keel::Context&,
TileSheet &src, TileSheet &src,
CompactTileSheet &dst) const noexcept { CompactTileSheet &dst) noexcept {
dst.bpp = src.bpp; dst.bpp = src.bpp;
dst.defaultPalette = ox::FileAddress{src.defaultPalette}; dst.defaultPalette = ox::FileAddress{src.defaultPalette};
dst.pixels = pixels(src); dst.pixels = pixels(src);

View File

@ -16,60 +16,26 @@ namespace nostalgia::gfx {
// Type converters // Type converters
class NostalgiaPaletteToPaletteV1Converter: public keel::Converter<NostalgiaPalette, PaletteV1> { ox::Error convertNostalgiaPaletteToPaletteV1(keel::Context&, NostalgiaPalette &src, PaletteV1 &dst) noexcept;
ox::Error convert(keel::Context&, NostalgiaPalette &src, PaletteV1 &dst) const noexcept final;
};
class PaletteV1ToPaletteV2Converter: public keel::Converter<PaletteV1, PaletteV2> { ox::Error convertPaletteV1ToPaletteV2(keel::Context&, PaletteV1 &src, PaletteV2 &dst) noexcept;
ox::Error convert(keel::Context&, PaletteV1 &src, PaletteV2 &dst) const noexcept final;
};
class PaletteV2ToPaletteV3Converter: public keel::Converter<PaletteV2, PaletteV3> { ox::Error convertPaletteV2ToPaletteV3(keel::Context&, PaletteV2 &src, PaletteV3 &dst) noexcept;
ox::Error convert(keel::Context&, PaletteV2 &src, PaletteV3 &dst) const noexcept final;
};
class PaletteV3ToPaletteV4Converter: public keel::Converter<PaletteV3, PaletteV4> { ox::Error convertPaletteV3ToPaletteV4(keel::Context&, PaletteV3 &src, PaletteV4 &dst) noexcept;
ox::Error convert(keel::Context&, PaletteV3 &src, PaletteV4 &dst) const noexcept final;
};
class PaletteV4ToPaletteV5Converter: public keel::Converter<PaletteV4, PaletteV5> { ox::Error convertPaletteV4ToPaletteV5(keel::Context&, PaletteV4 &src, PaletteV5 &dst) noexcept;
ox::Error convert(keel::Context&, PaletteV4 &src, PaletteV5 &dst) const noexcept final;
};
class PaletteToCompactPaletteConverter: public keel::Converter<Palette, CompactPalette> { ox::Error convertPaletteToCompactPalette(keel::Context&, Palette &src, CompactPalette &dst) noexcept;
ox::Error convert(keel::Context&, Palette &src, CompactPalette &dst) const noexcept final;
};
class TileSheetV1ToTileSheetV2Converter: public keel::Converter<TileSheetV1, TileSheetV2> { ox::Error convertTileSheetV1ToTileSheetV2(keel::Context&, TileSheetV1 &src, TileSheetV2 &dst) noexcept;
ox::Error convert(keel::Context&, TileSheetV1 &src, TileSheetV2 &dst) const noexcept final;
};
class TileSheetV2ToTileSheetV3Converter: public keel::Converter<TileSheetV2, TileSheetV3> { ox::Error convertTileSheetV2ToTileSheetV3(keel::Context&, TileSheetV2 &src, TileSheetV3 &dst) noexcept;
static void convertSubsheet(
TileSheetV2::SubSheet &src,
TileSheetV3::SubSheet &dst,
SubSheetId &idIt) noexcept;
ox::Error convert(keel::Context&, TileSheetV2 &src, TileSheetV3 &dst) const noexcept final;
};
class TileSheetV3ToTileSheetV4Converter: public keel::Converter<TileSheetV3, TileSheetV4> { ox::Error convertTileSheetV3ToTileSheetV4(keel::Context&, TileSheetV3 &src, TileSheetV4 &dst) noexcept;
static void convertSubsheet(
TileSheetV3::SubSheet &src,
TileSheetV4::SubSheet &dst,
SubSheetId &idIt) noexcept;
ox::Error convert(keel::Context&, TileSheetV3 &src, TileSheetV4 &dst) const noexcept final;
};
class TileSheetV4ToTileSheetV5Converter final: public keel::Converter<TileSheetV4, TileSheetV5> { ox::Error convertTileSheetV4ToTileSheetV5(keel::Context&, TileSheetV4 &src, TileSheetV5 &dst) noexcept;
static void convertSubsheet(
int bpp,
TileSheetV4::SubSheet &src,
TileSheetV5::SubSheet &dst) noexcept;
ox::Error convert(keel::Context&, TileSheetV4 &src, TileSheetV5 &dst) const noexcept override;
};
class TileSheetToCompactTileSheetConverter: public keel::Converter<TileSheet, CompactTileSheet> { ox::Error convertTileSheetToCompactTileSheet(keel::Context&, TileSheet &src, CompactTileSheet &dst) noexcept;
ox::Error convert(keel::Context&, TileSheet &src, CompactTileSheet &dst) const noexcept final;
};
} }

View File

@ -414,7 +414,7 @@ ox::Error TileSheetEditorImGui::exportSubsheetToPng(int const scale) const noexc
static_cast<unsigned>(width * scale), static_cast<unsigned>(width * scale),
static_cast<unsigned>(height * scale)); static_cast<unsigned>(height * scale));
if (err) { if (err) {
oxErrorf("Tilesheet export failed: {}", toStr(err)); oxErrorf("TileSheet export failed: {}", toStr(err));
} }
return err; return err;
} }

View File

@ -26,7 +26,7 @@ static class: public keel::Module {
} }
[[nodiscard]] [[nodiscard]]
ox::Vector<keel::BaseConverter const*> converters() const noexcept final { ox::Vector<keel::Converter> converters() const noexcept final {
return { return {
}; };
} }

View File

@ -4,7 +4,7 @@
#pragma once #pragma once
#include <ox/claw/claw.hpp> #include <ox/claw/read.hpp>
#include <ox/fs/fs.hpp> #include <ox/fs/fs.hpp>
#include "validation.hpp" #include "validation.hpp"

View File

@ -8,11 +8,11 @@
#include <ox/std/memory.hpp> #include <ox/std/memory.hpp>
#include "assetmanager.hpp" #include "assetmanager.hpp"
#include "typeconv.hpp"
namespace keel { namespace keel {
class Context; class Context;
using PackTransform = ox::Result<bool>(*)(Context&, ox::Buffer &clawData, ox::StringViewCR);
class Context { class Context {
public: public:
@ -22,7 +22,7 @@ class Context {
AssetManager assetManager; AssetManager assetManager;
ox::HashMap<ox::String, ox::UUID> pathToUuid; ox::HashMap<ox::String, ox::UUID> pathToUuid;
ox::HashMap<ox::UUIDStr, ox::String> uuidToPath; ox::HashMap<ox::UUIDStr, ox::String> uuidToPath;
ox::Vector<class BaseConverter const*> converters; ox::Vector<Converter> converters;
ox::Vector<PackTransform> packTransforms; ox::Vector<PackTransform> packTransforms;
#else #else
std::size_t preloadSectionOffset = 0; std::size_t preloadSectionOffset = 0;
@ -45,7 +45,7 @@ constexpr ox::SpanView<PackTransform> packTransforms(
#endif #endif
} }
constexpr ox::SpanView<class BaseConverter const*> converters( constexpr ox::SpanView<Converter> converters(
[[maybe_unused]] Context const&ctx) noexcept { [[maybe_unused]] Context const&ctx) noexcept {
#ifndef OX_BARE_METAL #ifndef OX_BARE_METAL
return ctx.converters; return ctx.converters;

View File

@ -32,7 +32,7 @@ class Module {
[[nodiscard]] [[nodiscard]]
virtual ox::Vector<TypeDescGenerator> types() const noexcept; virtual ox::Vector<TypeDescGenerator> types() const noexcept;
[[nodiscard]] [[nodiscard]]
virtual ox::Vector<const keel::BaseConverter*> converters() const noexcept; virtual ox::Vector<Converter> converters() const noexcept;
[[nodiscard]] [[nodiscard]]
virtual ox::Vector<PackTransform> packTransforms() const noexcept; virtual ox::Vector<PackTransform> packTransforms() const noexcept;
}; };

View File

@ -4,15 +4,17 @@
#pragma once #pragma once
#include <ox/claw/write.hpp>
#include <ox/std/def.hpp> #include <ox/std/def.hpp>
#include <ox/std/error.hpp> #include <ox/std/error.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include "asset.hpp" #include "asset.hpp"
#include "context.hpp"
namespace keel { namespace keel {
class Context;
class Wrap { class Wrap {
public: public:
virtual ~Wrap() = default; virtual ~Wrap() = default;
@ -113,7 +115,7 @@ class BaseConverter {
virtual ox::Result<ox::UPtr<Wrap>> convertPtrToPtr(keel::Context &ctx, Wrap &src) const noexcept = 0; virtual ox::Result<ox::UPtr<Wrap>> convertPtrToPtr(keel::Context &ctx, Wrap &src) const noexcept = 0;
virtual ox::Result<ox::UPtr<Wrap>> convertBuffToPtr( virtual ox::Result<ox::UPtr<Wrap>> convertBuffToPtr(
keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept = 0; Context &ctx, ox::BufferView const&srcBuff) const noexcept = 0;
[[nodiscard]] [[nodiscard]]
constexpr bool matches( constexpr bool matches(
@ -125,21 +127,37 @@ class BaseConverter {
}; };
template<typename SrcType, typename DstType>
class Converter: public BaseConverter { template<auto Func>
class ConverterFunc final: public BaseConverter {
private:
template<typename SrcType, typename DstType>
struct ParamPack {
using Src = SrcType;
using Dst = DstType;
};
template<typename Src, typename Dst>
static ParamPack<Src, Dst> extractParams(ox::Error (*)(Context&, Src&, Dst&)) {
return {};
}
public: public:
using SrcType = typename decltype(extractParams(Func))::Src;
using DstType = typename decltype(extractParams(Func))::Dst;
[[nodiscard]] [[nodiscard]]
constexpr ox::StringView srcTypeName() const noexcept final { constexpr ox::StringView srcTypeName() const noexcept override {
return ox::ModelTypeName_v<SrcType>; return ox::ModelTypeName_v<SrcType>;
} }
[[nodiscard]] [[nodiscard]]
constexpr int srcTypeVersion() const noexcept final { constexpr int srcTypeVersion() const noexcept override {
return ox::ModelTypeVersion_v<SrcType>; return ox::ModelTypeVersion_v<SrcType>;
} }
[[nodiscard]] [[nodiscard]]
constexpr bool srcMatches(ox::StringViewCR pSrcTypeName, int pSrcTypeVersion) const noexcept final { constexpr bool srcMatches(ox::StringViewCR pSrcTypeName, int pSrcTypeVersion) const noexcept override {
constexpr auto SrcTypeName = ox::requireModelTypeName<SrcType>(); constexpr auto SrcTypeName = ox::requireModelTypeName<SrcType>();
constexpr auto SrcTypeVersion = ox::requireModelTypeVersion<SrcType>(); constexpr auto SrcTypeVersion = ox::requireModelTypeVersion<SrcType>();
return pSrcTypeName == SrcTypeName return pSrcTypeName == SrcTypeName
@ -147,7 +165,7 @@ class Converter: public BaseConverter {
} }
[[nodiscard]] [[nodiscard]]
constexpr bool dstMatches(ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept final { constexpr bool dstMatches(ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept override {
constexpr auto DstTypeName = ox::StringView{ox::requireModelTypeName<DstType>()}; constexpr auto DstTypeName = ox::StringView{ox::requireModelTypeName<DstType>()};
constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>(); constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
return dstTypeName == DstTypeName return dstTypeName == DstTypeName
@ -155,14 +173,14 @@ class Converter: public BaseConverter {
} }
ox::Result<ox::UPtr<Wrap>> convertPtrToPtr( ox::Result<ox::UPtr<Wrap>> convertPtrToPtr(
keel::Context &ctx, Wrap &src) const noexcept final { Context &ctx, Wrap &src) const noexcept override {
ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()}; ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()};
OX_RETURN_ERROR(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(*dst.value))); OX_RETURN_ERROR(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(*dst.value)));
return dst; return dst;
} }
ox::Result<ox::UPtr<Wrap>> convertBuffToPtr( ox::Result<ox::UPtr<Wrap>> convertBuffToPtr(
keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept final { Context &ctx, ox::BufferView const&srcBuff) const noexcept override {
OX_REQUIRE_M(src, readAsset<SrcType>(srcBuff)); OX_REQUIRE_M(src, readAsset<SrcType>(srcBuff));
ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()}; ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()};
OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst.value))); OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst.value)));
@ -170,24 +188,48 @@ class Converter: public BaseConverter {
} }
protected: protected:
virtual ox::Error convert(keel::Context &ctx, SrcType&, DstType&) const noexcept = 0; static ox::Error convert(Context &ctx, SrcType &src, DstType &dst) noexcept {
return Func(ctx, src, dst);
}
}; };
class Converter {
private:
ox::AllocAlias<BaseConverter> m_buff{};
BaseConverter *m_conv{};
public:
template<auto Func>
static Converter make() noexcept {
Converter out;
static_assert(sizeof(ConverterFunc<Func>) <= sizeof(out.m_buff));
out.m_conv = new (out.m_buff.data()) ConverterFunc<Func>{};
return out;
}
constexpr Converter() {}
Converter(Converter const &other) noexcept:
m_buff{other.m_buff},
m_conv{m_buff.data()} {}
[[nodiscard]]
BaseConverter const *converter() const noexcept {
return m_conv;
}
};
ox::Result<ox::UPtr<Wrap>> convert( ox::Result<ox::UPtr<Wrap>> convert(
keel::Context &ctx, Context &ctx,
ox::BufferView const&srcBuffer, ox::BufferView const&srcBuffer,
ox::StringViewCR dstTypeName, ox::StringViewCR dstTypeName,
int dstTypeVersion) noexcept; int dstTypeVersion) noexcept;
ox::Result<ox::UPtr<Wrap>> convert( ox::Result<ox::UPtr<Wrap>> convert(
keel::Context &ctx, Context &ctx,
Wrap &src, Wrap &src,
ox::StringViewCR dstTypeName, ox::StringViewCR dstTypeName,
int dstTypeVersion) noexcept; int dstTypeVersion) noexcept;
ox::Result<ox::UPtr<Wrap>> convert( ox::Result<ox::UPtr<Wrap>> convert(
keel::Context &ctx, Context &ctx,
auto &src, auto &src,
ox::StringViewCR dstTypeName, ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept { int const dstTypeVersion) noexcept {
@ -196,7 +238,7 @@ ox::Result<ox::UPtr<Wrap>> convert(
} }
ox::Result<ox::UPtr<Wrap>> convert( ox::Result<ox::UPtr<Wrap>> convert(
keel::Context &ctx, Context &ctx,
auto const&src, auto const&src,
ox::StringViewCR dstTypeName, ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept { int const dstTypeVersion) noexcept {
@ -207,27 +249,27 @@ ox::Result<ox::UPtr<Wrap>> convert(
template<typename DstType> template<typename DstType>
ox::Result<DstType> convertObjToObj( ox::Result<DstType> convertObjToObj(
keel::Context &ctx, Context &ctx,
auto &src) noexcept { auto &src) noexcept {
OX_REQUIRE_M(out, convert(ctx, WrapRef{src}, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>)); OX_REQUIRE_M(out, convert(ctx, WrapRef{src}, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
return std::move(wrapCast(*out)); return std::move(wrapCast(*out));
} }
template<typename DstType> template<typename DstType>
ox::Result<DstType> convert(keel::Context &ctx, ox::BufferView const&src) noexcept { ox::Result<DstType> convert(Context &ctx, ox::BufferView const&src) noexcept {
OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>)); OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
return std::move(wrapCast<DstType>(out)); return std::move(wrapCast<DstType>(out));
} }
template<typename DstType> template<typename DstType>
ox::Error convert(keel::Context &ctx, ox::BufferView const&buff, DstType &outObj) noexcept { ox::Error convert(Context &ctx, ox::BufferView const&buff, DstType &outObj) noexcept {
OX_REQUIRE(out, convert(ctx, buff, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>)); OX_REQUIRE(out, convert(ctx, buff, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
outObj = std::move(wrapCast<DstType>(*out)); outObj = std::move(wrapCast<DstType>(*out));
return {}; return {};
} }
template<typename DstType> template<typename DstType>
ox::Error convertObjToObj(keel::Context &ctx, auto &src, DstType &outObj) noexcept { ox::Error convertObjToObj(Context &ctx, auto &src, DstType &outObj) noexcept {
OX_REQUIRE(outPtr, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>)); OX_REQUIRE(outPtr, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
outObj = std::move(wrapCast<DstType>(*outPtr)); outObj = std::move(wrapCast<DstType>(*outPtr));
return {}; return {};
@ -235,13 +277,13 @@ ox::Error convertObjToObj(keel::Context &ctx, auto &src, DstType &outObj) noexce
template<typename DstType> template<typename DstType>
ox::Result<ox::Buffer> convertBuffToBuff( ox::Result<ox::Buffer> convertBuffToBuff(
keel::Context &ctx, ox::BufferView const&src, ox::ClawFormat const fmt) noexcept { Context &ctx, ox::BufferView const&src, ox::ClawFormat const fmt) noexcept {
OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>)); OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
return ox::writeClaw<DstType>(wrapCast<DstType>(*out), fmt); return ox::writeClaw<DstType>(wrapCast<DstType>(*out), fmt);
} }
template<typename From, typename To, ox::ClawFormat fmt = ox::ClawFormat::Metal> template<typename From, typename To, ox::ClawFormat fmt = ox::ClawFormat::Metal>
ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) noexcept { ox::Result<bool> transformRule(Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) noexcept {
if (typeId == ox::ModelTypeId_v<From>) { if (typeId == ox::ModelTypeId_v<From>) {
OX_RETURN_ERROR(keel::convertBuffToBuff<To>(ctx, buff, fmt).moveTo(buff)); OX_RETURN_ERROR(keel::convertBuffToBuff<To>(ctx, buff, fmt).moveTo(buff));
return true; return true;
@ -249,4 +291,6 @@ ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringV
return false; return false;
}; };
using PackTransform = ox::Result<bool>(*)(Context&, ox::Buffer &clawData, ox::StringViewCR);
} }

View File

@ -24,7 +24,7 @@ ox::Vector<TypeDescGenerator> Module::types() const noexcept {
return {}; return {};
} }
ox::Vector<keel::BaseConverter const*> Module::converters() const noexcept { ox::Vector<Converter> Module::converters() const noexcept {
return {}; return {};
} }

View File

@ -2,20 +2,21 @@
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/ */
#include <keel/context.hpp>
#include <keel/media.hpp> #include <keel/media.hpp>
#include <keel/typeconv.hpp> #include <keel/typeconv.hpp>
namespace keel { namespace keel {
static ox::Result<BaseConverter const*> findConverter( static ox::Result<BaseConverter const*> findConverter(
ox::SpanView<BaseConverter const*> const&converters, ox::SpanView<Converter> const&converters,
ox::StringViewCR srcTypeName, ox::StringViewCR srcTypeName,
int const srcTypeVersion, int const srcTypeVersion,
ox::StringViewCR dstTypeName, ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept { int const dstTypeVersion) noexcept {
for (auto const&c : converters) { for (auto const&c : converters) {
if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) { if (c.converter()->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) {
return c; return c.converter();
} }
} }
return ox::Error{1, "Could not find converter"}; return ox::Error{1, "Could not find converter"};
@ -31,7 +32,7 @@ static ox::Result<ox::UPtr<Wrap>> convert(BaseConverter const&c, Context &ctx, W
static ox::Result<ox::UPtr<Wrap>> convert( static ox::Result<ox::UPtr<Wrap>> convert(
Context &ctx, Context &ctx,
ox::SpanView<BaseConverter const*> const&converters, ox::SpanView<Converter> const&converters,
auto &src, auto &src,
ox::StringViewCR srcTypeName, ox::StringViewCR srcTypeName,
int const srcTypeVersion, int const srcTypeVersion,
@ -45,14 +46,14 @@ static ox::Result<ox::UPtr<Wrap>> convert(
} }
// try to chain multiple converters // try to chain multiple converters
for (auto const&subConverter : converters) { for (auto const&subConverter : converters) {
if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) { if (!subConverter.converter()->dstMatches(dstTypeName, dstTypeVersion)) {
continue; continue;
} }
const auto [intermediate, chainErr] = const auto [intermediate, chainErr] =
convert(ctx, converters, src, srcTypeName, srcTypeVersion, convert(ctx, converters, src, srcTypeName, srcTypeVersion,
subConverter->srcTypeName(), subConverter->srcTypeVersion()); subConverter.converter()->srcTypeName(), subConverter.converter()->srcTypeVersion());
if (!chainErr) { if (!chainErr) {
return subConverter->convertPtrToPtr(ctx, *intermediate); return subConverter.converter()->convertPtrToPtr(ctx, *intermediate);
} }
} }
return ox::Error{1, "Could not convert between types"}; return ox::Error{1, "Could not convert between types"};