Compare commits

..

No commits in common. "e598e7fe27e61d6ac0f164da3225826bde3c61af" and "8e816a261fcc3fb8d4293d8e7d235e7651d53783" have entirely different histories.

6 changed files with 48 additions and 133 deletions

View File

@ -140,16 +140,16 @@ constexpr Str getModelTypeName() noexcept {
return out; return out;
} }
template<typename T, typename Str = const char*> template<typename T>
[[nodiscard]] [[nodiscard]]
consteval auto requireModelTypeName() noexcept { consteval auto requireModelTypeName() noexcept {
constexpr auto name = getModelTypeName<T, Str>(); constexpr auto name = getModelTypeName<T>();
static_assert(ox::StringView{name}.len(), "Type lacks required TypeName"); static_assert(ox::StringView{name}.len(), "Type lacks required TypeName");
return name; return name;
} }
template<typename T, typename Str = const char*> template<typename T, typename Str = const char*>
constexpr auto ModelTypeName_v = requireModelTypeName<T, Str>(); constexpr auto ModelTypeName_v = getModelTypeName<T, Str>();
template<typename T, typename Str = const char*> template<typename T, typename Str = const char*>
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>(); constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();

View File

@ -67,7 +67,7 @@ static class: public keel::Module {
ox::Vector<keel::PackTransform> packTransforms() const noexcept final { ox::Vector<keel::PackTransform> packTransforms() const noexcept final {
return { return {
// convert tilesheets to CompactTileSheets // convert tilesheets to CompactTileSheets
[](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) -> ox::Result<bool> { [](keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) -> ox::Result<bool> {
if (typeId == ox::ModelTypeId_v<TileSheetV1> || if (typeId == ox::ModelTypeId_v<TileSheetV1> ||
typeId == ox::ModelTypeId_v<TileSheetV2> || typeId == ox::ModelTypeId_v<TileSheetV2> ||
typeId == ox::ModelTypeId_v<TileSheetV3> || typeId == ox::ModelTypeId_v<TileSheetV3> ||
@ -78,7 +78,7 @@ static class: public keel::Module {
} }
return false; return false;
}, },
[](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) -> ox::Result<bool> { [](keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) -> ox::Result<bool> {
if (typeId == ox::ModelTypeId_v<NostalgiaPalette> || if (typeId == ox::ModelTypeId_v<NostalgiaPalette> ||
typeId == ox::ModelTypeId_v<PaletteV1> || typeId == ox::ModelTypeId_v<PaletteV1> ||
typeId == ox::ModelTypeId_v<PaletteV2> || typeId == ox::ModelTypeId_v<PaletteV2> ||

View File

@ -12,7 +12,7 @@
namespace keel { namespace keel {
class Context; class Context;
using PackTransform = ox::Result<bool>(*)(Context&, ox::Buffer &clawData, ox::StringViewCR); using PackTransform = ox::Result<bool>(*)(Context&, ox::Buffer &clawData, ox::StringView);
class Context { class Context {
public: public:

View File

@ -70,7 +70,7 @@ constexpr auto makeLoader(Context &ctx) {
if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) { if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) {
return err; return err;
} }
OX_RETURN_ERROR(convert<T>(ctx, buff, obj)); OX_RETURN_ERROR(convert<T>(ctx, buff, &obj));
} }
return std::move(obj); return std::move(obj);
}; };

View File

@ -16,43 +16,10 @@ namespace keel {
class Wrap { class Wrap {
public: public:
virtual ~Wrap() = default; virtual ~Wrap() = default;
[[nodiscard]]
virtual ox::CStringView typeName() const noexcept = 0;
[[nodiscard]]
virtual int typeVersion() const noexcept = 0;
}; };
template<typename T> template<typename T>
class WrapT: public Wrap { class WrapInline: public Wrap {
public:
[[nodiscard]]
virtual constexpr T &obj() noexcept = 0;
};
template<typename T>
class WrapRef final: public WrapT<T> {
private:
T &m_obj;
public:
constexpr explicit WrapRef(T &obj): m_obj{obj} {}
ox::CStringView typeName() const noexcept override {
return ox::ModelTypeName_v<T>;
}
int typeVersion() const noexcept override {
return ox::ModelTypeVersion_v<T>;
}
constexpr T &obj() noexcept override {
return m_obj;
}
};
template<typename T>
class WrapInline final: public WrapT<T> {
private: private:
T m_obj; T m_obj;
@ -63,15 +30,8 @@ class WrapInline final: public WrapT<T> {
constexpr explicit WrapInline(Args &&...args): m_obj(ox::forward<Args>(args)...) { constexpr explicit WrapInline(Args &&...args): m_obj(ox::forward<Args>(args)...) {
} }
ox::CStringView typeName() const noexcept override { [[nodiscard]]
return ox::ModelTypeName_v<T>; constexpr T &obj() noexcept {
}
int typeVersion() const noexcept override {
return ox::ModelTypeVersion_v<T>;
}
constexpr T &obj() noexcept override {
return m_obj; return m_obj;
} }
@ -84,7 +44,7 @@ constexpr ox::UPtr<Wrap> makeWrap(Args &&...args) noexcept {
template<typename T> template<typename T>
constexpr T &wrapCast(Wrap &ptr) noexcept { constexpr T &wrapCast(Wrap &ptr) noexcept {
return static_cast<WrapT<T>&>(ptr).obj(); return static_cast<WrapInline<T>&>(ptr).obj();
} }
class BaseConverter { class BaseConverter {
@ -110,10 +70,10 @@ class BaseConverter {
[[nodiscard]] [[nodiscard]]
constexpr bool matches( constexpr bool matches(
ox::StringViewCR srcTypeName, int const srcTypeVersion, ox::StringViewCR srcTypeName, int srcTypeVersion,
ox::StringViewCR dstTypeName, int const dstTypeVersion) const noexcept { ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept {
return srcMatches(srcTypeName, srcTypeVersion) return srcMatches(srcTypeName, srcTypeVersion)
&& dstMatches(dstTypeName, dstTypeVersion); && dstMatches(dstTypeName, dstTypeVersion);
} }
}; };
@ -149,17 +109,17 @@ class Converter: public BaseConverter {
ox::Result<ox::UPtr<Wrap>> convertPtrToPtr( ox::Result<ox::UPtr<Wrap>> convertPtrToPtr(
keel::Context &ctx, Wrap &src) const noexcept final { keel::Context &ctx, Wrap &src) const noexcept final {
ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()}; auto dst = makeWrap<DstType>();
OX_RETURN_ERROR(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(*dst.value))); OX_RETURN_ERROR(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(*dst)));
return dst; return {std::move(dst)};
} }
ox::Result<ox::UPtr<Wrap>> convertBuffToPtr( ox::Result<ox::UPtr<Wrap>> convertBuffToPtr(
keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept final { keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept final {
OX_REQUIRE_M(src, readAsset<SrcType>(srcBuff)); OX_REQUIRE_M(src, readAsset<SrcType>(srcBuff));
ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()}; auto dst = makeWrap<DstType>();
OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst.value))); OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst)));
return dst; return {std::move(dst)};
} }
protected: protected:
@ -173,57 +133,34 @@ ox::Result<ox::UPtr<Wrap>> convert(
ox::StringViewCR dstTypeName, ox::StringViewCR dstTypeName,
int dstTypeVersion) noexcept; int dstTypeVersion) noexcept;
ox::Result<ox::UPtr<Wrap>> convert(
keel::Context &ctx,
Wrap &src,
ox::StringViewCR dstTypeName,
int dstTypeVersion) noexcept;
ox::Result<ox::UPtr<Wrap>> convert(
keel::Context &ctx,
auto &src,
ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept {
return convert(ctx, WrapRef{src}, dstTypeName, dstTypeVersion);
}
template<typename DstType> template<typename DstType>
ox::Result<DstType> convertObjToObj( ox::Result<DstType> convert(keel::Context &ctx, ox::BufferView const&srcBuffer) noexcept {
keel::Context &ctx, static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
auto &src) noexcept { static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
OX_REQUIRE_M(out, convert(ctx, WrapRef{src}, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>)); OX_REQUIRE(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion));
return std::move(wrapCast(*out));
}
template<typename DstType>
ox::Result<DstType> convert(keel::Context &ctx, ox::BufferView const&src) noexcept {
OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
return std::move(wrapCast<DstType>(out)); return std::move(wrapCast<DstType>(out));
} }
template<typename DstType> template<typename DstType>
ox::Error convert(keel::Context &ctx, ox::BufferView const&buff, DstType &outObj) noexcept { ox::Error convert(keel::Context &ctx, ox::BufferView const&buff, DstType *outObj) noexcept {
OX_REQUIRE(out, convert(ctx, buff, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>)); static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
outObj = std::move(wrapCast<DstType>(*out)); static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
return {}; OX_REQUIRE(outPtr, convert(ctx, buff, DstTypeName, DstTypeVersion));
} *outObj = std::move(wrapCast<DstType>(*outPtr));
template<typename DstType>
ox::Error convertObjToObj(keel::Context &ctx, auto &src, DstType &outObj) noexcept {
OX_REQUIRE(outPtr, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
outObj = std::move(wrapCast<DstType>(*outPtr));
return {}; return {};
} }
template<typename DstType> template<typename DstType>
ox::Result<ox::Buffer> convertBuffToBuff( ox::Result<ox::Buffer> convertBuffToBuff(
keel::Context &ctx, ox::BufferView const&src, ox::ClawFormat const fmt) noexcept { keel::Context &ctx, ox::BufferView const&srcBuffer, ox::ClawFormat fmt) noexcept {
OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>)); static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
OX_REQUIRE(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion));
return ox::writeClaw<DstType>(wrapCast<DstType>(*out), fmt); return ox::writeClaw<DstType>(wrapCast<DstType>(*out), fmt);
} }
template<typename From, typename To, ox::ClawFormat fmt = ox::ClawFormat::Metal> template<typename From, typename To, ox::ClawFormat fmt = ox::ClawFormat::Metal>
ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) noexcept { ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) noexcept {
if (typeId == ox::ModelTypeId_v<From>) { if (typeId == ox::ModelTypeId_v<From>) {
OX_RETURN_ERROR(keel::convertBuffToBuff<To>(ctx, buff, fmt).moveTo(buff)); OX_RETURN_ERROR(keel::convertBuffToBuff<To>(ctx, buff, fmt).moveTo(buff));
return true; return true;
@ -231,4 +168,5 @@ ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringV
return false; return false;
}; };
} }

View File

@ -10,38 +10,30 @@ namespace keel {
static ox::Result<BaseConverter const*> findConverter( static ox::Result<BaseConverter const*> findConverter(
ox::SpanView<BaseConverter const*> const&converters, ox::SpanView<BaseConverter const*> const&converters,
ox::StringViewCR srcTypeName, ox::StringViewCR srcTypeName,
int const srcTypeVersion, int srcTypeVersion,
ox::StringViewCR dstTypeName, ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept { int dstTypeVersion) noexcept {
for (auto const&c : converters) { for (auto const&c : converters) {
if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) { if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) {
return c; return c;
} }
} }
return ox::Error{1, "Could not find converter"}; return ox::Error(1, "Could not find converter");
}; };
static ox::Result<ox::UPtr<Wrap>> convert(BaseConverter const&c, Context &ctx, ox::BufferView const&src) noexcept {
return c.convertBuffToPtr(ctx, src);
}
static ox::Result<ox::UPtr<Wrap>> convert(BaseConverter const&c, Context &ctx, Wrap &src) noexcept {
return c.convertPtrToPtr(ctx, src);
}
static ox::Result<ox::UPtr<Wrap>> convert( static ox::Result<ox::UPtr<Wrap>> convert(
Context &ctx, keel::Context &ctx,
ox::SpanView<BaseConverter const*> const&converters, ox::SpanView<BaseConverter const*> const&converters,
auto &src, ox::BufferView const&srcBuffer,
ox::StringViewCR srcTypeName, ox::StringViewCR srcTypeName,
int const srcTypeVersion, int srcTypeVersion,
ox::StringViewCR dstTypeName, ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept { int dstTypeVersion) noexcept {
// look for direct converter // look for direct converter
auto const [c, err] = findConverter( auto [c, err] = findConverter(
converters, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); converters, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion);
if (!err) { if (!err) {
return convert(*c, ctx, src); return c->convertBuffToPtr(ctx, srcBuffer);
} }
// try to chain multiple converters // try to chain multiple converters
for (auto const&subConverter : converters) { for (auto const&subConverter : converters) {
@ -49,20 +41,20 @@ static ox::Result<ox::UPtr<Wrap>> convert(
continue; continue;
} }
const auto [intermediate, chainErr] = const auto [intermediate, chainErr] =
convert(ctx, converters, src, srcTypeName, srcTypeVersion, convert(ctx, converters, srcBuffer, srcTypeName, srcTypeVersion,
subConverter->srcTypeName(), subConverter->srcTypeVersion()); subConverter->srcTypeName(), subConverter->srcTypeVersion());
if (!chainErr) { if (!chainErr) {
return subConverter->convertPtrToPtr(ctx, *intermediate); 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<ox::UPtr<Wrap>> convert( ox::Result<ox::UPtr<Wrap>> convert(
Context &ctx, keel::Context &ctx,
ox::BufferView const&srcBuffer, ox::BufferView const&srcBuffer,
ox::StringViewCR dstTypeName, ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept { int dstTypeVersion) noexcept {
OX_REQUIRE(hdr, readAssetHeader(srcBuffer)); OX_REQUIRE(hdr, readAssetHeader(srcBuffer));
return convert( return convert(
ctx, ctx,
@ -74,19 +66,4 @@ ox::Result<ox::UPtr<Wrap>> convert(
dstTypeVersion); dstTypeVersion);
} }
ox::Result<ox::UPtr<Wrap>> convert(
Context &ctx,
Wrap &src,
ox::StringViewCR dstTypeName,
int const dstTypeVersion) noexcept {
return convert(
ctx,
converters(ctx),
src,
src.typeName(),
src.typeVersion(),
dstTypeName,
dstTypeVersion);
}
} }