Game.ReadSystem
Assembly: Assembly-CSharp
Namespace: Game.Serialization
Type: class
Base: GameSystemBase, IReadBufferProvider
Summary:
ReadSystem provides read-buffer provisioning for the game's deserialization pipeline. It reads raw or compressed buffer data from an asynchronous read descriptor (via StreamBinaryReader), handles optional decompression using CompressionUtils, and returns a ReadBuffer containing the uncompressed payload. The system also keeps track of read sizes in the SerializerSystem (m_SerializerSystem.totalSize) and manages the lifecycle of its StreamBinaryReader. Typical use is inside the save/load stack where the LoadGameSystem supplies the AsyncReadDescriptor to read from.
Fields
-
private struct BufferHeader
BufferHeader is a small unmanaged structure used to store both the uncompressed size (size) and compressed size (compressedSize) when the stored buffer format is compressed. -
private LoadGameSystem m_DeserializationSystem
Reference to the LoadGameSystem from the world. Used to obtain the AsyncReadDescriptor (dataDescriptor) that points to the saved data source. If the descriptor is Invalid, GetBuffer returns null. -
private SerializerSystem m_SerializerSystem
Reference to the SerializerSystem used to accumulate statistics (totalSize) for reporting/metrics about how many bytes were read. -
private StreamBinaryReader m_Reader
StreamBinaryReader used to actually read bytes from the AsyncReadDescriptor. It is lazily created when a read is first requested, and disposed/cleared on destroy/update (Clear()).
Properties
- No public properties are exposed by ReadSystem. It does implement IReadBufferProvider
which requires the GetBuffer methods (see Methods).
Constructors
public ReadSystem()
Default public constructor. Marked with [Preserve] to avoid stripping by build optimizers in deployment. The real initialization happens in OnCreate.
Methods
-
protected override void OnCreate()
Initializes the system by resolving/creating the LoadGameSystem and SerializerSystem from the world. Marked with [Preserve]. Does not allocate the StreamBinaryReader here; that's created on first GetBuffer call. -
protected override void OnDestroy()
Calls Clear() to dispose the StreamBinaryReader if present, then calls base.OnDestroy(). Marked with [Preserve]. -
protected override void OnUpdate()
Clears the StreamBinaryReader by calling Clear(). The system uses OnUpdate to ensure long-lived resources are released between updates. -
public unsafe ReadBuffer GetBuffer(BufferFormat format)
Primary synchronous buffer provider: - Returns null if LoadGameSystem.dataDescriptor is Invalid.
- Lazily constructs the StreamBinaryReader when needed.
- For compressed formats: reads a BufferHeader (size and compressedSize), increments SerializerSystem.totalSize, allocates a persistent NativeArray
for the compressed data, reads compressed bytes into it, decompresses into the returned ReadBuffer.buffer (via CompressionUtils.Decompress) and disposes the temporary NativeArray. - For BufferFormat.Raw: reads an int size then reads that many bytes directly into the ReadBuffer.buffer.
- Logs a warning for unsupported BufferFormat values.
- Increments SerializerSystem.totalSize by the header size and payload size as appropriate.
-
The returned ReadBuffer holds the uncompressed data and must be disposed by the caller when no longer needed.
-
public unsafe ReadBuffer GetBuffer(BufferFormat format, out JobHandle dependency)
Asynchronous-aware variant: - Behaves like the synchronous GetBuffer but attempts to read bytes into NativeArray or buffer without blocking; the StreamBinaryReader may return a JobHandle dependency when performing the read.
- For compressed formats: reads compressed bytes and sets up a decompression job (CompressionUtils.Decompress) that returns a JobHandle; the caller receives the JobHandle in the out parameter and is responsible for ensuring the job completes (dependency.Complete()) before accessing the returned ReadBuffer.buffer.
- The temporary NativeArray used to store compressed bytes is disposed with Dispose(dependency) so disposal happens after the dependency completes.
-
For raw format: ReadData may also return a dependency for the read of the raw bytes.
-
private void Clear()
Disposes and clears the StreamBinaryReader if it exists (called from OnDestroy and OnUpdate). -
private unsafe static void ReadData<T>(StreamBinaryReader reader, out T data) where T : unmanaged
Generic helper that reads sizeof(T) bytes from the StreamBinaryReader directly into an unmanaged T instance using UnsafeUtility.AddressOf. -
private unsafe static void ReadData(StreamBinaryReader reader, NativeArray<byte> data)
Helper that reads data.Length bytes into the provided NativeArraysynchronously. -
private unsafe static void ReadData(StreamBinaryReader reader, NativeArray<byte> data, out JobHandle dependency)
Helper that reads data.Length bytes into the provided NativeArrayand returns a JobHandle dependency for asynchronous completion.
Usage Example
// Example: synchronous read (blocks until data read and decompressed)
ReadSystem readSystem = world.GetOrCreateSystemManaged<ReadSystem>();
using (ReadBuffer buffer = readSystem.GetBuffer(BufferFormat.Compressed))
{
if (buffer != null)
{
// Access buffer.buffer (NativeArray<byte>) here.
// Ensure lifetime: dispose ReadBuffer when done (the using above).
}
}
// Example: asynchronous-aware read (returns a JobHandle dependency)
JobHandle dependency;
ReadBuffer asyncBuffer = readSystem.GetBuffer(BufferFormat.Compressed, out dependency);
if (asyncBuffer != null)
{
// Ensure the async work (read/decompress) has completed before accessing the buffer
dependency.Complete();
try
{
// Use asyncBuffer.buffer here
}
finally
{
asyncBuffer.Dispose();
}
}
Notes and important considerations: - Callers must Dispose the returned ReadBuffer to avoid native memory leaks. - When using the out JobHandle overload, always Complete() the returned JobHandle before accessing the ReadBuffer contents. - The system increments SerializerSystem.totalSize for both header and payload reads — this is used for tracking deserialization throughput and metrics. - Unsupported BufferFormat values are warned about in logs; only BufferFormat.Raw and compressible BufferFormat values are explicitly handled.