2024-09-05 19:15:47 +10:00
|
|
|
#pragma once
|
2023-06-20 14:33:09 +10:00
|
|
|
|
|
|
|
#include "StarNetElement.hpp"
|
|
|
|
|
|
|
|
namespace Star {
|
|
|
|
|
|
|
|
// Mixin for the NetElement that should be the top element for a network, wraps
|
|
|
|
// any NetElement class and manages the NetElementVersion.
|
|
|
|
template <typename BaseNetElement>
|
|
|
|
class NetElementTop : public BaseNetElement {
|
|
|
|
public:
|
|
|
|
NetElementTop();
|
|
|
|
|
2024-09-05 19:15:47 +10:00
|
|
|
// Writes the state update to the given DataStream then returns the version
|
|
|
|
// code that should be passed to the next call to writeState. If
|
|
|
|
// 'fromVersion' is 0, then this is a full write for an initial read of a
|
|
|
|
// slave NetElementTop.
|
|
|
|
pair<ByteArray, uint64_t> writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {});
|
2023-06-20 14:33:09 +10:00
|
|
|
// Reads a state produced by a call to writeState, optionally with the
|
|
|
|
// interpolation delay time for the data contained in this state update. If
|
|
|
|
// the state is a full update rather than a delta, the interoplation delay
|
|
|
|
// will be ignored. Blank updates are not necessary to send to be read by
|
|
|
|
// readState, *unless* extrapolation is enabled. If extrapolation is
|
|
|
|
// enabled, reading a blank update calls 'blankNetDelta' which is necessary
|
|
|
|
// to not improperly extrapolate past the end of incoming deltas.
|
2024-09-05 19:15:47 +10:00
|
|
|
void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {});
|
2023-06-20 14:33:09 +10:00
|
|
|
|
|
|
|
private:
|
|
|
|
using BaseNetElement::initNetVersion;
|
|
|
|
using BaseNetElement::netStore;
|
|
|
|
using BaseNetElement::netLoad;
|
|
|
|
using BaseNetElement::writeNetDelta;
|
|
|
|
using BaseNetElement::readNetDelta;
|
|
|
|
using BaseNetElement::blankNetDelta;
|
2024-09-05 19:15:47 +10:00
|
|
|
using BaseNetElement::checkWithRules;
|
2023-06-20 14:33:09 +10:00
|
|
|
|
|
|
|
NetElementVersion m_netVersion;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename BaseNetElement>
|
|
|
|
NetElementTop<BaseNetElement>::NetElementTop() {
|
|
|
|
BaseNetElement::initNetVersion(&m_netVersion);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename BaseNetElement>
|
2024-09-05 19:15:47 +10:00
|
|
|
pair<ByteArray, uint64_t> NetElementTop<BaseNetElement>::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) {
|
|
|
|
DataStreamBuffer ds;
|
|
|
|
ds.setStreamCompatibilityVersion(rules);
|
2023-06-20 14:33:09 +10:00
|
|
|
if (fromVersion == 0) {
|
|
|
|
ds.write<bool>(true);
|
2024-09-05 19:15:47 +10:00
|
|
|
BaseNetElement::netStore(ds, rules);
|
|
|
|
return {ds.takeData(), m_netVersion.increment()};
|
2023-06-20 14:33:09 +10:00
|
|
|
} else {
|
|
|
|
ds.write<bool>(false);
|
2024-09-05 19:15:47 +10:00
|
|
|
if (!BaseNetElement::writeNetDelta(ds, fromVersion, rules))
|
2023-06-20 14:33:09 +10:00
|
|
|
return {ByteArray(), m_netVersion.current()};
|
2024-09-05 19:15:47 +10:00
|
|
|
else
|
|
|
|
return {ds.takeData(), m_netVersion.increment()};
|
2023-06-20 14:33:09 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename BaseNetElement>
|
2024-09-05 19:15:47 +10:00
|
|
|
void NetElementTop<BaseNetElement>::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) {
|
2023-06-20 14:33:09 +10:00
|
|
|
if (data.empty()) {
|
|
|
|
BaseNetElement::blankNetDelta(interpolationTime);
|
|
|
|
} else {
|
2024-02-19 16:55:19 +01:00
|
|
|
DataStreamBuffer ds(std::move(data));
|
2024-09-05 19:15:47 +10:00
|
|
|
ds.setStreamCompatibilityVersion(rules);
|
2023-06-20 14:33:09 +10:00
|
|
|
if (ds.read<bool>())
|
2024-09-05 19:15:47 +10:00
|
|
|
BaseNetElement::netLoad(ds, rules);
|
2023-06-20 14:33:09 +10:00
|
|
|
else
|
2024-09-05 19:15:47 +10:00
|
|
|
BaseNetElement::readNetDelta(ds, interpolationTime, rules);
|
2023-06-20 14:33:09 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-05 19:15:47 +10:00
|
|
|
}
|