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

186 lines
5.5 KiB
C++
Raw Normal View History

2024-04-28 20:19:37 -03:00
#ifndef XNA_CONTENT_READER_HPP
#define XNA_CONTENT_READER_HPP
2024-06-03 21:55:09 -03:00
#include "../common/color.hpp"
#include "../common/numerics.hpp"
#include "../csharp/type.hpp"
#include "../default.hpp"
2024-12-13 17:28:46 -03:00
#include "csharp/io/binary.hpp"
#include "typereadermanager.hpp"
#include <any>
2024-12-13 17:28:46 -03:00
#include <cstdint>
#include <memory>
#include <string>
2024-04-28 20:19:37 -03:00
namespace xna {
2024-06-03 10:13:59 -03:00
//A worker object that implements most of ContentManager.Load.
2024-12-13 17:28:46 -03:00
class ContentReader : public csharp::BinaryReader, public std::enable_shared_from_this<ContentReader> {
2024-04-28 20:19:37 -03:00
public:
2024-12-13 17:28:46 -03:00
static std::shared_ptr<ContentReader> Create(std::shared_ptr<ContentManager> const& contentManager, std::shared_ptr<csharp::Stream>& input, std::string const& assetName);
2024-06-03 10:13:59 -03:00
// Reads a single object from the current stream.
template <typename T>
2024-06-01 20:33:35 -03:00
auto ReadObject();
2024-06-03 10:13:59 -03:00
// Reads a single object from the current stream.
template <typename T>
2024-07-13 22:50:52 -03:00
auto ReadObject(T& existingInstance);
2024-06-03 10:13:59 -03:00
// Reads a single object from the current stream.
2024-05-07 17:27:04 -03:00
template <typename T>
2024-06-01 20:33:35 -03:00
auto ReadObject(ContentTypeReader& typeReader);
2024-05-07 17:27:04 -03:00
2024-06-03 10:13:59 -03:00
// Reads a single object from the current stream.
2024-05-07 17:27:04 -03:00
template <typename T>
2024-07-13 22:50:52 -03:00
auto ReadObject(ContentTypeReader& typeReader, T& existingInstance);
2024-05-07 17:27:04 -03:00
2024-06-03 10:13:59 -03:00
//Reads a Vector2 value from the current stream.
Vector2 ReadVector2();
2024-06-03 10:13:59 -03:00
//Reads a Vector3 value from the current stream.
Vector3 ReadVector3();
2024-06-03 10:13:59 -03:00
//Reads a Vector4 value from the current stream.
Vector4 ReadVector4();
2024-06-03 10:13:59 -03:00
//Reads a Matrix value from the currently open stream.
Matrix ReadMatrix();
2024-06-03 10:13:59 -03:00
//Reads a Quaternion value from the current stream.
Quaternion ReadQuaternion();
2024-06-03 10:13:59 -03:00
//Reads a Color value from the currently open stream.
Color ReadColor();
2024-06-03 10:13:59 -03:00
//Reads a float value from the currently open stream.
2024-07-13 22:50:52 -03:00
float ReadSingle() override;
2024-06-03 10:13:59 -03:00
//Reads a double value from the currently open stream.
2024-07-13 22:50:52 -03:00
double ReadDouble() override;
2024-05-05 15:50:17 -03:00
2024-06-03 10:13:59 -03:00
//Gets the name of the asset currently being read by this ContentReader.
2024-12-13 17:28:46 -03:00
constexpr std::string AssetName() const {
2024-06-03 10:13:59 -03:00
return _assetName;
}
//Gets the ContentManager associated with the ContentReader.
2024-12-13 17:28:46 -03:00
std::shared_ptr<xna::ContentManager> ContentManager() const;
2024-06-03 10:13:59 -03:00
//
// Internal methods
//
template <typename T>
auto ReadAsset();
2024-12-13 17:28:46 -03:00
std::vector<uint8_t> ReadByteBuffer(size_t size);
2024-04-28 20:19:37 -03:00
private:
2024-12-13 17:28:46 -03:00
ContentReader(std::shared_ptr<xna::ContentManager> const& contentManager, std::shared_ptr<csharp::Stream>& input, std::string const& assetName, int32_t graphicsProfile)
: csharp::BinaryReader(input), _contentManager(contentManager), _assetName(assetName) {}
2024-05-01 19:09:43 -03:00
2024-12-13 17:28:46 -03:00
static std::shared_ptr<csharp::Stream> PrepareStream(std::shared_ptr<csharp::Stream>& input, std::string const& assetName, int32_t& graphicsProfile);
2024-05-01 19:09:43 -03:00
2024-12-13 17:28:46 -03:00
int32_t ReadHeader();
2024-05-01 19:09:43 -03:00
template <typename T>
2024-06-03 11:05:10 -03:00
auto ReadObjectInternal(std::any& existingInstance);
2024-05-07 17:27:04 -03:00
template <typename T>
2024-07-13 22:50:52 -03:00
auto ReadObjectInternal(ContentTypeReader& typeReader, Object& existingInstance);
template <typename T>
2024-07-13 22:50:52 -03:00
auto InvokeReader(ContentTypeReader& reader, Object& existingInstance);
2024-05-01 19:09:43 -03:00
private:
2024-12-13 17:28:46 -03:00
std::shared_ptr<xna::ContentManager> _contentManager = nullptr;
std::string _assetName;
std::vector<std::shared_ptr<ContentTypeReader>> typeReaders;
int32_t graphicsProfile{ 0 };
std::vector<uint8_t> byteBuffer;
static constexpr uint16_t XnbVersionProfileMask = 32512;
static constexpr uint16_t XnbCompressedVersion = 32773;
static constexpr uint16_t XnbVersion = 5;
static constexpr int32_t XnbVersionProfileShift = 8;
static constexpr char PlatformLabel = 'w';
static constexpr int32_t XnbPrologueSize = 10;
static constexpr int32_t XnbCompressedPrologueSize = 14;
2024-04-28 20:19:37 -03:00
};
template<typename T>
2024-07-13 22:50:52 -03:00
inline auto ContentReader::ReadObjectInternal(Object& existingInstance)
{
const auto num = Read7BitEncodedInt();
if (num == 0) {
misc::ReturnDefaultOrNull<T>();
}
const auto index = num - 1;
if (index >= typeReaders.size()) {
throw csharp::InvalidOperationException("Bad Xnb");
2024-05-30 17:37:40 -03:00
}
2024-07-13 22:50:52 -03:00
auto& reader = typeReaders[index];
2024-06-01 20:33:35 -03:00
2024-06-03 11:05:10 -03:00
return InvokeReader<T>(*reader, existingInstance);
}
template<typename T>
2024-07-13 22:50:52 -03:00
inline auto ContentReader::InvokeReader(ContentTypeReader& reader, Object& existingInstance)
{
auto contentTypeReader = reinterpret_cast<ContentTypeReaderT<T>*>(&reader);
2024-05-08 10:51:49 -03:00
T objB;
if (contentTypeReader) {
2024-05-08 10:51:49 -03:00
auto existingInstance1 = existingInstance.has_value() ? std::any_cast<T>(existingInstance) : T();
objB = contentTypeReader->Read(*this, existingInstance1);
return objB;
}
2024-07-07 16:06:05 -03:00
else {
throw csharp::InvalidOperationException();
2024-07-07 16:06:05 -03:00
}
return misc::ReturnDefaultOrNull<T>();
}
template<typename T>
2024-06-01 20:33:35 -03:00
inline auto ContentReader::ReadAsset()
{
const auto sharedResourceCount = ReadHeader();
2024-05-06 11:35:27 -03:00
auto obj = ReadObject<T>();
return obj;
}
template<typename T>
2024-06-01 20:33:35 -03:00
inline auto ContentReader::ReadObject()
{
auto a = std::any();
return ReadObjectInternal<T>(a);
}
template<typename T>
2024-07-13 22:50:52 -03:00
inline auto ContentReader::ReadObject(T& existingInstance)
{
2024-07-13 22:50:52 -03:00
return ReadObjectInternal<T>(Object(existingInstance));
}
2024-05-07 17:27:04 -03:00
template<typename T>
2024-06-01 20:33:35 -03:00
inline auto ContentReader::ReadObject(ContentTypeReader& typeReader)
2024-05-07 17:27:04 -03:00
{
auto obj = std::any();
return ReadObjectInternal<T>(typeReader, obj);
}
template<typename T>
2024-07-13 22:50:52 -03:00
inline auto ContentReader::ReadObject(ContentTypeReader& typeReader, T& existingInstance)
2024-05-07 17:27:04 -03:00
{
return ReadObjectInternal<T>(typeReader, std::any(existingInstance));
}
template<typename T>
2024-07-13 22:50:52 -03:00
inline auto ContentReader::ReadObjectInternal(ContentTypeReader& typeReader, Object& existingInstance)
2024-05-07 17:27:04 -03:00
{
2024-07-13 22:50:52 -03:00
if (typeReader.TargetIsValueType)
return InvokeReader<T>(typeReader, existingInstance);
return ReadObjectInternal<T>(existingInstance);
2024-05-07 17:27:04 -03:00
}
2024-04-28 20:19:37 -03:00
}
#endif