[nostalgia/core] Remove unnecessary serialization and deserialization from type conversion

This commit is contained in:
Gary Talent 2022-05-19 22:23:49 -05:00
parent 4ee08441b0
commit 7a942ac83c
3 changed files with 66 additions and 30 deletions

View File

@ -55,22 +55,22 @@ 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<ox::Buffer> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion, ox::ClawFormat fmt) noexcept { ox::Result<ClawObjPtr> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion) noexcept {
oxRequire(hdr, ox::readClawHeader(srcBuffer)); oxRequire(hdr, ox::readClawHeader(srcBuffer));
// look for direct converter // look for direct converter
auto [c, err] = findConverter(hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion); auto [c, err] = findConverter(hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion);
if (!err) { if (!err) {
return c->convertBuffToBuff(srcBuffer); return c->convertBuffToPtr(srcBuffer);
} }
// try to chain multiple converters // try to chain multiple converters
for (const auto &subConverter : converters) { for (const auto &subConverter : converters) {
if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) { if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) {
continue; continue;
} }
const auto [intermediateBuff, chainErr] = const auto [intermediate, chainErr] =
convert(srcBuffer, subConverter->srcTypeName(), subConverter->srcTypeVersion(), fmt); convert(srcBuffer, subConverter->srcTypeName(), subConverter->srcTypeVersion());
if (!chainErr) { if (!chainErr) {
return subConverter->convertBuffToBuff(intermediateBuff, fmt); return subConverter->convertPtrToPtr(intermediate);
} }
} }
return OxError(1, "Could not convert between types"); return OxError(1, "Could not convert between types");

View File

