![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 #ifndef __VARIABLE_DELTA_SERIALIZER_H 00002 #define __VARIABLE_DELTA_SERIALIZER_H 00003 00004 #include "VariableListDeltaTracker.h" 00005 #include "DS_MemoryPool.h" 00006 #include "NativeTypes.h" 00007 #include "BitStream.h" 00008 #include "PacketPriority.h" 00009 #include "DS_OrderedList.h" 00010 00011 namespace RakNet 00012 { 00013 00030 class VariableDeltaSerializer 00031 { 00032 protected: 00033 struct RemoteSystemVariableHistory; 00034 struct ChangedVariablesList; 00035 00036 public: 00037 VariableDeltaSerializer(); 00038 ~VariableDeltaSerializer(); 00039 00040 struct SerializationContext 00041 { 00042 SerializationContext(); 00043 ~SerializationContext(); 00044 00045 RakNetGUID guid; 00046 BitStream *bitStream; 00047 uint32_t rakPeerSendReceipt; 00048 RemoteSystemVariableHistory *variableHistory; 00049 RemoteSystemVariableHistory *variableHistoryIdentical; 00050 RemoteSystemVariableHistory *variableHistoryUnique; 00051 ChangedVariablesList *changedVariables; 00052 uint32_t sendReceipt; 00053 PacketReliability serializationMode; 00054 bool anyVariablesWritten; 00055 bool newSystemSend; // Force send all, do not record 00056 }; 00057 00058 struct DeserializationContext 00059 { 00060 BitStream *bitStream; 00061 }; 00062 00074 void BeginUnreliableAckedSerialize(SerializationContext *context, RakNetGUID _guid, BitStream *_bitStream, uint32_t _sendReceipt); 00075 00085 void BeginUniqueSerialize(SerializationContext *context, RakNetGUID _guid, BitStream *_bitStream); 00086 00095 void BeginIdenticalSerialize(SerializationContext *context, bool _isFirstSerializeToThisSystem, BitStream *_bitStream); 00096 00099 void EndSerialize(SerializationContext *context); 00100 00104 void BeginDeserialize(DeserializationContext *context, BitStream *_bitStream); 00105 00107 void EndDeserialize(DeserializationContext *context); 00108 00112 void AddRemoteSystemVariableHistory(RakNetGUID guid); 00113 00117 void RemoveRemoteSystemVariableHistory(RakNetGUID guid); 00118 00122 void OnPreSerializeTick(void); 00123 00140 void OnMessageReceipt(RakNetGUID guid, uint32_t receiptId, bool messageArrived); 00141 00149 template <class VarType> 00150 void SerializeVariable(SerializationContext *context, const VarType &variable) 00151 { 00152 if (context->newSystemSend) 00153 { 00154 if (context->variableHistory->variableListDeltaTracker.IsPastEndOfList()==false) 00155 { 00156 // previously sent data to another system 00157 context->bitStream->Write(true); 00158 context->bitStream->Write(variable); 00159 context->anyVariablesWritten=true; 00160 } 00161 else 00162 { 00163 // never sent data to another system 00164 context->variableHistory->variableListDeltaTracker.WriteVarToBitstream(variable, context->bitStream); 00165 context->anyVariablesWritten=true; 00166 } 00167 } 00168 else if (context->serializationMode==UNRELIABLE_WITH_ACK_RECEIPT) 00169 { 00170 context->anyVariablesWritten|= 00171 context->variableHistory->variableListDeltaTracker.WriteVarToBitstream(variable, context->bitStream, context->changedVariables->bitField, context->changedVariables->bitWriteIndex++); 00172 } 00173 else 00174 { 00175 if (context->variableHistoryIdentical) 00176 { 00177 // Identical serialization to a number of systems 00178 if (didComparisonThisTick==false) 00179 context->anyVariablesWritten|= 00180 context->variableHistory->variableListDeltaTracker.WriteVarToBitstream(variable, context->bitStream); 00181 // Else bitstream is written to at the end 00182 } 00183 else 00184 { 00185 // Per-system serialization 00186 context->anyVariablesWritten|= 00187 context->variableHistory->variableListDeltaTracker.WriteVarToBitstream(variable, context->bitStream); 00188 } 00189 } 00190 } 00191 00197 template <class VarType> 00198 bool DeserializeVariable(DeserializationContext *context, VarType &variable) 00199 { 00200 return VariableListDeltaTracker::ReadVarFromBitstream(variable, context->bitStream); 00201 } 00202 00203 00204 00205 protected: 00206 00207 // For a given send receipt from RakPeer::Send() track which variables we updated 00208 // 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 00209 struct ChangedVariablesList 00210 { 00211 uint32_t sendReceipt; 00212 unsigned short bitWriteIndex; 00213 unsigned char bitField[56]; 00214 }; 00215 00216 // static int Replica2ObjectComp( const uint32_t &key, ChangedVariablesList* const &data ); 00217 00218 static int UpdatedVariablesListPtrComp( const uint32_t &key, ChangedVariablesList* const &data ); 00219 00220 // 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() 00221 // Every serialize if a variable changes from its last value, send it out again 00222 // 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 00223 struct RemoteSystemVariableHistory 00224 { 00225 RakNetGUID guid; 00226 VariableListDeltaTracker variableListDeltaTracker; 00227 DataStructures::OrderedList<uint32_t,ChangedVariablesList*,VariableDeltaSerializer::UpdatedVariablesListPtrComp> updatedVariablesHistory; 00228 }; 00231 DataStructures::List<RemoteSystemVariableHistory*> remoteSystemVariableHistoryList; 00232 00233 // Because the ChangedVariablesList is created every serialize and destroyed every receipt I use a pool to avoid fragmentation 00234 DataStructures::MemoryPool<ChangedVariablesList> updatedVariablesMemoryPool; 00235 00236 bool didComparisonThisTick; 00237 RakNet::BitStream identicalSerializationBs; 00238 00239 void FreeVarsAssociatedWithReceipt(RakNetGUID guid, uint32_t receiptId); 00240 void DirtyAndFreeVarsAssociatedWithReceipt(RakNetGUID guid, uint32_t receiptId); 00241 unsigned int GetVarsWrittenPerRemoteSystemListIndex(RakNetGUID guid); 00242 void RemoveRemoteSystemVariableHistory(void); 00243 00244 RemoteSystemVariableHistory* GetRemoteSystemVariableHistory(RakNetGUID guid); 00245 00246 ChangedVariablesList *AllocChangedVariablesList(void); 00247 void FreeChangedVariablesList(ChangedVariablesList *changedVariables); 00248 void StoreChangedVariablesList(RemoteSystemVariableHistory *variableHistory, ChangedVariablesList *changedVariables, uint32_t sendReceipt); 00249 00250 RemoteSystemVariableHistory *StartVariableHistoryWrite(RakNetGUID guid); 00251 unsigned int GetRemoteSystemHistoryListIndex(RakNetGUID guid); 00252 00253 }; 00254 00255 } 00256 00257 #endif
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.