• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

VariableDeltaSerializer.h

Go to the documentation of this file.
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*,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

Generated on Thu Sep 30 2010 01:27:29 for RakNet by  doxygen 1.7.1