ezEngine  Milestone 7
ezArchiveWriter Class Reference

A chunk stream writer that supports storing reflected objects and pointer references. More...

#include <Archive.h>

Inheritance diagram for ezArchiveWriter:

Classes

struct  Temp
 
struct  TypeInfo
 

Public Member Functions

 ezArchiveWriter (ezStreamWriterBase &stream)
 The constructor takes another stream to which all write requests are passed along.
 
 ~ezArchiveWriter ()
 Destructor.
 
virtual ezResult WriteBytes (const void *pWriteBuffer, ezUInt64 uiBytesToWrite) override
 Overridden function. The same restrictions apply as for ezChunkStreamWriter::WriteBytes().
 
void WriteReflectedObject (const ezReflectedClass *pReflected)
 Serializes a reflected object to the archive. More...
 
void BeginTypedObject (const ezRTTI *pRtti, const void *pReference)
 Call this function when you want to write an object that has only static reflection information and that needs to be dynamically created at deserialization. More...
 
void EndTypedObject ()
 This needs to be called in conjunction with BeginTypedObject(), once the serialization of an object is finished.
 
ezUInt32 WriteObjectReference (const void *pReference)
 Writes a reference to the given object to the stream. Upon deserialization these references will be patched to the then existing object. More...
 
void AddObjectWrittenState (const void *pReference)
 Flags the given object as already written, which can be queried using HasObjectBeenWritten(). More...
 
bool HasObjectBeenWritten (const void *pReference) const
 Returns whether the given object reference has already been written before. This includes all objects written through BeginTypedObject() and WriteReflectedObject(). More...
 
void ResetObjectWrittenState ()
 Resets the knowledge about which objects have been written already. More...
 
virtual void BeginStream () override
 This must be called before writing any data to the stream.
 
virtual void EndStream () override
 This must be called once all writing to the archive is finished.
 
void RegisterTypeSerializer (const ezRTTI *pRttiBase, ezArchiveSerializer *pSerializer)
 Registers an ezArchiveSerializer to use for specific object types (and all derived classes). More...
 
- Public Member Functions inherited from ezChunkStreamWriter
 ezChunkStreamWriter (ezStreamWriterBase &stream)
 Pass the underlying stream writer to the constructor.
 
virtual void BeginChunk (const char *szName, ezUInt32 uiVersion)
 Opens the next chunk for writing. Chunks cannot be nested (except by using multiple chunk format writers).
 
virtual void EndChunk ()
 Closes the current chunk. More...
 
- Public Member Functions inherited from ezStreamWriterBase
 ezStreamWriterBase ()
 Constructor.
 
virtual ~ezStreamWriterBase ()
 Virtual destructor to ensure correct cleanup.
 
virtual ezResult Flush ()
 Flushes the stream, may be implemented (not necessary to implement the interface correctly) so that user code can ensure that content is written.
 
template<typename T >
ezResult WriteWordValue (const T *pWordValue)
 Helper method to write a word value correctly (copes with potentially different endianess)
 
template<typename T >
ezResult WriteDWordValue (const T *pDWordValue)
 Helper method to write a dword value correctly (copes with potentially different endianess)
 
template<typename T >
ezResult WriteQWordValue (const T *pQWordValue)
 Helper method to write a qword value correctly (copes with potentially different endianess)
 

Private Member Functions

ezArchiveSerializerGetTypeSerializer (const ezRTTI *pRttiBase)
 
void StoreType (const ezRTTI *pRtti)
 

Private Attributes

bool m_bWritingFile
 
ezMap< const ezRTTI
*, ezArchiveSerializer * > 
m_TypeSerializers
 
ezMap< const ezRTTI *, TypeInfom_WrittenTypes
 
ezDeque< const ezRTTI * > m_RttiToWrite
 
ezStreamWriterBasem_OutputStream
 
ezDeque< Tempm_Temp
 
ezMemoryStreamStorage m_StorageTemp
 
ezMemoryStreamWriter m_WriterTemp
 
ezSet< const void * > m_WrittenObjects
 
ezMap< const void *, ezUInt32 > m_ObjectReferences
 

Detailed Description

A chunk stream writer that supports storing reflected objects and pointer references.

ezArchiveWriter and ezArchiveReader implement a file format that is chunked (see ezChunkStreamWriter / ezChunkStreamReader) and supports storing and restoring of reflected objects, as well as pointer references between objects.

