diff --git a/src/nostalgia/core/typeconv.cpp b/src/nostalgia/core/typeconv.cpp index dabe413a..3226b974 100644 --- a/src/nostalgia/core/typeconv.cpp +++ b/src/nostalgia/core/typeconv.cpp @@ -46,7 +46,9 @@ static const auto converters = [] { return converters; }(); -static auto findConverter(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept -> ox::Result { +[[nodiscard]] +static auto findConverter(const char *srcTypeName, int srcTypeVersion, + const char *dstTypeName, int dstTypeVersion) noexcept -> ox::Result { for (auto &c : converters) { if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) { return c.get(); @@ -55,10 +57,11 @@ static auto findConverter(const ox::String &srcTypeName, int srcTypeVersion, con return OxError(1, "Could not find converter"); }; -ox::Result convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion) noexcept { - oxRequire(hdr, ox::readClawHeader(srcBuffer)); +static ox::Result convert(const ox::Buffer &srcBuffer, + const char *srcTypeName, int srcTypeVersion, + const char *dstTypeName, int dstTypeVersion) noexcept { // look for direct converter - auto [c, err] = findConverter(hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion); + auto [c, err] = findConverter(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); if (!err) { return c->convertBuffToPtr(srcBuffer); } @@ -68,7 +71,7 @@ ox::Result convert(const ox::Buffer &srcBuffer, const ox::String &ds continue; } const auto [intermediate, chainErr] = - convert(srcBuffer, subConverter->srcTypeName(), subConverter->srcTypeVersion()); + convert(srcBuffer, subConverter->srcTypeName(), subConverter->srcTypeVersion()); if (!chainErr) { return subConverter->convertPtrToPtr(intermediate); } @@ -76,6 +79,11 @@ ox::Result convert(const ox::Buffer &srcBuffer, const ox::String &ds return OxError(1, "Could not convert between types"); } +ox::Result convert(const ox::Buffer &srcBuffer, const char *dstTypeName, int dstTypeVersion) noexcept { + oxRequire(hdr, ox::readClawHeader(srcBuffer)); + return convert(srcBuffer, hdr.typeName.c_str(), hdr.typeVersion, dstTypeName, dstTypeVersion); +} + #endif } diff --git a/src/nostalgia/core/typeconv.hpp b/src/nostalgia/core/typeconv.hpp index d2b497a9..9f773741 100644 --- a/src/nostalgia/core/typeconv.hpp +++ b/src/nostalgia/core/typeconv.hpp @@ -14,116 +14,122 @@ namespace nostalgia::core { -class ModelContainer { +class Wrap { public: - virtual ~ModelContainer() = default; - virtual void *obj() noexcept = 0; - virtual const char *typeName() noexcept = 0; - virtual int typeVersion() noexcept = 0; + virtual ~Wrap() = default; }; template -class ModelContainerTemplate: public ModelContainer { +class WrapTemplate: public Wrap { private: T m_obj; public: - constexpr ModelContainerTemplate() = default; + constexpr WrapTemplate() = default; - void *obj() noexcept final { + [[nodiscard]] + constexpr auto obj() noexcept { return &m_obj; } - const char *typeName() noexcept final { - return T::TypeName; - } - - int typeVersion() noexcept final { - return T::TypeVersion; - } - }; -using ClawObjPtr = ox::UniquePtr; +using WrapPtr = ox::UniquePtr; + +template +constexpr auto wrapCast(const auto &ptr) noexcept { + return static_cast*>(ptr.get())->obj(); +} struct BaseConverter { virtual ~BaseConverter() noexcept = default; [[nodiscard]] - virtual ox::String srcTypeName() noexcept = 0; + virtual const char *srcTypeName() noexcept = 0; [[nodiscard]] virtual int srcTypeVersion() noexcept = 0; [[nodiscard]] - virtual bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0; + virtual bool srcMatches(const char *srcTypeName, int srcTypeVersion) const noexcept = 0; [[nodiscard]] - virtual bool matches(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0; + virtual bool dstMatches(const char *dstTypeName, int dstTypeVersion) const noexcept = 0; - virtual ox::Result convertPtrToPtr(const ClawObjPtr &src) noexcept = 0; + virtual ox::Result convertPtrToPtr(const WrapPtr &src) noexcept = 0; + + virtual ox::Result convertBuffToPtr(const ox::Buffer &srcBuff) noexcept = 0; + + [[nodiscard]] + inline bool matches(const char *srcTypeName, int srcTypeVersion, + const char *dstTypeName, int dstTypeVersion) const noexcept { + return srcMatches(srcTypeName, srcTypeVersion) + && dstMatches(dstTypeName, dstTypeVersion); + } - virtual ox::Result convertBuffToPtr(const ox::Buffer &srcBuff) noexcept = 0; }; template struct Converter: public BaseConverter{ - ox::String srcTypeName() noexcept final { + + virtual ox::Error convert(SrcType*, DstType*) noexcept = 0; + + [[nodiscard]] + const char *srcTypeName() noexcept final { return SrcType::TypeName; } + [[nodiscard]] int srcTypeVersion() noexcept final { return SrcType::TypeVersion; } - bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept final { - return dstTypeName == DstType::TypeName + [[nodiscard]] + bool srcMatches(const char *srcTypeName, int srcTypeVersion) const noexcept final { + return ox_strcmp(srcTypeName, SrcType::TypeName) == 0 + && srcTypeVersion == SrcType::TypeVersion; + } + + [[nodiscard]] + bool dstMatches(const char *dstTypeName, int dstTypeVersion) const noexcept final { + return ox_strcmp(dstTypeName, DstType::TypeName) == 0 && dstTypeVersion == DstType::TypeVersion; } - bool matches(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept final { - return srcTypeName == SrcType::TypeName - && dstTypeName == DstType::TypeName - && srcTypeVersion == SrcType::TypeVersion - && dstTypeVersion == DstType::TypeVersion; + ox::Result convertPtrToPtr(const WrapPtr &src) noexcept final { + auto dst = ox::make_unique>(); + oxReturnError(convert(wrapCast(src), wrapCast(dst))); + return ox::Result(std::move(dst)); } - virtual ox::Error convert(SrcType*, DstType*) noexcept { - return OxError(1); - } - - ox::Result convertPtrToPtr(const ClawObjPtr &src) noexcept final { - auto dst = ox::make_unique>(); - oxReturnError(convert(reinterpret_cast(src->obj()), reinterpret_cast(dst->obj()))); - return ox::Result(std::move(dst)); - } - - ox::Result convertBuffToPtr(const ox::Buffer &srcBuff) noexcept final { + ox::Result convertBuffToPtr(const ox::Buffer &srcBuff) noexcept final { oxRequireM(src, ox::readClaw(srcBuff)); - auto dst = ox::make_unique>(); - oxReturnError(convert(&src, reinterpret_cast(dst->obj()))); - return ox::Result(std::move(dst)); + auto dst = ox::make_unique>(); + oxReturnError(convert(&src, wrapCast(dst))); + return ox::Result(std::move(dst)); } + }; -ox::Result convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion) noexcept; +ox::Result convert(const ox::Buffer &srcBuffer, const char *dstTypeName, int dstTypeVersion) noexcept; template -ox::Result convert(const ox::Buffer &srcBuffer) noexcept { - return convert(srcBuffer, DstType::TypeName, DstType::TypeVersion); +ox::Result convert(const ox::Buffer &srcBuffer) noexcept { + oxRequire(out, convert(srcBuffer, DstType::TypeName, DstType::TypeVersion)); + return wrapCast(out); } template ox::Error convert(const ox::Buffer &buff, T *outObj) noexcept { - oxRequireM(outPtr, convert(buff, T::TypeName, T::TypeVersion)); - *outObj = std::move(*reinterpret_cast(outPtr->obj())); + oxRequire(outPtr, convert(buff, T::TypeName, T::TypeVersion)); + *outObj = std::move(*wrapCast(outPtr)); return OxError(0); } template ox::Result convertBuffToBuff(const ox::Buffer &srcBuffer, ox::ClawFormat fmt) noexcept { - oxRequireM(out, convert(srcBuffer, DstType::TypeName, DstType::TypeVersion)); - return ox::writeClaw(reinterpret_cast(out->obj()), fmt); + oxRequire(out, convert(srcBuffer, DstType::TypeName, DstType::TypeVersion)); + return ox::writeClaw(wrapCast(out), fmt); } }