SeriousProton icon indicating copy to clipboard operation
SeriousProton copied to clipboard

Improved replication

Open gcask opened this issue 3 years ago • 1 comments

This build's on @daid 's proposal from #115 .

It introduces a new type, replication::Field<T> which people can use to mark replicated... fields.

⚠️ This is still very much a draft, with an API in flux. Currently trying to match all existing functionalities (including debug features, network stats).

class Sample : public MultiplayerObject
{
  float old_way;
  float old_way_interval;
  replication::Field<float> new_way;
  replication::Field<float> new_way_interval;
public:
  Sample()
  : new_way{this}, new_way_interval{this, 1.5f} // <- this part is likely to change slightly, but that's the concept
  {
    registerMemberReplication(&old_way);
    registerMemberReplication(&old_way_interval, 1.5f);
  }
};```

replicated fields can be used transparently in most context: a const-ref accessor is provided, and overloads are set for the most common writing operations (assignments mainly).

The replication handling has been moved into a dedicated class, the `ControlBlock` (modeling after the shared_ptr logic).

While it follow just about the same overall pattern as the current replication logic, the few improvements are:
  * It's type-safe. No more `void*` party.
  * It doesn't need to keep previous values around: items are marked dirty when they change (or are assigned for some objects where it is too expensive to do change detection).
  * It's faster at sorting out changed vs unchanged values: both from not having to check for change *each* attempt at updating and through using a bitset.
  * It's smaller: The current `MemberReplicationInfo` is about 48B on a 64b system, whereas the `Field<[trivial type]>` is only 32B. This currently includes padding, and could probably be shrunk a little more.

The API is aiming to be easy to use, hard to misuse while still being somewhat open ended to allow introducing custom Field types.

Again still WIP, still a draft, but would definitely appreciate any early insights or feedback.

Currently planned:
 * Field should take a setting-like struct at the beginning, currently it's a little confusing. So from `field{this, min_interval, field_args...}` to `field{ {this, min_interval, other_settings? }, field_args... }`
 * Multiplayer stats - still need a macro for the name injection etc. Will likely go from `: field{...}` to `: replicatedField(field, ...)`.
 * Vector support.

gcask avatar May 22 '21 19:05 gcask

I'm going to table this for the foreseeable future - Very selfishly, it's a little too far off my intended target :)

gcask avatar May 25 '21 16:05 gcask