[nostalgia/core] Fix unnecessary ox::String instantiations

This commit is contained in:
Gary Talent 2022-05-21 03:09:04 -05:00
parent 7a942ac83c
commit f6ebb5b29f
2 changed files with 70 additions and 56 deletions

View File

@ -46,7 +46,9 @@ static const auto converters = [] {
return converters; return converters;
}(); }();
static auto findConverter(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept -> ox::Result<BaseConverter*> { [[nodiscard]]
static auto findConverter(const char *srcTypeName, int srcTypeVersion,
const char *dstTypeName, int dstTypeVersion) noexcept -> ox::Result<BaseConverter*> {
for (auto &c : converters) { for (auto &c : converters) {
if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) { if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) {
return c.get(); return c.get();
@ -55,10 +57,11 @@ static auto findConverter(const ox::String &srcTypeName, int srcTypeVersion, con
return OxError(1, "Could not find converter"); return OxError(1, "Could not find converter");
}; };
ox::Result<ClawObjPtr> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion) noexcept { static ox::Result<WrapPtr> convert(const ox::Buffer &srcBuffer,
oxRequire(hdr, ox::readClawHeader(srcBuffer)); const char *srcTypeName, int srcTypeVersion,
const char *dstTypeName, int dstTypeVersion) noexcept {
// look for direct converter // look for direct converter
auto [c, err] = findConverter(hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion); auto [c, err] = findConverter(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion);
if (!err) { if (!err) {
return c->convertBuffToPtr(srcBuffer); return c->convertBuffToPtr(srcBuffer);
} }
@ -76,6 +79,11 @@ ox::Result<ClawObjPtr> convert(const ox::Buffer &srcBuffer, const ox::String &ds
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 {
oxRequire(hdr, ox::readClawHeader(srcBuffer));
return convert(srcBuffer, hdr.typeName.c_str(), hdr.typeVersion, dstTypeName, dstTypeVersion);
}
#endif #endif
} }

View File

@ -14,116 +14,122 @@
namespace nostalgia::core { namespace nostalgia::core {
class ModelContainer { class Wrap {
public: public:
virtual ~ModelContainer() = default; virtual ~Wrap() = default;
virtual void *obj() noexcept = 0;
virtual const char *typeName() noexcept = 0;
virtual int typeVersion() noexcept = 0;
}; };
template<typename T> template<typename T>
class ModelContainerTemplate: public ModelContainer { class WrapTemplate: public Wrap {
private: private:
T m_obj; T m_obj;
public: public:
constexpr ModelContainerTemplate() = default; constexpr WrapTemplate() = default;
void *obj() noexcept final { [[nodiscard]]
constexpr auto obj() noexcept {
return &m_obj; return &m_obj;
} }
const char *typeName() noexcept final {
return T::TypeName;
}
int typeVersion() noexcept final {
return T::TypeVersion;
}
}; };
using ClawObjPtr = ox::UniquePtr<ModelContainer>; using WrapPtr = ox::UniquePtr<Wrap>;
template<typename T>
constexpr auto wrapCast(const auto &ptr) noexcept {
return static_cast<WrapTemplate<T>*>(ptr.get())->obj();
}
struct BaseConverter { struct BaseConverter {
virtual ~BaseConverter() noexcept = default; virtual ~BaseConverter() noexcept = default;
[[nodiscard]] [[nodiscard]]
virtual ox::String srcTypeName() noexcept = 0; virtual const char *srcTypeName() noexcept = 0;
[[nodiscard]] [[nodiscard]]
virtual int srcTypeVersion() noexcept = 0; virtual int srcTypeVersion() noexcept = 0;
[[nodiscard]] [[nodiscard]]
virtual bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0; virtual bool srcMatches(const char *srcTypeName, int srcTypeVersion) const noexcept = 0;
[[nodiscard]] [[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<ClawObjPtr> convertPtrToPtr(const ClawObjPtr &src) noexcept = 0; virtual ox::Result<WrapPtr> convertPtrToPtr(const WrapPtr &src) noexcept = 0;
virtual ox::Result<WrapPtr> 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<ClawObjPtr> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept = 0;
}; };
template<typename SrcType, typename DstType> template<typename SrcType, typename DstType>
struct Converter: public BaseConverter{ 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; return SrcType::TypeName;
} }
[[nodiscard]]
int srcTypeVersion() noexcept final { int srcTypeVersion() noexcept final {
return SrcType::TypeVersion; return SrcType::TypeVersion;
} }
bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept final { [[nodiscard]]
return dstTypeName == DstType::TypeName 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; && dstTypeVersion == DstType::TypeVersion;
} }
bool matches(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept final { ox::Result<WrapPtr> convertPtrToPtr(const WrapPtr &src) noexcept final {
return srcTypeName == SrcType::TypeName auto dst = ox::make_unique<WrapTemplate<DstType>>();
&& dstTypeName == DstType::TypeName oxReturnError(convert(wrapCast<SrcType>(src), wrapCast<DstType>(dst)));
&& srcTypeVersion == SrcType::TypeVersion return ox::Result<WrapPtr>(std::move(dst));
&& dstTypeVersion == DstType::TypeVersion;
} }
virtual ox::Error convert(SrcType*, DstType*) noexcept { ox::Result<WrapPtr> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept final {
return OxError(1);
}
ox::Result<ClawObjPtr> convertPtrToPtr(const ClawObjPtr &src) noexcept final {
auto dst = ox::make_unique<ModelContainerTemplate<DstType>>();
oxReturnError(convert(reinterpret_cast<SrcType *>(src->obj()), reinterpret_cast<DstType *>(dst->obj())));
return ox::Result<ClawObjPtr>(std::move(dst));
}
ox::Result<ClawObjPtr> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept final {
oxRequireM(src, ox::readClaw<SrcType>(srcBuff)); oxRequireM(src, ox::readClaw<SrcType>(srcBuff));
auto dst = ox::make_unique<ModelContainerTemplate<DstType>>(); auto dst = ox::make_unique<WrapTemplate<DstType>>();
oxReturnError(convert(&src, reinterpret_cast<DstType*>(dst->obj()))); oxReturnError(convert(&src, wrapCast<DstType>(dst)));
return ox::Result<ClawObjPtr>(std::move(dst)); return ox::Result<WrapPtr>(std::move(dst));
} }
}; };
ox::Result<ClawObjPtr> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion) noexcept; ox::Result<WrapPtr> convert(const ox::Buffer &srcBuffer, const char *dstTypeName, int dstTypeVersion) noexcept;
template<typename DstType> template<typename DstType>
ox::Result<ClawObjPtr> convert(const ox::Buffer &srcBuffer) noexcept { ox::Result<DstType> convert(const ox::Buffer &srcBuffer) noexcept {
return convert(srcBuffer, DstType::TypeName, DstType::TypeVersion); oxRequire(out, convert(srcBuffer, DstType::TypeName, DstType::TypeVersion));
return wrapCast<DstType>(out);
} }
template<typename T> template<typename T>
ox::Error convert(const ox::Buffer &buff, T *outObj) noexcept { ox::Error convert(const ox::Buffer &buff, T *outObj) noexcept {
oxRequireM(outPtr, convert(buff, T::TypeName, T::TypeVersion)); oxRequire(outPtr, convert(buff, T::TypeName, T::TypeVersion));
*outObj = std::move(*reinterpret_cast<T*>(outPtr->obj())); *outObj = std::move(*wrapCast<T>(outPtr));
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 {
oxRequireM(out, convert(srcBuffer, DstType::TypeName, DstType::TypeVersion)); oxRequire(out, convert(srcBuffer, DstType::TypeName, DstType::TypeVersion));
return ox::writeClaw<DstType>(reinterpret_cast<DstType*>(out->obj()), fmt); return ox::writeClaw<DstType>(wrapCast<DstType>(out), fmt);
} }
} }