diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.cpp index 2295a850d..5ef2a9811 100644 --- a/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.cpp +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.cpp @@ -6,6 +6,7 @@ namespace Volt void AssetSerializer::WriteMetadata(const AssetMetadata& metadata, const uint32_t version, BinaryStreamWriter& streamWriter) { SerializedAssetMetadataHeader metadataHeader{}; + metadataHeader.assetMetadataSize = sizeof(SerializedAssetMetadata); SerializedAssetMetadata serializedMetadata{}; serializedMetadata.handle = metadata.handle; @@ -15,4 +16,17 @@ namespace Volt streamWriter.Write(metadataHeader); streamWriter.Write(serializedMetadata); } + + SerializedAssetMetadata AssetSerializer::ReadMetadata(BinaryStreamReader& streamReader) + { + SerializedAssetMetadataHeader header{}; + SerializedAssetMetadata result{}; + + streamReader.Read(header); + VT_CORE_ASSERT(sizeof(SerializedAssetMetadata) == header.assetMetadataSize, "Size mismatch!"); + + streamReader.Read(result); + return result; + } + } diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.h b/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.h index 79b16ba33..a01d3361c 100644 --- a/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.h +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.h @@ -5,6 +5,7 @@ #include "Volt/Asset/Serialization/AssetSerializationCommon.h" #include "Volt/Utility/FileIO/BinaryStreamWriter.h" +#include "Volt/Utility/FileIO/BinaryStreamReader.h" namespace Volt { @@ -17,5 +18,6 @@ namespace Volt virtual bool Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const = 0; static void WriteMetadata(const AssetMetadata& metadata, const uint32_t version, BinaryStreamWriter& streamWriter); + static SerializedAssetMetadata ReadMetadata(BinaryStreamReader& streamReader); }; } diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.cpp deleted file mode 100644 index f4c3ada8f..000000000 --- a/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "vtpch.h" -#include "MeshImporter.h" - -#include "Volt/Asset/Mesh/Mesh.h" -#include "Volt/Asset/Mesh/Material.h" -#include "Volt/Asset/Serialization/AssetSerializationCommon.h" - -#include "Volt/Utility/FileIO/BinaryStreamWriter.h" - -namespace Volt -{ - constexpr uint32_t CURRENT_ASSET_VERSION = 1; - - struct MeshSerializationData - { - AssetHandle materialHandle; - - uint32_t vertexCount; - std::vector vertices; - - uint32_t indexCount; - std::vector indices; - - glm::vec3 boundingSphereCenter; - float boundingSphereRadius; - - std::vector subMeshes; - - static void Serialize(BinaryStreamWriter& streamWriter, const MeshSerializationData& data) - { - streamWriter.Write(data.materialHandle); - streamWriter.Write(data.vertexCount); - streamWriter.Write(data.vertices); - streamWriter.Write(data.indexCount); - streamWriter.Write(data.indices); - streamWriter.Write(data.boundingSphereCenter); - streamWriter.Write(data.boundingSphereRadius); - streamWriter.Write(data.subMeshes); - } - }; - - void MeshImporter::Serialize(const AssetMetadata& metadata, const Ref& asset) const - { - Ref mesh = std::reinterpret_pointer_cast(asset); - - BinaryStreamWriter streamWriter{}; - AssetSerializer::WriteMetadata(metadata, CURRENT_ASSET_VERSION, streamWriter); - - MeshSerializationData serializationData; - - streamWriter.Write(static_cast(mesh->mySubMeshes.size())); - streamWriter.Write(mesh->myMaterial->handle); - streamWriter.Write(serializationData); - } - - bool MeshImporter::Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const - { - return false; - } -} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.cpp new file mode 100644 index 000000000..416457b4e --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.cpp @@ -0,0 +1,110 @@ +#include "vtpch.h" +#include "MeshSerializer.h" + +#include "Volt/Asset/Mesh/Mesh.h" +#include "Volt/Asset/Mesh/Material.h" +#include "Volt/Asset/Serialization/AssetSerializationCommon.h" + +#include "Volt/Asset/AssetManager.h" + +namespace Volt +{ + constexpr uint32_t CURRENT_ASSET_VERSION = 1; + + struct MeshSerializationData + { + AssetHandle materialHandle; + + std::vector vertices; + std::vector indices; + + glm::vec3 boundingSphereCenter; + float boundingSphereRadius; + + std::vector subMeshes; + + static void Serialize(BinaryStreamWriter& streamWriter, const MeshSerializationData& data) + { + streamWriter.Write(data.materialHandle); + streamWriter.WriteRaw(data.vertices); + streamWriter.WriteRaw(data.indices); + streamWriter.Write(data.boundingSphereCenter); + streamWriter.Write(data.boundingSphereRadius); + streamWriter.Write(data.subMeshes); + } + + static void Deserialize(BinaryStreamReader& streamReader, MeshSerializationData& outData) + { + streamReader.Read(outData.materialHandle); + streamReader.ReadRaw(outData.vertices); + streamReader.ReadRaw(outData.indices); + streamReader.Read(outData.boundingSphereCenter); + streamReader.Read(outData.boundingSphereRadius); + streamReader.Read(outData.subMeshes); + } + }; + + void MeshSerializer::Serialize(const AssetMetadata& metadata, const Ref& asset) const + { + Ref mesh = std::reinterpret_pointer_cast(asset); + + BinaryStreamWriter streamWriter{}; + AssetSerializer::WriteMetadata(metadata, CURRENT_ASSET_VERSION, streamWriter); + + MeshSerializationData serializationData{}; + serializationData.materialHandle = mesh->GetMaterial()->handle; + serializationData.vertices = mesh->GetVertices(); + serializationData.indices = mesh->GetIndices(); + serializationData.boundingSphereCenter = mesh->GetBoundingSphere().center; + serializationData.boundingSphereRadius = mesh->GetBoundingSphere().radius; + serializationData.subMeshes = mesh->GetSubMeshes(); + + streamWriter.Write(serializationData); + + const auto filePath = AssetManager::GetFilesystemPath(metadata.filePath); + streamWriter.WriteToDisk(filePath); + } + + bool MeshSerializer::Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const + { + const auto filePath = AssetManager::GetFilesystemPath(metadata.filePath); + + if (!std::filesystem::exists(filePath)) + { + VT_CORE_ERROR("File {0} not found!", metadata.filePath); + destinationAsset->SetFlag(AssetFlag::Missing, true); + return false; + } + + BinaryStreamReader streamReader{ filePath }; + + if (!streamReader.IsStreamValid()) + { + VT_CORE_ERROR("Failed to open file: {0}!", metadata.filePath); + destinationAsset->SetFlag(AssetFlag::Invalid, true); + return false; + } + + SerializedAssetMetadata serializedMetadata = AssetSerializer::ReadMetadata(streamReader); + + MeshSerializationData serializationData{}; + streamReader.Read(serializationData); + + Ref mesh = std::reinterpret_pointer_cast(destinationAsset); + + mesh->myMaterial = AssetManager::QueueAsset(serializationData.materialHandle); + mesh->myVertices = serializationData.vertices; + mesh->myIndices = serializationData.indices; + mesh->myBoundingSphere.center = serializationData.boundingSphereCenter; + mesh->myBoundingSphere.radius = serializationData.boundingSphereRadius; + mesh->mySubMeshes = serializationData.subMeshes; + + for (auto& subMesh : mesh->mySubMeshes) + { + subMesh.GenerateHash(); + } + + mesh->Construct(); + return true; + } +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.h b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.h similarity index 83% rename from Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.h rename to Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.h index 2aab7a725..3f109147b 100644 --- a/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.h +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.h @@ -4,12 +4,10 @@ namespace Volt { - class MeshImporter : public AssetSerializer + class MeshSerializer : public AssetSerializer { public: void Serialize(const AssetMetadata& metadata, const Ref& asset) const override; bool Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const override; - - private: }; } diff --git a/Volt/Volt/src/Volt/Asset/Mesh/Mesh.h b/Volt/Volt/src/Volt/Asset/Mesh/Mesh.h index b40c14a38..4078f6f64 100644 --- a/Volt/Volt/src/Volt/Asset/Mesh/Mesh.h +++ b/Volt/Volt/src/Volt/Asset/Mesh/Mesh.h @@ -57,7 +57,7 @@ namespace Volt friend class FbxImporter; friend class MeshCompiler; - friend class MeshImporter; + friend class MeshSerializer; friend class MeshExporterUtilities; friend class VTMeshImporter; friend class GLTFImporter; diff --git a/Volt/Volt/src/Volt/Asset/Mesh/SubMesh.cpp b/Volt/Volt/src/Volt/Asset/Mesh/SubMesh.cpp index 6383c5e70..0c90c66bc 100644 --- a/Volt/Volt/src/Volt/Asset/Mesh/SubMesh.cpp +++ b/Volt/Volt/src/Volt/Asset/Mesh/SubMesh.cpp @@ -4,6 +4,9 @@ #include "Volt/Core/UUID.h" #include "Volt/Rendering/Shader/ShaderUtility.h" +#include "Volt/Utility/FileIO/BinaryStreamWriter.h" +#include "Volt/Utility/FileIO/BinaryStreamReader.h" + namespace Volt { SubMesh::SubMesh(uint32_t aMaterialIndex, uint32_t aVertexCount, uint32_t aIndexCount, uint32_t aVertexStartOffset, uint32_t aIndexStartOffset) @@ -38,6 +41,28 @@ namespace Volt return m_hash != rhs.m_hash; } + void SubMesh::Serialize(BinaryStreamWriter& streamWriter, const SubMesh& data) + { + streamWriter.Write(data.materialIndex); + streamWriter.Write(data.vertexCount); + streamWriter.Write(data.indexCount); + streamWriter.Write(data.vertexStartOffset); + streamWriter.Write(data.indexStartOffset); + streamWriter.Write(data.transform); + streamWriter.Write(data.name); + } + + void SubMesh::Deserialize(BinaryStreamReader& streamReader, SubMesh& outData) + { + streamReader.Read(outData.materialIndex); + streamReader.Read(outData.vertexCount); + streamReader.Read(outData.indexCount); + streamReader.Read(outData.vertexStartOffset); + streamReader.Read(outData.indexStartOffset); + streamReader.Read(outData.transform); + streamReader.Read(outData.name); + } + bool operator>(const SubMesh& lhs, const SubMesh& rhs) { return lhs.m_hash > rhs.m_hash; @@ -47,4 +72,4 @@ namespace Volt { return lhs.m_hash < rhs.m_hash; } -} \ No newline at end of file +} diff --git a/Volt/Volt/src/Volt/Asset/Mesh/SubMesh.h b/Volt/Volt/src/Volt/Asset/Mesh/SubMesh.h index 145308e89..eb720a977 100644 --- a/Volt/Volt/src/Volt/Asset/Mesh/SubMesh.h +++ b/Volt/Volt/src/Volt/Asset/Mesh/SubMesh.h @@ -6,6 +6,9 @@ namespace Volt { + class BinaryStreamWriter; + class BinaryStreamReader; + struct SubMesh { SubMesh(uint32_t aMaterialIndex, uint32_t aVertexCount, uint32_t aIndexCount, uint32_t aVertexStartOffset, uint32_t aIndexStartOffset); @@ -28,6 +31,9 @@ namespace Volt glm::mat4 transform = { 1.f }; std::string name; + static void Serialize(BinaryStreamWriter& streamWriter, const SubMesh& data); + static void Deserialize(BinaryStreamReader& streamReader, SubMesh& outData); + private: size_t m_hash = 0; }; diff --git a/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.cpp b/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.cpp index 6d60988ee..834bb90f0 100644 --- a/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.cpp +++ b/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.cpp @@ -2,6 +2,7 @@ #include "AssetSerializationCommon.h" #include "Volt/Utility/FileIO/BinaryStreamWriter.h" +#include "Volt/Utility/FileIO/BinaryStreamReader.h" namespace Volt { @@ -11,4 +12,11 @@ namespace Volt streamWriter.Write(data.type); streamWriter.Write(data.version); } + + void SerializedAssetMetadata::Deserialize(BinaryStreamReader& streamReader, SerializedAssetMetadata& outData) + { + streamReader.Read(outData.handle); + streamReader.Read(outData.type); + streamReader.Read(outData.version); + } } diff --git a/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.h b/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.h index 213254512..3a02fb84d 100644 --- a/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.h +++ b/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.h @@ -5,6 +5,7 @@ namespace Volt { class BinaryStreamWriter; + class BinaryStreamReader; struct SerializedAssetMetadata { @@ -13,6 +14,7 @@ namespace Volt uint32_t version; static void Serialize(BinaryStreamWriter& streamWriter, const SerializedAssetMetadata& data); + static void Deserialize(BinaryStreamReader& streamReader, SerializedAssetMetadata& outData); }; struct SerializedAssetMetadataHeader diff --git a/Volt/Volt/src/Volt/Core/UUID.cpp b/Volt/Volt/src/Volt/Core/UUID.cpp index 92fb395bf..cb41c48e8 100644 --- a/Volt/Volt/src/Volt/Core/UUID.cpp +++ b/Volt/Volt/src/Volt/Core/UUID.cpp @@ -2,6 +2,7 @@ #include "UUID.h" #include "Volt/Utility/FileIO/BinaryStreamWriter.h" +#include "Volt/Utility/FileIO/BinaryStreamReader.h" #include #include @@ -24,6 +25,11 @@ namespace Volt streamWriter.Write(data.myUUID); } + void UUID::Deserialize(BinaryStreamReader& streamReader, UUID& outData) + { + streamReader.Read(outData.myUUID); + } + UUID32::UUID32() : m_uuid(s_uniformDistribution32(s_engine32)) { diff --git a/Volt/Volt/src/Volt/Core/UUID.h b/Volt/Volt/src/Volt/Core/UUID.h index 2f8f5cb88..f5e0e3050 100644 --- a/Volt/Volt/src/Volt/Core/UUID.h +++ b/Volt/Volt/src/Volt/Core/UUID.h @@ -5,6 +5,7 @@ namespace Volt { class BinaryStreamWriter; + class BinaryStreamReader; class UUID { @@ -20,6 +21,7 @@ namespace Volt operator uint64_t() const { return myUUID; } static void Serialize(BinaryStreamWriter& streamWriter, const UUID& data); + static void Deserialize(BinaryStreamReader& streamReader, UUID& outData); private: uint64_t myUUID; diff --git a/Volt/Volt/src/Volt/Rendering/Vertex.h b/Volt/Volt/src/Volt/Rendering/Vertex.h index 13a128a2f..0af9cbb13 100644 --- a/Volt/Volt/src/Volt/Rendering/Vertex.h +++ b/Volt/Volt/src/Volt/Rendering/Vertex.h @@ -1,6 +1,7 @@ #pragma once #include "Volt/Rendering/Buffer/BufferLayout.h" +#include "Volt/Utility/FileIO/BinaryStreamWriter.h" #include #include diff --git a/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamReader.cpp b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamReader.cpp new file mode 100644 index 000000000..708e1d8f9 --- /dev/null +++ b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamReader.cpp @@ -0,0 +1,30 @@ +#include "vtpch.h" +#include "BinaryStreamReader.h" + +namespace Volt +{ + void BinaryStreamReader::ReadData(void* outData, const TypeHeader& serializedTypeHeader, const TypeHeader& constructedTypeHeader) + { + VT_CORE_ASSERT(serializedTypeHeader.baseTypeSize == constructedTypeHeader.baseTypeSize, "Base Type sizes must match!"); + m_stream.read(reinterpret_cast(outData), serializedTypeHeader.totalTypeSize); + } + + BinaryStreamReader::BinaryStreamReader(const std::filesystem::path& filePath) + { + m_stream = std::ifstream(filePath, std::ios::in | std::ios::binary); + } + + bool BinaryStreamReader::IsStreamValid() const + { + return m_stream.good(); + } + + TypeHeader BinaryStreamReader::ReadTypeHeader() + { + constexpr size_t typeHeaderSize = sizeof(TypeHeader); + + TypeHeader result{}; + m_stream.read(reinterpret_cast(&result), typeHeaderSize); + return result; + } +} diff --git a/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamReader.h b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamReader.h new file mode 100644 index 000000000..24902914d --- /dev/null +++ b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamReader.h @@ -0,0 +1,222 @@ +#pragma once + +#include "Volt/Utility/FileIO/StreamCommon.h" + +#include +#include +#include +#include +#include +#include + +namespace Volt +{ + class BinaryStreamReader + { + public: + BinaryStreamReader(const std::filesystem::path& filePath); + + bool IsStreamValid() const; + + template + void Read(T& outData); + + template<> + void Read(std::string& data); + + template + void Read(std::vector& data); + + template + void ReadRaw(std::vector& data); + + template + void Read(std::array& data); + + template + void Read(std::map& data); + + template + void Read(std::unordered_map& data); + + private: + TypeHeader ReadTypeHeader(); + void ReadData(void* outData, const TypeHeader& serializedTypeHeader, const TypeHeader& constructedTypeHeader); + + std::ifstream m_stream{}; + }; + + template + inline void BinaryStreamReader::Read(T& outData) + { + if constexpr (std::is_trivial()) + { + constexpr size_t typeSize = sizeof(T); + + TypeHeader typeHeader{}; + typeHeader.baseTypeSize = static_cast(typeSize); + typeHeader.totalTypeSize = static_cast(typeSize); + + TypeHeader serializedTypeHeader = ReadTypeHeader(); + ReadData(&outData, serializedTypeHeader, typeHeader); + } + else + { + T::Deserialize(*this, outData); + } + } + + template<> + inline void BinaryStreamReader::Read(std::string& data) + { + TypeHeader typeHeader{}; + typeHeader.baseTypeSize = sizeof(std::string); + TypeHeader serializedTypeHeader = ReadTypeHeader(); + + data.resize(serializedTypeHeader.totalTypeSize); + ReadData(data.data(), serializedTypeHeader, typeHeader); + } + + template + inline void BinaryStreamReader::Read(std::vector& data) + { + TypeHeader typeHeader{}; + typeHeader.baseTypeSize = sizeof(std::vector); + TypeHeader serializedTypeHeader = ReadTypeHeader(); + + data.resize(serializedTypeHeader.totalTypeSize / sizeof(F)); + + if constexpr (std::is_trivial()) + { + ReadData(data.data(), serializedTypeHeader, typeHeader); + } + else + { + for (size_t i = 0; i < data.size(); i++) + { + F::Deserialize(*this, data[i]); + } + } + } + + template + inline void BinaryStreamReader::ReadRaw(std::vector& data) + { + TypeHeader typeHeader{}; + typeHeader.baseTypeSize = sizeof(std::vector); + TypeHeader serializedTypeHeader = ReadTypeHeader(); + + data.resize(serializedTypeHeader.totalTypeSize / sizeof(F)); + ReadData(data.data(), serializedTypeHeader, typeHeader); + } + + template + inline void BinaryStreamReader::Read(std::array& data) + { + TypeHeader typeHeader{}; + typeHeader.baseTypeSize = sizeof(std::array); + TypeHeader serializedTypeHeader = ReadTypeHeader(); + + if constexpr (std::is_trivial()) + { + ReadData(data.data(), serializedTypeHeader, typeHeader); + } + else + { + for (size_t i = 0; i < data.size(); i++) + { + F::Deserialize(*this, data[i]); + } + } + } + + template + inline void BinaryStreamReader::Read(std::map& data) + { + TypeHeader typeHeader{}; + typeHeader.baseTypeSize = sizeof(std::map); + TypeHeader serializedTypeHeader = ReadTypeHeader(); + + const size_t elementCount = serializedTypeHeader.totalTypeSize / (sizeof(Key) + sizeof(Value)); + + for (size_t i = 0; i < elementCount; i++) + { + Key key{}; + + if constexpr (std::is_trivial()) + { + TypeHeader keyTypeHeader{}; + keyTypeHeader.baseTypeSize = sizeof(Key); + + TypeHeader keySerializedTypeHeader = ReadTypeHeader(); + ReadData(&key, keySerializedTypeHeader, keyTypeHeader); + } + else + { + Key::Deserialize(*this, key); + } + + Value value{}; + + if constexpr (std::is_trivial()) + { + TypeHeader valueTypeHeader{}; + valueTypeHeader.baseTypeSize = sizeof(Value); + + TypeHeader valueSerializedTypeHeader = ReadTypeHeader(); + ReadData(&value, valueSerializedTypeHeader, valueTypeHeader); + } + else + { + Value::Deserialize(*this, value); + } + + data.emplace(key, value); + } + } + + template + inline void BinaryStreamReader::Read(std::unordered_map& data) + { + TypeHeader typeHeader{}; + typeHeader.baseTypeSize = sizeof(std::unordered_map); + TypeHeader serializedTypeHeader = ReadTypeHeader(); + + const size_t elementCount = serializedTypeHeader.totalTypeSize / (sizeof(Key) + sizeof(Value)); + + for (size_t i = 0; i < elementCount; i++) + { + Key key{}; + + if constexpr (std::is_trivial()) + { + TypeHeader keyTypeHeader{}; + keyTypeHeader.baseTypeSize = sizeof(Key); + + TypeHeader keySerializedTypeHeader = ReadTypeHeader(); + ReadData(&key, keySerializedTypeHeader, keyTypeHeader); + } + else + { + Key::Deserialize(*this, key); + } + + Value value{}; + + if constexpr (std::is_trivial()) + { + TypeHeader valueTypeHeader{}; + valueTypeHeader.baseTypeSize = sizeof(Value); + + TypeHeader valueSerializedTypeHeader = ReadTypeHeader(); + ReadData(&value, valueSerializedTypeHeader, valueTypeHeader); + } + else + { + Value::Deserialize(*this, value); + } + + data.emplace(key, value); + } + } +} diff --git a/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.cpp b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.cpp index 2afa78f48..f57e13793 100644 --- a/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.cpp +++ b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.cpp @@ -3,6 +3,13 @@ namespace Volt { + void BinaryStreamWriter::WriteToDisk(const std::filesystem::path& targetFilepath) + { + std::ofstream stream(targetFilepath, std::ios::out | std::ios::binary); + stream.write(reinterpret_cast(m_data.data()), m_data.size()); + stream.close(); + } + void BinaryStreamWriter::WriteData(const void* data, const size_t size, const TypeHeader& typeHeader) { constexpr size_t typeHeaderSize = sizeof(TypeHeader); diff --git a/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.h b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.h index 8f990ecc8..a73ad32bc 100644 --- a/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.h +++ b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.h @@ -1,5 +1,7 @@ #pragma once +#include "Volt/Utility/FileIO/StreamCommon.h" + #include #include #include @@ -11,6 +13,9 @@ namespace Volt class BinaryStreamWriter { public: + void WriteToDisk(const std::filesystem::path& targetFilepath); + [[nodiscard]] const size_t GetSize() const { return m_data.size(); } + template [[nodiscard]] const size_t GetBinarySizeOfType(const T& object) const; @@ -29,6 +34,9 @@ namespace Volt template void Write(const std::vector& data); + template + void WriteRaw(const std::vector& data); + template void Write(const std::array& data); @@ -38,15 +46,7 @@ namespace Volt template void Write(const std::unordered_map& data); - [[nodiscard]] const size_t GetSize() const { return m_data.size(); } - private: - struct TypeHeader - { - uint16_t baseTypeSize; - uint32_t totalTypeSize; - }; - void WriteData(const void* data, const size_t size, const TypeHeader& typeHeader); void WriteData(const void* data, const size_t size); @@ -153,6 +153,16 @@ namespace Volt } } + template + inline void BinaryStreamWriter::WriteRaw(const std::vector& data) + { + TypeHeader header{}; + header.baseTypeSize = sizeof(std::vector); + header.totalTypeSize = static_cast(data.size() * sizeof(F)); + + WriteData(data.data(), data.size() * sizeof(F), header); + } + template inline void BinaryStreamWriter::Write(const std::array& data) { @@ -162,7 +172,7 @@ namespace Volt if constexpr (std::is_trivial_v) { - WriteData(data.data(), data.size() * sizeof(F), header); + WriteData(data.data(), COUNT * sizeof(F), header); } else { @@ -200,12 +210,34 @@ namespace Volt Value::Serialize(*this, value); } } - - } template inline void BinaryStreamWriter::Write(const std::unordered_map& data) { + TypeHeader header{}; + header.baseTypeSize = sizeof(std::unordered_map&data); + header.totalTypeSize = data.size() * sizeof(Key) + data.size() * sizeof(Value); + + for (const auto& [key, value] : data) + { + if constexpr (std::is_trivial_v) + { + WriteData(&key, sizeof(Key)); + } + else + { + Key::Serialize(*this, key); + } + + if constexpr (std::is_trivial_v) + { + WriteData(&value, sizeof(Value)); + } + else + { + Value::Serialize(*this, value); + } + } } } diff --git a/Volt/Volt/src/Volt/Utility/FileIO/StreamCommon.h b/Volt/Volt/src/Volt/Utility/FileIO/StreamCommon.h new file mode 100644 index 000000000..3d8c524ad --- /dev/null +++ b/Volt/Volt/src/Volt/Utility/FileIO/StreamCommon.h @@ -0,0 +1,10 @@ +#pragma once + +namespace Volt +{ + struct TypeHeader + { + uint16_t baseTypeSize; + uint32_t totalTypeSize; + }; +}