Merge commit 'ec6cf92c4763be5933ee6debbf97bce25b9fcfc9'
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/claw/claw.hpp>
|
||||
#include <ox/claw/read.hpp>
|
||||
#include <ox/fs/fs.hpp>
|
||||
|
||||
#include "validation.hpp"
|
||||
|
@ -8,11 +8,11 @@
|
||||
#include <ox/std/memory.hpp>
|
||||
|
||||
#include "assetmanager.hpp"
|
||||
#include "typeconv.hpp"
|
||||
|
||||
namespace keel {
|
||||
|
||||
class Context;
|
||||
using PackTransform = ox::Result<bool>(*)(Context&, ox::Buffer &clawData, ox::StringViewCR);
|
||||
|
||||
class Context {
|
||||
public:
|
||||
@ -22,7 +22,7 @@ class Context {
|
||||
AssetManager assetManager;
|
||||
ox::HashMap<ox::String, ox::UUID> pathToUuid;
|
||||
ox::HashMap<ox::UUIDStr, ox::String> uuidToPath;
|
||||
ox::Vector<class BaseConverter const*> converters;
|
||||
ox::Vector<Converter> converters;
|
||||
ox::Vector<PackTransform> packTransforms;
|
||||
#else
|
||||
std::size_t preloadSectionOffset = 0;
|
||||
@ -45,7 +45,7 @@ constexpr ox::SpanView<PackTransform> packTransforms(
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr ox::SpanView<class BaseConverter const*> converters(
|
||||
constexpr ox::SpanView<Converter> converters(
|
||||
[[maybe_unused]] Context const&ctx) noexcept {
|
||||
#ifndef OX_BARE_METAL
|
||||
return ctx.converters;
|
||||
|
@ -32,7 +32,7 @@ class Module {
|
||||
[[nodiscard]]
|
||||
virtual ox::Vector<TypeDescGenerator> types() const noexcept;
|
||||
[[nodiscard]]
|
||||
virtual ox::Vector<const keel::BaseConverter*> converters() const noexcept;
|
||||
virtual ox::Vector<Converter> converters() const noexcept;
|
||||
[[nodiscard]]
|
||||
virtual ox::Vector<PackTransform> packTransforms() const noexcept;
|
||||
};
|
||||
|
@ -4,15 +4,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/claw/write.hpp>
|
||||
#include <ox/std/def.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
|
||||
#include "asset.hpp"
|
||||
#include "context.hpp"
|
||||
|
||||
namespace keel {
|
||||
|
||||
class Context;
|
||||
|
||||
class Wrap {
|
||||
public:
|
||||
virtual ~Wrap() = default;
|
||||
@ -113,7 +115,7 @@ class BaseConverter {
|
||||
virtual ox::Result<ox::UPtr<Wrap>> convertPtrToPtr(keel::Context &ctx, Wrap &src) const noexcept = 0;
|
||||
|
||||
virtual ox::Result<ox::UPtr<Wrap>> convertBuffToPtr(
|
||||
keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept = 0;
|
||||
Context &ctx, ox::BufferView const&srcBuff) const noexcept = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool matches(
|
||||
@ -125,21 +127,37 @@ class BaseConverter {
|
||||
|
||||
};
|
||||
|
||||
template<typename SrcType, typename DstType>
|
||||
class Converter: public BaseConverter {
|
||||
|
||||
template<auto Func>
|
||||
class ConverterFunc final: public BaseConverter {
|
||||
private:
|
||||
template<typename SrcType, typename DstType>
|
||||
struct ParamPack {
|
||||
using Src = SrcType;
|
||||
using Dst = DstType;
|
||||
};
|
||||
|
||||
template<typename Src, typename Dst>
|
||||
static ParamPack<Src, Dst> extractParams(ox::Error (*)(Context&, Src&, Dst&)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
using SrcType = typename decltype(extractParams(Func))::Src;
|
||||
using DstType = typename decltype(extractParams(Func))::Dst;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr ox::StringView srcTypeName() const noexcept final {
|
||||
constexpr ox::StringView srcTypeName() const noexcept override {
|
||||
return ox::ModelTypeName_v<SrcType>;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr int srcTypeVersion() const noexcept final {
|
||||
constexpr int srcTypeVersion() const noexcept override {
|
||||
return ox::ModelTypeVersion_v<SrcType>;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool srcMatches(ox::StringViewCR pSrcTypeName, int pSrcTypeVersion) const noexcept final {
|
||||
constexpr bool srcMatches(ox::StringViewCR pSrcTypeName, int pSrcTypeVersion) const noexcept override {
|
||||
constexpr auto SrcTypeName = ox::requireModelTypeName<SrcType>();
|
||||
constexpr auto SrcTypeVersion = ox::requireModelTypeVersion<SrcType>();
|
||||
return pSrcTypeName == SrcTypeName
|
||||
@ -147,7 +165,7 @@ class Converter: public BaseConverter {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool dstMatches(ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept final {
|
||||
constexpr bool dstMatches(ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept override {
|
||||
constexpr auto DstTypeName = ox::StringView{ox::requireModelTypeName<DstType>()};
|
||||
constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
|
||||
return dstTypeName == DstTypeName
|
||||
@ -155,14 +173,14 @@ class Converter: public BaseConverter {
|
||||
}
|
||||
|
||||
ox::Result<ox::UPtr<Wrap>> convertPtrToPtr(
|
||||
keel::Context &ctx, Wrap &src) const noexcept final {
|
||||
Context &ctx, Wrap &src) const noexcept override {
|
||||
ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()};
|
||||
OX_RETURN_ERROR(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(*dst.value)));
|
||||
return dst;
|
||||
}
|
||||
|
||||
ox::Result<ox::UPtr<Wrap>> convertBuffToPtr(
|
||||
keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept final {
|
||||
Context &ctx, ox::BufferView const&srcBuff) const noexcept override {
|
||||
OX_REQUIRE_M(src, readAsset<SrcType>(srcBuff));
|
||||
ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()};
|
||||
OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst.value)));
|
||||
@ -170,24 +188,48 @@ class Converter: public BaseConverter {
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ox::Error convert(keel::Context &ctx, SrcType&, DstType&) const noexcept = 0;
|
||||
static ox::Error convert(Context &ctx, SrcType &src, DstType &dst) noexcept {
|
||||
return Func(ctx, src, dst);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Converter {
|
||||
private:
|
||||
ox::AllocAlias<BaseConverter> m_buff{};
|
||||
BaseConverter *m_conv{};
|
||||
public:
|
||||
template<auto Func>
|
||||
static Converter make() noexcept {
|
||||
Converter out;
|
||||
static_assert(sizeof(ConverterFunc<Func>) <= sizeof(out.m_buff));
|
||||
out.m_conv = new (out.m_buff.data()) ConverterFunc<Func>{};
|
||||
return out;
|
||||
}
|
||||
constexpr Converter() {}
|
||||
Converter(Converter const &other) noexcept:
|
||||
m_buff{other.m_buff},
|
||||
m_conv{m_buff.data()} {}
|
||||
[[nodiscard]]
|
||||
BaseConverter const *converter() const noexcept {
|
||||
return m_conv;
|
||||
}
|
||||
};
|
||||
|
||||
ox::Result<ox::UPtr<Wrap>> convert(
|
||||
keel::Context &ctx,
|
||||
Context &ctx,
|
||||
ox::BufferView const&srcBuffer,
|
||||
ox::StringViewCR dstTypeName,
|
||||
int dstTypeVersion) noexcept;
|
||||
|
||||
ox::Result<ox::UPtr<Wrap>> convert(
|
||||
keel::Context &ctx,
|
||||
Context &ctx,
|
||||
Wrap &src,
|
||||
ox::StringViewCR dstTypeName,
|
||||
int dstTypeVersion) noexcept;
|
||||
|
||||
ox::Result<ox::UPtr<Wrap>> convert(
|
||||
keel::Context &ctx,
|
||||
Context &ctx,
|
||||
auto &src,
|
||||
ox::StringViewCR dstTypeName,
|
||||
int const dstTypeVersion) noexcept {
|
||||
@ -196,7 +238,7 @@ ox::Result<ox::UPtr<Wrap>> convert(
|
||||
}
|
||||
|
||||
ox::Result<ox::UPtr<Wrap>> convert(
|
||||
keel::Context &ctx,
|
||||
Context &ctx,
|
||||
auto const&src,
|
||||
ox::StringViewCR dstTypeName,
|
||||
int const dstTypeVersion) noexcept {
|
||||
@ -207,27 +249,27 @@ ox::Result<ox::UPtr<Wrap>> convert(
|
||||
|
||||
template<typename DstType>
|
||||
ox::Result<DstType> convertObjToObj(
|
||||
keel::Context &ctx,
|
||||
Context &ctx,
|
||||
auto &src) noexcept {
|
||||
OX_REQUIRE_M(out, convert(ctx, WrapRef{src}, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
|
||||
return std::move(wrapCast(*out));
|
||||
}
|
||||
|
||||
template<typename DstType>
|
||||
ox::Result<DstType> convert(keel::Context &ctx, ox::BufferView const&src) noexcept {
|
||||
ox::Result<DstType> convert(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));
|
||||
}
|
||||
|
||||
template<typename DstType>
|
||||
ox::Error convert(keel::Context &ctx, ox::BufferView const&buff, DstType &outObj) noexcept {
|
||||
ox::Error convert(Context &ctx, ox::BufferView const&buff, DstType &outObj) noexcept {
|
||||
OX_REQUIRE(out, convert(ctx, buff, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
|
||||
outObj = std::move(wrapCast<DstType>(*out));
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename DstType>
|
||||
ox::Error convertObjToObj(keel::Context &ctx, auto &src, DstType &outObj) noexcept {
|
||||
ox::Error convertObjToObj(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 {};
|
||||
@ -235,13 +277,13 @@ ox::Error convertObjToObj(keel::Context &ctx, auto &src, DstType &outObj) noexce
|
||||
|
||||
template<typename DstType>
|
||||
ox::Result<ox::Buffer> convertBuffToBuff(
|
||||
keel::Context &ctx, ox::BufferView const&src, ox::ClawFormat const fmt) noexcept {
|
||||
Context &ctx, ox::BufferView const&src, ox::ClawFormat const fmt) noexcept {
|
||||
OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>));
|
||||
return ox::writeClaw<DstType>(wrapCast<DstType>(*out), fmt);
|
||||
}
|
||||
|
||||
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(Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) noexcept {
|
||||
if (typeId == ox::ModelTypeId_v<From>) {
|
||||
OX_RETURN_ERROR(keel::convertBuffToBuff<To>(ctx, buff, fmt).moveTo(buff));
|
||||
return true;
|
||||
@ -249,4 +291,6 @@ ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringV
|
||||
return false;
|
||||
};
|
||||
|
||||
using PackTransform = ox::Result<bool>(*)(Context&, ox::Buffer &clawData, ox::StringViewCR);
|
||||
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ ox::Vector<TypeDescGenerator> Module::types() const noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Vector<keel::BaseConverter const*> Module::converters() const noexcept {
|
||||
ox::Vector<Converter> Module::converters() const noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
15
deps/nostalgia/src/olympic/keel/src/typeconv.cpp
vendored
15
deps/nostalgia/src/olympic/keel/src/typeconv.cpp
vendored
@ -2,20 +2,21 @@
|
||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <keel/context.hpp>
|
||||
#include <keel/media.hpp>
|
||||
#include <keel/typeconv.hpp>
|
||||
|
||||
namespace keel {
|
||||
|
||||
static ox::Result<BaseConverter const*> findConverter(
|
||||
ox::SpanView<BaseConverter const*> const&converters,
|
||||
ox::SpanView<Converter> const&converters,
|
||||
ox::StringViewCR srcTypeName,
|
||||
int const srcTypeVersion,
|
||||
ox::StringViewCR dstTypeName,
|
||||
int const dstTypeVersion) noexcept {
|
||||
for (auto const&c : converters) {
|
||||
if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) {
|
||||
return c;
|
||||
if (c.converter()->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) {
|
||||
return c.converter();
|
||||
}
|
||||
}
|
||||
return ox::Error{1, "Could not find converter"};
|
||||
@ -31,7 +32,7 @@ static ox::Result<ox::UPtr<Wrap>> convert(BaseConverter const&c, Context &ctx, W
|
||||
|
||||
static ox::Result<ox::UPtr<Wrap>> convert(
|
||||
Context &ctx,
|
||||
ox::SpanView<BaseConverter const*> const&converters,
|
||||
ox::SpanView<Converter> const&converters,
|
||||
auto &src,
|
||||
ox::StringViewCR srcTypeName,
|
||||
int const srcTypeVersion,
|
||||
@ -45,14 +46,14 @@ static ox::Result<ox::UPtr<Wrap>> convert(
|
||||
}
|
||||
// try to chain multiple converters
|
||||
for (auto const&subConverter : converters) {
|
||||
if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) {
|
||||
if (!subConverter.converter()->dstMatches(dstTypeName, dstTypeVersion)) {
|
||||
continue;
|
||||
}
|
||||
const auto [intermediate, chainErr] =
|
||||
convert(ctx, converters, src, srcTypeName, srcTypeVersion,
|
||||
subConverter->srcTypeName(), subConverter->srcTypeVersion());
|
||||
subConverter.converter()->srcTypeName(), subConverter.converter()->srcTypeVersion());
|
||||
if (!chainErr) {
|
||||
return subConverter->convertPtrToPtr(ctx, *intermediate);
|
||||
return subConverter.converter()->convertPtrToPtr(ctx, *intermediate);
|
||||
}
|
||||
}
|
||||
return ox::Error{1, "Could not convert between types"};
|
||||
|
Reference in New Issue
Block a user