diff --git a/pages/documentation/framework-overview/serialization-and-resources/archive.md b/pages/documentation/framework-overview/serialization-and-resources/archive.md index 4b7608b..b856c5e 100644 --- a/pages/documentation/framework-overview/serialization-and-resources/archive.md +++ b/pages/documentation/framework-overview/serialization-and-resources/archive.md @@ -35,7 +35,10 @@ Errors during serialization of a safe block do not affect data outside of the bl - **EndBlock()**: Ends the current archive block (may postpone exceptions). - **Flush()**: Flushes all pending events (call before destructor). -ValidateName(ea::string_view name): Validates an element or block name. +- **ValidateName(ea::string_view name)**: Validates an element or block name. + - Empty names are not allowed + - Name must start with letter or underscore. + - Name must contain only letters, digits, underscores, dots or colons. ## Block Types: The class provides methods to open different types of blocks: @@ -49,7 +52,7 @@ The class provides methods to open different types of blocks: Let's take a look at ShaderBytecode::SerializeInBlock method. It takes an Archive object as an argument, which allows it to serialize data. The purpose of this method is to serialize various properties of shader bytecode into the given archive. -```c++ +```cpp void ShaderBytecode::SerializeInBlock(Archive& archive) { const unsigned version = archive.SerializeVersion(Version); @@ -88,3 +91,99 @@ For each VertexShaderAttribute in the vector, the following steps occur: - An unordered block is opened with the attribute’s name. - The semantic, semantic index, and input index of the attribute are serialized using SerializeValue. - Destructor of the block variable automatically closes the block. + +## Helper functions: + +### SerializeValue: + +```cpp +void SerializeValue(Archive& archive, const char* name, T& value); +``` + +**SerializeValue** function used as a default serializer option. If you define new primitive type that can be serialized with Archive it is recommended to define SerializeValue function for your time. + +Here is an example of SerializeValue defined for a SphericalHarmonicsDot9 type: +```cpp +void SerializeValue(Archive& archive, const char* name, SphericalHarmonicsDot9& value) +{ + ArchiveBlock block = archive.OpenUnorderedBlock(name); + SerializeValue(archive, "Ar", value.Ar_); + SerializeValue(archive, "Ag", value.Ag_); + SerializeValue(archive, "Ab", value.Ab_); + SerializeValue(archive, "Br", value.Br_); + SerializeValue(archive, "Bg", value.Bg_); + SerializeValue(archive, "Bb", value.Bb_); + SerializeValue(archive, "C", value.C_); +} +``` + +### SerializeOptionalValue: + +```cpp +/// Serialize element or block that's optional if archive type supports it. +/// There's no overhead on optionality if Archive doesn't support optional blocks. +template +void SerializeOptionalValue(Archive& archive, const char* name, T& value, const U& defaultValue = U{}, + const TSerializer& serializeValue = TSerializer{}) +``` + +### SerializeVectorAsObjects: + +```cpp +/// Serialize vector with standard interface. Content is serialized as separate objects. +template +void SerializeVectorAsObjects(Archive& archive, const char* name, T& vector, const char* element = "element", const TSerializer& serializeValue = TSerializer{}) +``` +The **SerializeVectorAsObjects** function is a templated utility for serializing a vector of objects (elements) using a standard interface. The function allows you to serialize each element of the vector separately. + +Parameters: +- **archive**: An Archive object representing the serialization target. +- **name**: A string specifying the name of the serialized vector (used as a block name in the archive). +- **vector**: A reference to the vector of elements to be serialized. +- **element** (optional): A string specifying the name of each individual element (used within the block). +- **serializeValue** (optional): A serializer function (defaulting to Detail::DefaultSerializer) responsible for serializing an individual element. + +Steps in Serialization: + +- Determine the number of elements in the vector (numElements). +- Open an array block within the archive with the specified name and the determined size. +- If the archive is in input mode (i.e., deserialization), adjust the vector size based on the size hint provided by the block. +- Iterate over each element in the vector: + - Call the serializeValue function to serialize the element using the specified element name. + +### SerializeMap: + +```cpp +/// Serialize map or hash map with with standard interface. +template +void SerializeMap(Archive& archive, const char* name, T& map, const char* element = "element", + const TSerializer& serializeValue = TSerializer{}, bool clear = true) +``` + +The purpose of this function is to serialize the key-value pairs stored in a map (or hash map) into an Archive. It abstracts away the serialization process, allowing you to work with different types of maps consistently. + +Parameters: + +- **archive**: An Archive object representing the serialization target. +- **name**: A string specifying the name of the serialized map (used as a block name in the archive). +- **map**: A reference to the map (or hash map) to be serialized. +- **element** (optional): A string specifying the name of each individual element (used within the block). +- **serializeValue** (optional): A serializer function (defaulting to Detail::DefaultSerializer) responsible for serializing individual key-value pairs. +- **clear** (optional): A boolean flag indicating whether to clear the map before deserialization (input mode). + +Type Traits and Conditional Compilation: + +The function uses type traits and conditional compilation (if constexpr) to handle different scenarios. If the value type of the map is Variant and the serializer type matches the default (Detail::DefaultSerializer), it follows one path. Otherwise, it takes a different path. + +Serialization Process: +- The function opens an array block within the archive with the specified name and the size equal to the map’s size. +- If the archive is in input mode (i.e., deserialization): + - If clear is true, it clears the map. + - It iterates over the expected number of elements (based on the block’s size hint): + - Opens an unordered block for each element. + - Deserializes the key using serializeValue. + - Deserializes the value (either directly or via SerializeVariantInBlock if the value type is Variant). +- If the archive is in output mode (i.e., serialization): + - It iterates over each key-value pair in the map: + - Opens an unordered block for each element. + - Serializes the key and value using serializeValue. \ No newline at end of file