Object serialization with MemoryX

The main idea of serialization framework is to decouple what should be persisted (i.e. object fields) and how it should be done (i.e. details of specific data format). This way, serialization schema needs to be defined only once for each class, while specific formats can be carried out by corresponding writers/parsers, or "serializers".

Defining class serialization schema

In order to be processed by serialization framework, class must implement armarx::Serializable interface.

Example:

#include <ArmarXCore/interface/observers/Serialization.h>
class MyClass: public armarx::Serializable {
private: // object state to be serialized
double x;
std::string name;
std::vector<int> vec;
public: // (de)serialization methods
virtual void serialize(const armarx::ObjectSerializerBasePtr& serializer, const ::Ice::Current& c = ::Ice::Current()) const;
virtual void deserialize(const armarx::ObjectSerializerBasePtr& serializer, const ::Ice::Current& c = ::Ice::Current());
public:
... // getters/setters etc
};
void MyClass::serialize(const armarx::ObjectSerializerBasePtr& serializer, const ::Ice::Current& c) const {
AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
obj->setDouble("x", this->x);
obj->setString("name", this->name);
obj->setIntArray("vec", this->vec);
}
void MyClass::deserialize(const armarx::ObjectSerializerBasePtr& serializer, const ::Ice::Current& c) {
AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
this->x = obj->getDouble("x");
this->name = obj->getString("name");
obj->getIntArray("vec", this->vec);
}

Format-specific serializers

All serializers must be derived from abstract base class armarx::AbstractObjectSerializer. It provides setters/getters for basic datatypes and armarx::Variant. Moreover, it defines fromString/toString methods which must be implemented in descendants and perform parsing/saving an object from/to string representation.

Currently, serializer for JSON is implemented (s. memoryx::JSONObject).

Sample usage:

Ice::CommunicatorPtr ic = ... // get communicator
JSONObjectPtr jsonSerializer = new JSONObject(ic);
MyClass myObj = new MyClass();
... // init data members
myObj->serialize(jsonSerializer);
const std::string jsonString = jsonSerializer->toString();
std::cout << jsonString << std::endl;

The output would look like:

{ x: 0.13, name: "myCoolObj", vec: [1, 2, 3, 4, 5] }
cyberglove_with_calib_22dof.ic
ic
Definition: cyberglove_with_calib_22dof.py:22
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
IceInternal::Handle< ::Ice::Communicator >
armarx::JSONObjectPtr
IceInternal::Handle< JSONObject > JSONObjectPtr
Definition: JSONObject.h:34
armarx::AbstractObjectSerializerPtr
IceInternal::Handle< AbstractObjectSerializer > AbstractObjectSerializerPtr
Definition: AbstractObjectSerializer.h:45
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28