diff options
Diffstat (limited to 'core/src/Utils')
-rw-r--r-- | core/src/Utils/IO/Archive.cpp | 5 | ||||
-rw-r--r-- | core/src/Utils/IO/Archive.hpp | 4 | ||||
-rw-r--r-- | core/src/Utils/IO/DataStream.hpp | 68 | ||||
-rw-r--r-- | core/src/Utils/IO/Helper.hpp | 43 | ||||
-rw-r--r-- | core/src/Utils/IO/StringIntegration.hpp | 18 | ||||
-rw-r--r-- | core/src/Utils/IO/TslArrayIntegration.hpp | 26 | ||||
-rw-r--r-- | core/src/Utils/IO/TslRobinIntegration.hpp | 54 | ||||
-rw-r--r-- | core/src/Utils/IO/UuidIntegration.hpp | 8 | ||||
-rw-r--r-- | core/src/Utils/IO/VectorIntegration.hpp | 21 | ||||
-rw-r--r-- | core/src/Utils/Vector.hpp | 50 |
10 files changed, 149 insertions, 148 deletions
diff --git a/core/src/Utils/IO/Archive.cpp b/core/src/Utils/IO/Archive.cpp index 6c4084f..aa47b67 100644 --- a/core/src/Utils/IO/Archive.cpp +++ b/core/src/Utils/IO/Archive.cpp @@ -10,6 +10,11 @@ constexpr uint8_t kByteOrderMark = []() { } }(); +std::span<const uint8_t, 8> DataArchive::GetMagicNumbers() +{ + return std::span<const uint8_t, 8>{ kMagicNumbers }; +} + std::optional<InputDataStream> DataArchive::LoadFile(const std::filesystem::path& path) { auto stream = InputDataStream(InputFileStream(path)); diff --git a/core/src/Utils/IO/Archive.hpp b/core/src/Utils/IO/Archive.hpp index 28e7c99..1bb8b59 100644 --- a/core/src/Utils/IO/Archive.hpp +++ b/core/src/Utils/IO/Archive.hpp @@ -2,12 +2,16 @@ #include "Utils/IO/DataStream.hpp" +#include <cstdint> #include <filesystem> #include <optional> +#include <span> class DataArchive { public: + static std::span<const uint8_t, 8> GetMagicNumbers(); + // TODO more complete impl static std::optional<InputDataStream> LoadFile(const std::filesystem::path& path); static std::optional<OutputDataStream> SaveFile(const std::filesystem::path& path); diff --git a/core/src/Utils/IO/DataStream.hpp b/core/src/Utils/IO/DataStream.hpp index 58fae7d..3c00f4c 100644 --- a/core/src/Utils/IO/DataStream.hpp +++ b/core/src/Utils/IO/DataStream.hpp @@ -72,29 +72,7 @@ public: template <class TObject> void ReadObject(TObject& obj) { - if constexpr (requires(TObject t) { t.ReadFromDataStream(std::declval<BaseDataStream>()); }) { - obj.ReadFromDataStream(*this); - } else if constexpr (requires(TObject t) { t.OperateIOProxy(std::declval<InputDataStream>()); }) { - obj.OperateIOProxy(*this); - } else { - static_assert(false && sizeof(TObject), "This type does not have integration with InputDataStream."); - } - } - - /// Helper to invoke either Read() or ReadObject(). Note that this function doesn't account for types that needs and adapter. - /// This is intended for writing IO adapters, users that's writing IO logic shouldn't using this - it increases compile time while reducing readability. - template <class T> - void ReadGeneric(T& t) - { - if constexpr (requires(T tt, InputDataStream ss) { ss.Read(tt); }) { - Read(t); - } else if constexpr (requires(T tt, InputDataStream ss) { ss.ReadEnum(tt); }) { - ReadEnum(t); - } else if constexpr (requires(T tt, InputDataStream ss) { ss.ReadObject(tt); }) { - ReadObject(t); - } else { - static_assert(false && sizeof(T), "This type is neither a 'value' nor an 'object'."); - } + obj.ReadFromDataStream(*this); } template <class TAdapter, class TObject> @@ -104,7 +82,7 @@ public: } public: - // Proxy functions for OperateIOProxy + // Proxy functions for writing templated IO functions template <class T> void Bytes(size_t byteCount, T* buffer) @@ -119,6 +97,12 @@ public: } template <class T> + void Enum(T& t) + { + ReadEnum(t); + } + + template <class T> void Object(T& obj) { ReadObject(obj); @@ -180,41 +164,19 @@ public: } template <class TObject> - void WriteObject(TObject& obj) + void WriteObject(const TObject& obj) { - if constexpr (requires(TObject t) { t.WriteToDataStream(std::declval<BaseDataStream>()); }) { - obj.WriteToDataStream(*this); - } else if constexpr (requires(TObject t) { t.OperateIOProxy(std::declval<OutputDataStream>()); }) { - obj.OperateIOProxy(*this); - } else { - static_assert(false && sizeof(TObject), "This type does not have integration with OutputDataStream."); - } - } - - /// Helper to invoke either Write() or WriteObject(). Note that this function doesn't account for types that needs and adapter. - /// This is intended for writing IO adapters, users that's writing IO logic shouldn't using this - it increases compile time while reducing readability. - template <class T> - void WriteGeneric(T& t) - { - if constexpr (requires(T tt, OutputDataStream ss) { ss.Write(tt); }) { - Write(t); - } else if constexpr (requires(T tt, OutputDataStream ss) { ss.WriteEnum(tt); }) { - WriteEnum(t); - } else if constexpr (requires(T tt, OutputDataStream ss) { ss.WriteObject(tt); }) { - WriteObject(t); - } else { - static_assert(false && sizeof(T), "This type is neither a 'value' nor an 'object'."); - } + obj.WriteToDataStream(*this); } template <class TAdapter, class TObject> - void WriteObjectAdapted(TObject& obj) + void WriteObjectAdapted(const TObject& obj) { TAdapter::WriteToDataStream(*this, obj); } public: - // Proxy functions for OperateIOProxy + // Proxy functions for writing templated IO functions template <class T> void Bytes(size_t byteCount, T* buffer) @@ -229,6 +191,12 @@ public: } template <class T> + void Enum(T t) + { + WriteEnum(t); + } + + template <class T> void Object(T& obj) { WriteObject(obj); diff --git a/core/src/Utils/IO/Helper.hpp b/core/src/Utils/IO/Helper.hpp new file mode 100644 index 0000000..ebd47a7 --- /dev/null +++ b/core/src/Utils/IO/Helper.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include "Utils/IO/DataStream.hpp" + +namespace DataStreamAdapters { + +/// Helper to invoke either Read() or ReadObject(). +/// This is intended for writing IO adapters, users that's writing IO logic shouldn't using this - it increases compile time while reducing readability. +template <class TAdapter, class T> +void ReadHelper(InputDataStream& stream, T& t) +{ + if constexpr (!std::is_same_v<TAdapter, void>) { + stream.ReadObjectAdapted<TAdapter>(t); + } else if constexpr (requires(T tt, InputDataStream ss) { ss.Read(tt); }) { + stream.Read(t); + } else if constexpr (requires(T tt, InputDataStream ss) { ss.ReadEnum(tt); }) { + stream.ReadEnum(t); + } else if constexpr (requires(T tt, InputDataStream ss) { ss.ReadObject(tt); }) { + stream.ReadObject(t); + } else { + static_assert(false && sizeof(T), "This type is neither a 'value' nor an 'object'."); + } +} + +/// Helper to invoke either Write() or WriteObject(). +/// This is intended for writing IO adapters, users that's writing IO logic shouldn't using this - it increases compile time while reducing readability. +template <class TAdapter, class T> +void WriteHelper(OutputDataStream& stream, T& t) +{ + if constexpr (!std::is_same_v<TAdapter, void>) { + stream.WriteObjectAdapted<TAdapter>(t); + } else if constexpr (requires(T tt, OutputDataStream ss) { ss.Write(tt); }) { + stream.Write(t); + } else if constexpr (requires(T tt, OutputDataStream ss) { ss.WriteEnum(tt); }) { + stream.WriteEnum(t); + } else if constexpr (requires(T tt, OutputDataStream ss) { ss.WriteObject(tt); }) { + stream.WriteObject(t); + } else { + static_assert(false && sizeof(T), "This type is neither a 'value' nor an 'object'."); + } +} + +} // namespace DataStreamAdapters diff --git a/core/src/Utils/IO/StringIntegration.hpp b/core/src/Utils/IO/StringIntegration.hpp index 20dc882..536cb83 100644 --- a/core/src/Utils/IO/StringIntegration.hpp +++ b/core/src/Utils/IO/StringIntegration.hpp @@ -9,29 +9,29 @@ namespace DataStreamAdapters { struct String { - static void ReadFromDataStream(InputDataStream& s, std::string& str) + static void ReadFromDataStream(InputDataStream& stream, std::string& str) { uint64_t size; - s.Read(size); + stream.Read(size); str = {}; str.reserve(size); - s.ReadBytes(size, std::back_inserter(str)); + stream.ReadBytes(size, std::back_inserter(str)); } - static void WriteToDataStream(OutputDataStream& s, const std::string& str) + static void WriteToDataStream(OutputDataStream& stream, const std::string& str) { - s.Write((uint64_t)str.size()); - s.WriteBytes(str.size(), str.data()); + stream.Write((uint64_t)str.size()); + stream.WriteBytes(str.size(), str.data()); } }; struct StringView { - static void WriteToDataStream(OutputDataStream& s, const std::string_view& str) + static void WriteToDataStream(OutputDataStream& stream, const std::string_view& str) { - s.Write((uint64_t)str.size()); - s.WriteBytes(str.size(), str.data()); + stream.Write((uint64_t)str.size()); + stream.WriteBytes(str.size(), str.data()); } }; } // namespace DataStreamAdapters diff --git a/core/src/Utils/IO/TslArrayIntegration.hpp b/core/src/Utils/IO/TslArrayIntegration.hpp index eebea02..af1197c 100644 --- a/core/src/Utils/IO/TslArrayIntegration.hpp +++ b/core/src/Utils/IO/TslArrayIntegration.hpp @@ -1,6 +1,7 @@ #pragma once #include "Utils/IO/DataStream.hpp" +#include "Utils/IO/Helper.hpp" #include "Utils/IO/StringIntegration.hpp" #include <tsl/array_map.h> @@ -15,43 +16,34 @@ template <class TAdapter = void> struct TslArrayMap { template <class TValue> - static void ReadFromDataStream(InputDataStream& s, tsl::robin_map<char, TValue>& map) + static void ReadFromDataStream(InputDataStream& stream, tsl::array_map<char, TValue>& map) { static_assert(std::is_default_constructible_v<TValue>); static_assert(std::is_move_constructible_v<TValue>); uint64_t size; - s.Read(size); + stream.Read(size); map.reserve(size); for (uint64_t i = 0; i < size; ++i) { std::string key; - s.ReadObjectAdapted<DataStreamAdapters::String>(key); + stream.ReadObjectAdapted<DataStreamAdapters::String>(key); TValue value; - if constexpr (std::is_same_v<TAdapter, void>) { - s.ReadGeneric(value); - } else { - s.ReadObjectAdapted<TAdapter>(value); - } + ReadHelper<TAdapter>(stream, value); map.insert(key, std::move(value)); } } template <class TValue> - static void WriteToDataStream(OutputDataStream& s, const tsl::robin_map<char, TValue>& map) + static void WriteToDataStream(OutputDataStream& stream, const tsl::array_map<char, TValue>& map) { - s.Write((uint64_t)map.size()); + stream.Write((uint64_t)map.size()); for (auto it = map.begin(); it != map.end(); ++it) { - s.WriteObjectAdapted<DataStreamAdapters::StringView>(it.key_sv()); - - if constexpr (std::is_same_v<TAdapter, void>) { - s.WriteGeneric(it.value()); - } else { - s.WriteObjectAdapted<TAdapter>(it.value()); - } + stream.WriteObjectAdapted<DataStreamAdapters::StringView>(it.key_sv()); + WriteHelper<TAdapter>(stream, it.value()); } } }; diff --git a/core/src/Utils/IO/TslRobinIntegration.hpp b/core/src/Utils/IO/TslRobinIntegration.hpp index c800e52..50775fe 100644 --- a/core/src/Utils/IO/TslRobinIntegration.hpp +++ b/core/src/Utils/IO/TslRobinIntegration.hpp @@ -1,6 +1,7 @@ #pragma once #include "Utils/IO/DataStream.hpp" +#include "Utils/IO/Helper.hpp" #include <tsl/robin_map.h> #include <tsl/robin_set.h> @@ -11,51 +12,34 @@ template <class TKeyAdapter = void, class TValueAdapter = void> struct TslRobinMap { template <class TKey, class TValue> - static void ReadFromDataStream(InputDataStream& s, tsl::robin_map<TKey, TValue>& map) + static void ReadFromDataStream(InputDataStream& stream, tsl::robin_map<TKey, TValue>& map) { static_assert(std::is_default_constructible_v<TValue>); static_assert(std::is_move_constructible_v<TValue>); uint64_t size; - s.Read(size); + stream.Read(size); map.reserve(size); for (uint64_t i = 0; i < size; ++i) { TKey key; - if constexpr (std::is_same_v<TKeyAdapter, void>) { - s.ReadGeneric(key); - } else { - s.ReadObjectAdapted<TKeyAdapter>(key); - } + ReadHelper<TKeyAdapter>(stream, key); TValue value; - if constexpr (std::is_same_v<TValueAdapter, void>) { - s.ReadGeneric(value); - } else { - s.ReadObjectAdapted<TValueAdapter>(value); - } + ReadHelper<TValueAdapter>(stream, value); map.insert(std::move(key), std::move(value)); } } template <class TKey, class TValue> - static void WriteToDataStream(OutputDataStream& s, const tsl::robin_map<TKey, TValue>& map) + static void WriteToDataStream(OutputDataStream& stream, const tsl::robin_map<TKey, TValue>& map) { - s.Write((uint64_t)map.size()); + stream.Write((uint64_t)map.size()); for (auto it = map.begin(); it != map.end(); ++it) { - if constexpr (std::is_same_v<TKeyAdapter, void>) { - s.WriteGeneric(it.key()); - } else { - s.WriteObjectAdapted<TKeyAdapter>(it.key()); - } - - if constexpr (std::is_same_v<TValueAdapter, void>) { - s.WriteGeneric(it.value()); - } else { - s.WriteObjectAdapted<TValueAdapter>(it.value()); - } + WriteHelper<TKeyAdapter>(stream, it.key()); + WriteHelper<TValueAdapter>(stream, it.value()); } } }; @@ -64,38 +48,30 @@ template <class TAdapter = void> struct TslRobinSet { template <class TElement> - static void ReadFromDataStream(InputDataStream& s, tsl::robin_set<TElement>& set) + static void ReadFromDataStream(InputDataStream& stream, tsl::robin_set<TElement>& set) { static_assert(std::is_default_constructible_v<TElement>); static_assert(std::is_move_constructible_v<TElement>); uint64_t size; - s.Read(size); + stream.Read(size); set.reserve(size); for (uint64_t i = 0; i < size; ++i) { TElement element; - if constexpr (std::is_same_v<TAdapter, void>) { - s.ReadGeneric(element); - } else { - s.ReadObjectAdapted<TAdapter>(element); - } + ReadHelper<TAdapter>(stream, element); set.insert(std::move(element)); } } template <class TElement> - static void WriteToDataStream(OutputDataStream& s, const tsl::array_set<TElement>& set) + static void WriteToDataStream(OutputDataStream& stream, const tsl::robin_set<TElement>& set) { - s.Write((uint64_t)set.size()); + stream.Write((uint64_t)set.size()); for (auto& element : set) { - if constexpr (std::is_same_v<TAdapter, void>) { - s.WriteGeneric(element); - } else { - s.WriteObjectAdapted<TAdapter>(element); - } + WriteHelper<TAdapter>(stream, element); } } }; diff --git a/core/src/Utils/IO/UuidIntegration.hpp b/core/src/Utils/IO/UuidIntegration.hpp index d8a0304..d028c50 100644 --- a/core/src/Utils/IO/UuidIntegration.hpp +++ b/core/src/Utils/IO/UuidIntegration.hpp @@ -10,18 +10,18 @@ namespace DataStreamAdapters { struct Uuid { - static void ReadFromDataStream(InputDataStream& s, uuids::uuid& uuid) + static void ReadFromDataStream(InputDataStream& stream, uuids::uuid& uuid) { uint8_t buffer[16]; - s.ReadBytes(16, buffer); + stream.ReadBytes(16, buffer); uuid = uuids::uuid(gsl::span<uint8_t, 16>{ buffer }); } - static void WriteToDataStream(OutputDataStream& s, const uuids::uuid& uuid) + static void WriteToDataStream(OutputDataStream& stream, const uuids::uuid& uuid) { auto gslSpan = uuid.as_bytes(); - s.WriteBytes(gslSpan.size(), gslSpan.data()); + stream.WriteBytes(gslSpan.size(), gslSpan.data()); } }; } // namespace DataStreamAdapters diff --git a/core/src/Utils/IO/VectorIntegration.hpp b/core/src/Utils/IO/VectorIntegration.hpp index da663a4..3689505 100644 --- a/core/src/Utils/IO/VectorIntegration.hpp +++ b/core/src/Utils/IO/VectorIntegration.hpp @@ -1,6 +1,7 @@ #pragma once #include "Utils/IO/DataStream.hpp" +#include "Utils/IO/Helper.hpp" #include <type_traits> #include <vector> @@ -10,39 +11,31 @@ template <class TAdapter = void> struct Vector { template <class TElement> - static void ReadFromDataStream(InputDataStream& s, std::vector<TElement>& vec) + static void ReadFromDataStream(InputDataStream& stream, std::vector<TElement>& vec) { static_assert(std::is_default_constructible_v<TElement>); static_assert(std::is_move_constructible_v<TElement>); uint64_t size; - s.Read(size); + stream.Read(size); vec.clear(); vec.reserve(size); for (uint64_t i = 0; i < size; ++i) { TElement element; - if constexpr (std::is_same_v<TAdapter, void>) { - s.ReadGeneric(element); - } else { - s.ReadObjectAdapted<TAdapter>(element); - } + ReadHelper<TAdapter>(stream, element); vec.push_back(std::move(element)); } } template <class TElement> - static void WriteToDataStream(OutputDataStream& s, const std::vector<TElement>& vec) + static void WriteToDataStream(OutputDataStream& stream, const std::vector<TElement>& vec) { - s.Write((uint64_t)vec.size()); + stream.Write((uint64_t)vec.size()); for (auto& element : vec) { - if constexpr (std::is_same_v<TAdapter, void>) { - s.WriteGeneric(element); - } else { - s.WriteObjectAdapted<TAdapter>(element); - } + WriteHelper<TAdapter>(stream, element); } } }; diff --git a/core/src/Utils/Vector.hpp b/core/src/Utils/Vector.hpp index 3d4d251..4d3f3b3 100644 --- a/core/src/Utils/Vector.hpp +++ b/core/src/Utils/Vector.hpp @@ -1,5 +1,7 @@ #pragma once +#include "Utils/IO/DataStream.hpp" + template <class T> struct Vec2 { @@ -15,11 +17,16 @@ struct Vec2 }; } - template <class TProxy> - void OperateIOProxy(TProxy& proxy) + void ReadFromDataStream(InputDataStream& stream) { - proxy.Value(x); - proxy.Value(y); + stream.Value(x); + stream.Value(y); + } + + void WriteToDataStream(OutputDataStream& stream) const + { + stream.Value(x); + stream.Value(y); } friend constexpr bool operator==(const Vec2& a, const Vec2& b) = default; @@ -55,12 +62,18 @@ struct Vec3 }; } - template <class TProxy> - void OperateIOProxy(TProxy& proxy) + void ReadFromDataStream(InputDataStream& stream) + { + stream.Value(x); + stream.Value(y); + stream.Value(z); + } + + void WriteToDataStream(OutputDataStream& stream) const { - proxy.Value(x); - proxy.Value(y); - proxy.Value(z); + stream.Value(x); + stream.Value(y); + stream.Value(z); } friend constexpr bool operator==(const Vec3& a, const Vec3& b) = default; @@ -98,13 +111,20 @@ struct Vec4 }; } - template <class TProxy> - void OperateIOProxy(TProxy& proxy) + void ReadFromDataStream(InputDataStream& stream) + { + stream.Value(x); + stream.Value(y); + stream.Value(z); + stream.Value(w); + } + + void WriteToDataStream(OutputDataStream& stream) const { - proxy.Value(x); - proxy.Value(y); - proxy.Value(z); - proxy.Value(w); + stream.Value(x); + stream.Value(y); + stream.Value(z); + stream.Value(w); } friend constexpr bool operator==(const Vec4& a, const Vec4& b) = default; |