1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00
xn65/inc/content/typereadermanager.hpp

126 lines
4.9 KiB
C++
Raw Normal View History

2024-05-01 19:09:43 -03:00
#ifndef XNA_CONTENT_TYPEREADER_HPP
#define XNA_CONTENT_TYPEREADER_HPP
2024-05-02 10:52:08 -03:00
#include "../csharp/type.hpp"
2024-05-01 19:09:43 -03:00
#include "../default.hpp"
#include <algorithm>
2024-05-02 10:52:08 -03:00
#include <map>
#include <any>
2024-05-01 19:09:43 -03:00
namespace xna {
2024-05-02 10:52:08 -03:00
//-------------------------------------------------------//
// ContentTypeReader //
//-------------------------------------------------------//
2024-06-03 16:10:20 -03:00
//Worker for reading a specific managed type from a binary format.
class ContentTypeReader {
2024-05-01 19:09:43 -03:00
public:
virtual Int TypeVersion() { return 0; }
2024-05-02 10:52:08 -03:00
virtual bool CanDeserializeIntoExistingObject() { return false; }
2024-06-03 16:10:20 -03:00
//Retrieves and caches nested type readers. Called by the framework at creation time.
2024-05-07 17:27:04 -03:00
virtual void Initialize(sptr<ContentTypeReaderManager> const& manager) {}
2024-06-03 16:10:20 -03:00
//Gets the type handled by this reader component.
sptr<Type> TargetType() { return _targetType; }
//Reads a strongly typed object from the current stream.
virtual std::any Read(ContentReader& input, std::any& existingInstance) = 0;
2024-05-01 19:09:43 -03:00
protected:
2024-06-03 16:10:20 -03:00
ContentTypeReader(sptr<Type> const& targetType) : _targetType(targetType)
2024-05-31 22:30:45 -03:00
{
2024-06-03 16:10:20 -03:00
}
2024-05-01 19:09:43 -03:00
2024-05-02 10:52:08 -03:00
public:
2024-06-03 16:10:20 -03:00
//Let's admit that the target is primarily of type value, if not it must be manually set to false
2024-05-31 22:30:45 -03:00
bool TargetIsValueType{ true };
2024-05-02 10:52:08 -03:00
2024-05-01 19:09:43 -03:00
private:
2024-05-02 10:52:08 -03:00
sptr<Type> _targetType = nullptr;
2024-06-03 16:10:20 -03:00
};
2024-06-03 16:10:20 -03:00
//Worker for reading a specific managed type from a binary format.
//Derive from this class to add new data types to the content pipeline system.
template <class T>
class ContentTypeReaderT : public ContentTypeReader {
2024-05-30 17:37:40 -03:00
public:
2024-06-03 16:10:20 -03:00
//For some reason ListReader<T> needs a default constructor
ContentTypeReaderT() : ContentTypeReader(typeof<T>()) {}
protected:
2024-06-03 16:10:20 -03:00
ContentTypeReaderT(sptr<Type> const& targetType) : ContentTypeReader(targetType) {}
public:
2024-06-03 16:10:20 -03:00
//Reads a strongly typed object from the current stream.
std::any Read(ContentReader& input, std::any& existingInstance) override {
if (existingInstance.has_value() && !(existingInstance.type() == typeid(T)))
2024-06-03 17:06:28 -03:00
throw std::runtime_error("ContentTypeReader<T>::Read: bad xbn, wrong type.");
2024-06-03 16:10:20 -03:00
auto existingInstance1 = XnaHelper::ReturnDefaultOrNull<T>();
auto obj = Read(input, existingInstance1);
return obj;
}
2024-06-03 16:10:20 -03:00
//Reads a strongly typed object from the current stream.
2024-05-08 10:51:49 -03:00
virtual T Read(ContentReader& input, T& existingInstance) = 0;
2024-06-03 16:10:20 -03:00
};
2024-05-01 19:09:43 -03:00
2024-05-02 10:52:08 -03:00
//-------------------------------------------------------//
// ContentTypeReaderActivador //
//-------------------------------------------------------//
2024-05-01 19:09:43 -03:00
class ContentTypeReaderActivador {
public:
using Activador = sptr<ContentTypeReader>(*)();
2024-06-03 17:06:28 -03:00
static sptr<ContentTypeReader> CreateInstance(sptr<Type> const& type);
static void SetActivador(sptr<Type> const& type, Activador activador);
2024-05-01 19:09:43 -03:00
private:
2024-05-02 10:52:08 -03:00
inline static auto activators = std::map<size_t, Activador>();
2024-05-01 19:09:43 -03:00
ContentTypeReaderActivador();
ContentTypeReaderActivador(ContentTypeReaderActivador&&);
ContentTypeReaderActivador(ContentTypeReaderActivador&);
};
using PContentTypeReader = sptr<ContentTypeReader>;
2024-05-02 10:52:08 -03:00
using PType = sptr<Type>;
2024-05-01 19:09:43 -03:00
2024-05-02 10:52:08 -03:00
//-------------------------------------------------------//
// ContentTypeReaderManager //
//-------------------------------------------------------//
2024-05-01 19:09:43 -03:00
class ContentTypeReaderManager {
public:
static std::vector<PContentTypeReader> ReadTypeManifest(Int typeCount, sptr<ContentReader>& contentReader, xna_error_nullarg);
2024-05-02 10:52:08 -03:00
static sptr<ContentTypeReader> GetTypeReader(sptr<Type> const& targetType, sptr<ContentReader>& contentReader, xna_error_nullarg);
2024-06-03 16:10:20 -03:00
2024-05-02 10:52:08 -03:00
inline sptr<ContentTypeReader> GetTypeReader(sptr<Type> const& targetType, xna_error_nullarg) {
2024-05-01 19:09:43 -03:00
return ContentTypeReaderManager::GetTypeReader(targetType, this->contentReader, err);
}
2024-05-02 10:52:08 -03:00
inline static bool ContainsTypeReader(sptr<Type> const& targetType) {
2024-05-01 19:09:43 -03:00
return ContentTypeReaderManager::targetTypeToReader.contains(targetType);
}
private:
ContentTypeReaderManager(sptr<ContentReader>& contentReader);
static sptr<ContentTypeReader> GetTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, std::vector<PContentTypeReader>& newTypeReaders, xna_error_nullarg);
2024-05-02 10:52:08 -03:00
static bool InstantiateTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_nullarg);
2024-05-01 19:09:43 -03:00
static void AddTypeReader(String const& readerTypeName, sptr<ContentReader>& contentReader, sptr<ContentTypeReader>& reader, xna_error_nullarg);
2024-06-03 16:10:20 -03:00
static void RollbackAddReaders(std::vector<sptr<ContentTypeReader>>& newTypeReaders);
2024-06-03 17:06:28 -03:00
static void RollbackAddReader(std::map<String, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader);
static void RollbackAddReader(std::map<PType, PContentTypeReader>& dictionary, sptr<ContentTypeReader>& reader);
2024-05-01 19:09:43 -03:00
private:
sptr<ContentReader> contentReader = nullptr;
2024-05-02 10:52:08 -03:00
inline static auto nameToReader = std::map<String, PContentTypeReader>();
inline static auto targetTypeToReader = std::map<PType, PContentTypeReader>();
inline static auto readerTypeToReader = std::map<PType, PContentTypeReader>();
2024-06-03 16:10:20 -03:00
2024-05-01 19:09:43 -03:00
static void initMaps();
};
}
#endif