[nostalgia/core] Make type conv system access type info correctly

This commit is contained in:
Gary Talent 2022-05-25 01:58:11 -05:00
parent a8244b9313
commit 9ad5771767
2 changed files with 58 additions and 38 deletions

View File

@ -4,6 +4,8 @@
#include <ox/claw/read.hpp> #include <ox/claw/read.hpp>
#include "gfx.hpp"
#include "typeconv.hpp" #include "typeconv.hpp"
namespace nostalgia::core { namespace nostalgia::core {
@ -57,9 +59,9 @@ static auto findConverter(const char *srcTypeName, int srcTypeVersion,
return OxError(1, "Could not find converter"); return OxError(1, "Could not find converter");
}; };
static ox::Result<WrapPtr> convert(const ox::Buffer &srcBuffer, static ox::Result<ox::UniquePtr<Wrap>> convert(const ox::Buffer &srcBuffer,
const char *srcTypeName, int srcTypeVersion, const char *srcTypeName, int srcTypeVersion,
const char *dstTypeName, int dstTypeVersion) noexcept { const char *dstTypeName, int dstTypeVersion) noexcept {
// look for direct converter // look for direct converter
auto [c, err] = findConverter(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); auto [c, err] = findConverter(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion);
if (!err) { if (!err) {
@ -71,15 +73,16 @@ static ox::Result<WrapPtr> convert(const ox::Buffer &srcBuffer,
continue; continue;
} }
const auto [intermediate, chainErr] = const auto [intermediate, chainErr] =
convert(srcBuffer, subConverter->srcTypeName(), subConverter->srcTypeVersion()); convert(srcBuffer, srcTypeName, srcTypeVersion,
subConverter->srcTypeName(), subConverter->srcTypeVersion());
if (!chainErr) { if (!chainErr) {
return subConverter->convertPtrToPtr(intermediate); return subConverter->convertPtrToPtr(intermediate.get());
} }
} }
return OxError(1, "Could not convert between types"); return OxError(1, "Could not convert between types");
} }
ox::Result<WrapPtr> convert(const ox::Buffer &srcBuffer, const char *dstTypeName, int dstTypeVersion) noexcept { ox::Result<ox::UniquePtr<Wrap>> convert(const ox::Buffer &srcBuffer, const char *dstTypeName, int dstTypeVersion) noexcept {
oxRequire(hdr, ox::readClawHeader(srcBuffer)); oxRequire(hdr, ox::readClawHeader(srcBuffer));
return convert(srcBuffer, hdr.typeName.c_str(), hdr.typeVersion, dstTypeName, dstTypeVersion); return convert(srcBuffer, hdr.typeName.c_str(), hdr.typeVersion, dstTypeName, dstTypeVersion);
} }

View File

