You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
355 lines
14 KiB
355 lines
14 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Helper classes and functions for the save/restore system. These |
|
// classes are internally structured to distinguish simple from |
|
// complex types. |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef SAVERESTORE_H |
|
#define SAVERESTORE_H |
|
|
|
#include "isaverestore.h" |
|
#include "utlvector.h" |
|
#include "filesystem.h" |
|
|
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
//------------------------------------- |
|
|
|
class CSaveRestoreData; |
|
class CSaveRestoreSegment; |
|
class CGameSaveRestoreInfo; |
|
struct typedescription_t; |
|
struct edict_t; |
|
struct datamap_t; |
|
class CBaseEntity; |
|
struct interval_t; |
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// CSave |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
class CSave : public ISave |
|
{ |
|
public: |
|
CSave( CSaveRestoreData *pdata ); |
|
|
|
//--------------------------------- |
|
// Logging |
|
void StartLogging( const char *pszLogName ); |
|
void EndLogging( void ); |
|
|
|
//--------------------------------- |
|
bool IsAsync(); |
|
|
|
//--------------------------------- |
|
|
|
int GetWritePos() const; |
|
void SetWritePos(int pos); |
|
|
|
//--------------------------------- |
|
// Datamap based writing |
|
// |
|
|
|
int WriteAll( const void *pLeafObject, datamap_t *pLeafMap ) { return DoWriteAll( pLeafObject, pLeafMap, pLeafMap ); } |
|
|
|
int WriteFields( const char *pname, const void *pBaseData, datamap_t *pMap, typedescription_t *pFields, int fieldCount ); |
|
|
|
//--------------------------------- |
|
// Block support |
|
// |
|
|
|
virtual void StartBlock( const char *pszBlockName ); |
|
virtual void StartBlock(); |
|
virtual void EndBlock(); |
|
|
|
//--------------------------------- |
|
// Primitive types |
|
// |
|
|
|
void WriteShort( const short *value, int count = 1 ); |
|
void WriteInt( const int *value, int count = 1 ); // Save an int |
|
void WriteBool( const bool *value, int count = 1 ); // Save a bool |
|
void WriteFloat( const float *value, int count = 1 ); // Save a float |
|
void WriteData( const char *pdata, int size ); // Save a binary data block |
|
void WriteString( const char *pstring ); // Save a null-terminated string |
|
void WriteString( const string_t *stringId, int count = 1 ); // Save a null-terminated string (engine string) |
|
void WriteVector( const Vector &value ); // Save a vector |
|
void WriteVector( const Vector *value, int count = 1 ); // Save a vector array |
|
void WriteQuaternion( const Quaternion &value ); // Save a Quaternion |
|
void WriteQuaternion( const Quaternion *value, int count = 1 ); // Save a Quaternion array |
|
void WriteVMatrix( const VMatrix *value, int count = 1 ); // Save a vmatrix array |
|
|
|
// Note: All of the following will write out both a header and the data. On restore, |
|
// this needs to be cracked |
|
void WriteShort( const char *pname, const short *value, int count = 1 ); |
|
void WriteInt( const char *pname, const int *value, int count = 1 ); // Save an int |
|
void WriteBool( const char *pname, const bool *value, int count = 1 ); // Save a bool |
|
void WriteFloat( const char *pname, const float *value, int count = 1 ); // Save a float |
|
void WriteData( const char *pname, int size, const char *pdata ); // Save a binary data block |
|
void WriteString( const char *pname, const char *pstring ); // Save a null-terminated string |
|
void WriteString( const char *pname, const string_t *stringId, int count = 1 ); // Save a null-terminated string (engine string) |
|
void WriteVector( const char *pname, const Vector &value ); // Save a vector |
|
void WriteVector( const char *pname, const Vector *value, int count = 1 ); // Save a vector array |
|
void WriteQuaternion( const char *pname, const Quaternion &value ); // Save a Quaternion |
|
void WriteQuaternion( const char *pname, const Quaternion *value, int count = 1 ); // Save a Quaternion array |
|
void WriteVMatrix( const char *pname, const VMatrix *value, int count = 1 ); |
|
//--------------------------------- |
|
// Game types |
|
// |
|
|
|
void WriteTime( const char *pname, const float *value, int count = 1 ); // Save a float (timevalue) |
|
void WriteTick( const char *pname, const int *value, int count = 1 ); // Save a int (timevalue) |
|
void WritePositionVector( const char *pname, const Vector &value ); // Offset for landmark if necessary |
|
void WritePositionVector( const char *pname, const Vector *value, int count = 1 ); // array of pos vectors |
|
void WriteFunction( datamap_t *pMap, const char *pname, inputfunc_t **value, int count = 1 ); // Save a function pointer |
|
|
|
void WriteEntityPtr( const char *pname, CBaseEntity **ppEntity, int count = 1 ); |
|
void WriteEdictPtr( const char *pname, edict_t **ppEdict, int count = 1 ); |
|
void WriteEHandle( const char *pname, const EHANDLE *pEHandle, int count = 1 ); |
|
|
|
virtual void WriteTime( const float *value, int count = 1 ); // Save a float (timevalue) |
|
virtual void WriteTick( const int *value, int count = 1 ); // Save a int (timevalue) |
|
virtual void WritePositionVector( const Vector &value ); // Offset for landmark if necessary |
|
virtual void WritePositionVector( const Vector *value, int count = 1 ); // array of pos vectors |
|
|
|
virtual void WriteEntityPtr( CBaseEntity **ppEntity, int count = 1 ); |
|
virtual void WriteEdictPtr( edict_t **ppEdict, int count = 1 ); |
|
virtual void WriteEHandle( const EHANDLE *pEHandle, int count = 1 ); |
|
void WriteVMatrixWorldspace( const char *pname, const VMatrix *value, int count = 1 ); // Save a vmatrix array |
|
void WriteVMatrixWorldspace( const VMatrix *value, int count = 1 ); // Save a vmatrix array |
|
void WriteMatrix3x4Worldspace( const matrix3x4_t *value, int count ); |
|
void WriteMatrix3x4Worldspace( const char *pname, const matrix3x4_t *value, int count ); |
|
|
|
void WriteInterval( const interval_t *value, int count = 1 ); // Save an interval |
|
void WriteInterval( const char *pname, const interval_t *value, int count = 1 ); |
|
|
|
//--------------------------------- |
|
|
|
int EntityIndex( const CBaseEntity *pEntity ); |
|
int EntityFlagsSet( int entityIndex, int flags ); |
|
|
|
CGameSaveRestoreInfo *GetGameSaveRestoreInfo() { return m_pGameInfo; } |
|
|
|
private: |
|
|
|
//--------------------------------- |
|
bool IsLogging( void ); |
|
void Log( const char *pName, fieldtype_t fieldType, void *value, int count ); |
|
|
|
//--------------------------------- |
|
|
|
void BufferField( const char *pname, int size, const char *pdata ); |
|
void BufferData( const char *pdata, int size ); |
|
void WriteHeader( const char *pname, int size ); |
|
|
|
int DoWriteAll( const void *pLeafObject, datamap_t *pLeafMap, datamap_t *pCurMap ); |
|
bool WriteField( const char *pname, void *pData, datamap_t *pRootMap, typedescription_t *pField ); |
|
|
|
bool WriteBasicField( const char *pname, void *pData, datamap_t *pRootMap, typedescription_t *pField ); |
|
|
|
int DataEmpty( const char *pdata, int size ); |
|
void BufferString( char *pdata, int len ); |
|
|
|
int CountFieldsToSave( const void *pBaseData, typedescription_t *pFields, int fieldCount ); |
|
bool ShouldSaveField( const void *pData, typedescription_t *pField ); |
|
|
|
//--------------------------------- |
|
// Game info methods |
|
// |
|
|
|
bool WriteGameField( const char *pname, void *pData, datamap_t *pRootMap, typedescription_t *pField ); |
|
int EntityIndex( const edict_t *pentLookup ); |
|
|
|
//--------------------------------- |
|
|
|
CUtlVector<int> m_BlockStartStack; |
|
|
|
// Stream data |
|
CSaveRestoreSegment *m_pData; |
|
|
|
// Game data |
|
CGameSaveRestoreInfo *m_pGameInfo; |
|
|
|
FileHandle_t m_hLogFile; |
|
bool m_bAsync; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// CRestore |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
class CRestore : public IRestore |
|
{ |
|
public: |
|
CRestore( CSaveRestoreData *pdata ); |
|
|
|
int GetReadPos() const; |
|
void SetReadPos( int pos ); |
|
|
|
//--------------------------------- |
|
// Datamap based reading |
|
// |
|
|
|
int ReadAll( void *pLeafObject, datamap_t *pLeafMap ) { return DoReadAll( pLeafObject, pLeafMap, pLeafMap ); } |
|
|
|
int ReadFields( const char *pname, void *pBaseData, datamap_t *pMap, typedescription_t *pFields, int fieldCount ); |
|
void EmptyFields( void *pBaseData, typedescription_t *pFields, int fieldCount ); |
|
|
|
//--------------------------------- |
|
// Block support |
|
// |
|
|
|
virtual void StartBlock( SaveRestoreRecordHeader_t *pHeader ); |
|
virtual void StartBlock( char szBlockName[SIZE_BLOCK_NAME_BUF] ); |
|
virtual void StartBlock(); |
|
virtual void EndBlock(); |
|
|
|
//--------------------------------- |
|
// Field header cracking |
|
// |
|
|
|
void ReadHeader( SaveRestoreRecordHeader_t *pheader ); |
|
int SkipHeader() { SaveRestoreRecordHeader_t header; ReadHeader( &header ); return header.size; } |
|
const char * StringFromHeaderSymbol( int symbol ); |
|
|
|
//--------------------------------- |
|
// Primitive types |
|
// |
|
|
|
short ReadShort( void ); |
|
int ReadShort( short *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadInt( int *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadInt( void ); |
|
int ReadBool( bool *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadFloat( float *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadData( char *pData, int size, int nBytesAvailable ); |
|
void ReadString( char *pDest, int nSizeDest, int nBytesAvailable ); // A null-terminated string |
|
int ReadString( string_t *pString, int count = 1, int nBytesAvailable = 0); |
|
int ReadVector( Vector *pValue ); |
|
int ReadVector( Vector *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadQuaternion( Quaternion *pValue ); |
|
int ReadQuaternion( Quaternion *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadVMatrix( VMatrix *pValue, int count = 1, int nBytesAvailable = 0); |
|
|
|
//--------------------------------- |
|
// Game types |
|
// |
|
|
|
int ReadTime( float *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadTick( int *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadPositionVector( Vector *pValue ); |
|
int ReadPositionVector( Vector *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadFunction( datamap_t *pMap, inputfunc_t **pValue, int count = 1, int nBytesAvailable = 0); |
|
|
|
int ReadEntityPtr( CBaseEntity **ppEntity, int count = 1, int nBytesAvailable = 0 ); |
|
int ReadEdictPtr( edict_t **ppEdict, int count = 1, int nBytesAvailable = 0 ); |
|
int ReadEHandle( EHANDLE *pEHandle, int count = 1, int nBytesAvailable = 0 ); |
|
int ReadVMatrixWorldspace( VMatrix *pValue, int count = 1, int nBytesAvailable = 0); |
|
int ReadMatrix3x4Worldspace( matrix3x4_t *pValue, int nElems = 1, int nBytesAvailable = 0 ); |
|
int ReadInterval( interval_t *interval, int count = 1, int nBytesAvailable = 0 ); |
|
|
|
//--------------------------------- |
|
|
|
void SetGlobalMode( int global ) { m_global = global; } |
|
void PrecacheMode( bool mode ) { m_precache = mode; } |
|
bool GetPrecacheMode( void ) { return m_precache; } |
|
|
|
CGameSaveRestoreInfo *GetGameSaveRestoreInfo() { return m_pGameInfo; } |
|
|
|
private: |
|
//--------------------------------- |
|
// Read primitives |
|
// |
|
|
|
char * BufferPointer( void ); |
|
void BufferSkipBytes( int bytes ); |
|
|
|
int DoReadAll( void *pLeafObject, datamap_t *pLeafMap, datamap_t *pCurMap ); |
|
|
|
typedescription_t *FindField( const char *pszFieldName, typedescription_t *pFields, int fieldCount, int *pIterator ); |
|
void ReadField( const SaveRestoreRecordHeader_t &header, void *pDest, datamap_t *pRootMap, typedescription_t *pField ); |
|
|
|
void ReadBasicField( const SaveRestoreRecordHeader_t &header, void *pDest, datamap_t *pRootMap, typedescription_t *pField ); |
|
|
|
void BufferReadBytes( char *pOutput, int size ); |
|
|
|
template <typename T> |
|
int ReadSimple( T *pValue, int nElems, int nBytesAvailable ) // must be inline in class to keep MSVS happy |
|
{ |
|
int desired = nElems * sizeof(T); |
|
int actual; |
|
|
|
if ( nBytesAvailable == 0 ) |
|
actual = desired; |
|
else |
|
{ |
|
Assert( nBytesAvailable % sizeof(T) == 0 ); |
|
actual = MIN( desired, nBytesAvailable ); |
|
} |
|
|
|
BufferReadBytes( (char *)pValue, actual ); |
|
|
|
if ( actual < nBytesAvailable ) |
|
BufferSkipBytes( nBytesAvailable - actual ); |
|
|
|
return ( actual / sizeof(T) ); |
|
} |
|
|
|
bool ShouldReadField( typedescription_t *pField ); |
|
bool ShouldEmptyField( typedescription_t *pField ); |
|
|
|
//--------------------------------- |
|
// Game info methods |
|
// |
|
CBaseEntity * EntityFromIndex( int entityIndex ); |
|
void ReadGameField( const SaveRestoreRecordHeader_t &header, void *pDest, datamap_t *pRootMap, typedescription_t *pField ); |
|
|
|
//--------------------------------- |
|
|
|
CUtlVector<int> m_BlockEndStack; |
|
|
|
// Stream data |
|
CSaveRestoreSegment *m_pData; |
|
|
|
// Game data |
|
CGameSaveRestoreInfo * m_pGameInfo; |
|
int m_global; // Restoring a global entity? |
|
bool m_precache; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// An interface passed into the OnSave method of all entities |
|
//----------------------------------------------------------------------------- |
|
abstract_class IEntitySaveUtils |
|
{ |
|
public: |
|
// Adds a level transition save dependency |
|
virtual void AddLevelTransitionSaveDependency( CBaseEntity *pEntity1, CBaseEntity *pEntity2 ) = 0; |
|
|
|
// Gets the # of dependencies for a particular entity |
|
virtual int GetEntityDependencyCount( CBaseEntity *pEntity ) = 0; |
|
|
|
// Gets all dependencies for a particular entity |
|
virtual int GetEntityDependencies( CBaseEntity *pEntity, int nCount, CBaseEntity **ppEntList ) = 0; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Singleton interface |
|
//----------------------------------------------------------------------------- |
|
IEntitySaveUtils *GetEntitySaveUtils(); |
|
|
|
|
|
//============================================================================= |
|
|
|
#endif // SAVERESTORE_H
|
|
|