[keel,nostalgia] Further simplify writing type converters
Some checks failed
Build / build (push) Failing after 14s

This commit is contained in:
Gary Talent 2025-04-17 00:22:47 -05:00
parent 844656d557
commit 56b79f414d
8 changed files with 59 additions and 98 deletions

View File

@ -14,19 +14,6 @@
namespace nostalgia::gfx {
static class: public keel::Module {
private:
keel::ConverterFunc<ConvertNostalgiaPaletteToPaletteV1> m_nostalgiaPaletteToPaletteV1Converter;
keel::ConverterFunc<ConvertPaletteV1ToPaletteV2> m_paletteV1ToPaletteV2Converter;
keel::ConverterFunc<ConvertPaletteV2ToPaletteV3> m_paletteV2ToPaletteV3Converter;
keel::ConverterFunc<ConvertPaletteV3ToPaletteV4> m_paletteV3ToPaletteV4Converter;
keel::ConverterFunc<ConvertPaletteV4ToPaletteV5> m_paletteV4ToPaletteV5Converter;
keel::ConverterFunc<ConvertPaletteToCompactPalette> m_paletteToCompactPaletteConverter;
keel::ConverterFunc<ConvertTileSheetV1ToTileSheetV2> m_tileSheetV1ToTileSheetV2Converter;
keel::ConverterFunc<ConvertTileSheetV2ToTileSheetV3> m_tileSheetV2ToTileSheetV3Converter;
keel::ConverterFunc<ConvertTileSheetV3ToTileSheetV4> m_tileSheetV3ToTileSheetV4Converter;
keel::ConverterFunc<ConvertTileSheetV4ToTileSheetV5> m_tileSheetV4ToTileSheetV5Converter;
keel::ConverterFunc<ConvertTileSheetToCompactTileSheet>m_tileSheetToCompactTileSheetConverter;
public:
[[nodiscard]]
ox::String id() const noexcept override {
@ -52,19 +39,19 @@ static class: public keel::Module {
}
[[nodiscard]]
ox::Vector<keel::BaseConverter const*> converters() const noexcept final {
ox::Vector<keel::ConverterWrap> converters() const noexcept final {
return {
&m_nostalgiaPaletteToPaletteV1Converter,
&m_paletteV1ToPaletteV2Converter,
&m_paletteV2ToPaletteV3Converter,
&m_paletteV3ToPaletteV4Converter,
&m_paletteV4ToPaletteV5Converter,
&m_paletteToCompactPaletteConverter,
&m_tileSheetV1ToTileSheetV2Converter,
&m_tileSheetV2ToTileSheetV3Converter,
&m_tileSheetV3ToTileSheetV4Converter,
&m_tileSheetV4ToTileSheetV5Converter,
&m_tileSheetToCompactTileSheetConverter,
keel::ConverterWrap::make<ConvertNostalgiaPaletteToPaletteV1>(),
keel::ConverterWrap::make<ConvertPaletteV1ToPaletteV2>(),
keel::ConverterWrap::make<ConvertPaletteV2ToPaletteV3>(),
keel::ConverterWrap::make<ConvertPaletteV3ToPaletteV4>(),
keel::ConverterWrap::make<ConvertPaletteV4ToPaletteV5>(),
keel::ConverterWrap::make<ConvertPaletteToCompactPalette>(),
keel::ConverterWrap::make<ConvertTileSheetV1ToTileSheetV2>(),
keel::ConverterWrap::make<ConvertTileSheetV2ToTileSheetV3>(),
keel::ConverterWrap::make<ConvertTileSheetV3ToTileSheetV4>(),
keel::ConverterWrap::make<ConvertTileSheetV4ToTileSheetV5>(),
keel::ConverterWrap::make<ConvertTileSheetToCompactTileSheet>(),
};
}

View File

@ -16,10 +16,7 @@ namespace nostalgia::gfx {
// Type converters
ox::Error ConvertNostalgiaPaletteToPaletteV1(
keel::Context&,
NostalgiaPalette &src,
PaletteV1 &dst) noexcept;
ox::Error ConvertNostalgiaPaletteToPaletteV1(keel::Context&, NostalgiaPalette &src, PaletteV1 &dst) noexcept;
ox::Error ConvertPaletteV1ToPaletteV2(keel::Context&, PaletteV1 &src, PaletteV2 &dst) noexcept;

View File

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

View File

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

View File

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

View File

@ -9,10 +9,11 @@
#include <ox/std/string.hpp>
#include "asset.hpp"
#include "context.hpp"
namespace keel {
class Context;
class Wrap {
public:
virtual ~Wrap() = default;
@ -125,58 +126,9 @@ class BaseConverter {
};
template<typename SrcType, typename DstType>
class Converter: public BaseConverter {
public:
[[nodiscard]]
constexpr ox::StringView srcTypeName() const noexcept final {
return ox::ModelTypeName_v<SrcType>;
}
[[nodiscard]]
constexpr int srcTypeVersion() const noexcept final {
return ox::ModelTypeVersion_v<SrcType>;
}
[[nodiscard]]
constexpr bool srcMatches(ox::StringViewCR pSrcTypeName, int pSrcTypeVersion) const noexcept final {
constexpr auto SrcTypeName = ox::requireModelTypeName<SrcType>();
constexpr auto SrcTypeVersion = ox::requireModelTypeVersion<SrcType>();
return pSrcTypeName == SrcTypeName
&& pSrcTypeVersion == SrcTypeVersion;
}
[[nodiscard]]
constexpr bool dstMatches(ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept final {
constexpr auto DstTypeName = ox::StringView{ox::requireModelTypeName<DstType>()};
constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
return dstTypeName == DstTypeName
&& dstTypeVersion == DstTypeVersion;
}
ox::Result<ox::UPtr<Wrap>> convertPtrToPtr(
keel::Context &ctx, Wrap &src) const noexcept final {
ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()};
OX_RETURN_ERROR(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(*dst.value)));
return dst;
}
ox::Result<ox::UPtr<Wrap>> convertBuffToPtr(
keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept final {
OX_REQUIRE_M(src, readAsset<SrcType>(srcBuff));
ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()};
OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst.value)));
return dst;
}
protected:
virtual ox::Error convert(keel::Context &ctx, SrcType&, DstType&) const noexcept = 0;
};
template<auto Func>
class ConverterFunc: public BaseConverter {
class Converter: public BaseConverter {
private:
template<typename SrcType, typename DstType>
struct ParamExtractor {
@ -241,20 +193,42 @@ class ConverterFunc: public BaseConverter {
};
class ConverterWrap {
private:
ox::AllocAlias<BaseConverter> m_buff{};
BaseConverter *m_conv{};
public:
template<auto Func>
static ConverterWrap make() {
ConverterWrap out;
static_assert(sizeof(Converter<Func>) <= sizeof(out.m_buff));
out.m_conv = new (out.m_buff.data()) Converter<Func>{};
return out;
}
constexpr ConverterWrap() {}
ConverterWrap(ConverterWrap const &other):
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(
keel::Context &ctx,
Context &ctx,
ox::BufferView const&srcBuffer,
ox::StringViewCR dstTypeName,
int dstTypeVersion) noexcept;
ox::Result<ox::UPtr<Wrap>> convert(
keel::Context &ctx,
Context &ctx,
Wrap &src,
ox::StringViewCR dstTypeName,
int dstTypeVersion) noexcept;
ox::Result<ox::UPtr<Wrap>> convert(
keel::Context &ctx,
Context &ctx,
auto &src,
ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept {
@ -263,7 +237,7 @@ ox::Result<ox::UPtr<Wrap>> convert(
}
ox::Result<ox::UPtr<Wrap>> convert(
keel::Context &ctx,
Context &ctx,
auto const&src,
ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept {
@ -274,7 +248,7 @@ ox::Result<ox::UPtr<Wrap>> convert(
template<typename DstType>
ox::Result<DstType> convertObjToObj(
keel::Context &ctx,
Context &ctx,
auto &src) noexcept {
OX_REQUIRE_M(out, convert(ctx, WrapRef{src}, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
return std::move(wrapCast(*out));
@ -316,4 +290,6 @@ ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringV
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 {};
}
ox::Vector<keel::BaseConverter const*> Module::converters() const noexcept {
ox::Vector<ConverterWrap> Module::converters() const noexcept {
return {};
}

View File

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