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.cpp
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 #include "slikenet/VariableDeltaSerializer.h"
17
18 using namespace SLNet;
19
20 VariableDeltaSerializer::VariableDeltaSerializer() {didComparisonThisTick=false;}
21 VariableDeltaSerializer::~VariableDeltaSerializer() {RemoveRemoteSystemVariableHistory();}
22
23 VariableDeltaSerializer::SerializationContext::SerializationContext() {variableHistoryIdentical=0; variableHistoryUnique=0;}
24 VariableDeltaSerializer::SerializationContext::~SerializationContext() {}
25
26 void VariableDeltaSerializer::OnMessageReceipt(RakNetGUID guid, uint32_t receiptId, bool messageArrived)
27 {
28 // Module?
29 if (messageArrived)
30 FreeVarsAssociatedWithReceipt(guid, receiptId);
31 else
32 DirtyAndFreeVarsAssociatedWithReceipt(guid, receiptId);
33
34 }
35
36 void VariableDeltaSerializer::BeginUnreliableAckedSerialize(SerializationContext *context, RakNetGUID _guid, BitStream *_bitStream, uint32_t _sendReceipt)
37 {
38 RakAssert(_guid!=UNASSIGNED_RAKNET_GUID);
39 context->anyVariablesWritten=false;
40 context->guid=_guid;
41 context->bitStream=_bitStream;
42 if (context->variableHistoryUnique==0)
43 context->variableHistoryUnique=StartVariableHistoryWrite(_guid);
44 context->variableHistory=context->variableHistoryUnique;
45 context->sendReceipt=_sendReceipt;
46 context->changedVariables = AllocChangedVariablesList();
47 context->newSystemSend=false;
48 context->serializationMode=UNRELIABLE_WITH_ACK_RECEIPT;
49 }
50
51 void VariableDeltaSerializer::BeginUniqueSerialize(SerializationContext *context, RakNetGUID _guid, BitStream *_bitStream)
52 {
53 RakAssert(_guid!=UNASSIGNED_RAKNET_GUID);
54 context->anyVariablesWritten=false;
55 context->guid=_guid;
56 context->bitStream=_bitStream;
57 if (context->variableHistoryUnique==0)
58 context->variableHistoryUnique=StartVariableHistoryWrite(_guid);
59 context->variableHistory=context->variableHistoryUnique;
60 context->newSystemSend=false;
61
62 context->serializationMode=RELIABLE;
63 }
64
65
66 void VariableDeltaSerializer::BeginIdenticalSerialize(SerializationContext *context, bool _isFirstSendToRemoteSystem, BitStream *_bitStream)
67 {
68 context->anyVariablesWritten=false;
69 context->guid=UNASSIGNED_RAKNET_GUID;
70 context->bitStream=_bitStream;
71 context->serializationMode=RELIABLE;
72 if (context->variableHistoryIdentical==0)
73 context->variableHistoryIdentical=StartVariableHistoryWrite(UNASSIGNED_RAKNET_GUID);
74 context->variableHistory=context->variableHistoryIdentical;
75 context->newSystemSend=_isFirstSendToRemoteSystem;
76 }
77
78 void VariableDeltaSerializer::EndSerialize(SerializationContext *context)
79 {
80 if (context->serializationMode==UNRELIABLE_WITH_ACK_RECEIPT)
81 {
82 if (context->anyVariablesWritten==false)
83 {
84 context->bitStream->Reset();
85 FreeChangedVariablesList(context->changedVariables);
86 return;
87 }
88
89 StoreChangedVariablesList(context->variableHistory, context->changedVariables, context->sendReceipt);
90 }
91 else
92 {
93 if (context->variableHistoryIdentical)
94 {
95 if (didComparisonThisTick==false)
96 {
97 didComparisonThisTick=true;
98 identicalSerializationBs.Reset();
99
100 if (context->anyVariablesWritten==false)
101 {
102 context->bitStream->Reset();
103 return;
104 }
105
106 identicalSerializationBs.Write(context->bitStream);
107 context->bitStream->ResetReadPointer();
108 }
109 else
110 {
111 context->bitStream->Write(&identicalSerializationBs);
112 identicalSerializationBs.ResetReadPointer();
113 }
114 }
115 else if (context->anyVariablesWritten==false)
116 {
117 context->bitStream->Reset();
118 return;
119 }
120 }
121 }
122
123 void VariableDeltaSerializer::BeginDeserialize(DeserializationContext *context, BitStream *_bitStream)
124 {
125 context->bitStream=_bitStream;
126 }
127
128 void VariableDeltaSerializer::EndDeserialize(DeserializationContext *context)
129 {
130 (void) context;
131 }
132
133 void VariableDeltaSerializer::AddRemoteSystemVariableHistory(RakNetGUID guid)
134 {
135 (void) guid;
136 }
137
138 void VariableDeltaSerializer::RemoveRemoteSystemVariableHistory(RakNetGUID guid)
139 {
140 unsigned int idx,idx2;
141 idx = GetVarsWrittenPerRemoteSystemListIndex(guid);
142 if (idx==(unsigned int)-1)
143 return;
144
145 if (remoteSystemVariableHistoryList[idx]->guid==guid)
146 {
147 // Memory pool doesn't call destructor
148 for (idx2=0; idx2 < remoteSystemVariableHistoryList[idx]->updatedVariablesHistory.Size(); idx2++)
149 {
150 FreeChangedVariablesList(remoteSystemVariableHistoryList[idx]->updatedVariablesHistory[idx2]);
151 }
152
153 delete remoteSystemVariableHistoryList[idx];
154 remoteSystemVariableHistoryList.RemoveAtIndexFast(idx);
155 return;
156 }
157 }
158
159 int SLNet::VariableDeltaSerializer::UpdatedVariablesListPtrComp( const uint32_t &key, ChangedVariablesList* const &data )
160 {
161 if (key<data->sendReceipt)
162 return -1;
163 if (key==data->sendReceipt)
164 return 0;
165 return 1;
166 }
167
168 void VariableDeltaSerializer::FreeVarsAssociatedWithReceipt(RakNetGUID guid, uint32_t receiptId)
169 {
170 unsigned int idx, idx2;
171 idx = GetVarsWrittenPerRemoteSystemListIndex(guid);
172 if (idx==(unsigned int)-1)
173 return;
174
175 RemoteSystemVariableHistory* vprs = remoteSystemVariableHistoryList[idx];
176 bool objectExists;
177 idx2=vprs->updatedVariablesHistory.GetIndexFromKey(receiptId,&objectExists);
178 if (objectExists)
179 {
180 // Free this history node
181 FreeChangedVariablesList(vprs->updatedVariablesHistory[idx2]);
182 vprs->updatedVariablesHistory.RemoveAtIndex(idx2);
183 }
184 }
185
186 void VariableDeltaSerializer::DirtyAndFreeVarsAssociatedWithReceipt(RakNetGUID guid, uint32_t receiptId)
187 {
188 unsigned int idx, idx2;
189 idx = GetVarsWrittenPerRemoteSystemListIndex(guid);
190 if (idx==(unsigned int)-1)
191 return;
192
193 RemoteSystemVariableHistory* vprs = remoteSystemVariableHistoryList[idx];
194 bool objectExists;
195 idx2=vprs->updatedVariablesHistory.GetIndexFromKey(receiptId,&objectExists);
196 if (objectExists)
197 {
198 // 'Dirty' all variables sent this update, meaning they will be resent the next time Serialize() is called
199 vprs->variableListDeltaTracker.FlagDirtyFromBitArray(vprs->updatedVariablesHistory[idx2]->bitField);
200
201 // Free this history node
202 FreeChangedVariablesList(vprs->updatedVariablesHistory[idx2]);
203 vprs->updatedVariablesHistory.RemoveAtIndex(idx2);
204 }
205 }
206 unsigned int VariableDeltaSerializer::GetVarsWrittenPerRemoteSystemListIndex(RakNetGUID guid)
207 {
208 unsigned int idx;
209 for (idx=0; idx < remoteSystemVariableHistoryList.Size(); idx++)
210 {
211 if (remoteSystemVariableHistoryList[idx]->guid==guid)
212 return idx;
213 }
214 return (unsigned int) -1;
215 }
216 void VariableDeltaSerializer::RemoveRemoteSystemVariableHistory(void)
217 {
218 unsigned int idx,idx2;
219 for (idx=0; idx < remoteSystemVariableHistoryList.Size(); idx++)
220 {
221 for (idx2=0; idx2 < remoteSystemVariableHistoryList[idx]->updatedVariablesHistory.Size(); idx2++)
222 {
223 FreeChangedVariablesList(remoteSystemVariableHistoryList[idx]->updatedVariablesHistory[idx2]);
224 }
225
226 delete remoteSystemVariableHistoryList[idx];
227 }
228 remoteSystemVariableHistoryList.Clear(false,_FILE_AND_LINE_);
229 }
230
231 VariableDeltaSerializer::RemoteSystemVariableHistory* VariableDeltaSerializer::GetRemoteSystemVariableHistory(RakNetGUID guid)
232 {
233 unsigned int rshli = GetRemoteSystemHistoryListIndex(guid);
234 return remoteSystemVariableHistoryList[rshli];
235 }
236
237 VariableDeltaSerializer::ChangedVariablesList *VariableDeltaSerializer::AllocChangedVariablesList(void)
238 {
239 VariableDeltaSerializer::ChangedVariablesList *p = updatedVariablesMemoryPool.Allocate(_FILE_AND_LINE_);
240 p->bitWriteIndex=0;
241 p->bitField[0]=0;
242 return p;
243 }
244 void VariableDeltaSerializer::FreeChangedVariablesList(ChangedVariablesList *changedVariables)
245 {
246 updatedVariablesMemoryPool.Release(changedVariables, _FILE_AND_LINE_);
247 }
248 void VariableDeltaSerializer::StoreChangedVariablesList(RemoteSystemVariableHistory *variableHistory, ChangedVariablesList *changedVariables, uint32_t sendReceipt)
249 {
250 changedVariables->sendReceipt=sendReceipt;
251 variableHistory->updatedVariablesHistory.Insert(changedVariables->sendReceipt,changedVariables,true,_FILE_AND_LINE_);
252 }
253
254 VariableDeltaSerializer::RemoteSystemVariableHistory *VariableDeltaSerializer::StartVariableHistoryWrite(RakNetGUID guid)
255 {
256 RemoteSystemVariableHistory *variableHistory;
257
258 unsigned int rshli = GetRemoteSystemHistoryListIndex(guid);
259 if (rshli==(unsigned int) -1)
260 {
261 variableHistory = new RemoteSystemVariableHistory;
262 variableHistory->guid=guid;
263 remoteSystemVariableHistoryList.Push(variableHistory,_FILE_AND_LINE_);
264 }
265 else
266 {
267 variableHistory=remoteSystemVariableHistoryList[rshli];
268 }
269
270 variableHistory->variableListDeltaTracker.StartWrite();
271 return variableHistory;
272 }
273 unsigned int VariableDeltaSerializer::GetRemoteSystemHistoryListIndex(RakNetGUID guid)
274 {
275 // Find the variable tracker for the target system
276 unsigned int idx;
277 for (idx=0; idx < remoteSystemVariableHistoryList.Size(); idx++)
278 {
279 if (remoteSystemVariableHistoryList[idx]->guid==guid)
280 {
281 return idx;
282 }
283 }
284 return (unsigned int) -1;
285 }
286
287 void VariableDeltaSerializer::OnPreSerializeTick(void)
288 {
289 didComparisonThisTick=false;
290 }