doom3-bfg/neo/sys/Snapshot.h
2012-11-26 12:58:24 -06:00

201 lines
8.7 KiB
C++

/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
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.
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.
===========================================================================
*/
#ifndef __SNAPSHOT_H__
#define __SNAPSHOT_H__
#include "snapshot_jobs.h"
extern idCVar net_verboseSnapshot;
#define NET_VERBOSESNAPSHOT_PRINT if ( net_verboseSnapshot.GetInteger() > 0 ) idLib::Printf
#define NET_VERBOSESNAPSHOT_PRINT_LEVEL( X, Y ) if ( net_verboseSnapshot.GetInteger() >= ( X ) ) idLib::Printf( Y )
/*
A snapshot contains a list of objects and their states
*/
class idSnapShot {
public:
idSnapShot();
idSnapShot( const idSnapShot & other );
~idSnapShot();
void operator=( const idSnapShot & other );
// clears the snapshot
void Clear();
int GetTime() const { return time; }
void SetTime( int t ) { time = t; }
int GetRecvTime() const { return recvTime; }
void SetRecvTime( int t ) { recvTime = t; }
// Loads only sequence and baseSequence values from the compressed stream
static void PeekDeltaSequence( const char * deltaMem, int deltaSize, int & sequence, int & baseSequence );
// Reads a new object state packet, which is assumed to be delta compressed against this snapshot
bool ReadDeltaForJob( const char * deltaMem, int deltaSize, int visIndex, idSnapShot * templateStates );
bool ReadDelta( idFile * file, int visIndex );
// Writes an object state packet which is delta compressed against the old snapshot
struct objectBuffer_t {
objectBuffer_t() : data( NULL ), size( 0 ) { }
objectBuffer_t( int s ) : data( NULL ), size( s ) { Alloc( s ); }
objectBuffer_t( const objectBuffer_t & o ) : data( NULL ), size( 0 ) { *this = o; }
~objectBuffer_t() { _Release(); }
void Alloc( int size );
int NumRefs() { return data == NULL ? 0 : data[size]; }
objectSize_t Size() const { return size; }
byte * Ptr() { return data == NULL ? NULL : data ; }
byte & operator[]( int i ) { return data[i]; }
void operator=( const objectBuffer_t & other );
// (not making private because of idSnapshot)
void _AddRef();
void _Release();
private:
byte * data;
objectSize_t size;
};
struct objectState_t {
objectState_t() :
objectNum( 0 ),
visMask( MAX_UNSIGNED_TYPE( uint32 ) ),
stale( false ),
deleted( false ),
changedCount( 0 ),
createdFromTemplate( false ),
expectedSequence( 0 )
{ }
void Print( const char * name );
uint16 objectNum;
objectBuffer_t buffer;
uint32 visMask;
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
bool deleted;
int changedCount; // Incremented each time the state changed
int expectedSequence;
bool createdFromTemplate;
};
struct submitDeltaJobsInfo_t {
objParms_t * objParms; // Start of object parms
int maxObjParms; // Max parms (which will dictate how many objects can be processed)
uint8 * objMemory; // Memory that objects were written out to
objHeader_t * headers; // Memory for headers
int maxHeaders;
int maxObjMemory; // Max memory (which will dictate when syncs need to occur)
lzwParm_t * lzwParms; // Start of lzw parms
int maxDeltaParms; // Max lzw parms (which will dictate how many syncs we can have)
idSnapShot * oldSnap; // snap we are comparing this snap to (to produce a delta)
int visIndex;
int baseSequence;
idSnapShot * templateStates; // states for new snapObj that arent in old states
lzwInOutData_t * lzwInOutData;
};
void SubmitWriteDeltaToJobs( const submitDeltaJobsInfo_t & submitDeltaJobInfo );
bool WriteDelta( idSnapShot & old, int visIndex, idFile * file, int maxLength, int optimalLength = 0 );
// Adds an object to the state, overwrites any existing object with the same number
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 ); }
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 ); }
objectState_t * S_AddObject( int objectNum, uint32 visMask, const char * buffer, int size, const char * tag = NULL );
bool CopyObject( const idSnapShot & oldss, int objectNum, bool forceStale = false );
int CompareObject( const idSnapShot * oldss, int objectNum, int start=0, int end=0, int oldStart=0 );
// returns the number of objects in this snapshot
int NumObjects() const { return objectStates.Num(); }
// Returns the object number of the specified object, also fills the bitmsg
int GetObjectMsgByIndex( int i, idBitMsg & msg, bool ignoreIfStale = false ) const;
// returns true if the object was found in the snapshot
bool GetObjectMsgByID( int objectNum, idBitMsg & msg, bool ignoreIfStale = false ) { return GetObjectMsgByIndex( FindObjectIndexByID( objectNum ), msg, ignoreIfStale ) == objectNum; }
// returns the object index or -1 if it's not found
int FindObjectIndexByID( int objectNum ) const;
// returns the object by id, or NULL if not found
objectState_t * FindObjectByID( int objectNum ) const;
// Returns whether or not an object is stale
bool ObjectIsStaleByIndex( int i ) const;
int ObjectChangedCountByIndex( int i ) const;
// clears the empty states from the snapshot snapshot
void CleanupEmptyStates();
void PrintReport();
void UpdateExpectedSeq( int newSeq );
void ApplyToExistingState( int objId, idBitMsg & msg );
objectState_t * GetTemplateState( int objNum, idSnapShot * templateStates, objectState_t * newState = NULL );
void RemoveObject( int objId );
private:
idList< objectState_t *, TAG_IDLIB_LIST_SNAPSHOT> objectStates;
idBlockAlloc< objectState_t, 16, TAG_NETWORKING > allocatedObjs;
int time;
int recvTime;
int BinarySearch( int objectNum ) const;
objectState_t & FindOrCreateObjectByID( int objectNum ); // objIndex is optional parm for returning the index of the obj
void SubmitObjectJob( const submitDeltaJobsInfo_t & submitDeltaJobsInfo, // Struct containing parameters originally passed in to SubmitWriteDeltaToJobs
objectState_t * newState, // New obj state (can be NULL, which means deleted)
objectState_t * oldState, // Old obj state (can be NULL, which means new)
objParms_t *& baseObjParm, // Starting obj parm of current stream
objParms_t *& curObjParm, // Current obj parm of current stream
objHeader_t *& curHeader, // Current header dest
uint8 *& curObjDest, // Current write pos of current obj
lzwParm_t *& curlzwParm ); // Current delta parm for next lzw job
void SubmitLZWJob(
const submitDeltaJobsInfo_t & writeDeltaInfo, // Struct containing parameters originally passed in to SubmitWriteDeltaToJobs
objParms_t *& baseObjParm, // Pointer to the first obj parm for the current stream
objParms_t *& curObjParm, // Current obj parm
lzwParm_t *& curlzwParm, // Current delta parm
bool saveDictionary // If true, this is the first of several calls which will be appended
);
void WriteObject( idFile * file, int visIndex, objectState_t * newState, objectState_t * oldState, int & lastobjectNum );
void FreeObjectState( int index );
};
#endif // __SNAPSHOT_H__