open-simulation-platform / libcosim

OSP C++ co-simulation library
https://open-simulation-platform.github.io/libcosim
Mozilla Public License 2.0
54 stars 10 forks source link

Enable exporting and importing subsimulator state #769

Open kyllingstad opened 1 month ago

kyllingstad commented 1 month ago

This is a follow-up to #765 and the second and final step to close #756. It is part of a PR series which will culminate in the implementation of #757, and until that point, I am targeting the dev/state-persistence branch rather than master.

Here, I've implemented functionality to export the internal state of individual subsimulators in a generic, structured form, and to import it again later.

This exported form is intended as an intermediate step before serialisation to disk. The idea was to create a type that can be inspected and serialised to almost any file format we'd like.

The type is defined by cosim::serialization::node in cosim/serialization.hpp. It is a hierarchical, dynamic data type with support for a variety of primitive scalar types and a few aggregate types: strings, arrays of nodes, dictionaries of nodes, and binary blobs. (Think JSON-like structure, only in-memory and with more types.)

Edit: node was originally a homebrew type. Now, it is based on Boost.PropertyTree. Otherwise, the description above still fits pretty well.

kyllingstad commented 1 month ago

Hm. Seems like my little trick of storing an incomplete node type in an unordered_map doesn't work on GCC 9. It worked locally for me, but I use a more recent compiler. I've changed this PR to "draft" status while I figure out what to do about it.

kyllingstad commented 1 month ago

Ok, I made it work now.

It seems that to make a recursive map-like data type in standard C++, one has to hide the internal type, for example by messing about with void* pointers. Rather than do this myself, I have replaced the homemade cosim::serialization::node class with an alias for boost::property_tree::basic_ptree. The downside of this is a slightly less elegant API, but this is more than outweighed by the confidence we get from using tried-and-true code. Plus, we're already using ptree elsewhere in libcosim, so there's no extra dependency baggage involved.