Compare commits
	
		
			2 Commits
		
	
	
		
			8e816a261f
			...
			e598e7fe27
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e598e7fe27 | |||
| ba9e720f9f | 
							
								
								
									
										6
									
								
								deps/ox/src/ox/model/typenamecatcher.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/ox/src/ox/model/typenamecatcher.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -140,16 +140,16 @@ constexpr Str getModelTypeName() noexcept { | |||||||
| 	return out; | 	return out; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename T> | template<typename T, typename Str = const char*> | ||||||
| [[nodiscard]] | [[nodiscard]] | ||||||
| consteval auto requireModelTypeName() noexcept { | consteval auto requireModelTypeName() noexcept { | ||||||
| 	constexpr auto name = getModelTypeName<T>(); | 	constexpr auto name = getModelTypeName<T, Str>(); | ||||||
| 	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 = getModelTypeName<T, Str>(); | constexpr auto ModelTypeName_v = requireModelTypeName<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>(); | ||||||
|   | |||||||
| @@ -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::StringView typeId) -> ox::Result<bool> { | 				[](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR 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::StringView typeId) -> ox::Result<bool> { | 				[](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR 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> || | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| namespace keel { | namespace keel { | ||||||
|  |  | ||||||
| class Context; | class Context; | ||||||
| using PackTransform = ox::Result<bool>(*)(Context&, ox::Buffer &clawData, ox::StringView); | using PackTransform = ox::Result<bool>(*)(Context&, ox::Buffer &clawData, ox::StringViewCR); | ||||||
|  |  | ||||||
| class Context { | class Context { | ||||||
| 	public: | 	public: | ||||||
|   | |||||||
| @@ -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); | ||||||
| 	}; | 	}; | ||||||
|   | |||||||
| @@ -16,10 +16,43 @@ 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 WrapInline: public Wrap { | class WrapT: 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; | ||||||
|  |  | ||||||
| @@ -30,8 +63,15 @@ class WrapInline: public Wrap { | |||||||
| 		constexpr explicit WrapInline(Args &&...args): m_obj(ox::forward<Args>(args)...) { | 		constexpr explicit WrapInline(Args &&...args): m_obj(ox::forward<Args>(args)...) { | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		[[nodiscard]] | 		ox::CStringView typeName() const noexcept override { | ||||||
| 		constexpr T &obj() noexcept { | 			return ox::ModelTypeName_v<T>; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		int typeVersion() const noexcept override { | ||||||
|  | 			return ox::ModelTypeVersion_v<T>; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		constexpr T &obj() noexcept override { | ||||||
| 			return m_obj; | 			return m_obj; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -44,7 +84,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<WrapInline<T>&>(ptr).obj(); | 	return static_cast<WrapT<T>&>(ptr).obj(); | ||||||
| } | } | ||||||
|  |  | ||||||
| class BaseConverter { | class BaseConverter { | ||||||
| @@ -70,8 +110,8 @@ class BaseConverter { | |||||||
|  |  | ||||||
| 		[[nodiscard]] | 		[[nodiscard]] | ||||||
| 		constexpr bool matches( | 		constexpr bool matches( | ||||||
| 				ox::StringViewCR srcTypeName, int srcTypeVersion, | 				ox::StringViewCR srcTypeName, int const srcTypeVersion, | ||||||
| 				ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept { | 				ox::StringViewCR dstTypeName, int const dstTypeVersion) const noexcept { | ||||||
| 			return srcMatches(srcTypeName, srcTypeVersion) | 			return srcMatches(srcTypeName, srcTypeVersion) | ||||||
| 			    && dstMatches(dstTypeName, dstTypeVersion); | 			    && dstMatches(dstTypeName, dstTypeVersion); | ||||||
| 		} | 		} | ||||||
| @@ -109,17 +149,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 { | ||||||
| 			auto dst = makeWrap<DstType>(); | 			ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()}; | ||||||
| 			OX_RETURN_ERROR(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(*dst))); | 			OX_RETURN_ERROR(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(*dst.value))); | ||||||
| 			return {std::move(dst)}; | 			return 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)); | ||||||
| 			auto dst = makeWrap<DstType>(); | 			ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()}; | ||||||
| 			OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst))); | 			OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst.value))); | ||||||
| 			return {std::move(dst)}; | 			return dst; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	protected: | 	protected: | ||||||
| @@ -133,34 +173,57 @@ 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> convert(keel::Context &ctx, ox::BufferView const&srcBuffer) noexcept { | ox::Result<DstType> convertObjToObj( | ||||||
| 	static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>(); | 		keel::Context &ctx, | ||||||
| 	static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>(); | 		auto &src) noexcept { | ||||||
| 	OX_REQUIRE(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion)); | 	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_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 { | ||||||
| 	static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>(); | 	OX_REQUIRE(out, convert(ctx, buff, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<DstType>)); | ||||||
| 	static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>(); | 	outObj = std::move(wrapCast<DstType>(*out)); | ||||||
| 	OX_REQUIRE(outPtr, convert(ctx, buff, DstTypeName, DstTypeVersion)); | 	return {}; | ||||||
| 	*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&srcBuffer, ox::ClawFormat fmt) noexcept { | 		keel::Context &ctx, ox::BufferView const&src, ox::ClawFormat const fmt) noexcept { | ||||||
| 	static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>(); | 	OX_REQUIRE(out, convert(ctx, src, ox::ModelTypeName_v<DstType>, ox::ModelTypeVersion_v<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::StringView typeId) noexcept { | ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR 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; | ||||||
| @@ -168,5 +231,4 @@ ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringV | |||||||
| 	return false; | 	return false; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,30 +10,38 @@ 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 srcTypeVersion, | 		int const srcTypeVersion, | ||||||
| 		ox::StringViewCR dstTypeName, | 		ox::StringViewCR dstTypeName, | ||||||
| 		int dstTypeVersion) noexcept { | 		int const 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( | ||||||
| 		keel::Context &ctx, | 		Context &ctx, | ||||||
| 		ox::SpanView<BaseConverter const*> const&converters, | 		ox::SpanView<BaseConverter const*> const&converters, | ||||||
| 		ox::BufferView const&srcBuffer, | 		auto &src, | ||||||
| 		ox::StringViewCR srcTypeName, | 		ox::StringViewCR srcTypeName, | ||||||
| 		int srcTypeVersion, | 		int const srcTypeVersion, | ||||||
| 		ox::StringViewCR dstTypeName, | 		ox::StringViewCR dstTypeName, | ||||||
| 		int dstTypeVersion) noexcept { | 		int const dstTypeVersion) noexcept { | ||||||
| 	// look for direct converter | 	// look for direct converter | ||||||
| 	auto [c, err] = findConverter( | 	auto const [c, err] = findConverter( | ||||||
| 			converters, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); | 			converters, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); | ||||||
| 	if (!err) { | 	if (!err) { | ||||||
| 		return c->convertBuffToPtr(ctx, srcBuffer); | 		return convert(*c, ctx, src); | ||||||
| 	} | 	} | ||||||
| 	// try to chain multiple converters | 	// try to chain multiple converters | ||||||
| 	for (auto const&subConverter : converters) { | 	for (auto const&subConverter : converters) { | ||||||
| @@ -41,20 +49,20 @@ static ox::Result<ox::UPtr<Wrap>> convert( | |||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 		const auto [intermediate, chainErr] = | 		const auto [intermediate, chainErr] = | ||||||
| 			convert(ctx, converters, srcBuffer, srcTypeName, srcTypeVersion, | 			convert(ctx, converters, src, 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( | ||||||
| 		keel::Context &ctx, | 		Context &ctx, | ||||||
| 		ox::BufferView const&srcBuffer, | 		ox::BufferView const&srcBuffer, | ||||||
| 		ox::StringViewCR dstTypeName, | 		ox::StringViewCR dstTypeName, | ||||||
| 		int dstTypeVersion) noexcept { | 		int const dstTypeVersion) noexcept { | ||||||
| 	OX_REQUIRE(hdr, readAssetHeader(srcBuffer)); | 	OX_REQUIRE(hdr, readAssetHeader(srcBuffer)); | ||||||
| 	return convert( | 	return convert( | ||||||
| 			ctx, | 			ctx, | ||||||
| @@ -66,4 +74,19 @@ 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); | ||||||
|  | } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user