Skip to content

Commit

Permalink
More on Archive
Browse files Browse the repository at this point in the history
  • Loading branch information
gleblebedev committed May 8, 2024
1 parent 957f430 commit ed0af0a
Showing 1 changed file with 101 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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);
Expand Down Expand Up @@ -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 <class T, class U = EmptyObject, class TSerializer = Detail::DefaultSerializer>
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 <class T, class TSerializer = Detail::DefaultSerializer>
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 <class T, class TSerializer = Detail::DefaultSerializer>
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.

0 comments on commit ed0af0a

Please sign in to comment.