@ -6,12 +6,11 @@
#include <ox/std/def.hpp> #include <ox/std/def.hpp>
#include <ox/std/error.hpp> #include <ox/std/error.hpp>
#include <ox/std/optional.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/claw/read.hpp>
#include <ox/claw/write.hpp> #include <ox/claw/write.hpp>
#include "gfx.hpp"
namespace nostalgia::core { namespace nostalgia::core {
class Wrap { class Wrap {
@ -20,12 +19,16 @@ class Wrap {
}; };
template<typename T> template<typename T>
class WrapTemplate: public Wrap { class WrapInline: public Wrap {
private: private:
T m_obj; T m_obj;
public: public:
constexpr WrapTemplate() = default; constexpr WrapInline() = default;
template<typename... Args>
constexpr explicit WrapInline(Args &&...args): m_obj(ox::forward<Args>(args)...) {
}
[[nodiscard]] [[nodiscard]]
constexpr auto obj() noexcept { constexpr auto obj() noexcept {
@ -34,11 +37,14 @@ class WrapTemplate: public Wrap {
}; };
using WrapPtr = ox::UniquePtr<Wrap>; template<typename T, typename... Args>
constexpr auto makeWrap(Args &&...args) noexcept {
return ox::make_unique<WrapInline<T>>(ox::forward<Args>(args)...);
}
template<typename T> template<typename T>
constexpr auto wrapCast(const auto &ptr) noexcept { constexpr auto wrapCast(auto ptr) noexcept {
return static_cast<WrapTemplate<T>*>(ptr.get())->obj(); return static_cast<WrapInline<T>*>(ptr)->obj();
} }
struct BaseConverter { struct BaseConverter {
@ -56,9 +62,9 @@ struct BaseConverter {
[[nodiscard]] [[nodiscard]]
virtual bool dstMatches(const char *dstTypeName, int dstTypeVersion) const noexcept = 0; virtual bool dstMatches(const char *dstTypeName, int dstTypeVersion) const noexcept = 0;
virtual ox::Result<WrapPtr> convertPtrToPtr(const WrapPtr &src) noexcept = 0; virtual ox::Result<ox::UniquePtr<Wrap>> convertPtrToPtr(Wrap *src) noexcept = 0;
virtual ox::Result<WrapPtr> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept = 0; virtual ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept = 0;
[[nodiscard]] [[nodiscard]]
inline bool matches(const char *srcTypeName, int srcTypeVersion, inline bool matches(const char *srcTypeName, int srcTypeVersion,
@ -76,60 +82,71 @@ struct Converter: public BaseConverter{
[[nodiscard]] [[nodiscard]]
const char *srcTypeName() noexcept final { const char *srcTypeName() noexcept final {
return SrcType::TypeName; return ox::requireModelTypeName<SrcType>();
} }
[[nodiscard]] [[nodiscard]]
int srcTypeVersion() noexcept final { int srcTypeVersion() noexcept final {
return SrcType::TypeVersion; return ox::requireModelTypeVersion<SrcType>();
} }
[[nodiscard]] [[nodiscard]]
bool srcMatches(const char *srcTypeName, int srcTypeVersion) const noexcept final { bool srcMatches(const char *srcTypeName, int srcTypeVersion) const noexcept final {
return ox_strcmp(srcTypeName, SrcType::TypeName) == 0 static constexpr auto SrcTypeName = ox::requireModelTypeName<SrcType>();
&& srcTypeVersion == SrcType::TypeVersion; static constexpr auto SrcTypeVersion = ox::requireModelTypeVersion<SrcType>();
return ox_strcmp(srcTypeName, SrcTypeName) == 0
&& srcTypeVersion == SrcTypeVersion;
} }
[[nodiscard]] [[nodiscard]]
bool dstMatches(const char *dstTypeName, int dstTypeVersion) const noexcept final { bool dstMatches(const char *dstTypeName, int dstTypeVersion) const noexcept final {
return ox_strcmp(dstTypeName, DstType::TypeName) == 0 static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
&& dstTypeVersion == DstType::TypeVersion; static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
return ox_strcmp(dstTypeName, DstTypeName) == 0
&& dstTypeVersion == DstTypeVersion;
} }
ox::Result<WrapPtr> convertPtrToPtr(const WrapPtr &src) noexcept final { ox::Result<ox::UniquePtr<Wrap>> convertPtrToPtr(Wrap *src) noexcept final {
auto dst = ox::make_unique<WrapTemplate<DstType>>(); auto dst = makeWrap<DstType>();
oxReturnError(convert(wrapCast<SrcType>(src), wrapCast<DstType>(dst))); oxReturnError(convert(wrapCast<SrcType>(src), wrapCast<DstType>(dst.get())));
return ox::Result<WrapPtr>(std::move(dst)); return ox::Result<ox::UniquePtr<Wrap>>(std::move(dst));
} }
ox::Result<WrapPtr> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept final { ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept final {
oxRequireM(src, ox::readClaw<SrcType>(srcBuff)); oxRequireM(src, ox::readClaw<SrcType>(srcBuff));
auto dst = ox::make_unique<WrapTemplate<DstType>>(); auto dst = makeWrap<DstType>();
oxReturnError(convert(&src, wrapCast<DstType>(dst))); oxReturnError(convert(&src, wrapCast<DstType>(dst.get())));
return ox::Result<WrapPtr>(std::move(dst)); return ox::Result<ox::UniquePtr<Wrap>>(std::move(dst));
} }
}; };
ox::Result<WrapPtr> convert(const ox::Buffer &srcBuffer, const char *dstTypeName, int dstTypeVersion) noexcept; ox::Result<ox::UniquePtr<Wrap>> convert(const ox::Buffer &srcBuffer,
const char *dstTypeName, int dstTypeVersion) noexcept;
template<typename DstType> template<typename DstType>
ox::Result<DstType> convert(const ox::Buffer &srcBuffer) noexcept { ox::Result<DstType> convert(const ox::Buffer &srcBuffer) noexcept {
oxRequire(out, convert(srcBuffer, DstType::TypeName, DstType::TypeVersion)); static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
oxRequire(out, convert(srcBuffer, DstTypeName, DstTypeVersion));
return wrapCast<DstType>(out); return wrapCast<DstType>(out);
} }
template<typename T> template<typename DstType>
ox::Error convert(const ox::Buffer &buff, T *outObj) noexcept { ox::Error convert(const ox::Buffer &buff, DstType *outObj) noexcept {
oxRequire(outPtr, convert(buff, T::TypeName, T::TypeVersion)); static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
*outObj = std::move(*wrapCast<T>(outPtr)); static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
oxRequire(outPtr, convert(buff, DstTypeName, DstTypeVersion));
*outObj = std::move(*wrapCast<DstType>(outPtr.get()));
return OxError(0); return OxError(0);
} }
template<typename DstType> template<typename DstType>
ox::Result<ox::Buffer> convertBuffToBuff(const ox::Buffer &srcBuffer, ox::ClawFormat fmt) noexcept { ox::Result<ox::Buffer> convertBuffToBuff(const ox::Buffer &srcBuffer, ox::ClawFormat fmt) noexcept {
oxRequire(out, convert(srcBuffer, DstType::TypeName, DstType::TypeVersion)); static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
return ox::writeClaw<DstType>(wrapCast<DstType>(out), fmt); static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
oxRequire(out, convert(srcBuffer, DstTypeName, DstTypeVersion));
return ox::writeClaw<DstType>(wrapCast<DstType>(out.get()), fmt);
} }
} }