When a reflected object is written to the archive, all necessary information to restore the object is written along with it. When reading an archive, this information is used to restore the correct instance type. Version information for reflected objects is also stored.

For types that cannot be restored without additional information, ezArchiveSerializer objects can be used to store custom information and/or to recreate objects through specialized methods.

References (pointers) to objects can be stored as well, and will be restored by the reader when the stream is closed and all referenced objects are known. References to objects that were not deserialized will be set to nullptr.

When a type is encountered during deserialization, that is unknown to the system, all objects of that type will be skipped, including nested objects. This makes the archive serialization very robust in situations where custom types (e.g. through plugins) are used.

Additionally, since it builds on the chunk stream format, entire sections may be skipped during deserialization.


Class Documentation

struct ezArchiveWriter::TypeInfo
Class Members
ezUInt32 m_uiObjects
ezUInt16 m_uiTypeID

Member Function Documentation

void ezArchiveWriter::AddObjectWrittenState ( const void *  pReference)

Flags the given object as already written, which can be queried using HasObjectBeenWritten().

This is not necessary to call manually, unless you want to do custom serialization logic for which this might be useful. This function is automatically called for all objects stored through BeginTypedObject() or WriteReflectedObject().

void ezArchiveWriter::BeginTypedObject ( const ezRTTI pRtti,
const void *  pReference 
)

Call this function when you want to write an object that has only static reflection information and that needs to be dynamically created at deserialization.

This allows to serialize classes with their type information, such that at deserialization time the loader knows which type of object to create. If an object is derived from ezReflectedClass, you can use WriteReflectedObject() instead.

If an object has reflection information, but at deserialization time it is clear which type of object will be loaded, it is not necessary to use this. For example an ezVec3 can be stored without any RTTI data.

Note
You may write objects nested. If you do and the deserialization is unable to create a parent object, the entire sub-tree of nested objects will be skipped, even when the nested objects could be deserialized.
bool ezArchiveWriter::HasObjectBeenWritten ( const void *  pReference) const

Returns whether the given object reference has already been written before. This includes all objects written through BeginTypedObject() and WriteReflectedObject().

This can be used to check whether some object has already been properly stored and whether it would be sufficient to only write a reference.

See Also
ResetObjectWrittenState()
void ezArchiveWriter::RegisterTypeSerializer ( const ezRTTI pRttiBase,
ezArchiveSerializer pSerializer 
)

Registers an ezArchiveSerializer to use for specific object types (and all derived classes).

All serializers must be registered before the archive is written to. Every time a typed / reflected object is written to the archive, it is checked whether there is a serializer for this object type (or any of its base classes). If so, that serializer is called to store additional data to the stream, before the object itself is serialized. The ezArchiveReader must then also use a serializer to read that additional data and create the object of the proper type. This way one can store custom data per object which may be required to allocate the object. This mechanism can also be used to put a custom allocator in place, even though no additional data is required. E.g. if an object needs to be allocated through a special interface (e.g. ezWorld) and cannot be globally allocated the serializer can take care of that.

void ezArchiveWriter::ResetObjectWrittenState ( )

Resets the knowledge about which objects have been written already.

This can be used to make sure that objects are written again to the same archive, which might be necessary when different chunks are written and should be independent from each other, so that a chunk can be skipped, but the next chunk duplicates all necessary data.

ezUInt32 ezArchiveWriter::WriteObjectReference ( const void *  pReference)

Writes a reference to the given object to the stream. Upon deserialization these references will be patched to the then existing object.

You can store ANY pointer as a reference, even to objects that are not written through BeginTypedObject() and these references can also be restored, as long as you manually make sure that the reference information is passed to ezArchiveReader properly.

This function returns the integer token under which the reference is stored in the archive. This might be useful, if you want to store and restore custom references.

void ezArchiveWriter::WriteReflectedObject ( const ezReflectedClass pReflected)

Serializes a reflected object to the archive.

This function internally calls BeginTypedObject() and EndTypedObject(). It also calls ezReflectedClass::Serialize() on the given object. This should be the preferred method to serialize objects that are derived from ezReflectedClass, if its exact type is not known at deserialization time and needs to be read from the archive as well. WriteReflectedObject will write all necessary information to the archive to restore the exact object type later. It will also store the object's version number, so that the deserialization code can properly read the data.


The documentation for this class was generated from the following files: