Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarNetElementTop.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/StarNetElementTop.hpp')
-rw-r--r--source/core/StarNetElementTop.hpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/source/core/StarNetElementTop.hpp b/source/core/StarNetElementTop.hpp
new file mode 100644
index 0000000..fa85688
--- /dev/null
+++ b/source/core/StarNetElementTop.hpp
@@ -0,0 +1,82 @@
+#ifndef STAR_NET_ELEMENT_TOP_HPP
+#define STAR_NET_ELEMENT_TOP_HPP
+
+#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();
+
+ // Returns the state update, combined with 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);
+ // 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.
+ void readNetState(ByteArray data, float interpolationTime = 0.0);
+
+private:
+ using BaseNetElement::initNetVersion;
+ using BaseNetElement::netStore;
+ using BaseNetElement::netLoad;
+ using BaseNetElement::writeNetDelta;
+ using BaseNetElement::readNetDelta;
+ using BaseNetElement::blankNetDelta;
+
+ NetElementVersion m_netVersion;
+};
+
+template <typename BaseNetElement>
+NetElementTop<BaseNetElement>::NetElementTop() {
+ BaseNetElement::initNetVersion(&m_netVersion);
+}
+
+template <typename BaseNetElement>
+pair<ByteArray, uint64_t> NetElementTop<BaseNetElement>::writeNetState(uint64_t fromVersion) {
+ if (fromVersion == 0) {
+ DataStreamBuffer ds;
+ ds.write<bool>(true);
+ BaseNetElement::netStore(ds);
+ m_netVersion.increment();
+ return {ds.takeData(), m_netVersion.current()};
+
+ } else {
+ DataStreamBuffer ds;
+ ds.write<bool>(false);
+ if (!BaseNetElement::writeNetDelta(ds, fromVersion)) {
+ return {ByteArray(), m_netVersion.current()};
+ } else {
+ m_netVersion.increment();
+ return {ds.takeData(), m_netVersion.current()};
+ }
+ }
+}
+
+template <typename BaseNetElement>
+void NetElementTop<BaseNetElement>::readNetState(ByteArray data, float interpolationTime) {
+ if (data.empty()) {
+ BaseNetElement::blankNetDelta(interpolationTime);
+
+ } else {
+ DataStreamBuffer ds(move(data));
+
+ if (ds.read<bool>())
+ BaseNetElement::netLoad(ds);
+ else
+ BaseNetElement::readNetDelta(ds, interpolationTime);
+ }
+}
+
+}
+
+#endif