#ifndef XNA_CONTENT_TYPEREADER_HPP #define XNA_CONTENT_TYPEREADER_HPP #include "../csharp/type.hpp" #include "../default.hpp" #include #include #include namespace xna { //-------------------------------------------------------// // ContentTypeReader // //-------------------------------------------------------// class ContentTypeReader { public: virtual Int TypeVersion() { return 0; } virtual bool CanDeserializeIntoExistingObject() { return false; } virtual void Initialize(sptr const& manager) {} sptr TargetType() { return _targetType; } virtual std::any Read(ContentReader& input, std::any& existingInstance) = 0; protected: ContentTypeReader(sptr const& targetType) : _targetType(targetType) { //TargetIsValueType = targetType->IsValueType(); } public: //Vamos admitir que primariamente o alvo é tipo valor //caso não seja deve ser setado manualmente para falso bool TargetIsValueType{ true }; private: sptr _targetType = nullptr; }; template class ContentTypeReaderT : public ContentTypeReader { public: //Por algum motivo ListReader necessita de um construtor padrão ContentTypeReaderT() : ContentTypeReader(typeof()) { auto a = T(); } 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; }; //-------------------------------------------------------// // ContentTypeReaderActivador // //-------------------------------------------------------// class ContentTypeReaderActivador { public: using Activador = sptr(*)(); static sptr CreateInstance(sptr const& type, xna_error_nullarg) { if (!type) { xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL); return nullptr; } const auto hash = type->GetHashCode(); if (!activators.contains(hash)) return nullptr; auto activador = activators[hash]; if (!activador) return nullptr; return activador(); } static void SetActivador(sptr const& type, Activador activador, xna_error_nullarg) { if (!type) { xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL); return; } const auto hash = type->GetHashCode(); if (!activators.contains(hash)) activators.insert({ hash, activador }); } private: inline static auto activators = std::map(); ContentTypeReaderActivador(); ContentTypeReaderActivador(ContentTypeReaderActivador&&); ContentTypeReaderActivador(ContentTypeReaderActivador&); }; using PContentTypeReader = sptr; using PType = sptr; //-------------------------------------------------------// // ContentTypeReaderManager // //-------------------------------------------------------// class ContentTypeReaderManager { public: static std::vector ReadTypeManifest(Int typeCount, sptr& contentReader, xna_error_nullarg); static sptr GetTypeReader(sptr const& targetType, sptr& contentReader, xna_error_nullarg); inline sptr GetTypeReader(sptr const& targetType, xna_error_nullarg) { return ContentTypeReaderManager::GetTypeReader(targetType, this->contentReader, err); } inline static bool ContainsTypeReader(sptr const& targetType) { return ContentTypeReaderManager::targetTypeToReader.contains(targetType); } private: ContentTypeReaderManager(sptr& contentReader); static sptr GetTypeReader(String const& readerTypeName, sptr& contentReader, std::vector& newTypeReaders, xna_error_nullarg); static bool InstantiateTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader, xna_error_nullarg); static void AddTypeReader(String const& readerTypeName, sptr& contentReader, sptr& reader, xna_error_nullarg); static void RollbackAddReaders(std::vector>& newTypeReaders); static void RollbackAddReader(std::map& dictionary, sptr& reader) { std::map>::iterator it; for (it = dictionary.begin(); it != dictionary.end(); it++) { if (it->second == reader) { dictionary.erase(it->first); it = dictionary.begin(); } } } static void RollbackAddReader(std::map& dictionary, sptr& reader) { std::map>::iterator it; for (it = dictionary.begin(); it != dictionary.end(); it++) { if (it->second == reader) { dictionary.erase(it->first); it = dictionary.begin(); } } } private: sptr contentReader = nullptr; inline static auto nameToReader = std::map(); inline static auto targetTypeToReader = std::map(); inline static auto readerTypeToReader = std::map(); static void initMaps(); }; } #endif