Object serialization#
Modules which have INCLUDE_MARSHAL in their vtk.module will opt their headers into the automated code generation of (de)serializers. Only classes which are annotated by the VTK_MARSHALAUTO wrapping hint will have generated serialization code.
Automated code generation#
The vtkWrapSerDes executable makes use of the WrappingTools package to automatically generate:
A serializer function with signature:
Note
Generated only for classes annotated by
VTK_MARSHALAUTOmacrostatic nlohmann:json Serialize_vtkClassName(vtkObjectBase*, vtkSerializer*)
A deserializer function with signature:
Note
Generated only for classes annotated by
VTK_MARSHALAUTOmacrostatic void Deserialize_vtkClassName(const nlohmann::json&, vtkObjectBase*, vtkDeserializer*)
A invoker function with signature:
Note
Generated for classes annotated by
VTK_MARSHALAUTOorVTK_MARSHALMANUALmacrostatic nlohmann::json Invoke_vtkClassName(vtkInvoker* invoker, vtkObjectBase* objectBase, const char* methodName, nlohmann::json args)
A registrar function that registers
the serializer function with a serializer instance
the deserializer function with a deserializer instance
the constructor of the VTK class with a deserializer instance
Here is an example for the class
vtkObject:int RegisterHandlers_vtkObjectSerDes(void* ser, void* deser, void* invoker) { int success = 0; if (auto* asObjectBase = static_cast<vtkObjectBase*>(ser)) { if (auto* serializer = vtkSerializer::SafeDownCast(asObjectBase)) { serializer->RegisterHandler(typeid(vtkObject), Serialize_vtkObject); success = 1; } } if (auto* asObjectBase = static_cast<vtkObjectBase*>(deser)) { if (auto* deserializer = vtkDeserializer::SafeDownCast(asObjectBase)) { deserializer->RegisterHandler(typeid(vtkObject), Deserialize_vtkObject); deserializer->RegisterConstructor("vtkObject", []() { return vtkObject::New(); }); success = 1; } } if (auto* asObjectBase = static_cast<vtkObjectBase*>(invoker)) { if (auto* invokerObject = vtkDeserializer::SafeDownCast(asObjectBase)) { invokerObject->RegisterHandler(typeid(vtkObject), Invoke_vtkObject); success = 1; } } return success; }
Manual marshal code#
On the other hand, the VTK_MARSHALMANUAL macro is used to indicate that a class
will take part in marshalling, but it cannot trivially (de)serialize it’s properties.
This is because one or more of the class’s properties may not have an appropriate
setter/getter function that is recognized by the VTK property parser.
For such classes, a developer is expected to provide the code to serialize and deserialize the class in vtkClassNameSerDesHelper.cxx
That file must satisfy these conditions:
It must live in the same module as
vtkClassName.It must export a function
int RegisterHandlers_vtkClassNameSerDesHelper(void*, void*, void*)with C linkage.It must define and declare the
staticfunctions from automated-code-generation.Finally, it must implement the helper function
RegisterHandlers_vtkClassNameSerDesHelperto register your handlers with the object manager. Please see theRegisterHandlers_vtkObjectSerDessample code in automated-code-generation for guidance on implementing this helper.
Example:
int RegisterHandlers_vtkClassNameSerDesHelper(void* ser, void* deser, void* invoker)
{
// See RegisterHandlers_vtkObjectSerDes for what must go here.
}
that registers:
a serializer function with a serializer instance
a deserializer function with a deserializer instance
a constructor of the VTK class with a deserializer instance
Optionally, a function that can call methods by name on an object with an invoker instance. The wrapping tool automatically generates this code even for classes annotated by
VTK_MARSHALMANUAL. You can overwrite that in your customRegisterHandlers_vtkClassNameSerDesHelper.
Marshal hint macro#
Classes which are annotated with
VTK_MARSHALAUTOare considered by thevtkWrapSerDesexecutable.Classes annotated with
VTK_MARSHALMANUALare hand coded in the same module. Here are some examples:Common/Core/vtkCollectionSerDesHelper.cxxforCommon/Core/vtkCollection.hCommon/DataModel/vtkCellArraySerDesHelper.cxxforCommon/DataModel/vtkCellArray.h
Convenient script to annotate headers and module#
The Utilities/Marshalling/marshal_macro_annotate_headers.py script annotates headers for automatic or manual serialization. It is fed and driven by the accompanying Utilities/Marshalling/VTK_MARSHALAUTO.txt, Utilities/Marshalling/VTK_MARSHALMANUAL.txt and Utilities/Marshalling/ignore.txt.
When the
-u, --updateargument is used, headers are in-place edited to use theVTK_MARSHAL(AUTO|MANUAL)wrapping hint. Files that already have this hint are untouched.When the
-t, --testargument is used, the source tree is checked for inconsistent use of marshal macros.