@ -14,22 +14,56 @@
namespace nostalgia::core { namespace nostalgia::core {
class ModelContainer {
public:
virtual ~ModelContainer() = default;
virtual void *obj() noexcept = 0;
virtual const char *typeName() noexcept = 0;
virtual int typeVersion() noexcept = 0;
};
template<typename T>
class ModelContainerTemplate: public ModelContainer {
private:
T m_obj;
public:
constexpr ModelContainerTemplate() = default;
void *obj() noexcept final {
return &m_obj;
}
const char *typeName() noexcept final {
return T::TypeName;
}
int typeVersion() noexcept final {
return T::TypeVersion;
}
};
using ClawObjPtr = ox::UniquePtr<ModelContainer>;
struct BaseConverter { struct BaseConverter {
virtual ~BaseConverter() noexcept = default; virtual ~BaseConverter() noexcept = default;
[[nodiscard]]
virtual ox::String srcTypeName() noexcept = 0; virtual ox::String srcTypeName() noexcept = 0;
[[nodiscard]]
virtual int srcTypeVersion() noexcept = 0; virtual int srcTypeVersion() noexcept = 0;
virtual bool srcMatches(const ox::String &srcTypeName, int srcTypeVersion) noexcept = 0; [[nodiscard]]
virtual bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0; virtual bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0;
[[nodiscard]]
virtual bool matches(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0; virtual bool matches(const ox::String &srcTypeName, int srcTypeVersion, const ox::String &dstTypeName, int dstTypeVersion) noexcept = 0;
virtual ox::Error convertRaw(const ox::Buffer &pV1Buff, void *pV2) noexcept = 0; virtual ox::Result<ClawObjPtr> convertPtrToPtr(const ClawObjPtr &src) noexcept = 0;
virtual ox::Result<ox::Buffer> convertBuffToBuff(const ox::Buffer &srcBuff, ox::ClawFormat dstFmt = ox::ClawFormat::Metal) noexcept = 0; virtual ox::Result<ClawObjPtr> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept = 0;
}; };
template<typename SrcType, typename DstType> template<typename SrcType, typename DstType>
@ -42,11 +76,6 @@ struct Converter: public BaseConverter{
return SrcType::TypeVersion; return SrcType::TypeVersion;
} }
bool srcMatches(const ox::String &srcTypeName, int srcTypeVersion) noexcept final {
return srcTypeName == DstType::TypeName
&& srcTypeVersion == DstType::TypeVersion;
}
bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept final { bool dstMatches(const ox::String &dstTypeName, int dstTypeVersion) noexcept final {
return dstTypeName == DstType::TypeName return dstTypeName == DstType::TypeName
&& dstTypeVersion == DstType::TypeVersion; && dstTypeVersion == DstType::TypeVersion;
@ -63,31 +92,38 @@ struct Converter: public BaseConverter{
return OxError(1); return OxError(1);
} }
ox::Error convertRaw(const ox::Buffer &pV1Buff, void *pV2) noexcept override { ox::Result<ClawObjPtr> convertPtrToPtr(const ClawObjPtr &src) noexcept final {
oxRequireM(src, ox::readClaw<SrcType>(pV1Buff)); auto dst = ox::make_unique<ModelContainerTemplate<DstType>>();
auto dst = static_cast<DstType*>(pV2); oxReturnError(convert(reinterpret_cast<SrcType *>(src->obj()), reinterpret_cast<DstType *>(dst->obj())));
return convert(&src, dst); return ox::Result<ClawObjPtr>(std::move(dst));
} }
ox::Result<ox::Buffer> convertBuffToBuff(const ox::Buffer &srcBuff, ox::ClawFormat dstFmt) noexcept final { ox::Result<ClawObjPtr> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept final {
DstType dst; oxRequireM(src, ox::readClaw<SrcType>(srcBuff));
oxReturnError(convertRaw(srcBuff, &dst)); auto dst = ox::make_unique<ModelContainerTemplate<DstType>>();
oxRequireM(out, ox::writeClaw(&dst, dstFmt)); oxReturnError(convert(&src, reinterpret_cast<DstType*>(dst->obj())));
return out; return ox::Result<ClawObjPtr>(std::move(dst));
} }
}; };
ox::Result<ox::Buffer> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion, ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept; ox::Result<ClawObjPtr> convert(const ox::Buffer &srcBuffer, const ox::String &dstTypeName, int dstTypeVersion) noexcept;
template<typename T> template<typename DstType>
ox::Result<ox::Buffer> convert(const ox::Buffer &srcBuffer, ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept { ox::Result<ClawObjPtr> convert(const ox::Buffer &srcBuffer) noexcept {
return convert(srcBuffer, T::TypeName, T::TypeVersion, fmt); return convert(srcBuffer, DstType::TypeName, DstType::TypeVersion);
} }
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(outBuff, convert<T>(buff)); oxRequireM(outPtr, convert(buff, T::TypeName, T::TypeVersion));
return ox::readClaw<T>(outBuff).moveTo(outObj); *outObj = std::move(*reinterpret_cast<T*>(outPtr->obj()));
return OxError(0);
}
template<typename DstType>
ox::Result<ox::Buffer> convertBuffToBuff(const ox::Buffer &srcBuffer, ox::ClawFormat fmt) noexcept {
oxRequireM(out, convert(srcBuffer, DstType::TypeName, DstType::TypeVersion));
return ox::writeClaw<DstType>(reinterpret_cast<DstType*>(out->obj()), fmt);
} }
} }

View File

@ -36,7 +36,7 @@ static ox::Error doTransformations(ox::FileSystem *dest, const ox::String &fileP
// load file // load file
oxRequireM(buff, dest->read(filePath.c_str())); oxRequireM(buff, dest->read(filePath.c_str()));
if (filePath.endsWith(".ng")) { if (filePath.endsWith(".ng")) {
oxReturnError(core::convert<core::CompactTileSheet>(buff).moveTo(&buff)); oxReturnError(core::convertBuffToBuff<core::CompactTileSheet>(buff, ox::ClawFormat::Metal).moveTo(&buff));
} }
// do transformations // do transformations
oxReturnError(pathToInode(buff).moveTo(&buff)); oxReturnError(pathToInode(buff).moveTo(&buff));