#ifndef XNA_CONTENT_READER_HPP #define XNA_CONTENT_READER_HPP #include "../default.hpp" #include "../csharp/binary.hpp" #include "../csharp/type.hpp" #include "typereadermanager.hpp" #include #include "../common/vectors.hpp" #include "../common/matrix.hpp" #include "../common/quaternion.hpp" #include "../common/color.hpp" namespace xna { class ContentReader : public BinaryReader, public std::enable_shared_from_this{ public: static sptr Create(ContentManager* contentManager, sptr& input, String const& assetName); template sptr ReadAsset(); template T ReadObject(); template T ReadObject(T existingInstance); Vector2 ReadVector2(); Vector3 ReadVector3(); Vector4 ReadVector4(); Matrix ReadMatrix(); Quaternion ReadQuaternion(); Color ReadColor(); float ReadSingle(); double ReadDouble(); private: ContentReader(ContentManager* contentManager, sptr& input, String const& assetName, Int graphicsProfile) : BinaryReader(input), _contentManager(contentManager), _assetName(assetName){} static sptr PrepareStream(sptr& input, String const& assetName, Int& graphicsProfile); Int ReadHeader(); template T ReadObjectInternal(std::any& existingInstance, xna_error_nullarg); template T InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg); private: ContentManager* _contentManager = nullptr; String _assetName; std::vector> typeReaders; Int graphicsProfile{ 0 }; }; template inline T ContentReader::ReadObjectInternal(std::any& existingInstance, xna_error_ptr_arg) { const auto num = Read7BitEncodedInt(); if (num == 0) { return T(); } const auto index = num - 1; if (index >= typeReaders.size()) { xna_error_apply(err, XnaErrorCode::ARGUMENT_OUT_OF_RANGE); return T(); } return InvokeReader(typeReaders[index], existingInstance); } template inline T ContentReader::InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_ptr_arg) { auto contentTypeReader = reinterpret_cast*>(&reader); T objB = T(); if (contentTypeReader) { T existingInstance1 = existingInstance.has_value() ? std::any_cast(existingInstance) : T(); objB = contentTypeReader->Read(*this, existingInstance1); } return T(); } template inline sptr ContentReader::ReadAsset() { const auto sharedResourceCount = ReadHeader(); T obj = ReadObject(); //this.ReadSharedResources(sharedResourceCount); return obj; } template inline T ContentReader::ReadObject() { return ReadObjectInternal(nullptr); } template inline T ContentReader::ReadObject(T existingInstance) { return ReadObjectInternal(std::any(existingInstance)); } } #endif