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; | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| template<typename T, typename Str = const char*> | ||||
| [[nodiscard]] | ||||
| 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"); | ||||
| 	return name; | ||||
| } | ||||
|  | ||||
| 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*> | ||||
| constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>(); | ||||
|   | ||||
| @@ -67,7 +67,7 @@ static class: public keel::Module { | ||||
| 		ox::Vector<keel::PackTransform> packTransforms() const noexcept final { | ||||
| 			return { | ||||
| 				// 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> || | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV2> || | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV3> || | ||||
| @@ -78,7 +78,7 @@ static class: public keel::Module { | ||||
| 					} | ||||
| 					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> || | ||||
| 					    typeId == ox::ModelTypeId_v<PaletteV1> || | ||||
| 					    typeId == ox::ModelTypeId_v<PaletteV2> || | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| namespace keel { | ||||
|  | ||||
| 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 { | ||||
| 	public: | ||||
|   | ||||
| @@ -70,7 +70,7 @@ constexpr auto makeLoader(Context &ctx) { | ||||
| 			if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) { | ||||
| 				return err; | ||||
| 			} | ||||
| 			OX_RETURN_ERROR(convert<T>(ctx, buff, &obj)); | ||||
| 			OX_RETURN_ERROR(convert<T>(ctx, buff, obj)); | ||||
| 		} | ||||
| 		return std::move(obj); | ||||
| 	}; | ||||
|   | ||||
| @@ -16,10 +16,43 @@ namespace keel { | ||||
| class Wrap { | ||||
| 	public: | ||||
| 		virtual ~Wrap() = default; | ||||
| 		[[nodiscard]] | ||||
| 		virtual ox::CStringView typeName() const noexcept = 0; | ||||
| 		[[nodiscard]] | ||||
| 		virtual int typeVersion() const noexcept = 0; | ||||
| }; | ||||
|  | ||||
| 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: | ||||
| 		T m_obj; | ||||
|  | ||||
| @@ -30,8 +63,15 @@ class WrapInline: public Wrap { | ||||
| 		constexpr explicit WrapInline(Args &&...args): m_obj(ox::forward<Args>(args)...) { | ||||
| 		} | ||||
|  | ||||
| 		[[nodiscard]] | ||||
| 		constexpr T &obj() noexcept { | ||||
| 		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; | ||||
| 		} | ||||
|  | ||||
| @@ -44,7 +84,7 @@ constexpr ox::UPtr<Wrap> makeWrap(Args &&...args) noexcept { | ||||
|  | ||||
| template<typename T> | ||||
| constexpr T &wrapCast(Wrap &ptr) noexcept { | ||||
| 	return static_cast<WrapInline<T>&>(ptr).obj(); | ||||
| 	return static_cast<WrapT<T>&>(ptr).obj(); | ||||
| } | ||||
|  | ||||
| class BaseConverter { | ||||
| @@ -70,10 +110,10 @@ class BaseConverter { | ||||
|  | ||||
| 		[[nodiscard]] | ||||
| 		constexpr bool matches( | ||||
| 				ox::StringViewCR srcTypeName, int srcTypeVersion, | ||||
| 				ox::StringViewCR dstTypeName, int dstTypeVersion) const noexcept { | ||||
| 				ox::StringViewCR srcTypeName, int const srcTypeVersion, | ||||
| 				ox::StringViewCR dstTypeName, int const dstTypeVersion) const noexcept { | ||||
| 			return srcMatches(srcTypeName, srcTypeVersion) | ||||
| 				 && dstMatches(dstTypeName, dstTypeVersion); | ||||
| 			    && dstMatches(dstTypeName, dstTypeVersion); | ||||
| 		} | ||||
|  | ||||
| }; | ||||
| @@ -109,17 +149,17 @@ class Converter: public BaseConverter { | ||||
|  | ||||
| 		ox::Result<ox::UPtr<Wrap>> convertPtrToPtr( | ||||
| 				keel::Context &ctx, Wrap &src) const noexcept final { | ||||
| 			auto dst = makeWrap<DstType>(); | ||||
| 			OX_RETURN_ERROR(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(*dst))); | ||||
| 			return {std::move(dst)}; | ||||
| 			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 { | ||||
| 			OX_REQUIRE_M(src, readAsset<SrcType>(srcBuff)); | ||||
| 			auto dst = makeWrap<DstType>(); | ||||
| 			OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst))); | ||||
| 			return {std::move(dst)}; | ||||
| 			ox::Result<ox::UPtr<Wrap>> dst{makeWrap<DstType>()}; | ||||
| 			OX_RETURN_ERROR(convert(ctx, src, wrapCast<DstType>(*dst.value))); | ||||
| 			return dst; | ||||
| 		} | ||||
|  | ||||
| 	protected: | ||||
| @@ -133,34 +173,57 @@ ox::Result<ox::UPtr<Wrap>> convert( | ||||
| 		ox::StringViewCR dstTypeName, | ||||
| 		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> | ||||
| ox::Result<DstType> convert(keel::Context &ctx, ox::BufferView const&srcBuffer) noexcept { | ||||
| 	static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>(); | ||||
| 	static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>(); | ||||
| 	OX_REQUIRE(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion)); | ||||
| ox::Result<DstType> convertObjToObj( | ||||
| 		keel::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_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 { | ||||
| 	static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>(); | ||||
| 	static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>(); | ||||
| 	OX_REQUIRE(outPtr, convert(ctx, buff, DstTypeName, DstTypeVersion)); | ||||
| 	*outObj = std::move(wrapCast<DstType>(*outPtr)); | ||||
| 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>)); | ||||
| 	outObj = std::move(wrapCast<DstType>(*out)); | ||||
| 	return {}; | ||||
| } | ||||
|  | ||||
| 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 {}; | ||||
| } | ||||
|  | ||||
| template<typename DstType> | ||||
| ox::Result<ox::Buffer> convertBuffToBuff( | ||||
| 		keel::Context &ctx, ox::BufferView const&srcBuffer, ox::ClawFormat fmt) noexcept { | ||||
| 	static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>(); | ||||
| 	static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>(); | ||||
| 	OX_REQUIRE(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion)); | ||||
| 		keel::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::StringView typeId) noexcept { | ||||
| ox::Result<bool> transformRule(keel::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; | ||||
| @@ -168,5 +231,4 @@ ox::Result<bool> transformRule(keel::Context &ctx, ox::Buffer &buff, ox::StringV | ||||
| 	return false; | ||||
| }; | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -10,30 +10,38 @@ namespace keel { | ||||
| static ox::Result<BaseConverter const*> findConverter( | ||||
| 		ox::SpanView<BaseConverter const*> const&converters, | ||||
| 		ox::StringViewCR srcTypeName, | ||||
| 		int srcTypeVersion, | ||||
| 		int const srcTypeVersion, | ||||
| 		ox::StringViewCR dstTypeName, | ||||
| 		int dstTypeVersion) noexcept { | ||||
| 		int const dstTypeVersion) noexcept { | ||||
| 	for (auto const&c : converters) { | ||||
| 		if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) { | ||||
| 			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( | ||||
| 		keel::Context &ctx, | ||||
| 		Context &ctx, | ||||
| 		ox::SpanView<BaseConverter const*> const&converters, | ||||
| 		ox::BufferView const&srcBuffer, | ||||
| 		auto &src, | ||||
| 		ox::StringViewCR srcTypeName, | ||||
| 		int srcTypeVersion, | ||||
| 		int const srcTypeVersion, | ||||
| 		ox::StringViewCR dstTypeName, | ||||
| 		int dstTypeVersion) noexcept { | ||||
| 		int const dstTypeVersion) noexcept { | ||||
| 	// look for direct converter | ||||
| 	auto [c, err] = findConverter( | ||||
| 	auto const [c, err] = findConverter( | ||||
| 			converters, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); | ||||
| 	if (!err) { | ||||
| 		return c->convertBuffToPtr(ctx, srcBuffer); | ||||
| 		return convert(*c, ctx, src); | ||||
| 	} | ||||
| 	// try to chain multiple converters | ||||
| 	for (auto const&subConverter : converters) { | ||||
| @@ -41,20 +49,20 @@ static ox::Result<ox::UPtr<Wrap>> convert( | ||||
| 			continue; | ||||
| 		} | ||||
| 		const auto [intermediate, chainErr] = | ||||
| 			convert(ctx, converters, srcBuffer, srcTypeName, srcTypeVersion, | ||||
| 			convert(ctx, converters, src, srcTypeName, srcTypeVersion, | ||||
| 			        subConverter->srcTypeName(), subConverter->srcTypeVersion()); | ||||
| 		if (!chainErr) { | ||||
| 			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( | ||||
| 		keel::Context &ctx, | ||||
| 		Context &ctx, | ||||
| 		ox::BufferView const&srcBuffer, | ||||
| 		ox::StringViewCR dstTypeName, | ||||
| 		int dstTypeVersion) noexcept { | ||||
| 		int const dstTypeVersion) noexcept { | ||||
| 	OX_REQUIRE(hdr, readAssetHeader(srcBuffer)); | ||||
| 	return convert( | ||||
| 			ctx, | ||||
| @@ -66,4 +74,19 @@ ox::Result<ox::UPtr<Wrap>> convert( | ||||
| 			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