This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

413 lines
15 KiB
C++

//========= 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 "filesystem.h"
#include "isaverestore.h"
#include "utlvector.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