From e598e7fe27e61d6ac0f164da3225826bde3c61af Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 15 Jan 2025 23:44:18 -0600 Subject: [PATCH] [nostalgia,keel] Add ability to types Obj to Obj --- .../modules/core/src/keel/keelmodule.cpp | 4 +- src/olympic/keel/include/keel/context.hpp | 2 +- src/olympic/keel/include/keel/media.hpp | 2 +- src/olympic/keel/include/keel/typeconv.hpp | 118 +++++++++++++----- src/olympic/keel/src/typeconv.cpp | 49 ++++++-- 5 files changed, 130 insertions(+), 45 deletions(-) diff --git a/src/nostalgia/modules/core/src/keel/keelmodule.cpp b/src/nostalgia/modules/core/src/keel/keelmodule.cpp index 8f788d64..e56d90d2 100644 --- a/src/nostalgia/modules/core/src/keel/keelmodule.cpp +++ b/src/nostalgia/modules/core/src/keel/keelmodule.cpp @@ -67,7 +67,7 @@ static class: public keel::Module { ox::Vector packTransforms() const noexcept final { return { // convert tilesheets to CompactTileSheets - [](keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) -> ox::Result { + [](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) -> ox::Result { if (typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || @@ -78,7 +78,7 @@ static class: public keel::Module { } return false; }, - [](keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) -> ox::Result { + [](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) -> ox::Result { if (typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || diff --git a/src/olympic/keel/include/keel/context.hpp b/src/olympic/keel/include/keel/context.hpp index a64fd610..b128bbf0 100644 --- a/src/olympic/keel/include/keel/context.hpp +++ b/src/olympic/keel/include/keel/context.hpp @@ -12,7 +12,7 @@ namespace keel { class Context; -using PackTransform = ox::Result(*)(Context&, ox::Buffer &clawData, ox::StringView); +using PackTransform = ox::Result(*)(Context&, ox::Buffer &clawData, ox::StringViewCR); class Context { public: diff --git a/src/olympic/keel/include/keel/media.hpp b/src/olympic/keel/include/keel/media.hpp index 7accfae9..069e202b 100644 --- a/src/olympic/keel/include/keel/media.hpp +++ b/src/olympic/keel/include/keel/media.hpp @@ -70,7 +70,7 @@ constexpr auto makeLoader(Context &ctx) { if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) { return err; } - OX_RETURN_ERROR(convert(ctx, buff, &obj)); + OX_RETURN_ERROR(convert(ctx, buff, obj)); } return std::move(obj); }; diff --git a/src/olympic/keel/include/keel/typeconv.hpp b/src/olympic/keel/include/keel/typeconv.hpp index 7041e250..3d9ea007 100644 --- a/src/olympic/keel/include/keel/typeconv.hpp +++ b/src/olympic/keel/include/keel/typeconv.hpp @@ -16,10 +16,43 @@ namespace keel { class Wrap { public: virtual ~Wrap() = default; + [[nodiscard]] + virtual ox::CStringView typeName() const noexcept = 0; + [[nodiscard]] + virtual int typeVersion() const noexcept = 0; }; template -class WrapInline: public Wrap { +class WrapT: public Wrap { + public: + [[nodiscard]] + virtual constexpr T &obj() noexcept = 0; +}; + +template +class WrapRef final: public WrapT { + private: + T &m_obj; + + public: + constexpr explicit WrapRef(T &obj): m_obj{obj} {} + + ox::CStringView typeName() const noexcept override { + return ox::ModelTypeName_v; + } + + int typeVersion() const noexcept override { + return ox::ModelTypeVersion_v; + } + + constexpr T &obj() noexcept override { + return m_obj; + } + +}; + +template +class WrapInline final: public WrapT { private: T m_obj; @@ -30,8 +63,15 @@ class WrapInline: public Wrap { constexpr explicit WrapInline(Args &&...args): m_obj(ox::forward(args)...) { } - [[nodiscard]] - constexpr T &obj() noexcept { + ox::CStringView typeName() const noexcept override { + return ox::ModelTypeName_v; + } + + int typeVersion() const noexcept override { + return ox::ModelTypeVersion_v; + } + + constexpr T &obj() noexcept override { return m_obj; } @@ -44,7 +84,7 @@ constexpr ox::UPtr makeWrap(Args &&...args) noexcept { template constexpr T &wrapCast(Wrap &ptr) noexcept { - return static_cast&>(ptr).obj(); + return static_cast&>(ptr).obj(); } class BaseConverter { @@ -70,10 +110,10 @@ class BaseConverter { [[nodiscard]] constexpr bool matches( - ox::StringViewCR srcTypeName, int srcTypeVersion, - ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept { + ox::StringViewCR srcTypeName, int const srcTypeVersion, + ox::StringViewCR dstTypeName, int const dstTypeVersion) const noexcept { return srcMatches(srcTypeName, srcTypeVersion) - && dstMatches(dstTypeName, dstTypeVersion); + && dstMatches(dstTypeName, dstTypeVersion); } }; @@ -109,17 +149,17 @@ class Converter: public BaseConverter { ox::Result> convertPtrToPtr( keel::Context &ctx, Wrap &src) const noexcept final { - auto dst = makeWrap(); - OX_RETURN_ERROR(convert(ctx, wrapCast(src), wrapCast(*dst))); - return {std::move(dst)}; + ox::Result> dst{makeWrap()}; + OX_RETURN_ERROR(convert(ctx, wrapCast(src), wrapCast(*dst.value))); + return dst; } ox::Result> convertBuffToPtr( keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept final { OX_REQUIRE_M(src, readAsset(srcBuff)); - auto dst = makeWrap(); - OX_RETURN_ERROR(convert(ctx, src, wrapCast(*dst))); - return {std::move(dst)}; + ox::Result> dst{makeWrap()}; + OX_RETURN_ERROR(convert(ctx, src, wrapCast(*dst.value))); + return dst; } protected: @@ -133,34 +173,57 @@ ox::Result> convert( ox::StringViewCR dstTypeName, int dstTypeVersion) noexcept; +ox::Result> convert( + keel::Context &ctx, + Wrap &src, + ox::StringViewCR dstTypeName, + int dstTypeVersion) noexcept; + +ox::Result> convert( + keel::Context &ctx, + auto &src, + ox::StringViewCR dstTypeName, + int const dstTypeVersion) noexcept { + return convert(ctx, WrapRef{src}, dstTypeName, dstTypeVersion); +} + template -ox::Result convert(keel::Context &ctx, ox::BufferView const&srcBuffer) noexcept { - static constexpr auto DstTypeName = ox::requireModelTypeName(); - static constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); - OX_REQUIRE(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion)); +ox::Result convertObjToObj( + keel::Context &ctx, + auto &src) noexcept { + OX_REQUIRE_M(out, convert(ctx, WrapRef{src}, ox::ModelTypeName_v, ox::ModelTypeVersion_v)); + return std::move(wrapCast(*out)); +} + +template +ox::Result convert(keel::Context &ctx, ox::BufferView const&src) noexcept { + OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v, ox::ModelTypeVersion_v)); return std::move(wrapCast(out)); } template -ox::Error convert(keel::Context &ctx, ox::BufferView const&buff, DstType *outObj) noexcept { - static constexpr auto DstTypeName = ox::requireModelTypeName(); - static constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); - OX_REQUIRE(outPtr, convert(ctx, buff, DstTypeName, DstTypeVersion)); - *outObj = std::move(wrapCast(*outPtr)); +ox::Error convert(keel::Context &ctx, ox::BufferView const&buff, DstType &outObj) noexcept { + OX_REQUIRE(out, convert(ctx, buff, ox::ModelTypeName_v, ox::ModelTypeVersion_v)); + outObj = std::move(wrapCast(*out)); + return {}; +} + +template +ox::Error convertObjToObj(keel::Context &ctx, auto &src, DstType &outObj) noexcept { + OX_REQUIRE(outPtr, convert(ctx, src, ox::ModelTypeName_v, ox::ModelTypeVersion_v)); + outObj = std::move(wrapCast(*outPtr)); return {}; } template ox::Result convertBuffToBuff( - keel::Context &ctx, ox::BufferView const&srcBuffer, ox::ClawFormat fmt) noexcept { - static constexpr auto DstTypeName = ox::requireModelTypeName(); - static constexpr auto DstTypeVersion = ox::requireModelTypeVersion(); - OX_REQUIRE(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion)); + keel::Context &ctx, ox::BufferView const&src, ox::ClawFormat const fmt) noexcept { + OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v, ox::ModelTypeVersion_v)); return ox::writeClaw(wrapCast(*out), fmt); } template -ox::Result transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) noexcept { +ox::Result transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) noexcept { if (typeId == ox::ModelTypeId_v) { OX_RETURN_ERROR(keel::convertBuffToBuff(ctx, buff, fmt).moveTo(buff)); return true; @@ -168,5 +231,4 @@ ox::Result transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringV return false; }; - } diff --git a/src/olympic/keel/src/typeconv.cpp b/src/olympic/keel/src/typeconv.cpp index aeb598b9..531e7370 100644 --- a/src/olympic/keel/src/typeconv.cpp +++ b/src/olympic/keel/src/typeconv.cpp @@ -10,30 +10,38 @@ namespace keel { static ox::Result findConverter( ox::SpanView const&converters, ox::StringViewCR srcTypeName, - int srcTypeVersion, + int const srcTypeVersion, ox::StringViewCR dstTypeName, - int dstTypeVersion) noexcept { + int const dstTypeVersion) noexcept { for (auto const&c : converters) { if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) { return c; } } - return ox::Error(1, "Could not find converter"); + return ox::Error{1, "Could not find converter"}; }; +static ox::Result> convert(BaseConverter const&c, Context &ctx, ox::BufferView const&src) noexcept { + return c.convertBuffToPtr(ctx, src); +} + +static ox::Result> convert(BaseConverter const&c, Context &ctx, Wrap &src) noexcept { + return c.convertPtrToPtr(ctx, src); +} + static ox::Result> convert( - keel::Context &ctx, + Context &ctx, ox::SpanView const&converters, - ox::BufferView const&srcBuffer, + auto &src, ox::StringViewCR srcTypeName, - int srcTypeVersion, + int const srcTypeVersion, ox::StringViewCR dstTypeName, - int dstTypeVersion) noexcept { + int const dstTypeVersion) noexcept { // look for direct converter - auto [c, err] = findConverter( + auto const [c, err] = findConverter( converters, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); if (!err) { - return c->convertBuffToPtr(ctx, srcBuffer); + return convert(*c, ctx, src); } // try to chain multiple converters for (auto const&subConverter : converters) { @@ -41,20 +49,20 @@ static ox::Result> convert( continue; } const auto [intermediate, chainErr] = - convert(ctx, converters, srcBuffer, srcTypeName, srcTypeVersion, + convert(ctx, converters, src, srcTypeName, srcTypeVersion, subConverter->srcTypeName(), subConverter->srcTypeVersion()); if (!chainErr) { return subConverter->convertPtrToPtr(ctx, *intermediate); } } - return ox::Error(1, "Could not convert between types"); + return ox::Error{1, "Could not convert between types"}; } ox::Result> convert( - keel::Context &ctx, + Context &ctx, ox::BufferView const&srcBuffer, ox::StringViewCR dstTypeName, - int dstTypeVersion) noexcept { + int const dstTypeVersion) noexcept { OX_REQUIRE(hdr, readAssetHeader(srcBuffer)); return convert( ctx, @@ -66,4 +74,19 @@ ox::Result> convert( dstTypeVersion); } +ox::Result> convert( + Context &ctx, + Wrap &src, + ox::StringViewCR dstTypeName, + int const dstTypeVersion) noexcept { + return convert( + ctx, + converters(ctx), + src, + src.typeName(), + src.typeVersion(), + dstTypeName, + dstTypeVersion); +} + }