diff --git a/framework/content/reader.cpp b/framework/content/reader.cpp index cdb5d3d..d35837e 100644 --- a/framework/content/reader.cpp +++ b/framework/content/reader.cpp @@ -2,16 +2,19 @@ #include "content/manager.hpp" #include "content/lzx/decoderstream.hpp" #include "content/typereadermanager.hpp" -#include "content/manager.hpp" namespace xna { - sptr ContentReader::Create(ContentManager* contentManager, sptr& input, String const& assetName) + sptr ContentReader::Create(sptr const& contentManager, sptr& input, String const& assetName) { Int graphicsProfile = 0; input = ContentReader::PrepareStream(input, assetName, graphicsProfile); return std::shared_ptr(new ContentReader(contentManager, input, assetName, graphicsProfile)); } + sptr ContentReader::ContentManager() const { + return _contentManager; + } + Vector2 ContentReader::ReadVector2() { Vector2 vector2; @@ -91,25 +94,22 @@ namespace xna { std::vector ContentReader::ReadByteBuffer(size_t size, xna_error_ptr_arg) { - std::vector& buffer = _contentManager->byteBuffer; - - if (buffer.empty() || buffer.size() < size) + if (byteBuffer.empty() || byteBuffer.size() < size) { - buffer = std::vector(size); - //_contentManager->byteBuffer = buffer; + byteBuffer.resize(size); } Int num = 0; for (size_t index = 0; index < size; index += num) { - num = Read(buffer, index, size - index); + num = Read(byteBuffer, index, size - index); if (num == 0) { xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); return std::vector(); } } - return buffer; + return byteBuffer; } sptr ContentReader::PrepareStream(sptr& input, String const& assetName, Int& graphicsProfile) @@ -117,15 +117,16 @@ namespace xna { BinaryReader binaryReader = BinaryReader(input); if (binaryReader.ReadByte() != 'X' || binaryReader.ReadByte() != 'N' || binaryReader.ReadByte() != 'B') - return nullptr; + throw std::runtime_error("ContentReader::PrepareStream: Bad xbn platform."); Int num1 = 0; - auto _byte = binaryReader.ReadByte(); //desfazer - if (_byte == 'w') - num1 = binaryReader.ReadUInt16(); - else + auto wbyte = binaryReader.ReadByte(); + + if(wbyte != 'w') throw std::runtime_error("ContentReader::PrepareStream: Bad xbn file."); + num1 = binaryReader.ReadUInt16(); + graphicsProfile = (num1 & XnbVersionProfileMask) >> XnbVersionProfileShift; bool flag = false; @@ -138,13 +139,13 @@ namespace xna { flag = true; break; default: - return nullptr; + throw std::runtime_error("ContentReader::PrepareStream: Bad xbn version."); } const auto num2 = binaryReader.ReadInt32(); - if ((num2 - 10) > input->Length() - input->Position()) - return nullptr; + if ((static_cast(num2) - 10) > input->Length() - input->Position()) + throw std::runtime_error("ContentReader::PrepareStream: Bad xbn size."); if (!flag) return input; diff --git a/inc/content/manager.hpp b/inc/content/manager.hpp index 813a99a..df7b2cc 100644 --- a/inc/content/manager.hpp +++ b/inc/content/manager.hpp @@ -9,7 +9,7 @@ namespace xna { //The run-time component which loads managed objects from the binary files produced by the design time content pipeline. - class ContentManager { + class ContentManager : public std::enable_shared_from_this { public: ContentManager(sptr const& services) : _rootDirectory("") { @@ -82,7 +82,8 @@ namespace xna { if (!input) return XnaHelper::ReturnDefaultOrNull(); - auto contentReader = ContentReader::Create(this, input, assetName); + const auto _this = shared_from_this(); + auto contentReader = ContentReader::Create(_this, input, assetName); auto asset = contentReader->ReadAsset(); return asset; @@ -94,8 +95,7 @@ namespace xna { friend class ContentReader; friend class Game; - String _rootDirectory; - std::vector byteBuffer; + String _rootDirectory; sptr _services = nullptr; std::map> _loadedAssets; diff --git a/inc/content/reader.hpp b/inc/content/reader.hpp index 94b0e17..12e140e 100644 --- a/inc/content/reader.hpp +++ b/inc/content/reader.hpp @@ -10,38 +10,63 @@ #include namespace xna { + //A worker object that implements most of ContentManager.Load. class ContentReader : public BinaryReader, public std::enable_shared_from_this { public: - static sptr Create(ContentManager* contentManager, sptr& input, String const& assetName); + static sptr Create(sptr const& contentManager, sptr& input, String const& assetName); + + // Reads a single object from the current stream. + template + auto ReadObject(); + + // Reads a single object from the current stream. + template + auto ReadObject(T existingInstance); + + // Reads a single object from the current stream. + template + auto ReadObject(ContentTypeReader& typeReader); + + // Reads a single object from the current stream. + template + auto ReadObject(ContentTypeReader& typeReader, T existingInstance); + + //Reads a Vector2 value from the current stream. + Vector2 ReadVector2(); + //Reads a Vector3 value from the current stream. + Vector3 ReadVector3(); + //Reads a Vector4 value from the current stream. + Vector4 ReadVector4(); + //Reads a Matrix value from the currently open stream. + Matrix ReadMatrix(); + //Reads a Quaternion value from the current stream. + Quaternion ReadQuaternion(); + //Reads a Color value from the currently open stream. + Color ReadColor(); + //Reads a float value from the currently open stream. + float ReadSingle(); + //Reads a double value from the currently open stream. + double ReadDouble(); + + //Gets the name of the asset currently being read by this ContentReader. + constexpr String AssetName() const { + return _assetName; + } + + //Gets the ContentManager associated with the ContentReader. + sptr ContentManager() const; + + // + // Internal methods + // template auto ReadAsset(); - template - auto ReadObject(); - - template - auto ReadObject(T existingInstance); - - template - auto ReadObject(ContentTypeReader& typeReader); - - template - auto ReadObject(ContentTypeReader& typeReader, T existingInstance); - - Vector2 ReadVector2(); - Vector3 ReadVector3(); - Vector4 ReadVector4(); - Matrix ReadMatrix(); - Quaternion ReadQuaternion(); - Color ReadColor(); - float ReadSingle(); - double ReadDouble(); - - std::vector ReadByteBuffer(size_t size, xna_error_nullarg); + std::vector ReadByteBuffer(size_t size, xna_error_nullarg); private: - ContentReader(ContentManager* contentManager, sptr& input, String const& assetName, Int graphicsProfile) + ContentReader(sptr const& contentManager, sptr& input, String const& assetName, Int graphicsProfile) : BinaryReader(input), _contentManager(contentManager), _assetName(assetName) {} static sptr PrepareStream(sptr& input, String const& assetName, Int& graphicsProfile); @@ -58,10 +83,11 @@ namespace xna { auto InvokeReader(ContentTypeReader& reader, std::any& existingInstance, xna_error_nullarg); private: - ContentManager* _contentManager = nullptr; + sptr _contentManager = nullptr; String _assetName; std::vector> typeReaders; Int graphicsProfile{ 0 }; + std::vector byteBuffer; static constexpr Ushort XnbVersionProfileMask = 32512; static constexpr Ushort XnbCompressedVersion = 32773;