Snapshot.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #ifndef __SNAPSHOT_H__
  21. #define __SNAPSHOT_H__
  22. #include "snapshot_jobs.h"
  23. extern idCVar net_verboseSnapshot;
  24. #define NET_VERBOSESNAPSHOT_PRINT if ( net_verboseSnapshot.GetInteger() > 0 ) idLib::Printf
  25. #define NET_VERBOSESNAPSHOT_PRINT_LEVEL( X, Y ) if ( net_verboseSnapshot.GetInteger() >= ( X ) ) idLib::Printf( Y )
  26. /*
  27. A snapshot contains a list of objects and their states
  28. */
  29. class idSnapShot {
  30. public:
  31. idSnapShot();
  32. idSnapShot( const idSnapShot & other );
  33. ~idSnapShot();
  34. void operator=( const idSnapShot & other );
  35. // clears the snapshot
  36. void Clear();
  37. int GetTime() const { return time; }
  38. void SetTime( int t ) { time = t; }
  39. int GetRecvTime() const { return recvTime; }
  40. void SetRecvTime( int t ) { recvTime = t; }
  41. // Loads only sequence and baseSequence values from the compressed stream
  42. static void PeekDeltaSequence( const char * deltaMem, int deltaSize, int & sequence, int & baseSequence );
  43. // Reads a new object state packet, which is assumed to be delta compressed against this snapshot
  44. bool ReadDeltaForJob( const char * deltaMem, int deltaSize, int visIndex, idSnapShot * templateStates );
  45. bool ReadDelta( idFile * file, int visIndex );
  46. // Writes an object state packet which is delta compressed against the old snapshot
  47. struct objectBuffer_t {
  48. objectBuffer_t() : data( NULL ), size( 0 ) { }
  49. objectBuffer_t( int s ) : data( NULL ), size( s ) { Alloc( s ); }
  50. objectBuffer_t( const objectBuffer_t & o ) : data( NULL ), size( 0 ) { *this = o; }
  51. ~objectBuffer_t() { _Release(); }
  52. void Alloc( int size );
  53. int NumRefs() { return data == NULL ? 0 : data[size]; }
  54. objectSize_t Size() const { return size; }
  55. byte * Ptr() { return data == NULL ? NULL : data ; }
  56. byte & operator[]( int i ) { return data[i]; }
  57. void operator=( const objectBuffer_t & other );
  58. // (not making private because of idSnapshot)
  59. void _AddRef();
  60. void _Release();
  61. private:
  62. byte * data;
  63. objectSize_t size;
  64. };
  65. struct objectState_t {
  66. objectState_t() :
  67. objectNum( 0 ),
  68. visMask( MAX_UNSIGNED_TYPE( uint32 ) ),
  69. stale( false ),
  70. deleted( false ),
  71. changedCount( 0 ),
  72. createdFromTemplate( false ),
  73. expectedSequence( 0 )
  74. { }
  75. void Print( const char * name );
  76. uint16 objectNum;
  77. objectBuffer_t buffer;
  78. uint32 visMask;
  79. bool stale; // easy way for clients to check if ss obj is stale. Probably temp till client side of vismask system is more fleshed out
  80. bool deleted;
  81. int changedCount; // Incremented each time the state changed
  82. int expectedSequence;
  83. bool createdFromTemplate;
  84. };
  85. struct submitDeltaJobsInfo_t {
  86. objParms_t * objParms; // Start of object parms
  87. int maxObjParms; // Max parms (which will dictate how many objects can be processed)
  88. uint8 * objMemory; // Memory that objects were written out to
  89. objHeader_t * headers; // Memory for headers
  90. int maxHeaders;
  91. int maxObjMemory; // Max memory (which will dictate when syncs need to occur)
  92. lzwParm_t * lzwParms; // Start of lzw parms
  93. int maxDeltaParms; // Max lzw parms (which will dictate how many syncs we can have)
  94. idSnapShot * oldSnap; // snap we are comparing this snap to (to produce a delta)
  95. int visIndex;
  96. int baseSequence;
  97. idSnapShot * templateStates; // states for new snapObj that arent in old states
  98. lzwInOutData_t * lzwInOutData;
  99. };
  100. void SubmitWriteDeltaToJobs( const submitDeltaJobsInfo_t & submitDeltaJobInfo );
  101. bool WriteDelta( idSnapShot & old, int visIndex, idFile * file, int maxLength, int optimalLength = 0 );
  102. // Adds an object to the state, overwrites any existing object with the same number
  103. objectState_t * S_AddObject( int objectNum, uint32 visMask, const idBitMsg & msg, const char * tag = NULL ) { return S_AddObject( objectNum, visMask, msg.GetReadData(), msg.GetSize(), tag ); }
  104. objectState_t * S_AddObject( int objectNum, uint32 visMask, const byte * buffer, int size, const char * tag = NULL ) { return S_AddObject( objectNum, visMask, (const char *)buffer, size, tag ); }
  105. objectState_t * S_AddObject( int objectNum, uint32 visMask, const char * buffer, int size, const char * tag = NULL );
  106. bool CopyObject( const idSnapShot & oldss, int objectNum, bool forceStale = false );
  107. int CompareObject( const idSnapShot * oldss, int objectNum, int start=0, int end=0, int oldStart=0 );
  108. // returns the number of objects in this snapshot
  109. int NumObjects() const { return objectStates.Num(); }
  110. // Returns the object number of the specified object, also fills the bitmsg
  111. int GetObjectMsgByIndex( int i, idBitMsg & msg, bool ignoreIfStale = false ) const;
  112. // returns true if the object was found in the snapshot
  113. bool GetObjectMsgByID( int objectNum, idBitMsg & msg, bool ignoreIfStale = false ) { return GetObjectMsgByIndex( FindObjectIndexByID( objectNum ), msg, ignoreIfStale ) == objectNum; }
  114. // returns the object index or -1 if it's not found
  115. int FindObjectIndexByID( int objectNum ) const;
  116. // returns the object by id, or NULL if not found
  117. objectState_t * FindObjectByID( int objectNum ) const;
  118. // Returns whether or not an object is stale
  119. bool ObjectIsStaleByIndex( int i ) const;
  120. int ObjectChangedCountByIndex( int i ) const;
  121. // clears the empty states from the snapshot snapshot
  122. void CleanupEmptyStates();
  123. void PrintReport();
  124. void UpdateExpectedSeq( int newSeq );
  125. void ApplyToExistingState( int objId, idBitMsg & msg );
  126. objectState_t * GetTemplateState( int objNum, idSnapShot * templateStates, objectState_t * newState = NULL );
  127. void RemoveObject( int objId );
  128. private:
  129. idList< objectState_t *, TAG_IDLIB_LIST_SNAPSHOT> objectStates;
  130. idBlockAlloc< objectState_t, 16, TAG_NETWORKING > allocatedObjs;
  131. int time;
  132. int recvTime;
  133. int BinarySearch( int objectNum ) const;
  134. objectState_t & FindOrCreateObjectByID( int objectNum ); // objIndex is optional parm for returning the index of the obj
  135. void SubmitObjectJob( const submitDeltaJobsInfo_t & submitDeltaJobsInfo, // Struct containing parameters originally passed in to SubmitWriteDeltaToJobs
  136. objectState_t * newState, // New obj state (can be NULL, which means deleted)
  137. objectState_t * oldState, // Old obj state (can be NULL, which means new)
  138. objParms_t *& baseObjParm, // Starting obj parm of current stream
  139. objParms_t *& curObjParm, // Current obj parm of current stream
  140. objHeader_t *& curHeader, // Current header dest
  141. uint8 *& curObjDest, // Current write pos of current obj
  142. lzwParm_t *& curlzwParm ); // Current delta parm for next lzw job
  143. void SubmitLZWJob(
  144. const submitDeltaJobsInfo_t & writeDeltaInfo, // Struct containing parameters originally passed in to SubmitWriteDeltaToJobs
  145. objParms_t *& baseObjParm, // Pointer to the first obj parm for the current stream
  146. objParms_t *& curObjParm, // Current obj parm
  147. lzwParm_t *& curlzwParm, // Current delta parm
  148. bool saveDictionary // If true, this is the first of several calls which will be appended
  149. );
  150. void WriteObject( idFile * file, int visIndex, objectState_t * newState, objectState_t * oldState, int & lastobjectNum );
  151. void FreeObjectState( int index );
  152. };
  153. #endif // __SNAPSHOT_H__