From acef4d97871591b3d30833fe855aa28572ee3b8b Mon Sep 17 00:00:00 2001 From: Danilo Date: Fri, 3 May 2024 11:49:01 -0300 Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=B5es=20em=20ContentReader?= =?UTF-8?q?=20e=20Manager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/content/manager.hpp | 5 +- framework/content/reader.cpp | 97 ++++++++++++++++++++++++- framework/content/reader.hpp | 96 ++++++++++++++++++++++-- framework/content/typereadermanager.cpp | 12 +-- framework/content/typereadermanager.hpp | 52 ++++++------- framework/csharp/object.cpp | 9 --- framework/csharp/object.hpp | 1 - framework/csharp/type.cpp | 23 ++---- framework/csharp/type.hpp | 92 ++++++++++++++--------- 9 files changed, 275 insertions(+), 112 deletions(-) diff --git a/framework/content/manager.hpp b/framework/content/manager.hpp index 7dfe009..05db4f7 100644 --- a/framework/content/manager.hpp +++ b/framework/content/manager.hpp @@ -49,10 +49,13 @@ namespace xna { return obj2; } - public: + protected: template sptr ReadAsset(String const& assetName) { auto input = OpenStream(assetName); + auto contentReader = ContentReader::Create(this, input, assetName); + + return contentReader->ReadAsset(); } sptr OpenStream(String const& assetName) { diff --git a/framework/content/reader.cpp b/framework/content/reader.cpp index 7f6a211..e108343 100644 --- a/framework/content/reader.cpp +++ b/framework/content/reader.cpp @@ -4,12 +4,91 @@ #include "typereadermanager.hpp" namespace xna { - sptr ContentReader::Create(ContentManager* contentManager, Stream* input, String const& assetName) + sptr ContentReader::Create(ContentManager* contentManager, sptr& input, String const& assetName) { - return sptr(); + Int graphicsProfile = 0; + input = ContentReader::PrepareStream(input, assetName, graphicsProfile); + return std::shared_ptr(new ContentReader(contentManager, input, assetName, graphicsProfile)); } - sptr ContentReader::PrepareStream(sptr& input, String const* assetName, Int& graphicsProfile) + Vector2 ContentReader::ReadVector2() + { + Vector2 vector2; + vector2.X = ReadSingle(); + vector2.Y = ReadSingle(); + return vector2; + } + + Vector3 ContentReader::ReadVector3() + { + Vector3 vector3; + vector3.X = ReadSingle(); + vector3.Y = ReadSingle(); + vector3.Z = ReadSingle(); + return vector3; + } + + Vector4 ContentReader::ReadVector4() + { + Vector4 vector4; + vector4.X = ReadSingle(); + vector4.Y = ReadSingle(); + vector4.Z = ReadSingle(); + vector4.W = ReadSingle(); + return vector4; + } + + Matrix ContentReader::ReadMatrix() + { + Matrix matrix; + matrix.M11 = ReadSingle(); + matrix.M12 = ReadSingle(); + matrix.M13 = ReadSingle(); + matrix.M14 = ReadSingle(); + matrix.M21 = ReadSingle(); + matrix.M22 = ReadSingle(); + matrix.M23 = ReadSingle(); + matrix.M24 = ReadSingle(); + matrix.M31 = ReadSingle(); + matrix.M32 = ReadSingle(); + matrix.M33 = ReadSingle(); + matrix.M34 = ReadSingle(); + matrix.M41 = ReadSingle(); + matrix.M42 = ReadSingle(); + matrix.M43 = ReadSingle(); + matrix.M44 = ReadSingle(); + return matrix; + } + + Quaternion ContentReader::ReadQuaternion() + { + Quaternion quaternion; + quaternion.X = ReadSingle(); + quaternion.Y = ReadSingle(); + quaternion.Z = ReadSingle(); + quaternion.W = ReadSingle(); + return quaternion; + } + + Color ContentReader::ReadColor() + { + const auto packedValue = ReadUInt32(); + return Color(packedValue); + } + + float ContentReader::ReadSingle() + { + const auto int32 = ReadUInt32(); + return *(float*)&int32; + } + + double ContentReader::ReadDouble() + { + const auto int64 = ReadUInt64(); + return *(double*)&int64; + } + + sptr ContentReader::PrepareStream(sptr& input, String const& assetName, Int& graphicsProfile) { BinaryReader binaryReader = BinaryReader(input); @@ -54,6 +133,16 @@ namespace xna { } Int ContentReader::ReadHeader() { - //typeReaders = ContentTypeReaderManager::ReadTypeManifest(this->Read7BitEncodedInt(), this); + auto _this = shared_from_this(); + typeReaders = ContentTypeReaderManager::ReadTypeManifest(this->Read7BitEncodedInt(), _this); + auto length = this->Read7BitEncodedInt(); + + if (length > 0) + { + //TODO: length > 0 + } + + return length; + } } diff --git a/framework/content/reader.hpp b/framework/content/reader.hpp index e7382c4..0f8fc77 100644 --- a/framework/content/reader.hpp +++ b/framework/content/reader.hpp @@ -3,29 +3,111 @@ #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{ + class ContentReader : public BinaryReader, public std::enable_shared_from_this{ public: - static sptr Create(ContentManager* contentManager, Stream* input, String const& assetName); + static sptr Create(ContentManager* contentManager, sptr& input, String const& assetName); template - sptr ReadAsset() { - return nullptr; - } + 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, sptrconst& input, String const& assetName) + 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); + 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 \ No newline at end of file diff --git a/framework/content/typereadermanager.cpp b/framework/content/typereadermanager.cpp index 636b7c5..43c3f5b 100644 --- a/framework/content/typereadermanager.cpp +++ b/framework/content/typereadermanager.cpp @@ -82,7 +82,7 @@ namespace xna { std::map, sptr>::iterator it; for (it = readerTypeToReader.begin(); it != readerTypeToReader.end(); it++) { - if (it->first->FullName == readerTypeName) + if (it->first->FullName() == readerTypeName) type = it->first; } @@ -111,7 +111,8 @@ namespace xna { } ContentTypeReaderManager::targetTypeToReader.insert({ targetType, reader }); - ContentTypeReaderManager::readerTypeToReader.insert({ reader->GetType(), reader }); + //ContentTypeReaderManager::readerTypeToReader.insert({ reader->GetType(), reader }); + ContentTypeReaderManager::readerTypeToReader.insert({ typeof(*reader), reader}); ContentTypeReaderManager::nameToReader.insert({ readerTypeName, reader }); } @@ -139,10 +140,5 @@ namespace xna { targetTypeToReader.insert({ typeof(), contentTypeReader}); readerTypeToReader.insert({ typeof(), contentTypeReader}); } - } - - sptr ObjectReader::Read(ContentReader input, sptr existingInstance) - { - return nullptr; - } + } } \ No newline at end of file diff --git a/framework/content/typereadermanager.hpp b/framework/content/typereadermanager.hpp index 784df69..79a812f 100644 --- a/framework/content/typereadermanager.hpp +++ b/framework/content/typereadermanager.hpp @@ -5,42 +5,43 @@ #include "../default.hpp" #include #include +#include namespace xna { //-------------------------------------------------------// // ContentTypeReader // //-------------------------------------------------------// - class ContentTypeReader : public Object { - public: - ContentTypeReader(){} - + class ContentTypeReader { public: virtual Int TypeVersion() { return 0; } virtual bool CanDeserializeIntoExistingObject() { return false; } virtual void Initialize(sptr& manager) {} - sptr TargetType() { return _targetType; } - - virtual sptr GetType() const override { - auto type = New(); - type->FullName = "xna::ContentTypeReader"; - type->Namespace = "xna"; - type->IsClass = true; - return type; - } + sptr TargetType() { return _targetType; } + virtual std::any Read(ContentReader& input, std::any& existingInstance) = 0; protected: ContentTypeReader(sptr const& targetType) : _targetType(targetType) - { - } - - virtual sptr Read(ContentReader input, sptr existingInstance) = 0; + {} public: bool TargetIsValueType{ false }; private: sptr _targetType = nullptr; + }; + + template + class ContentTypeReaderT : public ContentTypeReader { + protected: + ContentTypeReaderT(sptr const& targetType) : ContentTypeReader(targetType){} + + public: + virtual std::any Read(ContentReader& input, std::any& existingInstance) override{ + return std::any(); + } + + virtual T Read(ContentReader& input, T existingInstance) = 0; }; //-------------------------------------------------------// @@ -165,24 +166,17 @@ namespace xna { //-------------------------------------------------------// // ObjectReader // //-------------------------------------------------------// - class ObjectReader : public ContentTypeReader { + class ObjectReader : public ContentTypeReaderT { public: - ObjectReader() : ContentTypeReader(typeof(this)){ + ObjectReader() : ContentTypeReaderT(typeof()) { ContentTypeReaderActivador::SetActivador(typeof(this), []() -> sptr { auto obj = New (); return reinterpret_pointer_cast(obj); }); - } + } - // Inherited via ContentTypeReader - sptr Read(ContentReader input, sptr existingInstance) override; - - sptr GetType() const override{ - auto type = New(); - type->FullName = "xna::ObjectReader"; - type->Namespace = "xna"; - type->IsClass = true; - return type; + virtual Object Read(ContentReader& input, Object existingInstance) override { + return Object(); } }; } diff --git a/framework/csharp/object.cpp b/framework/csharp/object.cpp index 374dd51..6b61c37 100644 --- a/framework/csharp/object.cpp +++ b/framework/csharp/object.cpp @@ -2,15 +2,6 @@ #include "type.hpp" namespace xna { - sptr Object::GetType() const - { - auto type = New(); - type->FullName = "xna::Object"; - type->Namespace = "xna"; - type->IsClass = true; - return type; - } - size_t Object::GetHashCode() const { size_t seed = 0; diff --git a/framework/csharp/object.hpp b/framework/csharp/object.hpp index 9d30039..6fedc8c 100644 --- a/framework/csharp/object.hpp +++ b/framework/csharp/object.hpp @@ -6,7 +6,6 @@ namespace xna { class Object { public: - virtual sptr GetType() const; virtual size_t GetHashCode() const; }; } diff --git a/framework/csharp/type.cpp b/framework/csharp/type.cpp index 1f01559..b4ceeec 100644 --- a/framework/csharp/type.cpp +++ b/framework/csharp/type.cpp @@ -1,27 +1,14 @@ #include "type.hpp" namespace xna { - sptr Type::GetType() const - { - auto type = New(); - type->FullName = "xna::Type"; - type->Namespace = "xna"; - type->IsClass = true; - return type; - } - size_t Type::GetHashCode() const { size_t seed = 0; - XnaHHashCombine(seed, Namespace); - XnaHHashCombine(seed, FullName); - XnaHHashCombine(seed, IsInterface); - XnaHHashCombine(seed, IsArray); - XnaHHashCombine(seed, IsPointer); - XnaHHashCombine(seed, IsClass); - XnaHHashCombine(seed, IsCOMObject); - XnaHHashCombine(seed, IsEnum); - XnaHHashCombine(seed, IsValueType); + XnaHHashCombine(seed, fullName); + XnaHHashCombine(seed, isClass); + XnaHHashCombine(seed, isEnum); + XnaHHashCombine(seed, isValueType); + XnaHHashCombine(seed, isPrimitive); return seed; } diff --git a/framework/csharp/type.hpp b/framework/csharp/type.hpp index c75043e..335296a 100644 --- a/framework/csharp/type.hpp +++ b/framework/csharp/type.hpp @@ -3,59 +3,81 @@ #include "../default.hpp" #include "object.hpp" +#include +#include namespace xna { class Type : public Object { public: - String Namespace; - String FullName; - bool IsInterface{ false }; - bool IsArray{ false }; - bool IsPointer{ false }; - bool IsClass{ false }; - bool IsCOMObject{ false }; - bool IsEnum{ false }; - bool IsValueType{ false }; + constexpr String FullName() const { return fullName; } + constexpr bool IsClass() const { return isClass; } + constexpr bool IsEnum() const { return isEnum; } + constexpr bool IsValueType() const { return isValueType; } + constexpr bool IsPrimitive() const { return isPrimitive; } - constexpr bool operator==(const Type& other) const - { - return Namespace == other.Namespace - && FullName == other.FullName - && IsInterface == other.IsInterface - && IsArray == other.IsArray - && IsPointer == other.IsPointer - && IsClass == other.IsClass - && IsCOMObject == other.IsCOMObject - && IsEnum == other.IsEnum - && IsValueType == other.IsValueType; - } - - virtual sptr GetType() const override; virtual size_t GetHashCode() const; + constexpr bool operator==(const Type& other) const { + return + fullName == other.fullName + && isClass == other.isClass + && isEnum == other.isEnum + && isValueType == other.isValueType + && isPrimitive == other.isPrimitive; + } + bool operator()(Type const& t1, Type const& t2) const { return t1.GetHashCode() < t2.GetHashCode(); } - }; + + template + friend sptr typeof(); + + private: + String fullName; + bool isClass{ false }; + bool isEnum{ false }; + bool isValueType{ false }; + bool isPrimitive{ false }; + }; template inline sptr typeof() { - auto t = New(); - auto obj = reinterpret_pointer_cast(t); + if (std::is_arithmetic::value) { + auto primitiveType = New(); + primitiveType->fullName = typeid(T).name(); + primitiveType->isPrimitive = true; + primitiveType->isValueType = true; + return primitiveType; + } - if (!obj) return nullptr; - - return obj->GetType(); - } + if (std::is_enum::value) { + auto enumType = New(); + enumType->fullName = typeid(T).name(); + enumType->isValueType = true; + enumType->isEnum = true; + return enumType; + } + + if (std::is_class::value) { + auto classType = New(); + classType->fullName = typeid(T).name(); + classType->isClass = true; + + return classType; + } + + return nullptr; + } template inline sptr typeof(T const* object) { - auto obj = reinterpret_cast(object); + return typeof(); + } - if (!obj) - return nullptr; - - return obj->GetType(); + template + inline sptr typeof(T const& object) { + return typeof(); } }