For e.g. #1673 we should have some backwards compatibility to allow loading older replays even if there are some changes to serialized game commands.
The main contribution to this is the VersionedSerializer class in libutil which is an adapter over the serializer adding a version. To be as uninvasive as possible it allows to be used only for parts. E.g. an instance being passed a Serializer instance can create a VersionedSerializer on top of it for the duration of the method and afterwards the caller can use the original Serializer without even knowing about this process. This is done by recording the position of the Serializer and advancing it by the amount of bytes read through the Adapter.
I also translated/updated the docstrings and while doing that I found some places for major improvements:
The random seed needs to be set when recording a replay, so require passing it
We don't need Replay::IsValid but only IsRecording/IsReplaying
ReadGF can return a proper optional instead of a bool setting a pointer param
Reading a replay command involved reading the type and calling the right function afterwards. To much detail on the caller -> Use a variant
Boost.Variant2 is superior to both Boost.Variant and std::variant by being trivial in some cases and being never empty, so use it and add a typedef for easier usability (instead of boost::variant2::variant)
Return std::string references for some accessors instead of copies
GetDataWritable + SetLength is inconvenient as we always need them paired up, so do that in one function
Allow a Deserializer to use an existing buffer, i.e. don't copy data when passed to the ctor of Serializer
For e.g. #1673 we should have some backwards compatibility to allow loading older replays even if there are some changes to serialized game commands.
The main contribution to this is the
VersionedSerializer
class in libutil which is an adapter over the serializer adding a version. To be as uninvasive as possible it allows to be used only for parts. E.g. an instance being passed aSerializer
instance can create aVersionedSerializer
on top of it for the duration of the method and afterwards the caller can use the originalSerializer
without even knowing about this process. This is done by recording the position of the Serializer and advancing it by the amount of bytes read through the Adapter.I also translated/updated the docstrings and while doing that I found some places for major improvements:
Replay::IsValid
but onlyIsRecording/IsReplaying
ReadGF
can return a proper optional instead of a bool setting a pointer paramstd::variant
by being trivial in some cases and being never empty, so use it and add a typedef for easier usability (instead ofboost::variant2::variant
)std::string
references for some accessors instead of copiesGetDataWritable + SetLength
is inconvenient as we always need them paired up, so do that in one functionSerializer