Skip to content

backmp11: Provide a reflection API and serialization support for Boost.Serialization, Boost.JSON and nlohmann/json #197

@chandryan

Description

@chandryan

Problem:
The serializer interface in backmp11 is defined as a generic friend declaration without providing an implementation.
While this allows different user-provided serializer implementations, it requires users to understand implementation details of the back-end and potentially breaks when the implementation details change.

Solution approach:
Provide a reflection API to successively iterate over all internal members of a state machine.
Such an API provides a flexible mechanism to facilitate the integration of different serialization libraries as well as any other use case that requires reflection, without requiring the user to be aware which members are present in the state machine.

The reflection API should support the most widely used serialization libraries.
Good candidates for out-of-the-box support in MSM are:

  • Boost.Serialization (part of Boost)
  • Boost.JSON (part of Boost & key-value serialization, nice feature to make a state machine's state human-readable)
  • nlohman/json (popular library)

Boost.Serialization and other binary serialization approaches can be serialized into a binary stream. Support for JSON serialization additionally requires keys to distinguish between different members of the same type.

The reflection can be provided as a free function in the backmp11 namespace. Reflection is a rare use case and a free function keeps the state_machine API lean.

// Reflect on a state_machine's members.
// ...
template<typename StateMachine, typename F>
void reflect(StateMachine& sm, F&& f);

Overview of a few serialization libraries:

Boost.Serialization:
132 stars on GitHub but probably a widely used library. Stars for Boost libraries have limited significance.

  • bidirectional syntax: operator& on the archive
  • Input/output syntax: operator>> , operator<< on the archive

cereal:
4.6k stars on GitHub, seems widespread. Inspired by Boost.Serialization, said to be a moremodern alternative.

  • bidirectional syntax: operator() on the archive with support for variadic arguments
  • Alternatively supports the Boost.Serialization operators for compatibility reasons

zpp_bits:
1k stars on GitHub.

  • bidirectional syntax: operator() on the archive with support for variadic arguments

bitsery:
1.2k stars on GitHub. Claims to be very efficient.

  • bidirectional syntax: Custom methods of the archive depending on the phyiscal layout
    • examples: archive.value1b(sm.m_event_processing);

Requires library-specific adapter code due to the custom methods.

nlohman/json:
49.3k stars on GitHub.
Does not work with binary streams, all state machine members must be passed with keys for identification.
Possiblity for support needs to be investigated. It would be a nice feature for easy introspection into a state machine.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions