SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VariableDeltaSerializer.h
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
16 #ifndef __VARIABLE_DELTA_SERIALIZER_H
17 #define __VARIABLE_DELTA_SERIALIZER_H
18
19 #include "VariableListDeltaTracker.h"
20 #include "DS_MemoryPool.h"
21 #include "NativeTypes.h"
22 #include "BitStream.h"
23 #include "PacketPriority.h"
24 #include "DS_OrderedList.h"
25
26 namespace SLNet
27 {
28
45 class RAK_DLL_EXPORT VariableDeltaSerializer
46 {
47 protected:
48 struct RemoteSystemVariableHistory;
49 struct ChangedVariablesList;
50
51 public:
52 VariableDeltaSerializer();
53 ~VariableDeltaSerializer();
54
55 struct SerializationContext
56 {
57 SerializationContext();
58 ~SerializationContext();
59
60 RakNetGUID guid;
61 BitStream *bitStream;
62 uint32_t rakPeerSendReceipt;
63 RemoteSystemVariableHistory *variableHistory;
64 RemoteSystemVariableHistory *variableHistoryIdentical;
65 RemoteSystemVariableHistory *variableHistoryUnique;
66 ChangedVariablesList *changedVariables;
67 uint32_t sendReceipt;
68 PacketReliability serializationMode;
69 bool anyVariablesWritten;
70 bool newSystemSend; // Force send all, do not record
71 };
72
73 struct DeserializationContext
74 {
75 BitStream *bitStream;
76 };
77
89 void BeginUnreliableAckedSerialize(SerializationContext *context, RakNetGUID _guid, BitStream *_bitStream, uint32_t _sendReceipt);
90
100 void BeginUniqueSerialize(SerializationContext *context, RakNetGUID _guid, BitStream *_bitStream);
101
110 void BeginIdenticalSerialize(SerializationContext *context, bool _isFirstSerializeToThisSystem, BitStream *_bitStream);
111
114 void EndSerialize(SerializationContext *context);
115
119 void BeginDeserialize(DeserializationContext *context, BitStream *_bitStream);
120
122 void EndDeserialize(DeserializationContext *context);
123
127 void AddRemoteSystemVariableHistory(RakNetGUID guid);
128
132 void RemoveRemoteSystemVariableHistory(RakNetGUID guid);
133
137 void OnPreSerializeTick(void);
138
155 void OnMessageReceipt(RakNetGUID guid, uint32_t receiptId, bool messageArrived);
156
164 template <class VarType>
165 void SerializeVariable(SerializationContext *context, const VarType &variable)
166 {
167 if (context->newSystemSend)
168 {
169 if (context->variableHistory->variableListDeltaTracker.IsPastEndOfList()==false)
170 {
171 // previously sent data to another system
172 context->bitStream->Write(true);
173 context->bitStream->Write(variable);
174 context->anyVariablesWritten=true;
175 }
176 else
177 {
178 // never sent data to another system
179 context->variableHistory->variableListDeltaTracker.WriteVarToBitstream(variable, context->bitStream);
180 context->anyVariablesWritten=true;
181 }
182 }
183 else if (context->serializationMode==UNRELIABLE_WITH_ACK_RECEIPT)
184 {
185 context->anyVariablesWritten|=
186 context->variableHistory->variableListDeltaTracker.WriteVarToBitstream(variable, context->bitStream, context->changedVariables->bitField, context->changedVariables->bitWriteIndex++);
187 }
188 else
189 {
190 if (context->variableHistoryIdentical)
191 {
192 // Identical serialization to a number of systems
193 if (didComparisonThisTick==false)
194 context->anyVariablesWritten|=
195 context->variableHistory->variableListDeltaTracker.WriteVarToBitstream(variable, context->bitStream);
196 // Else bitstream is written to at the end
197 }
198 else
199 {
200 // Per-system serialization
201 context->anyVariablesWritten|=
202 context->variableHistory->variableListDeltaTracker.WriteVarToBitstream(variable, context->bitStream);
203 }
204 }
205 }
206
212 template <class VarType>
213 bool DeserializeVariable(DeserializationContext *context, VarType &variable)
214 {
215 return VariableListDeltaTracker::ReadVarFromBitstream(variable, context->bitStream);
216 }
217
218
219
220 protected:
221
222 // For a given send receipt from RakPeer::Send() track which variables we updated
223 // That way if that send does not arrive (ID_SND_RECEIPT_LOSS) we can mark those variables as dirty to resend them with current values
224 struct ChangedVariablesList
225 {
226 uint32_t sendReceipt;
227 unsigned short bitWriteIndex;
228 unsigned char bitField[56];
229 };
230
231 // static int Replica2ObjectComp( const uint32_t &key, ChangedVariablesList* const &data );
232
233 static int UpdatedVariablesListPtrComp( const uint32_t &key, ChangedVariablesList* const &data );
234
235 // For each remote system, track the last values of variables we sent to them, and the history of what values changed per call to Send()
236 // Every serialize if a variable changes from its last value, send it out again
237 // Also if a send does not arrive (ID_SND_RECEIPT_LOSS) we use updatedVariablesHistory to mark those variables as dirty, to resend them unreliably with the current values
238 struct RemoteSystemVariableHistory
239 {
240 RakNetGUID guid;
241 VariableListDeltaTracker variableListDeltaTracker;
242 DataStructures::OrderedList<uint32_t,ChangedVariablesList*,VariableDeltaSerializer::UpdatedVariablesListPtrComp> updatedVariablesHistory;
243 };
246 DataStructures::List<RemoteSystemVariableHistory*> remoteSystemVariableHistoryList;
247
248 // Because the ChangedVariablesList is created every serialize and destroyed every receipt I use a pool to avoid fragmentation
249 DataStructures::MemoryPool<ChangedVariablesList> updatedVariablesMemoryPool;
250
251 bool didComparisonThisTick;
252 SLNet::BitStream identicalSerializationBs;
253
254 void FreeVarsAssociatedWithReceipt(RakNetGUID guid, uint32_t receiptId);
255 void DirtyAndFreeVarsAssociatedWithReceipt(RakNetGUID guid, uint32_t receiptId);
256 unsigned int GetVarsWrittenPerRemoteSystemListIndex(RakNetGUID guid);
257 void RemoveRemoteSystemVariableHistory(void);
258
259 RemoteSystemVariableHistory* GetRemoteSystemVariableHistory(RakNetGUID guid);
260
261 ChangedVariablesList *AllocChangedVariablesList(void);
262 void FreeChangedVariablesList(ChangedVariablesList *changedVariables);
263 void StoreChangedVariablesList(RemoteSystemVariableHistory *variableHistory, ChangedVariablesList *changedVariables, uint32_t sendReceipt);
264
265 RemoteSystemVariableHistory *StartVariableHistoryWrite(RakNetGUID guid);
266 unsigned int GetRemoteSystemHistoryListIndex(RakNetGUID guid);
267
268 };
269
270 }
271
272 #endif