mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2024-12-23 01:59:43 +08:00
Added SDK changes for Dark Messiah engine.
This commit is contained in:
parent
f57b1bd008
commit
292352ea2d
Binary file not shown.
19
notes.txt
19
notes.txt
@ -1,18 +1,9 @@
|
||||
*********
|
||||
* About *
|
||||
*********
|
||||
This version of the Source/Half-Life 2 SDK attempts to provide support for GCC 4.x and remove as many
|
||||
warnings as possible when compiling under Windows or Linux. In addition, the -fpermissive option has
|
||||
been removed from the Linux makefiles and -Wall has been added.
|
||||
This version of the Source SDK is meant only for compiling server plugins for
|
||||
the engine that runs Might and Magic: Dark Messiah Multiplayer. An official SDK
|
||||
is not available and will likely never be released.
|
||||
|
||||
*********
|
||||
* Notes *
|
||||
*********
|
||||
1. The file "Makefile.mod" located in the linux_sdk directory has been renamed to "Makefile.game" in
|
||||
order to avoid potential conflicts with the Modula-2 compiler. GNU Make may issue an error about the
|
||||
file with its original name and try to execute m2c (the Modula-2 compiler program).
|
||||
|
||||
2. Makefiles for choreoobjects_i486.a, mathlib_i486.a, and tier1_i486.a have been added in the linux_sdk
|
||||
directory to ease compiling of these static libraries on Linux if it ever becomes necessary.
|
||||
|
||||
3. The SDK does not currently compile with GCC 4.2. This will be addressed in the future.
|
||||
This is a modified version of the Episode One SDK. Changes to it were reverse
|
||||
engineered from the Dark Messiah engine and game binaries.
|
||||
|
177
public/edict.h
177
public/edict.h
@ -72,8 +72,6 @@ class IServerEntity;
|
||||
|
||||
|
||||
#define FL_EDICT_CHANGED (1<<0) // Game DLL sets this when the entity state changes
|
||||
// Mutually exclusive with FL_EDICT_PARTIAL_CHANGE.
|
||||
|
||||
#define FL_EDICT_FREE (1<<1) // this edict if free for reuse
|
||||
#define FL_EDICT_FULL (1<<2) // this is a full server entity
|
||||
|
||||
@ -82,82 +80,10 @@ class IServerEntity;
|
||||
#define FL_EDICT_DONTSEND (1<<4) // don't transmit this entity
|
||||
#define FL_EDICT_PVSCHECK (1<<5) // always transmit entity, but cull against PVS
|
||||
|
||||
// Used by local network backdoor.
|
||||
#define FL_EDICT_PENDING_DORMANT_CHECK (1<<6)
|
||||
|
||||
// This is always set at the same time EFL_DIRTY_PVS_INFORMATION is set, but it
|
||||
// gets cleared in a different place.
|
||||
#define FL_EDICT_DIRTY_PVS_INFORMATION (1<<7)
|
||||
|
||||
// This is used internally to edict_t to remember that it's carrying a
|
||||
// "full change list" - all its properties might have changed their value.
|
||||
#define FL_FULL_EDICT_CHANGED (1<<8)
|
||||
|
||||
|
||||
// Max # of variable changes we'll track in an entity before we treat it
|
||||
// like they all changed.
|
||||
#define MAX_CHANGE_OFFSETS 19
|
||||
#define MAX_EDICT_CHANGE_INFOS 100
|
||||
|
||||
|
||||
class CEdictChangeInfo
|
||||
{
|
||||
public:
|
||||
// Edicts remember the offsets of properties that change
|
||||
unsigned short m_ChangeOffsets[MAX_CHANGE_OFFSETS];
|
||||
unsigned short m_nChangeOffsets;
|
||||
};
|
||||
|
||||
// Shared between engine and game DLL.
|
||||
class CSharedEdictChangeInfo
|
||||
{
|
||||
public:
|
||||
CSharedEdictChangeInfo()
|
||||
{
|
||||
m_iSerialNumber = 1;
|
||||
}
|
||||
|
||||
// Matched against edict_t::m_iChangeInfoSerialNumber to determine if its
|
||||
// change info is valid.
|
||||
unsigned short m_iSerialNumber;
|
||||
|
||||
CEdictChangeInfo m_ChangeInfos[MAX_EDICT_CHANGE_INFOS];
|
||||
unsigned short m_nChangeInfos; // How many are in use this frame.
|
||||
};
|
||||
extern CSharedEdictChangeInfo *g_pSharedChangeInfo;
|
||||
|
||||
class IChangeInfoAccessor
|
||||
{
|
||||
public:
|
||||
inline void SetChangeInfo( unsigned short info )
|
||||
{
|
||||
m_iChangeInfo = info;
|
||||
}
|
||||
|
||||
inline void SetChangeInfoSerialNumber( unsigned short sn )
|
||||
{
|
||||
m_iChangeInfoSerialNumber = sn;
|
||||
}
|
||||
|
||||
inline unsigned short GetChangeInfo() const
|
||||
{
|
||||
return m_iChangeInfo;
|
||||
}
|
||||
|
||||
inline unsigned short GetChangeInfoSerialNumber() const
|
||||
{
|
||||
return m_iChangeInfoSerialNumber;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned short m_iChangeInfo;
|
||||
unsigned short m_iChangeInfoSerialNumber;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
// NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!!
|
||||
class CBaseEdict
|
||||
{
|
||||
public:
|
||||
@ -183,24 +109,14 @@ public:
|
||||
bool HasStateChanged() const;
|
||||
void ClearStateChanged();
|
||||
void StateChanged();
|
||||
void StateChanged( unsigned short offset );
|
||||
|
||||
void ClearTransmitState();
|
||||
|
||||
void SetChangeInfo( unsigned short info );
|
||||
void SetChangeInfoSerialNumber( unsigned short sn );
|
||||
unsigned short GetChangeInfo() const;
|
||||
unsigned short GetChangeInfoSerialNumber() const;
|
||||
|
||||
public:
|
||||
|
||||
// NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it.
|
||||
// NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!!
|
||||
#ifdef _XBOX
|
||||
unsigned short m_fStateFlags;
|
||||
#else
|
||||
int m_fStateFlags;
|
||||
#endif
|
||||
|
||||
// NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it.
|
||||
int m_NetworkSerialNumber; // Game DLL sets this when it gets a serial number for its EHANDLE.
|
||||
@ -212,18 +128,6 @@ protected:
|
||||
IServerUnknown *m_pUnk;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
IChangeInfoAccessor *GetChangeAccessor(); // The engine implements this and the game .dll implements as
|
||||
const IChangeInfoAccessor *GetChangeAccessor() const; // The engine implements this and the game .dll implements as
|
||||
// as callback through to the engine!!!
|
||||
|
||||
// NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!!
|
||||
// This breaks HL2_VC6!!!!!
|
||||
// References a CEdictChangeInfo with a list of modified network props.
|
||||
//unsigned short m_iChangeInfo;
|
||||
//unsigned short m_iChangeInfoSerialNumber;
|
||||
|
||||
friend void InitializeEntityDLLFields( edict_t *pEdict );
|
||||
};
|
||||
|
||||
@ -253,73 +157,14 @@ inline bool CBaseEdict::HasStateChanged() const
|
||||
|
||||
inline void CBaseEdict::ClearStateChanged()
|
||||
{
|
||||
m_fStateFlags &= ~(FL_EDICT_CHANGED | FL_FULL_EDICT_CHANGED);
|
||||
SetChangeInfoSerialNumber( 0 );
|
||||
m_fStateFlags &= ~FL_EDICT_CHANGED;
|
||||
}
|
||||
|
||||
inline void CBaseEdict::StateChanged()
|
||||
{
|
||||
// Note: this should only happen for properties in data tables that used some
|
||||
// kind of pointer dereference. If the data is directly offsetable
|
||||
m_fStateFlags |= (FL_EDICT_CHANGED | FL_FULL_EDICT_CHANGED);
|
||||
SetChangeInfoSerialNumber( 0 );
|
||||
}
|
||||
|
||||
inline void CBaseEdict::StateChanged( unsigned short offset )
|
||||
{
|
||||
if ( m_fStateFlags & FL_FULL_EDICT_CHANGED )
|
||||
return;
|
||||
|
||||
m_fStateFlags |= FL_EDICT_CHANGED;
|
||||
|
||||
IChangeInfoAccessor *accessor = GetChangeAccessor();
|
||||
|
||||
if ( accessor->GetChangeInfoSerialNumber() == g_pSharedChangeInfo->m_iSerialNumber )
|
||||
{
|
||||
// Ok, I still own this one.
|
||||
CEdictChangeInfo *p = &g_pSharedChangeInfo->m_ChangeInfos[accessor->GetChangeInfo()];
|
||||
|
||||
// Now add this offset to our list of changed variables.
|
||||
for ( unsigned short i=0; i < p->m_nChangeOffsets; i++ )
|
||||
if ( p->m_ChangeOffsets[i] == offset )
|
||||
return;
|
||||
|
||||
if ( p->m_nChangeOffsets == MAX_CHANGE_OFFSETS )
|
||||
{
|
||||
// Invalidate our change info.
|
||||
accessor->SetChangeInfoSerialNumber( 0 );
|
||||
m_fStateFlags |= FL_FULL_EDICT_CHANGED; // So we don't get in here again.
|
||||
}
|
||||
else
|
||||
{
|
||||
p->m_ChangeOffsets[p->m_nChangeOffsets++] = offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( g_pSharedChangeInfo->m_nChangeInfos == MAX_EDICT_CHANGE_INFOS )
|
||||
{
|
||||
// Shucks.. have to mark the edict as fully changed because we don't have room to remember this change.
|
||||
accessor->SetChangeInfoSerialNumber( 0 );
|
||||
m_fStateFlags |= FL_FULL_EDICT_CHANGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get a new CEdictChangeInfo and fill it out.
|
||||
accessor->SetChangeInfo( g_pSharedChangeInfo->m_nChangeInfos );
|
||||
g_pSharedChangeInfo->m_nChangeInfos++;
|
||||
|
||||
accessor->SetChangeInfoSerialNumber( g_pSharedChangeInfo->m_iSerialNumber );
|
||||
|
||||
CEdictChangeInfo *p = &g_pSharedChangeInfo->m_ChangeInfos[accessor->GetChangeInfo()];
|
||||
p->m_ChangeOffsets[0] = offset;
|
||||
p->m_nChangeOffsets = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void CBaseEdict::SetFree()
|
||||
{
|
||||
m_fStateFlags |= FL_EDICT_FREE;
|
||||
@ -381,25 +226,6 @@ inline const char * CBaseEdict::GetClassName() const
|
||||
return m_pNetworkable->GetClassName();
|
||||
}
|
||||
|
||||
inline void CBaseEdict::SetChangeInfo( unsigned short info )
|
||||
{
|
||||
GetChangeAccessor()->SetChangeInfo( info );
|
||||
}
|
||||
|
||||
inline void CBaseEdict::SetChangeInfoSerialNumber( unsigned short sn )
|
||||
{
|
||||
GetChangeAccessor()->SetChangeInfoSerialNumber( sn );
|
||||
}
|
||||
|
||||
inline unsigned short CBaseEdict::GetChangeInfo() const
|
||||
{
|
||||
return GetChangeAccessor()->GetChangeInfo();
|
||||
}
|
||||
|
||||
inline unsigned short CBaseEdict::GetChangeInfoSerialNumber() const
|
||||
{
|
||||
return GetChangeAccessor()->GetChangeInfoSerialNumber();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The engine's internal representation of an entity, including some
|
||||
@ -424,5 +250,4 @@ inline ICollideable *edict_t::GetCollideable()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#endif // EDICT_H
|
||||
|
@ -75,8 +75,11 @@ class CStandardSendProxies;
|
||||
abstract_class IVEngineServer
|
||||
{
|
||||
public:
|
||||
// Tell engine to change level ( "changelevel s1\n" or "changelevel2 s1 s2\n" )
|
||||
virtual void ChangeLevel( const char *s1, const char *s2 ) = 0;
|
||||
// Tell engine to change level.
|
||||
// changelevel s1 (multiplayer)
|
||||
// changelevel2 s1 s2 bLongLoading (single player)
|
||||
// changelevel3 s1 s2 video bLongLoading (single player)
|
||||
virtual void ChangeLevel( const char *s1, const char *s2, const char *video = NULL, bool bLongLoading = false ) = 0;
|
||||
|
||||
// Ask engine whether the specified map is a valid map file (exists and has valid version number).
|
||||
virtual int IsMapValid( const char *filename ) = 0;
|
||||
@ -87,6 +90,8 @@ public:
|
||||
// Is in Hammer editing mode?
|
||||
virtual int IsInEditMode( void ) = 0;
|
||||
|
||||
virtual bool Unknown0( void ) = 0;
|
||||
|
||||
// Add to the server/client lookup/precache table, the specified string is given a unique index
|
||||
// NOTE: The indices for PrecacheModel are 1 based
|
||||
// a 0 returned from those methods indicates the model or sound was not correctly precached
|
||||
@ -120,6 +125,8 @@ public:
|
||||
virtual int GetPlayerUserId( const edict_t *e ) = 0;
|
||||
virtual const char *GetPlayerNetworkIDString( const edict_t *e ) = 0;
|
||||
|
||||
virtual int Unknown1( void *a ) = 0;
|
||||
|
||||
// Return the current number of used edict slots
|
||||
virtual int GetEntityCount( void ) = 0;
|
||||
// Given an edict, returns the entity index
|
||||
@ -137,6 +144,8 @@ public:
|
||||
// Remove the specified edict and place back into the free edict list
|
||||
virtual void RemoveEdict( edict_t *e ) = 0;
|
||||
|
||||
virtual void Unknown2( void *a ) = 0;
|
||||
|
||||
// Memory allocation for entity class data
|
||||
virtual void *PvAllocEntPrivateData( long cb ) = 0;
|
||||
virtual void FreeEntPrivateData( void *pEntity ) = 0;
|
||||
@ -327,37 +336,13 @@ public:
|
||||
// than a bunch of individual SetAreaPortalState calls.
|
||||
virtual void SetAreaPortalStates( const int *portalNumbers, const int *isOpen, int nPortals ) = 0;
|
||||
|
||||
// Called when relevant edict state flags change.
|
||||
virtual void NotifyEdictFlagsChange( int iEdict ) = 0;
|
||||
|
||||
// Only valid during CheckTransmit. Also, only the PVS, networked areas, and
|
||||
// m_pTransmitInfo are valid in the returned strucutre.
|
||||
virtual const CCheckTransmitInfo* GetPrevCheckTransmitInfo( edict_t *pPlayerEdict ) = 0;
|
||||
|
||||
virtual CSharedEdictChangeInfo* GetSharedEdictChangeInfo() = 0;
|
||||
|
||||
// Tells the engine we can immdiately re-use all edict indices
|
||||
// even though we may not have waited enough time
|
||||
virtual void AllowImmediateEdictReuse( ) = 0;
|
||||
|
||||
// Returns true if the engine is an internal build. i.e. is using the internal bugreporter.
|
||||
virtual bool IsInternalBuild( void ) = 0;
|
||||
|
||||
virtual IChangeInfoAccessor *GetChangeAccessor( const edict_t *pEdict ) = 0;
|
||||
|
||||
// Call this to find out the value of a cvar on the client.
|
||||
//
|
||||
// It is an asynchronous query, and it will call IServerGameDLL::OnQueryCvarValueFinished when
|
||||
// the value comes in from the client.
|
||||
//
|
||||
// Store the return value if you want to match this specific query to the OnQueryCvarValueFinished call.
|
||||
// Returns InvalidQueryCvarCookie if the entity is invalid.
|
||||
virtual QueryCvarCookie_t StartQueryCvarValue( edict_t *pPlayerEntity, const char *pName ) = 0;
|
||||
virtual void Unknown3( void ) = 0;
|
||||
virtual void *Unknown4( void *, void *) = 0;
|
||||
virtual bool Unknown5( void ) = 0;
|
||||
virtual void Unknown6( int ) = 0;
|
||||
};
|
||||
|
||||
#define INTERFACEVERSION_SERVERGAMEDLL_VERSION_4 "ServerGameDLL004"
|
||||
#define INTERFACEVERSION_SERVERGAMEDLL_VERSION_5 "ServerGameDLL005"
|
||||
#define INTERFACEVERSION_SERVERGAMEDLL "ServerGameDLL006"
|
||||
#define INTERFACEVERSION_SERVERGAMEDLL "ServerGameDLL004"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: These are the interfaces that the game .dll exposes to the engine
|
||||
@ -398,6 +383,9 @@ public:
|
||||
// Called once during DLL shutdown
|
||||
virtual void DLLShutdown( void ) = 0;
|
||||
|
||||
virtual int Unknown0 ( void ) = 0;
|
||||
virtual int Unknown1 ( void ) = 0;
|
||||
|
||||
// Get the simulation interval (must be compiled with identical values into both client and game .dll for MOD!!!)
|
||||
// Right now this is only requested at server startup time so it can't be changed on the fly, etc.
|
||||
virtual float GetTickInterval( void ) const = 0;
|
||||
@ -438,24 +426,15 @@ public:
|
||||
// Hand over the StandardSendProxies in the game DLL's module.
|
||||
virtual CStandardSendProxies* GetStandardSendProxies() = 0;
|
||||
|
||||
virtual void Unknown2( int, int, int, int ) = 0;
|
||||
virtual void Unknown3( void ) = 0;
|
||||
|
||||
// Called once during startup for non-dedicated servers, after the game .dll has been loaded and after the client .dll has also been loaded
|
||||
virtual void PostInit() = 0;
|
||||
// Called once per frame even when no level is loaded...
|
||||
virtual void Think( bool finalTick ) = 0;
|
||||
|
||||
virtual void GetSaveCommentEx( char *comment, int maxlength, float flMinutes, float flSeconds ) = 0;
|
||||
#ifdef _XBOX
|
||||
virtual void GetTitleName( const char *pMapName, char* pTitleBuff, int titleBuffSize ) = 0;
|
||||
#endif
|
||||
|
||||
// * This function is new with version 6 of the interface.
|
||||
//
|
||||
// This is called when a query from IVEngineServer::StartQueryCvarValue is finished.
|
||||
// iCookie is the value returned by IVEngineServer::StartQueryCvarValue.
|
||||
// Added with version 2 of the interface.
|
||||
virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue )
|
||||
{
|
||||
}
|
||||
virtual void Unknown4( void * ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -570,17 +549,6 @@ public:
|
||||
|
||||
// Call periodically to poll steam for a CSER connection
|
||||
virtual void UpdateConnection( void ) = 0;
|
||||
|
||||
// If user has disabled stats tracking, do nothing
|
||||
virtual bool IsGameStatsLoggingEnabled() = 0;
|
||||
|
||||
// Gets a non-personally identifiable unique ID for this steam user, used for tracking total gameplay time across
|
||||
// multiple stats sessions, but isn't trackable back to their Steam account or id.
|
||||
// Buffer should be 16 bytes, ID will come back as a hexadecimal string version of a GUID
|
||||
virtual void GetPseudoUniqueId( char *buf, size_t bufsize ) = 0;
|
||||
|
||||
// For determining general % of users running using cyber cafe accounts...
|
||||
virtual bool IsCyberCafeUser( void ) = 0;
|
||||
};
|
||||
|
||||
#define INTERFACEVERSION_PLUGINHELPERSCHECK "PluginHelpersCheck001"
|
||||
|
@ -112,8 +112,6 @@ public:
|
||||
|
||||
// Retrieves list of all active sounds
|
||||
virtual void GetActiveSounds( CUtlVector< SndInfo_t >& sndlist ) = 0;
|
||||
|
||||
virtual void PrecacheSentenceGroup( const char *pGroupName ) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -141,12 +141,18 @@ public:
|
||||
// Traces a ray against a particular entity
|
||||
virtual void ClipRayToEntity( const Ray_t &ray, unsigned int fMask, IHandleEntity *pEnt, trace_t *pTrace ) = 0;
|
||||
|
||||
virtual void Unknown0( void *, void *, void *) = 0;
|
||||
|
||||
virtual void Unknown1( void *, void *, void *, void *, void *, void *, void *) = 0;
|
||||
|
||||
// Traces a ray against a particular entity
|
||||
virtual void ClipRayToCollideable( const Ray_t &ray, unsigned int fMask, ICollideable *pCollide, trace_t *pTrace ) = 0;
|
||||
|
||||
// A version that simply accepts a ray (can work as a traceline or tracehull)
|
||||
virtual void TraceRay( const Ray_t &ray, unsigned int fMask, ITraceFilter *pTraceFilter, trace_t *pTrace ) = 0;
|
||||
|
||||
virtual void Unknown2( void *, void *, void *, void *, void *) = 0;
|
||||
|
||||
// A version that sets up the leaf and entity lists and allows you to pass those in for collision.
|
||||
virtual void SetupLeafAndEntityListRay( const Ray_t &ray, CTraceListData &traceData ) = 0;
|
||||
virtual void SetupLeafAndEntityListBox( const Vector &vecBoxMin, const Vector &vecBoxMax, CTraceListData &traceData ) = 0;
|
||||
@ -165,6 +171,8 @@ public:
|
||||
// Same thing, but enumerate entitys within a box
|
||||
virtual void EnumerateEntities( const Vector &vecAbsMins, const Vector &vecAbsMaxs, IEntityEnumerator *pEnumerator ) = 0;
|
||||
|
||||
virtual int Unknown3( void ) = 0;
|
||||
|
||||
// Convert a handle entity to a collideable. Useful inside enumer
|
||||
virtual ICollideable *GetCollideable( IHandleEntity *pEntity ) = 0;
|
||||
|
||||
|
@ -28,19 +28,7 @@ typedef enum
|
||||
PLUGIN_STOP, // don't run the game dll function at all
|
||||
} PLUGIN_RESULT;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
eQueryCvarValueStatus_ValueIntact=0, // It got the value fine.
|
||||
eQueryCvarValueStatus_CvarNotFound=1,
|
||||
eQueryCvarValueStatus_NotACvar=2, // There's a ConCommand, but it's not a ConVar.
|
||||
eQueryCvarValueStatus_CvarProtected=3 // The cvar was marked with FCVAR_SERVER_CAN_NOT_QUERY, so the server is not allowed to have its value.
|
||||
} EQueryCvarValueStatus;
|
||||
|
||||
typedef int QueryCvarCookie_t;
|
||||
|
||||
#define InvalidQueryCvarCookie -1
|
||||
#define INTERFACEVERSION_ISERVERPLUGINCALLBACKS_VERSION_1 "ISERVERPLUGINCALLBACKS001"
|
||||
#define INTERFACEVERSION_ISERVERPLUGINCALLBACKS "ISERVERPLUGINCALLBACKS002"
|
||||
#define INTERFACEVERSION_ISERVERPLUGINCALLBACKS "ISERVERPLUGINCALLBACKS001"
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: callbacks the engine exposes to the 3rd party plugins (ala MetaMod)
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -99,13 +87,6 @@ public:
|
||||
|
||||
// A user has had their network id setup and validated
|
||||
virtual PLUGIN_RESULT NetworkIDValidated( const char *pszUserName, const char *pszNetworkID ) = 0;
|
||||
|
||||
// This is called when a query from IServerPluginHelpers::StartQueryCvarValue is finished.
|
||||
// iCookie is the value returned by IServerPluginHelpers::StartQueryCvarValue.
|
||||
// Added with version 2 of the interface.
|
||||
virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#define INTERFACEVERSION_ISERVERPLUGINHELPERS "ISERVERPLUGINHELPERS001"
|
||||
@ -139,15 +120,6 @@ public:
|
||||
//
|
||||
virtual void CreateMessage( edict_t *pEntity, DIALOG_TYPE type, KeyValues *data, IServerPluginCallbacks *plugin ) = 0;
|
||||
virtual void ClientCommand( edict_t *pEntity, const char *cmd ) = 0;
|
||||
|
||||
// Call this to find out the value of a cvar on the client.
|
||||
//
|
||||
// It is an asynchronous query, and it will call IServerPluginCallbacks::OnQueryCvarValueFinished when
|
||||
// the value comes in from the client.
|
||||
//
|
||||
// Store the return value if you want to match this specific query to the OnQueryCvarValueFinished call.
|
||||
// Returns InvalidQueryCvarCookie if the entity is invalid.
|
||||
virtual QueryCvarCookie_t StartQueryCvarValue( edict_t *pEntity, const char *pName ) = 0;
|
||||
};
|
||||
|
||||
#endif //ISERVERPLUGIN_H
|
||||
|
@ -99,10 +99,6 @@ public:
|
||||
// Gets a virtual terrain collision model (creates if necessary)
|
||||
// NOTE: This may return NULL if the terrain model cannot be virtualized
|
||||
virtual CPhysCollide *GetCollideForVirtualTerrain( const virtualterrainparams_t ¶ms ) = 0;
|
||||
|
||||
virtual bool IsUsingFBTexture( const model_t *model ) const = 0;
|
||||
|
||||
virtual const model_t *FindOrLoadModel( const char *name ) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -32,6 +32,10 @@ typedef int FileFindHandle_t;
|
||||
typedef void (*FileSystemLoggingFunc_t)( const char *fileName, const char *accessType );
|
||||
typedef int WaitForResourcesHandle_t;
|
||||
|
||||
// The handle is a CUtlSymbol for the dirname and the same for the filename, the accessor
|
||||
// copies them into a static char buffer for return.
|
||||
typedef void* FileNameHandle_t;
|
||||
|
||||
|
||||
#ifdef _XBOX
|
||||
typedef void* HANDLE;
|
||||
@ -86,104 +90,6 @@ enum FileWarningLevel_t
|
||||
|
||||
};
|
||||
|
||||
// In non-retail builds, enable the file blocking access tracking stuff...
|
||||
#if defined( TRACK_BLOCKING_IO )
|
||||
enum FileBlockingWarning_t
|
||||
{
|
||||
// Report how long synchronous i/o took to complete
|
||||
FILESYSTEM_BLOCKING_SYNCHRONOUS = 0,
|
||||
// Report how long async i/o took to complete if AsyncFileFinished caused it to load via "blocking" i/o
|
||||
FILESYSTEM_BLOCKING_ASYNCHRONOUS_BLOCK,
|
||||
// Report how long async i/o took to complete
|
||||
FILESYSTEM_BLOCKING_ASYNCHRONOUS,
|
||||
// Report how long the async "callback" took
|
||||
FILESYSTEM_BLOCKING_CALLBACKTIMING,
|
||||
|
||||
FILESYSTEM_BLOCKING_NUMBINS,
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
class FileBlockingItem
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
FB_ACCESS_OPEN = 1,
|
||||
FB_ACCESS_CLOSE = 2,
|
||||
FB_ACCESS_READ = 3,
|
||||
FB_ACCESS_WRITE = 4,
|
||||
FB_ACCESS_APPEND = 5,
|
||||
FB_ACCESS_SIZE = 6
|
||||
};
|
||||
|
||||
FileBlockingItem() :
|
||||
m_ItemType( (FileBlockingWarning_t)0 ),
|
||||
m_flElapsed( 0.0f ),
|
||||
m_nAccessType( 0 )
|
||||
{
|
||||
SetFileName( NULL );
|
||||
}
|
||||
|
||||
FileBlockingItem( int type, char const *filename, float elapsed, int accessType ) :
|
||||
m_ItemType( (FileBlockingWarning_t)type ),
|
||||
m_flElapsed( elapsed ),
|
||||
m_nAccessType( accessType )
|
||||
{
|
||||
SetFileName( filename );
|
||||
}
|
||||
|
||||
void SetFileName( char const *filename )
|
||||
{
|
||||
if ( !filename )
|
||||
{
|
||||
m_szFilename[ 0 ] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int len = Q_strlen( filename );
|
||||
if ( len >= sizeof( m_szFilename ) )
|
||||
{
|
||||
Q_strncpy( m_szFilename, &filename[ len - sizeof( m_szFilename ) + 1 ], sizeof( m_szFilename ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( m_szFilename, filename, sizeof( m_szFilename ) );
|
||||
}
|
||||
}
|
||||
|
||||
char const *GetFileName() const
|
||||
{
|
||||
return m_szFilename;
|
||||
}
|
||||
|
||||
FileBlockingWarning_t m_ItemType;
|
||||
float m_flElapsed;
|
||||
byte m_nAccessType;
|
||||
private:
|
||||
|
||||
char m_szFilename[ 32 ];
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
class IBlockingFileItemList
|
||||
{
|
||||
public:
|
||||
|
||||
// You can't call any of the below calls without locking first
|
||||
virtual void LockMutex() = 0;
|
||||
virtual void UnlockMutex() = 0;
|
||||
|
||||
virtual int First() const = 0;
|
||||
virtual int Next( int i ) const = 0;
|
||||
virtual int InvalidIndex() const = 0;
|
||||
|
||||
virtual const FileBlockingItem& Get( int index ) const = 0;
|
||||
|
||||
virtual void Reset() = 0;
|
||||
};
|
||||
|
||||
#endif // TRACK_BLOCKING_IO
|
||||
|
||||
enum FilesystemMountRetval_t
|
||||
{
|
||||
FILESYSTEM_MOUNT_OK = 0,
|
||||
@ -196,11 +102,6 @@ enum SearchPathAdd_t
|
||||
PATH_ADD_TO_TAIL, // Last path searched
|
||||
};
|
||||
|
||||
enum FilesystemOpenExFlags_t
|
||||
{
|
||||
FSOPEN_UNBUFFERED = ( 1 << 0 ),
|
||||
};
|
||||
|
||||
#define FILESYSTEM_INVALID_HANDLE ( FileHandle_t )0
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -554,77 +455,6 @@ public:
|
||||
|
||||
// Returns the file system statistics retreived by the implementation. Returns NULL if not supported.
|
||||
virtual const FileSystemStatistics *GetFilesystemStatistics() = 0;
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Start of new functions after Lost Coast release (7/05)
|
||||
//--------------------------------------------------------
|
||||
|
||||
virtual FileHandle_t OpenEx( const char *pFileName, const char *pOptions, unsigned flags = 0, const char *pathID = 0, char **ppszResolvedFilename = NULL ) = 0;
|
||||
|
||||
// Extended version of read provides more context to allow for more optimal reading
|
||||
virtual int ReadEx( void* pOutput, int sizeDest, int size, FileHandle_t file ) = 0;
|
||||
virtual int ReadFileEx( const char *pFileName, const char *pPath, void **ppBuf, bool bNullTerminate = false, bool bOptimalAlloc = false, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) = 0;
|
||||
|
||||
virtual FileNameHandle_t FindFileName( char const *pFileName ) = 0;
|
||||
|
||||
#if defined( TRACK_BLOCKING_IO )
|
||||
virtual void EnableBlockingFileAccessTracking( bool state ) = 0;
|
||||
virtual bool IsBlockingFileAccessEnabled() const = 0;
|
||||
|
||||
virtual IBlockingFileItemList *RetrieveBlockingFileAccessInfo() = 0;
|
||||
#endif
|
||||
|
||||
virtual void PurgePreloadedData() = 0;
|
||||
virtual void PreloadData() = 0;
|
||||
|
||||
// Fixme, we could do these via a string embedded into the compiled data, etc...
|
||||
enum KeyValuesPreloadType_t
|
||||
{
|
||||
TYPE_VMT,
|
||||
TYPE_SOUNDEMITTER,
|
||||
TYPE_SOUNDSCAPE,
|
||||
|
||||
NUM_PRELOAD_TYPES
|
||||
};
|
||||
|
||||
virtual void LoadCompiledKeyValues( KeyValuesPreloadType_t type, char const *archiveFile ) = 0;
|
||||
|
||||
// If the "PreloadedData" hasn't been purged, then this'll try and instance the KeyValues using the fast path of compiled keyvalues loaded during startup.
|
||||
// Otherwise, it'll just fall through to the regular KeyValues loading routines
|
||||
virtual KeyValues *LoadKeyValues( KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) = 0;
|
||||
virtual bool LoadKeyValues( KeyValues& head, KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) = 0;
|
||||
virtual bool ExtractRootKeyName( KeyValuesPreloadType_t type, char *outbuf, size_t bufsize, char const *filename, char const *pPathID = 0 ) = 0;
|
||||
|
||||
virtual FSAsyncStatus_t AsyncWrite(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend = false, FSAsyncControl_t *pControl = NULL ) = 0;
|
||||
// Async read functions with memory blame
|
||||
FSAsyncStatus_t AsyncReadCreditAlloc( const FileAsyncRequest_t &request, const char *pszFile, int line, FSAsyncControl_t *phControl = NULL ) { return AsyncReadMultipleCreditAlloc( &request, 1, pszFile, line, phControl ); }
|
||||
virtual FSAsyncStatus_t AsyncReadMultipleCreditAlloc( const FileAsyncRequest_t *pRequests, int nRequests, const char *pszFile, int line, FSAsyncControl_t *phControls = NULL ) = 0;
|
||||
|
||||
virtual bool GetFileTypeForFullPath( char const *pFullPath, wchar_t *buf, size_t bufSizeInBytes ) = 0;
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
virtual bool ReadToBuffer( FileHandle_t hFile, CUtlBuffer &buf, int nMaxBytes = 0, FSAllocFunc_t pfnAlloc = NULL ) = 0;
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Optimal IO operations
|
||||
//--------------------------------------------------------
|
||||
virtual bool GetOptimalIOConstraints( FileHandle_t hFile, unsigned *pOffsetAlign, unsigned *pSizeAlign, unsigned *pBufferAlign ) = 0;
|
||||
inline unsigned GetOptimalReadSize( FileHandle_t hFile, unsigned nLogicalSize );
|
||||
virtual void *AllocOptimalReadBuffer( FileHandle_t hFile, unsigned nSize = 0, unsigned nOffset = 0 ) = 0;
|
||||
virtual void FreeOptimalReadBuffer( void * ) = 0;
|
||||
|
||||
//--------------------------------------------------------
|
||||
//
|
||||
//--------------------------------------------------------
|
||||
virtual void BeginMapAccess() = 0;
|
||||
virtual void EndMapAccess() = 0;
|
||||
|
||||
// Returns true on success, otherwise false if it can't be resolved
|
||||
virtual bool FullPathToRelativePathEx( const char *pFullpath, const char *pPathId, char *pRelative, int maxlen ) = 0;
|
||||
|
||||
virtual int GetPathIndex( const FileNameHandle_t &handle ) = 0;
|
||||
virtual long GetPathTime( const char *pPath, const char *pPathID ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -662,19 +492,6 @@ private:
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline unsigned IFileSystem::GetOptimalReadSize( FileHandle_t hFile, unsigned nLogicalSize )
|
||||
{
|
||||
unsigned align;
|
||||
if ( IsPC() && GetOptimalIOConstraints( hFile, &align, NULL, NULL ) )
|
||||
return AlignValue( nLogicalSize, align );
|
||||
else if ( IsXbox() )
|
||||
return AlignValue( nLogicalSize, 512 );
|
||||
else
|
||||
return nLogicalSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// We include this here so it'll catch compile errors in VMPI early.
|
||||
#include "filesystem_passthru.h"
|
||||
|
||||
|
@ -139,7 +139,6 @@ public:
|
||||
virtual void AddLoggingFunc( void (*pfnLogFunc)( const char *fileName, const char *accessType ) ){ m_pFileSystemPassThru->AddLoggingFunc( pfnLogFunc ); }
|
||||
virtual void RemoveLoggingFunc( FileSystemLoggingFunc_t logFunc ) { m_pFileSystemPassThru->RemoveLoggingFunc( logFunc ); }
|
||||
virtual FSAsyncStatus_t AsyncReadMultiple( const FileAsyncRequest_t *pRequests, int nRequests, FSAsyncControl_t *pControls ) { return m_pFileSystemPassThru->AsyncReadMultiple( pRequests, nRequests, pControls ); }
|
||||
virtual FSAsyncStatus_t AsyncReadMultipleCreditAlloc( const FileAsyncRequest_t *pRequests, int nRequests, const char *pszFile, int line, FSAsyncControl_t *pControls ) { return m_pFileSystemPassThru->AsyncReadMultipleCreditAlloc( pRequests, nRequests, pszFile, line, pControls ); }
|
||||
virtual FSAsyncStatus_t AsyncFinish(FSAsyncControl_t hControl, bool wait) { return m_pFileSystemPassThru->AsyncFinish( hControl, wait ); }
|
||||
virtual FSAsyncStatus_t AsyncGetResult( FSAsyncControl_t hControl, void **ppData, int *pSize ) { return m_pFileSystemPassThru->AsyncGetResult( hControl, ppData, pSize ); }
|
||||
virtual FSAsyncStatus_t AsyncAbort(FSAsyncControl_t hControl) { return m_pFileSystemPassThru->AsyncAbort( hControl ); }
|
||||
@ -158,7 +157,6 @@ public:
|
||||
virtual bool IsFileImmediatelyAvailable(const char *pFileName) { return m_pFileSystemPassThru->IsFileImmediatelyAvailable( pFileName ); }
|
||||
virtual void GetLocalCopy( const char *pFileName ) { m_pFileSystemPassThru->GetLocalCopy( pFileName ); }
|
||||
virtual FileNameHandle_t FindOrAddFileName( char const *pFileName ) { return m_pFileSystemPassThru->FindOrAddFileName( pFileName ); }
|
||||
virtual FileNameHandle_t FindFileName( char const *pFileName ) { return m_pFileSystemPassThru->FindFileName( pFileName ); }
|
||||
virtual bool String( const FileNameHandle_t& handle, char *buf, int buflen ) { return m_pFileSystemPassThru->String( handle, buf, buflen ); }
|
||||
virtual bool IsOk2( FileHandle_t file ) { return IsOk(file); }
|
||||
virtual void RemoveSearchPaths( const char *szPathID ) { m_pFileSystemPassThru->RemoveSearchPaths( szPathID ); }
|
||||
@ -173,7 +171,6 @@ public:
|
||||
virtual void MarkPathIDByRequestOnly( const char *pPathID, bool bRequestOnly ) { m_pFileSystemPassThru->MarkPathIDByRequestOnly( pPathID, bRequestOnly ); }
|
||||
virtual bool AddPackFile( const char *fullpath, const char *pathID ) { return m_pFileSystemPassThru->AddPackFile( fullpath, pathID ); }
|
||||
virtual FSAsyncStatus_t AsyncAppend(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncAppend( pFileName, pSrc, nSrcBytes, bFreeMemory, pControl); }
|
||||
virtual FSAsyncStatus_t AsyncWrite(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncWrite( pFileName, pSrc, nSrcBytes, bFreeMemory, bAppend, pControl); }
|
||||
virtual FSAsyncStatus_t AsyncAppendFile(const char *pDestFileName, const char *pSrcFileName, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncAppendFile(pDestFileName, pSrcFileName, pControl); }
|
||||
virtual void AsyncFinishAll( int iToPriority ) { m_pFileSystemPassThru->AsyncFinishAll(iToPriority); }
|
||||
virtual void AsyncFinishAllWrites() { m_pFileSystemPassThru->AsyncFinishAllWrites(); }
|
||||
@ -183,41 +180,6 @@ public:
|
||||
virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize ) { return m_pFileSystemPassThru->RelativePathToFullPath( pFileName, pPathID, pLocalPath, localPathBufferSize ); }
|
||||
virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) { return m_pFileSystemPassThru->GetSearchPath( pathID, bGetPackFiles, pPath, nMaxLen ); }
|
||||
|
||||
virtual FileHandle_t OpenEx( const char *pFileName, const char *pOptions, unsigned flags = 0, const char *pathID = 0, char **ppszResolvedFilename = NULL ) { return m_pFileSystemPassThru->OpenEx( pFileName, pOptions, flags, pathID, ppszResolvedFilename );}
|
||||
virtual int ReadEx( void* pOutput, int destSize, int size, FileHandle_t file ) { return m_pFileSystemPassThru->ReadEx( pOutput, destSize, size, file ); }
|
||||
virtual int ReadFileEx( const char *pFileName, const char *pPath, void **ppBuf, bool bNullTerminate, bool bOptimalAlloc, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pFileSystemPassThru->ReadFileEx( pFileName, pPath, ppBuf, bNullTerminate, bOptimalAlloc, nMaxBytes, nStartingByte, pfnAlloc ); }
|
||||
|
||||
#if defined( TRACK_BLOCKING_IO )
|
||||
virtual void EnableBlockingFileAccessTracking( bool state ) { m_pFileSystemPassThru->EnableBlockingFileAccessTracking( state ); }
|
||||
virtual bool IsBlockingFileAccessEnabled() const { return m_pFileSystemPassThru->IsBlockingFileAccessEnabled(); }
|
||||
|
||||
virtual IBlockingFileItemList *RetrieveBlockingFileAccessInfo() { return m_pFileSystemPassThru->RetrieveBlockingFileAccessInfo(); }
|
||||
#endif
|
||||
virtual void PurgePreloadedData() {}
|
||||
virtual void PreloadData() {}
|
||||
|
||||
virtual void LoadCompiledKeyValues( KeyValuesPreloadType_t type, char const *archiveFile ) { m_pFileSystemPassThru->LoadCompiledKeyValues( type, archiveFile ); }
|
||||
|
||||
// If the "PreloadedData" hasn't been purged, then this'll try and instance the KeyValues using the fast path of compiled keyvalues loaded during startup.
|
||||
// Otherwise, it'll just fall through to the regular KeyValues loading routines
|
||||
virtual KeyValues *LoadKeyValues( KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) { return m_pFileSystemPassThru->LoadKeyValues( type, filename, pPathID ); }
|
||||
virtual bool LoadKeyValues( KeyValues& head, KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) { return m_pFileSystemPassThru->LoadKeyValues( head, type, filename, pPathID ); }
|
||||
virtual bool ExtractRootKeyName( KeyValuesPreloadType_t type, char *outbuf, size_t bufsize, char const *filename, char const *pPathID = 0 ) { return m_pFileSystemPassThru->ExtractRootKeyName( type, outbuf, bufsize, filename, pPathID ); }
|
||||
|
||||
virtual bool GetFileTypeForFullPath( char const *pFullPath, wchar_t *buf, size_t bufSizeInBytes ) { return m_pFileSystemPassThru->GetFileTypeForFullPath( pFullPath, buf, bufSizeInBytes ); }
|
||||
|
||||
virtual bool GetOptimalIOConstraints( FileHandle_t hFile, unsigned *pOffsetAlign, unsigned *pSizeAlign, unsigned *pBufferAlign ) { return m_pFileSystemPassThru->GetOptimalIOConstraints( hFile, pOffsetAlign, pSizeAlign, pBufferAlign ); }
|
||||
virtual void *AllocOptimalReadBuffer( FileHandle_t hFile, unsigned nSize, unsigned nOffset ) { return m_pFileSystemPassThru->AllocOptimalReadBuffer( hFile, nOffset, nSize ); }
|
||||
virtual void FreeOptimalReadBuffer( void *p ) { m_pFileSystemPassThru->FreeOptimalReadBuffer( p ); }
|
||||
|
||||
virtual void BeginMapAccess() { m_pFileSystemPassThru->BeginMapAccess(); }
|
||||
virtual void EndMapAccess() { m_pFileSystemPassThru->EndMapAccess(); }
|
||||
|
||||
virtual bool ReadToBuffer( FileHandle_t hFile, CUtlBuffer &buf, int nMaxBytes = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pFileSystemPassThru->ReadToBuffer( hFile, buf, nMaxBytes, pfnAlloc ); }
|
||||
virtual bool FullPathToRelativePathEx( const char *pFullPath, const char *pPathId, char *pRelative, int nMaxLen ) { return m_pFileSystemPassThru->FullPathToRelativePathEx( pFullPath, pPathId, pRelative, nMaxLen ); }
|
||||
virtual int GetPathIndex( const FileNameHandle_t &handle ) { return m_pFileSystemPassThru->GetPathIndex( handle ); }
|
||||
virtual long GetPathTime( const char *pPath, const char *pPathID ) { return m_pFileSystemPassThru->GetPathTime( pPath, pPathID ); }
|
||||
|
||||
protected:
|
||||
IFileSystem *m_pFileSystemPassThru;
|
||||
};
|
||||
|
@ -84,6 +84,8 @@ public:
|
||||
// Gets at the entity handle associated with the collideable
|
||||
virtual IHandleEntity *GetEntityHandle() = 0;
|
||||
|
||||
virtual void *Unknown() = 0;
|
||||
|
||||
// Tell the engine which class this object is.
|
||||
virtual ServerClass* GetServerClass() = 0;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======//
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: A dictionary mapping from symbol to structure
|
||||
//
|
||||
@ -14,12 +14,9 @@
|
||||
#endif
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include "utlrbtree.h"
|
||||
#include "utlsymbol.h"
|
||||
|
||||
// Include this because tons of code was implicitly getting utlsymbol or utlvector via utldict.h
|
||||
#include "tier1/utlsymbol.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A dictionary mapping from symbol to structure
|
||||
@ -34,8 +31,6 @@ public:
|
||||
CUtlDict( bool caseInsensitive = true, int growSize = 0, int initSize = 0 );
|
||||
~CUtlDict( );
|
||||
|
||||
void EnsureCapacity( int );
|
||||
|
||||
// gets particular elements
|
||||
T& Element( I i );
|
||||
const T& Element( I i ) const;
|
||||
@ -78,38 +73,44 @@ public:
|
||||
I Next( I i ) const;
|
||||
|
||||
protected:
|
||||
typedef CUtlMap<const char *, T, I> DictElementMap_t;
|
||||
struct DictElement_t
|
||||
{
|
||||
CUtlSymbol m_Name;
|
||||
T m_Data;
|
||||
};
|
||||
|
||||
static bool DictLessFunc( const DictElement_t &src1, const DictElement_t &src2 );
|
||||
typedef CUtlRBTree< DictElement_t, I > DictElementMap_t;
|
||||
|
||||
DictElementMap_t m_Elements;
|
||||
mutable CUtlSymbolTable m_SymbolTable;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// less function
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T, class I>
|
||||
bool CUtlDict<T, I>::DictLessFunc( const DictElement_t &src1, const DictElement_t &src2 )
|
||||
{
|
||||
return src1.m_Name < src2.m_Name;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T, class I>
|
||||
CUtlDict<T, I>::CUtlDict( bool caseInsensitive, int growSize, int initSize ) : m_Elements( growSize, initSize )
|
||||
CUtlDict<T, I>::CUtlDict( bool caseInsensitive, int growSize, int initSize ) : m_Elements( growSize, initSize, DictLessFunc ),
|
||||
m_SymbolTable( growSize, initSize, caseInsensitive )
|
||||
{
|
||||
if ( caseInsensitive )
|
||||
{
|
||||
m_Elements.SetLessFunc( CaselessStringLessThan );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Elements.SetLessFunc( StringLessThan );
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class I>
|
||||
CUtlDict<T, I>::~CUtlDict()
|
||||
{
|
||||
Purge();
|
||||
}
|
||||
|
||||
template <class T, class I>
|
||||
inline void CUtlDict<T, I>::EnsureCapacity( int num )
|
||||
{
|
||||
return m_Elements.EnsureCapacity( num );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// gets particular elements
|
||||
@ -117,13 +118,13 @@ inline void CUtlDict<T, I>::EnsureCapacity( int num )
|
||||
template <class T, class I>
|
||||
inline T& CUtlDict<T, I>::Element( I i )
|
||||
{
|
||||
return m_Elements[i];
|
||||
return m_Elements[i].m_Data;
|
||||
}
|
||||
|
||||
template <class T, class I>
|
||||
inline const T& CUtlDict<T, I>::Element( I i ) const
|
||||
{
|
||||
return m_Elements[i];
|
||||
return m_Elements[i].m_Data;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -132,13 +133,13 @@ inline const T& CUtlDict<T, I>::Element( I i ) const
|
||||
template <class T, class I>
|
||||
inline char *CUtlDict<T, I>::GetElementName( I i )
|
||||
{
|
||||
return (char *)m_Elements.Key( i );
|
||||
return (char *)( m_SymbolTable.String( m_Elements[ i ].m_Name ) );
|
||||
}
|
||||
|
||||
template <class T, class I>
|
||||
inline char const *CUtlDict<T, I>::GetElementName( I i ) const
|
||||
{
|
||||
return m_Elements.Key( i );
|
||||
return m_SymbolTable.String( m_Elements[ i ].m_Name );
|
||||
}
|
||||
|
||||
template <class T, class I>
|
||||
@ -156,12 +157,11 @@ inline const T & CUtlDict<T, I>::operator[]( I i ) const
|
||||
template <class T, class I>
|
||||
inline void CUtlDict<T, I>::SetElementName( I i, char const *pName )
|
||||
{
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
// TODO: This makes a copy of the old element
|
||||
// TODO: This relies on the rb tree putting the most recently
|
||||
// removed element at the head of the insert list
|
||||
free( (void *)m_Elements.Key( i ) );
|
||||
m_Elements.Reinsert( strdup( pName ), i );
|
||||
m_Elements[ i ].m_Name = m_SymbolTable.AddString( pName );
|
||||
m_Elements.Reinsert( i );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -200,7 +200,6 @@ inline I CUtlDict<T, I>::InvalidIndex()
|
||||
template <class T, class I>
|
||||
void CUtlDict<T, I>::RemoveAt(I elem)
|
||||
{
|
||||
free( (void *)m_Elements.Key( elem ) );
|
||||
m_Elements.RemoveAt(elem);
|
||||
}
|
||||
|
||||
@ -212,9 +211,7 @@ template <class T, class I> void CUtlDict<T, I>::Remove( const char *search )
|
||||
{
|
||||
I node = Find( search );
|
||||
if (node != InvalidIndex())
|
||||
{
|
||||
RemoveAt(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -224,20 +221,13 @@ template <class T, class I> void CUtlDict<T, I>::Remove( const char *search )
|
||||
template <class T, class I>
|
||||
void CUtlDict<T, I>::RemoveAll()
|
||||
{
|
||||
typename DictElementMap_t::IndexType_t index = m_Elements.FirstInorder();
|
||||
while ( index != m_Elements.InvalidIndex() )
|
||||
{
|
||||
free( (void *)m_Elements.Key( index ) );
|
||||
index = m_Elements.NextInorder( index );
|
||||
}
|
||||
|
||||
m_Elements.RemoveAll();
|
||||
}
|
||||
|
||||
template <class T, class I>
|
||||
void CUtlDict<T, I>::Purge()
|
||||
{
|
||||
RemoveAll();
|
||||
m_Elements.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
@ -248,8 +238,7 @@ void CUtlDict<T, I>::PurgeAndDeleteElements()
|
||||
I index = m_Elements.FirstInorder();
|
||||
while ( index != m_Elements.InvalidIndex() )
|
||||
{
|
||||
free( (void *)m_Elements.Key( index ) );
|
||||
delete m_Elements[index];
|
||||
delete m_Elements[index].m_Data;
|
||||
index = m_Elements.NextInorder( index );
|
||||
}
|
||||
|
||||
@ -263,15 +252,20 @@ void CUtlDict<T, I>::PurgeAndDeleteElements()
|
||||
template <class T, class I>
|
||||
I CUtlDict<T, I>::Insert( const char *pName, const T &element )
|
||||
{
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
return m_Elements.Insert( strdup( pName ), element );
|
||||
DictElement_t elem;
|
||||
elem.m_Name = m_SymbolTable.AddString( pName );
|
||||
I idx = m_Elements.Insert( elem );
|
||||
m_Elements[idx].m_Data = element;
|
||||
return idx;
|
||||
}
|
||||
|
||||
template <class T, class I>
|
||||
I CUtlDict<T, I>::Insert( const char *pName )
|
||||
{
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
return m_Elements.Insert( strdup( pName ) );
|
||||
DictElement_t elem;
|
||||
elem.m_Name = m_SymbolTable.AddString( pName );
|
||||
I idx = m_Elements.Insert( elem );
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
@ -281,11 +275,10 @@ I CUtlDict<T, I>::Insert( const char *pName )
|
||||
template <class T, class I>
|
||||
I CUtlDict<T, I>::Find( const char *pName ) const
|
||||
{
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
if ( pName )
|
||||
return m_Elements.Find( pName );
|
||||
else
|
||||
return InvalidIndex();
|
||||
DictElement_t elem;
|
||||
elem.m_Name = m_SymbolTable.AddString( pName );
|
||||
|
||||
return m_Elements.Find( elem );
|
||||
}
|
||||
|
||||
|
||||
@ -304,6 +297,4 @@ I CUtlDict<T, I>::Next( I i ) const
|
||||
return m_Elements.NextInorder(i);
|
||||
}
|
||||
|
||||
#include "tier0/memdbgoff.h"
|
||||
|
||||
#endif // UTLDICT_H
|
||||
|
@ -19,8 +19,8 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Purpose: An associative container. Pretty much identical to std::map.
|
||||
// Note this class is not thread safe
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <typename K, typename T, typename I = unsigned short>
|
||||
class CUtlMap
|
||||
@ -39,17 +39,17 @@ public:
|
||||
// at each increment.
|
||||
// LessFunc_t is required, but may be set after the constructor using SetLessFunc() below
|
||||
CUtlMap( int growSize = 0, int initSize = 0, LessFunc_t lessfunc = 0 )
|
||||
: m_Tree( growSize, initSize, CKeyLess( lessfunc ) )
|
||||
: m_Tree( growSize, initSize, TreeLessFunc )
|
||||
{
|
||||
m_pfnLess = lessfunc;
|
||||
}
|
||||
|
||||
CUtlMap( LessFunc_t lessfunc )
|
||||
: m_Tree( CKeyLess( lessfunc ) )
|
||||
: m_Tree( TreeLessFunc )
|
||||
{
|
||||
m_pfnLess = lessfunc;
|
||||
}
|
||||
|
||||
void EnsureCapacity( int num ) { m_Tree.EnsureCapacity( num ); }
|
||||
|
||||
// gets particular elements
|
||||
ElemType_t & Element( IndexType_t i ) { return m_Tree.Element( i ).elem; }
|
||||
const ElemType_t & Element( IndexType_t i ) const { return m_Tree.Element( i ).elem; }
|
||||
@ -77,7 +77,7 @@ public:
|
||||
// Sets the less func
|
||||
void SetLessFunc( LessFunc_t func )
|
||||
{
|
||||
m_Tree.SetLessFunc( CKeyLess( func ) );
|
||||
m_pfnLess = func;
|
||||
}
|
||||
|
||||
// Insert method (inserts in order)
|
||||
@ -86,13 +86,8 @@ public:
|
||||
Node_t node;
|
||||
node.key = key;
|
||||
node.elem = insert;
|
||||
return m_Tree.Insert( node );
|
||||
}
|
||||
|
||||
IndexType_t Insert( const KeyType_t &key )
|
||||
{
|
||||
Node_t node;
|
||||
node.key = key;
|
||||
Assert( m_pfnLess );
|
||||
KeyLessFunc( m_pfnLess );
|
||||
return m_Tree.Insert( node );
|
||||
}
|
||||
|
||||
@ -101,6 +96,8 @@ public:
|
||||
{
|
||||
Node_t dummyNode;
|
||||
dummyNode.key = key;
|
||||
Assert( m_pfnLess );
|
||||
KeyLessFunc( m_pfnLess );
|
||||
return m_Tree.Find( dummyNode );
|
||||
}
|
||||
|
||||
@ -110,6 +107,8 @@ public:
|
||||
{
|
||||
Node_t dummyNode;
|
||||
dummyNode.key = key;
|
||||
Assert( m_pfnLess );
|
||||
KeyLessFunc( m_pfnLess );
|
||||
return m_Tree.Remove( dummyNode );
|
||||
}
|
||||
|
||||
@ -126,7 +125,7 @@ public:
|
||||
void Reinsert( const KeyType_t &key, IndexType_t i )
|
||||
{
|
||||
m_Tree[i].key = key;
|
||||
m_Tree.Reinsert(i);
|
||||
Reinsert(i);
|
||||
}
|
||||
|
||||
IndexType_t InsertOrReplace( const KeyType_t &key, const ElemType_t &insert )
|
||||
@ -144,44 +143,38 @@ public:
|
||||
|
||||
struct Node_t
|
||||
{
|
||||
Node_t()
|
||||
{
|
||||
}
|
||||
|
||||
Node_t( const Node_t &from )
|
||||
: key( from.key ),
|
||||
elem( from.elem )
|
||||
{
|
||||
}
|
||||
|
||||
KeyType_t key;
|
||||
ElemType_t elem;
|
||||
};
|
||||
|
||||
class CKeyLess
|
||||
{
|
||||
public:
|
||||
CKeyLess( LessFunc_t lessFunc ) : m_LessFunc(lessFunc) {}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !m_LessFunc;
|
||||
}
|
||||
|
||||
bool operator()( const Node_t &left, const Node_t &right ) const
|
||||
{
|
||||
return m_LessFunc( left.key, right.key );
|
||||
}
|
||||
|
||||
LessFunc_t m_LessFunc;
|
||||
};
|
||||
|
||||
typedef CUtlRBTree<Node_t, I, CKeyLess> CTree;
|
||||
typedef CUtlRBTree<Node_t, I> CTree;
|
||||
|
||||
CTree *AccessTree() { return &m_Tree; }
|
||||
|
||||
protected:
|
||||
|
||||
static bool TreeLessFunc( const Node_t &left, const Node_t &right )
|
||||
{
|
||||
return (*KeyLessFunc())( left.key, right.key );
|
||||
}
|
||||
|
||||
static LessFunc_t KeyLessFunc( LessFunc_t pfnNew = NULL )
|
||||
{
|
||||
// @Note (toml 12-10-02): This is why the class is not thread safe. The way RB
|
||||
// tree is implemented, I could see no other efficient
|
||||
// and portable way to do this. This function local
|
||||
// static approach is used to not require
|
||||
// instantiation of a static data member or use
|
||||
// of Microsoft extensions (_declspec(selectany))
|
||||
static LessFunc_t pfnLess;
|
||||
|
||||
if ( pfnNew != NULL )
|
||||
pfnLess = pfnNew;
|
||||
return pfnLess;
|
||||
}
|
||||
|
||||
CTree m_Tree;
|
||||
LessFunc_t m_pfnLess;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -9,9 +9,8 @@
|
||||
#ifndef UTLRBTREE_H
|
||||
#define UTLRBTREE_H
|
||||
|
||||
#include "tier1/utlmemory.h"
|
||||
#undef MINMAX_H
|
||||
#include "minmax.h"
|
||||
//#include <assert.h>
|
||||
#include "utlmemory.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tool to generate a default compare function for any type that implements
|
||||
@ -44,40 +43,84 @@ void SetDefLessFunc( RBTREE_T &RBTree )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
RBTree.SetLessFunc( DefLessFunc( RBTREE_T::KeyType_t ) );
|
||||
#elif defined _LINUX
|
||||
#elif _LINUX
|
||||
RBTree.SetLessFunc( DefLessFunc( typename RBTREE_T::KeyType_t ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T>
|
||||
class CLessFuncCallerNormal
|
||||
{
|
||||
public:
|
||||
typedef bool (*LessFunc_t)( const T &, const T & );
|
||||
|
||||
CLessFuncCallerNormal( LessFunc_t func )
|
||||
{
|
||||
m_LessFunc = func;
|
||||
}
|
||||
|
||||
void Init( LessFunc_t func )
|
||||
{
|
||||
m_LessFunc = func;
|
||||
}
|
||||
|
||||
inline bool CallLessFunc( const T &a, const T &b, void *pUserData ) const
|
||||
{
|
||||
Assert( m_LessFunc );
|
||||
return m_LessFunc( a, b );
|
||||
}
|
||||
|
||||
LessFunc_t m_LessFunc;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class CLessFuncCallerUserData
|
||||
{
|
||||
public:
|
||||
typedef bool (*LessFunc_t)( const T &, const T &, void *pUserData );
|
||||
|
||||
CLessFuncCallerUserData( LessFunc_t func )
|
||||
{
|
||||
m_LessFunc = func;
|
||||
}
|
||||
|
||||
void Init( LessFunc_t func )
|
||||
{
|
||||
m_LessFunc = func;
|
||||
}
|
||||
|
||||
inline bool CallLessFunc( const T &a, const T &b, void *pUserData ) const
|
||||
{
|
||||
Assert( m_LessFunc );
|
||||
return m_LessFunc( a, b, pUserData );
|
||||
}
|
||||
|
||||
LessFunc_t m_LessFunc;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A red-black binary search tree
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I = unsigned short, typename L = bool (*)( const T &, const T & ) >
|
||||
template < class T, class I = unsigned short, class L=CLessFuncCallerNormal< T > >
|
||||
class CUtlRBTree
|
||||
{
|
||||
public:
|
||||
|
||||
// Less func typedef
|
||||
// Returns true if the first parameter is "less" than the second
|
||||
typedef T KeyType_t;
|
||||
typedef T ElemType_t;
|
||||
typedef I IndexType_t;
|
||||
|
||||
// Less func typedef
|
||||
// Returns true if the first parameter is "less" than the second
|
||||
typedef L LessFunc_t;
|
||||
typedef typename L::LessFunc_t MyLessFunc_t;
|
||||
|
||||
// constructor, destructor
|
||||
// Left at growSize = 0, the memory will first allocate 1 element and double in size
|
||||
// at each increment.
|
||||
// LessFunc_t is required, but may be set after the constructor using SetLessFunc() below
|
||||
CUtlRBTree( int growSize = 0, int initSize = 0, const LessFunc_t &lessfunc = 0 );
|
||||
CUtlRBTree( const LessFunc_t &lessfunc );
|
||||
CUtlRBTree( int growSize = 0, int initSize = 0, MyLessFunc_t lessfunc = 0 );
|
||||
CUtlRBTree( MyLessFunc_t lessfunc );
|
||||
~CUtlRBTree( );
|
||||
|
||||
void EnsureCapacity( int num );
|
||||
|
||||
void CopyFrom( const CUtlRBTree<T, I, L> &other );
|
||||
|
||||
// gets particular elements
|
||||
T& Element( I i );
|
||||
T const &Element( I i ) const;
|
||||
@ -120,24 +163,22 @@ public:
|
||||
int Depth() const;
|
||||
|
||||
// Sets the less func
|
||||
void SetLessFunc( const LessFunc_t &func );
|
||||
void SetLessFunc( MyLessFunc_t func );
|
||||
|
||||
// Allocation method
|
||||
I NewNode();
|
||||
|
||||
// Insert method (inserts in order)
|
||||
I Insert( T const &insert );
|
||||
void Insert( const T *pArray, int nItems );
|
||||
I InsertIfNotFound( T const &insert );
|
||||
I Insert( T const &insert, void *pLessFuncUserData=NULL );
|
||||
void Insert( const T *pArray, int nItems, void *pLessFuncUserData=NULL );
|
||||
|
||||
// Find method
|
||||
I Find( T const &search ) const;
|
||||
I Find( T const &search, void *pLessFuncUserData=NULL ) const;
|
||||
|
||||
// Remove methods
|
||||
void RemoveAt( I i );
|
||||
bool Remove( T const &remove );
|
||||
void RemoveAll( );
|
||||
void Purge();
|
||||
|
||||
// Allocation, deletion
|
||||
void FreeNode( I i );
|
||||
@ -160,12 +201,6 @@ public:
|
||||
// element into the tree.
|
||||
void Reinsert( I elem );
|
||||
|
||||
// swap in place
|
||||
void Swap( CUtlRBTree< T, I, L > &that );
|
||||
|
||||
private:
|
||||
// Can't copy the tree this way!
|
||||
CUtlRBTree<T, I, L>& operator=( const CUtlRBTree<T, I, L> &other );
|
||||
|
||||
protected:
|
||||
enum NodeColor_t
|
||||
@ -215,17 +250,17 @@ protected:
|
||||
I InsertAt( I parent, bool leftchild );
|
||||
|
||||
// copy constructors not allowed
|
||||
CUtlRBTree( CUtlRBTree<T, I, L> const &tree );
|
||||
CUtlRBTree( CUtlRBTree<T, I> const &tree );
|
||||
|
||||
// Inserts a node into the tree, doesn't copy the data in.
|
||||
void FindInsertionPosition( T const &insert, I &parent, bool &leftchild );
|
||||
void FindInsertionPosition( T const &insert, I &parent, bool &leftchild, void *pLessFuncUserData );
|
||||
|
||||
// Remove and add back an element in the tree.
|
||||
void Unlink( I elem );
|
||||
void Link( I elem );
|
||||
|
||||
// Used for sorting.
|
||||
LessFunc_t m_LessFunc;
|
||||
L m_LessFunc;
|
||||
|
||||
CUtlMemory<Node_t> m_Elements;
|
||||
I m_Root;
|
||||
@ -233,16 +268,12 @@ protected:
|
||||
I m_FirstFree;
|
||||
I m_TotalElements;
|
||||
|
||||
#if !defined(_XBOX) || defined(_DEBUG)
|
||||
Node_t* m_pElements;
|
||||
|
||||
void ResetDbgInfo()
|
||||
{
|
||||
m_pElements = (Node_t*)m_Elements.Base();
|
||||
}
|
||||
#else
|
||||
void ResetDbgInfo() {}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -250,78 +281,56 @@ protected:
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
inline CUtlRBTree<T, I, L>::CUtlRBTree( int growSize, int initSize, const LessFunc_t &lessfunc ) :
|
||||
m_LessFunc( lessfunc ),
|
||||
m_Elements( growSize, initSize ),
|
||||
m_Root( InvalidIndex() ),
|
||||
m_NumElements( 0 ),
|
||||
m_FirstFree( InvalidIndex() ),
|
||||
m_TotalElements( 0 )
|
||||
template <class T, class I, class L>
|
||||
inline CUtlRBTree<T, I, L>::CUtlRBTree( int growSize, int initSize, typename CUtlRBTree<T, I, L>::MyLessFunc_t lessfunc ) :
|
||||
m_Elements( growSize, initSize ),
|
||||
m_LessFunc( lessfunc ),
|
||||
m_Root( InvalidIndex() ),
|
||||
m_NumElements( 0 ), m_TotalElements( 0 ),
|
||||
m_FirstFree( InvalidIndex() )
|
||||
{
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
inline CUtlRBTree<T, I, L>::CUtlRBTree( const LessFunc_t &lessfunc ) :
|
||||
m_LessFunc( lessfunc ),
|
||||
m_Elements( 0, 0 ),
|
||||
m_Root( InvalidIndex() ),
|
||||
m_FirstFree( InvalidIndex() ),
|
||||
m_NumElements( 0 ), m_TotalElements( 0 )
|
||||
template <class T, class I, class L>
|
||||
inline CUtlRBTree<T, I, L>::CUtlRBTree( typename CUtlRBTree<T, I, L>::MyLessFunc_t lessfunc ) :
|
||||
m_Elements( 0, 0 ),
|
||||
m_LessFunc( lessfunc ),
|
||||
m_Root( InvalidIndex() ),
|
||||
m_NumElements( 0 ), m_TotalElements( 0 ),
|
||||
m_FirstFree( InvalidIndex() )
|
||||
{
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline CUtlRBTree<T, I, L>::~CUtlRBTree()
|
||||
{
|
||||
Purge();
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
inline void CUtlRBTree<T, I, L>::EnsureCapacity( int num )
|
||||
{
|
||||
return m_Elements.EnsureCapacity( num );
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
inline void CUtlRBTree<T, I, L>::CopyFrom( const CUtlRBTree<T, I, L> &other )
|
||||
{
|
||||
Purge();
|
||||
m_Elements.EnsureCapacity( other.m_Elements.Count() );
|
||||
memcpy( m_Elements.Base(), other.m_Elements.Base(), other.m_Elements.Count() * sizeof( T ) );
|
||||
m_LessFunc = other.m_LessFunc;
|
||||
m_Root = other.m_Root;
|
||||
m_NumElements = other.m_NumElements;
|
||||
m_FirstFree = other.m_FirstFree;
|
||||
m_TotalElements = other.m_TotalElements;
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// gets particular elements
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline T &CUtlRBTree<T, I, L>::Element( I i )
|
||||
{
|
||||
return m_Elements[i].m_Data;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline T const &CUtlRBTree<T, I, L>::Element( I i ) const
|
||||
{
|
||||
return m_Elements[i].m_Data;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline T &CUtlRBTree<T, I, L>::operator[]( I i )
|
||||
{
|
||||
return Element(i);
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline T const &CUtlRBTree<T, I, L>::operator[]( I i ) const
|
||||
{
|
||||
return Element(i);
|
||||
@ -337,7 +346,7 @@ inline T const &CUtlRBTree<T, I, L>::operator[]( I i ) const
|
||||
// Gets the root
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline I CUtlRBTree<T, I, L>::Root() const
|
||||
{
|
||||
return m_Root;
|
||||
@ -347,7 +356,7 @@ inline I CUtlRBTree<T, I, L>::Root() const
|
||||
// Num elements
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline unsigned int CUtlRBTree<T, I, L>::Count() const
|
||||
{
|
||||
return (unsigned int)m_NumElements;
|
||||
@ -357,7 +366,7 @@ inline unsigned int CUtlRBTree<T, I, L>::Count() const
|
||||
// Max "size" of the vector
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline I CUtlRBTree<T, I, L>::MaxElement() const
|
||||
{
|
||||
return (I)m_TotalElements;
|
||||
@ -368,19 +377,19 @@ inline I CUtlRBTree<T, I, L>::MaxElement() const
|
||||
// Gets the children
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline I CUtlRBTree<T, I, L>::Parent( I i ) const
|
||||
{
|
||||
return Links(i).m_Parent;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline I CUtlRBTree<T, I, L>::LeftChild( I i ) const
|
||||
{
|
||||
return Links(i).m_Left;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline I CUtlRBTree<T, I, L>::RightChild( I i ) const
|
||||
{
|
||||
return Links(i).m_Right;
|
||||
@ -390,13 +399,13 @@ inline I CUtlRBTree<T, I, L>::RightChild( I i ) const
|
||||
// Tests if a node is a left or right child
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline bool CUtlRBTree<T, I, L>::IsLeftChild( I i ) const
|
||||
{
|
||||
return LeftChild(Parent(i)) == i;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline bool CUtlRBTree<T, I, L>::IsRightChild( I i ) const
|
||||
{
|
||||
return RightChild(Parent(i)) == i;
|
||||
@ -407,13 +416,13 @@ inline bool CUtlRBTree<T, I, L>::IsRightChild( I i ) const
|
||||
// Tests if root or leaf
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline bool CUtlRBTree<T, I, L>::IsRoot( I i ) const
|
||||
{
|
||||
return i == m_Root;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline bool CUtlRBTree<T, I, L>::IsLeaf( I i ) const
|
||||
{
|
||||
return (LeftChild(i) == InvalidIndex()) && (RightChild(i) == InvalidIndex());
|
||||
@ -424,12 +433,9 @@ inline bool CUtlRBTree<T, I, L>::IsLeaf( I i ) const
|
||||
// Checks if a node is valid and in the tree
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline bool CUtlRBTree<T, I, L>::IsValidIndex( I i ) const
|
||||
{
|
||||
if ( !m_Elements.IsIdxValid( i ) )
|
||||
return false;
|
||||
|
||||
return LeftChild(i) != i;
|
||||
}
|
||||
|
||||
@ -438,7 +444,7 @@ inline bool CUtlRBTree<T, I, L>::IsValidIndex( I i ) const
|
||||
// Invalid index
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline I CUtlRBTree<T, I, L>::InvalidIndex()
|
||||
{
|
||||
return (I)~0;
|
||||
@ -449,7 +455,7 @@ inline I CUtlRBTree<T, I, L>::InvalidIndex()
|
||||
// returns the tree depth (not a very fast operation)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline int CUtlRBTree<T, I, L>::Depth() const
|
||||
{
|
||||
return Depth(Root());
|
||||
@ -459,19 +465,19 @@ inline int CUtlRBTree<T, I, L>::Depth() const
|
||||
// Sets the children
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline void CUtlRBTree<T, I, L>::SetParent( I i, I parent )
|
||||
{
|
||||
Links(i).m_Parent = parent;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline void CUtlRBTree<T, I, L>::SetLeftChild( I i, I child )
|
||||
{
|
||||
Links(i).m_Left = child;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline void CUtlRBTree<T, I, L>::SetRightChild( I i, I child )
|
||||
{
|
||||
Links(i).m_Right = child;
|
||||
@ -481,7 +487,7 @@ inline void CUtlRBTree<T, I, L>::SetRightChild( I i, I child )
|
||||
// Gets at the links
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline typename CUtlRBTree<T, I, L>::Links_t const &CUtlRBTree<T, I, L>::Links( I i ) const
|
||||
{
|
||||
// Sentinel node, makes life easier
|
||||
@ -494,7 +500,7 @@ inline typename CUtlRBTree<T, I, L>::Links_t const &CUtlRBTree<T, I, L>::Links(
|
||||
*(Links_t*)&s_Sentinel;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline typename CUtlRBTree<T, I, L>::Links_t &CUtlRBTree<T, I, L>::Links( I i )
|
||||
{
|
||||
Assert(i != InvalidIndex());
|
||||
@ -505,13 +511,13 @@ inline typename CUtlRBTree<T, I, L>::Links_t &CUtlRBTree<T, I, L>::Links( I i )
|
||||
// Checks if a link is red or black
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline bool CUtlRBTree<T, I, L>::IsRed( I i ) const
|
||||
{
|
||||
return (Links(i).m_Tag == RED);
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline bool CUtlRBTree<T, I, L>::IsBlack( I i ) const
|
||||
{
|
||||
return (Links(i).m_Tag == BLACK);
|
||||
@ -522,13 +528,13 @@ inline bool CUtlRBTree<T, I, L>::IsBlack( I i ) const
|
||||
// Sets/gets node color
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline typename CUtlRBTree<T, I, L>::NodeColor_t CUtlRBTree<T, I, L>::Color( I i ) const
|
||||
{
|
||||
return (NodeColor_t)Links(i).m_Tag;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
inline void CUtlRBTree<T, I, L>::SetColor( I i, typename CUtlRBTree<T, I, L>::NodeColor_t c )
|
||||
{
|
||||
Links(i).m_Tag = (I)c;
|
||||
@ -538,7 +544,7 @@ inline void CUtlRBTree<T, I, L>::SetColor( I i, typename CUtlRBTree<T, I, L>::No
|
||||
// Allocates/ deallocates nodes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::NewNode()
|
||||
{
|
||||
I newElem;
|
||||
@ -571,7 +577,7 @@ I CUtlRBTree<T, I, L>::NewNode()
|
||||
return newElem;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::FreeNode( I i )
|
||||
{
|
||||
Assert( IsValidIndex(i) && (i != InvalidIndex()) );
|
||||
@ -586,7 +592,7 @@ void CUtlRBTree<T, I, L>::FreeNode( I i )
|
||||
// Rotates node i to the left
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::RotateLeft(I elem)
|
||||
{
|
||||
I rightchild = RightChild(elem);
|
||||
@ -616,7 +622,7 @@ void CUtlRBTree<T, I, L>::RotateLeft(I elem)
|
||||
// Rotates node i to the right
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::RotateRight(I elem)
|
||||
{
|
||||
I leftchild = LeftChild(elem);
|
||||
@ -646,7 +652,7 @@ void CUtlRBTree<T, I, L>::RotateRight(I elem)
|
||||
// Rebalances the tree after an insertion
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::InsertRebalance(I elem)
|
||||
{
|
||||
while ( !IsRoot(elem) && (Color(Parent(elem)) == RED) )
|
||||
@ -721,7 +727,7 @@ void CUtlRBTree<T, I, L>::InsertRebalance(I elem)
|
||||
// Insert a node into the tree
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::InsertAt( I parent, bool leftchild )
|
||||
{
|
||||
I i = NewNode();
|
||||
@ -730,7 +736,7 @@ I CUtlRBTree<T, I, L>::InsertAt( I parent, bool leftchild )
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::LinkToParent( I i, I parent, bool isLeft )
|
||||
{
|
||||
Links_t &elem = Links(i);
|
||||
@ -760,7 +766,7 @@ void CUtlRBTree<T, I, L>::LinkToParent( I i, I parent, bool isLeft )
|
||||
// Rebalance the tree after a deletion
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::RemoveRebalance(I elem)
|
||||
{
|
||||
while (elem != m_Root && IsBlack(elem))
|
||||
@ -850,7 +856,7 @@ void CUtlRBTree<T, I, L>::RemoveRebalance(I elem)
|
||||
SetColor( elem, BLACK );
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::Unlink( I elem )
|
||||
{
|
||||
if ( elem != InvalidIndex() )
|
||||
@ -921,7 +927,7 @@ void CUtlRBTree<T, I, L>::Unlink( I elem )
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::Link( I elem )
|
||||
{
|
||||
if ( elem != InvalidIndex() )
|
||||
@ -939,7 +945,7 @@ void CUtlRBTree<T, I, L>::Link( I elem )
|
||||
// Delete a node from the tree
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::RemoveAt(I elem)
|
||||
{
|
||||
if ( elem != InvalidIndex() )
|
||||
@ -956,7 +962,7 @@ void CUtlRBTree<T, I, L>::RemoveAt(I elem)
|
||||
// remove a node in the tree
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L> bool CUtlRBTree<T, I, L>::Remove( T const &search )
|
||||
template <class T, class I, class L> bool CUtlRBTree<T, I, L>::Remove( T const &search )
|
||||
{
|
||||
I node = Find( search );
|
||||
if (node != InvalidIndex())
|
||||
@ -972,7 +978,7 @@ template <class T, class I, typename L> bool CUtlRBTree<T, I, L>::Remove( T cons
|
||||
// Removes all nodes from the tree
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::RemoveAll()
|
||||
{
|
||||
// Just iterate through the whole list and add to free list
|
||||
@ -994,32 +1000,12 @@ void CUtlRBTree<T, I, L>::RemoveAll()
|
||||
m_NumElements = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Removes all nodes from the tree and purges memory
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
void CUtlRBTree<T, I, L>::Purge()
|
||||
{
|
||||
for (int i = (int)m_TotalElements; --i >= 0; )
|
||||
{
|
||||
I idx = (I)i;
|
||||
if (IsValidIndex(idx))
|
||||
Destruct( &Element(idx) );
|
||||
}
|
||||
m_Root = InvalidIndex();
|
||||
m_NumElements = 0;
|
||||
m_TotalElements = 0;
|
||||
m_FirstFree = InvalidIndex();
|
||||
m_Elements.Purge();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// iteration
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::FirstInorder() const
|
||||
{
|
||||
I i = m_Root;
|
||||
@ -1028,7 +1014,7 @@ I CUtlRBTree<T, I, L>::FirstInorder() const
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::NextInorder( I i ) const
|
||||
{
|
||||
Assert(IsValidIndex(i));
|
||||
@ -1051,7 +1037,7 @@ I CUtlRBTree<T, I, L>::NextInorder( I i ) const
|
||||
return parent;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::PrevInorder( I i ) const
|
||||
{
|
||||
Assert(IsValidIndex(i));
|
||||
@ -1074,7 +1060,7 @@ I CUtlRBTree<T, I, L>::PrevInorder( I i ) const
|
||||
return parent;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::LastInorder() const
|
||||
{
|
||||
I i = m_Root;
|
||||
@ -1083,13 +1069,14 @@ I CUtlRBTree<T, I, L>::LastInorder() const
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::FirstPreorder() const
|
||||
{
|
||||
return m_Root;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::NextPreorder( I i ) const
|
||||
{
|
||||
if (LeftChild(i) != InvalidIndex())
|
||||
@ -1109,14 +1096,14 @@ I CUtlRBTree<T, I, L>::NextPreorder( I i ) const
|
||||
return InvalidIndex();
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::PrevPreorder( I i ) const
|
||||
{
|
||||
Assert(0); // not implemented yet
|
||||
return InvalidIndex();
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::LastPreorder() const
|
||||
{
|
||||
I i = m_Root;
|
||||
@ -1133,7 +1120,7 @@ I CUtlRBTree<T, I, L>::LastPreorder() const
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::FirstPostorder() const
|
||||
{
|
||||
I i = m_Root;
|
||||
@ -1147,7 +1134,7 @@ I CUtlRBTree<T, I, L>::FirstPostorder() const
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::NextPostorder( I i ) const
|
||||
{
|
||||
I parent = Parent(i);
|
||||
@ -1172,7 +1159,7 @@ I CUtlRBTree<T, I, L>::NextPostorder( I i ) const
|
||||
}
|
||||
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::Reinsert( I elem )
|
||||
{
|
||||
Unlink( elem );
|
||||
@ -1184,7 +1171,7 @@ void CUtlRBTree<T, I, L>::Reinsert( I elem )
|
||||
// returns the tree depth (not a very fast operation)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
int CUtlRBTree<T, I, L>::Depth( I node ) const
|
||||
{
|
||||
if (node == InvalidIndex())
|
||||
@ -1192,16 +1179,16 @@ int CUtlRBTree<T, I, L>::Depth( I node ) const
|
||||
|
||||
int depthright = Depth( RightChild(node) );
|
||||
int depthleft = Depth( LeftChild(node) );
|
||||
|
||||
return max(depthright, depthleft) + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes sure the tree is valid after every operation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
template <class T, class I, class L>
|
||||
bool CUtlRBTree<T, I, L>::IsValid() const
|
||||
{
|
||||
if ( !Count() )
|
||||
@ -1277,11 +1264,13 @@ InvalidTree:
|
||||
// Sets the less func
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T, class I, typename L>
|
||||
void CUtlRBTree<T, I, L>::SetLessFunc( const typename CUtlRBTree<T, I, L>::LessFunc_t &func )
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::SetLessFunc( typename CUtlRBTree<T, I, L>::MyLessFunc_t func )
|
||||
{
|
||||
if (!m_LessFunc)
|
||||
m_LessFunc = func;
|
||||
if (!m_LessFunc.m_LessFunc)
|
||||
{
|
||||
m_LessFunc.Init( func );
|
||||
}
|
||||
else
|
||||
{
|
||||
// need to re-sort the tree here....
|
||||
@ -1295,10 +1284,10 @@ void CUtlRBTree<T, I, L>::SetLessFunc( const typename CUtlRBTree<T, I, L>::LessF
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Inserts a node into the tree, doesn't copy the data in.
|
||||
template <class T, class I, typename L>
|
||||
void CUtlRBTree<T, I, L>::FindInsertionPosition( T const &insert, I &parent, bool &leftchild )
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::FindInsertionPosition( T const &insert, I &parent, bool &leftchild, void *pLessFuncUserData )
|
||||
{
|
||||
Assert( m_LessFunc );
|
||||
Assert( m_LessFunc.m_LessFunc );
|
||||
|
||||
/* find where node belongs */
|
||||
I current = m_Root;
|
||||
@ -1307,7 +1296,7 @@ void CUtlRBTree<T, I, L>::FindInsertionPosition( T const &insert, I &parent, boo
|
||||
while (current != InvalidIndex())
|
||||
{
|
||||
parent = current;
|
||||
if (m_LessFunc( insert, Element(current) ))
|
||||
if (m_LessFunc.CallLessFunc( insert, Element(current), pLessFuncUserData ))
|
||||
{
|
||||
leftchild = true; current = LeftChild(current);
|
||||
}
|
||||
@ -1318,75 +1307,43 @@ void CUtlRBTree<T, I, L>::FindInsertionPosition( T const &insert, I &parent, boo
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class I, typename L>
|
||||
I CUtlRBTree<T, I, L>::Insert( T const &insert )
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::Insert( T const &insert, void *pLessFuncUserData )
|
||||
{
|
||||
// use copy constructor to copy it in
|
||||
I parent;
|
||||
bool leftchild;
|
||||
FindInsertionPosition( insert, parent, leftchild );
|
||||
FindInsertionPosition( insert, parent, leftchild, pLessFuncUserData );
|
||||
I newNode = InsertAt( parent, leftchild );
|
||||
CopyConstruct( &Element( newNode ), insert );
|
||||
return newNode;
|
||||
}
|
||||
|
||||
|
||||
template <class T, class I, typename L>
|
||||
void CUtlRBTree<T, I, L>::Insert( const T *pArray, int nItems )
|
||||
template <class T, class I, class L>
|
||||
void CUtlRBTree<T, I, L>::Insert( const T *pArray, int nItems, void *pLessFuncUserData )
|
||||
{
|
||||
while ( nItems-- )
|
||||
{
|
||||
Insert( *pArray++ );
|
||||
Insert( *pArray++, pLessFuncUserData );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T, class I, typename L>
|
||||
I CUtlRBTree<T, I, L>::InsertIfNotFound( T const &insert )
|
||||
{
|
||||
// use copy constructor to copy it in
|
||||
I parent;
|
||||
bool leftchild;
|
||||
|
||||
I current = m_Root;
|
||||
parent = InvalidIndex();
|
||||
leftchild = false;
|
||||
while (current != InvalidIndex())
|
||||
{
|
||||
parent = current;
|
||||
if (m_LessFunc( insert, Element(current) ))
|
||||
{
|
||||
leftchild = true; current = LeftChild(current);
|
||||
}
|
||||
else if (m_LessFunc( Element(current), insert ))
|
||||
{
|
||||
leftchild = false; current = RightChild(current);
|
||||
}
|
||||
else
|
||||
// Match found, no insertion
|
||||
return InvalidIndex();
|
||||
}
|
||||
|
||||
I newNode = InsertAt( parent, leftchild );
|
||||
CopyConstruct( &Element( newNode ), insert );
|
||||
return newNode;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// finds a node in the tree
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T, class I, typename L>
|
||||
I CUtlRBTree<T, I, L>::Find( T const &search ) const
|
||||
|
||||
template <class T, class I, class L>
|
||||
I CUtlRBTree<T, I, L>::Find( T const &search, void *pLessFuncUserData ) const
|
||||
{
|
||||
Assert( m_LessFunc );
|
||||
Assert( m_LessFunc.m_LessFunc );
|
||||
|
||||
I current = m_Root;
|
||||
while (current != InvalidIndex())
|
||||
{
|
||||
if (m_LessFunc( search, Element(current) ))
|
||||
if (m_LessFunc.CallLessFunc( search, Element(current), pLessFuncUserData ))
|
||||
current = LeftChild(current);
|
||||
else if (m_LessFunc( Element(current), search ))
|
||||
else if (m_LessFunc.CallLessFunc( Element(current), search, pLessFuncUserData ))
|
||||
current = RightChild(current);
|
||||
else
|
||||
break;
|
||||
@ -1395,20 +1352,7 @@ I CUtlRBTree<T, I, L>::Find( T const &search ) const
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// swap in place
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T, class I, typename L>
|
||||
void CUtlRBTree<T, I, L>::Swap( CUtlRBTree< T, I, L > &that )
|
||||
{
|
||||
m_Elements.Swap( that.m_Elements );
|
||||
swap( m_LessFunc, that.m_LessFunc );
|
||||
swap( m_Root, that.m_Root );
|
||||
swap( m_NumElements, that.m_NumElements );
|
||||
swap( m_FirstFree, that.m_FirstFree );
|
||||
swap( m_TotalElements, that.m_TotalElements );
|
||||
swap( m_pElements, that.m_pElements );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // UTLRBTREE_H
|
||||
|
@ -1,147 +0,0 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef UTLSTRING_H
|
||||
#define UTLSTRING_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "tier1/utlmemory.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Base class, containing simple memory management
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtlBinaryBlock
|
||||
{
|
||||
public:
|
||||
CUtlBinaryBlock( int growSize = 0, int initSize = 0 );
|
||||
|
||||
// NOTE: nInitialLength indicates how much of the buffer starts full
|
||||
CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength );
|
||||
CUtlBinaryBlock( const void* pMemory, int nSizeInBytes );
|
||||
CUtlBinaryBlock( const CUtlBinaryBlock& src );
|
||||
|
||||
void Get( void *pValue, int nMaxLen ) const;
|
||||
void Set( const void *pValue, int nLen );
|
||||
const void *Get( ) const;
|
||||
void *Get( );
|
||||
|
||||
unsigned char& operator[]( int i );
|
||||
const unsigned char& operator[]( int i ) const;
|
||||
|
||||
int Length() const;
|
||||
void SetLength( int nLength ); // Undefined memory will result
|
||||
bool IsEmpty() const;
|
||||
|
||||
bool IsReadOnly() const;
|
||||
|
||||
CUtlBinaryBlock &operator=( const CUtlBinaryBlock &src );
|
||||
|
||||
// Test for equality
|
||||
bool operator==( const CUtlBinaryBlock &src ) const;
|
||||
|
||||
private:
|
||||
CUtlMemory<unsigned char> m_Memory;
|
||||
int m_nActualLength;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class inlines
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const void *CUtlBinaryBlock::Get( ) const
|
||||
{
|
||||
return m_Memory.Base();
|
||||
}
|
||||
|
||||
inline void *CUtlBinaryBlock::Get( )
|
||||
{
|
||||
return m_Memory.Base();
|
||||
}
|
||||
|
||||
inline int CUtlBinaryBlock::Length() const
|
||||
{
|
||||
return m_nActualLength;
|
||||
}
|
||||
|
||||
inline unsigned char& CUtlBinaryBlock::operator[]( int i )
|
||||
{
|
||||
return m_Memory[i];
|
||||
}
|
||||
|
||||
inline const unsigned char& CUtlBinaryBlock::operator[]( int i ) const
|
||||
{
|
||||
return m_Memory[i];
|
||||
}
|
||||
|
||||
inline bool CUtlBinaryBlock::IsReadOnly() const
|
||||
{
|
||||
return m_Memory.IsReadOnly();
|
||||
}
|
||||
|
||||
inline bool CUtlBinaryBlock::IsEmpty() const
|
||||
{
|
||||
return Length() == 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Simple string class.
|
||||
// NOTE: This is *not* optimal! Use in tools, but not runtime code
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtlString
|
||||
{
|
||||
public:
|
||||
CUtlString();
|
||||
CUtlString( const char *pString );
|
||||
CUtlString( const CUtlString& string );
|
||||
|
||||
// Attaches the string to external memory. Useful for avoiding a copy
|
||||
CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength );
|
||||
CUtlString( const void* pMemory, int nSizeInBytes );
|
||||
|
||||
const char *Get( ) const;
|
||||
void Set( const char *pValue );
|
||||
|
||||
// Converts to c-strings
|
||||
operator const char*() const;
|
||||
|
||||
// for compatibility switching items from UtlSymbol
|
||||
const char *String() const { return Get(); }
|
||||
|
||||
// Returns strlen
|
||||
int Length() const;
|
||||
bool IsEmpty() const;
|
||||
|
||||
// Sets the length (used to serialize into the buffer )
|
||||
void SetLength( int nLen );
|
||||
char *Get();
|
||||
|
||||
CUtlString &operator=( const CUtlString &src );
|
||||
CUtlString &operator=( const char *src );
|
||||
|
||||
// Test for equality
|
||||
bool operator==( const CUtlString &src ) const;
|
||||
bool operator==( const char *src ) const;
|
||||
|
||||
private:
|
||||
CUtlBinaryBlock m_Storage;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inline methods
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool CUtlString::IsEmpty() const
|
||||
{
|
||||
return Length() == 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // UTLSTRING_H
|
@ -9,16 +9,14 @@
|
||||
#ifndef UTLSYMBOL_H
|
||||
#define UTLSYMBOL_H
|
||||
|
||||
#include "tier0/threadtools.h"
|
||||
#include "tier1/utlrbtree.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "utlrbtree.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CUtlSymbolTable;
|
||||
class CUtlSymbolTableMT;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -64,10 +62,10 @@ protected:
|
||||
static void Initialize();
|
||||
|
||||
// returns the current symbol table
|
||||
static CUtlSymbolTableMT* CurrTable();
|
||||
static CUtlSymbolTable* CurrTable();
|
||||
|
||||
// The standard global symbol table
|
||||
static CUtlSymbolTableMT* s_pSymbolTable;
|
||||
static CUtlSymbolTable* s_pSymbolTable;
|
||||
|
||||
static bool s_bAllowStaticSymbolTable;
|
||||
|
||||
@ -131,28 +129,8 @@ protected:
|
||||
unsigned short m_iOffset; // Index into the string pool.
|
||||
};
|
||||
|
||||
class CLess
|
||||
{
|
||||
public:
|
||||
CLess( int ignored = 0 ) {} // permits default initialization to NULL in CUtlRBTree
|
||||
bool operator!() const { return false; }
|
||||
bool operator()( const CStringPoolIndex &left, const CStringPoolIndex &right ) const;
|
||||
};
|
||||
|
||||
friend class CLess;
|
||||
|
||||
// Stores the symbol lookup
|
||||
class CTree : public CUtlRBTree<CStringPoolIndex, unsigned short, CLess>
|
||||
{
|
||||
public:
|
||||
CTree( int growSize, int initSize ) : CUtlRBTree<CStringPoolIndex, unsigned short, CLess>( growSize, initSize ) {}
|
||||
friend class CUtlSymbolTable::CLess; // Needed to allow CLess to calculate pointer to symbol table
|
||||
};
|
||||
|
||||
CTree m_Lookup;
|
||||
bool m_bInsensitive;
|
||||
char const* m_pUserSearchString;
|
||||
|
||||
CUtlRBTree< CStringPoolIndex, unsigned short, CLessFuncCallerUserData<CStringPoolIndex> > m_Lookup;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -164,6 +142,8 @@ protected:
|
||||
// stores the string data
|
||||
CUtlVector<StringPool_t*> m_StringPools;
|
||||
|
||||
// Stored before using the RBTree comparisons.
|
||||
const char *m_pLessCtxUserString;
|
||||
|
||||
|
||||
private:
|
||||
@ -172,89 +152,10 @@ private:
|
||||
|
||||
const char* StringFromIndex( const CStringPoolIndex &index ) const;
|
||||
|
||||
};
|
||||
|
||||
class CUtlSymbolTableMT : private CUtlSymbolTable
|
||||
{
|
||||
public:
|
||||
CUtlSymbolTableMT( int growSize = 0, int initSize = 32, bool caseInsensitive = false )
|
||||
: CUtlSymbolTable( growSize, initSize, caseInsensitive )
|
||||
{
|
||||
}
|
||||
|
||||
CUtlSymbol AddString( char const* pString )
|
||||
{
|
||||
m_mutex.Lock();
|
||||
CUtlSymbol result = CUtlSymbolTable::AddString( pString );
|
||||
m_mutex.Unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
CUtlSymbol Find( char const* pString )
|
||||
{
|
||||
m_mutex.Lock();
|
||||
CUtlSymbol result = CUtlSymbolTable::Find( pString );
|
||||
m_mutex.Unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
char const* String( CUtlSymbol id ) const
|
||||
{
|
||||
m_mutex.Lock();
|
||||
const char *pszResult = CUtlSymbolTable::String( id );
|
||||
m_mutex.Unlock();
|
||||
return pszResult;
|
||||
}
|
||||
|
||||
private:
|
||||
CThreadMutex m_mutex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CUtlFilenameSymbolTable:
|
||||
// description:
|
||||
// This class defines a symbol table of individual filenames, stored more
|
||||
// efficiently than a standard symbol table. Internally filenames are broken
|
||||
// up into file and path entries, and a file handle class allows convenient
|
||||
// access to these.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The handle is a CUtlSymbol for the dirname and the same for the filename, the accessor
|
||||
// copies them into a static char buffer for return.
|
||||
typedef void* FileNameHandle_t;
|
||||
|
||||
// Symbol table for more efficiently storing filenames by breaking paths and filenames apart.
|
||||
// Refactored from BaseFileSystem.h
|
||||
class CUtlFilenameSymbolTable
|
||||
{
|
||||
// Internal representation of a FileHandle_t
|
||||
// If we get more than 64K filenames, we'll have to revisit...
|
||||
// Right now CUtlSymbol is a short, so this packs into an int/void * pointer size...
|
||||
struct FileNameHandleInternal_t
|
||||
{
|
||||
FileNameHandleInternal_t()
|
||||
{
|
||||
path = 0;
|
||||
file = 0;
|
||||
}
|
||||
|
||||
// Part before the final '/' character
|
||||
unsigned short path;
|
||||
// Part after the final '/', including extension
|
||||
unsigned short file;
|
||||
};
|
||||
|
||||
// Symbol table storing the file names:
|
||||
CUtlSymbolTableMT m_FileNames;
|
||||
|
||||
public:
|
||||
FileNameHandle_t FindOrAddFileName( char const *pFileName );
|
||||
FileNameHandle_t FindFileName( char const *pFileName );
|
||||
int PathIndex(const FileNameHandle_t &handle) { return (( const FileNameHandleInternal_t * )&handle)->path; }
|
||||
|
||||
bool String( const FileNameHandle_t& handle, char *buf, int buflen );
|
||||
// Less function, for sorting strings
|
||||
static bool SymLess( CStringPoolIndex const& i1, CStringPoolIndex const& i2, void *pUserData );
|
||||
// case insensitive less function
|
||||
static bool SymLessi( CStringPoolIndex const& i1, CStringPoolIndex const& i2, void *pUserData );
|
||||
};
|
||||
|
||||
|
||||
|
@ -469,24 +469,21 @@ void KeyValues::UsesEscapeSequences(bool state)
|
||||
bool KeyValues::LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID )
|
||||
{
|
||||
Assert(filesystem);
|
||||
#ifndef _LINUX
|
||||
Assert( IsXbox() || ( IsPC() && _heapchk() == _HEAPOK ) );
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
Assert(_heapchk() == _HEAPOK);
|
||||
#endif
|
||||
|
||||
FileHandle_t f = filesystem->Open(resourceName, "rb", pathID);
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
s_LastFileLoadingFrom = (char*)resourceName;
|
||||
|
||||
// load file into a null-terminated buffer
|
||||
int fileSize = filesystem->Size(f);
|
||||
unsigned bufSize = ((IFileSystem *)filesystem)->GetOptimalReadSize( f, fileSize + 1 );
|
||||
|
||||
char *buffer = (char*)((IFileSystem *)filesystem)->AllocOptimalReadBuffer( f, bufSize );
|
||||
char *buffer = (char *)MemAllocScratch(fileSize + 1);
|
||||
|
||||
Assert(buffer);
|
||||
|
||||
((IFileSystem *)filesystem)->ReadEx(buffer, bufSize, fileSize, f); // read into local buffer
|
||||
filesystem->Read(buffer, fileSize, f); // read into local buffer
|
||||
|
||||
buffer[fileSize] = 0; // null terminate file as EOF
|
||||
|
||||
@ -494,7 +491,7 @@ bool KeyValues::LoadFromFile( IBaseFileSystem *filesystem, const char *resourceN
|
||||
|
||||
bool retOK = LoadFromBuffer( resourceName, buffer, filesystem );
|
||||
|
||||
((IFileSystem *)filesystem)->FreeOptimalReadBuffer( buffer );
|
||||
MemFreeScratch();
|
||||
|
||||
return retOK;
|
||||
}
|
||||
|
@ -275,18 +275,10 @@
|
||||
RelativePath=".\utlbuffer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlstring.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlsymbol.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\xboxstubs.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
|
@ -1,218 +0,0 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "tier1/utlstring.h"
|
||||
#include "vstdlib/strtools.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Base class, containing simple memory management
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlBinaryBlock::CUtlBinaryBlock( int growSize, int initSize ) : m_Memory( growSize, initSize )
|
||||
{
|
||||
m_nActualLength = 0;
|
||||
}
|
||||
|
||||
CUtlBinaryBlock::CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Memory( (unsigned char*)pMemory, nSizeInBytes )
|
||||
{
|
||||
m_nActualLength = nInitialLength;
|
||||
}
|
||||
|
||||
CUtlBinaryBlock::CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ) : m_Memory( (const unsigned char*)pMemory, nSizeInBytes )
|
||||
{
|
||||
m_nActualLength = nSizeInBytes;
|
||||
}
|
||||
|
||||
CUtlBinaryBlock::CUtlBinaryBlock( const CUtlBinaryBlock& src )
|
||||
{
|
||||
Set( src.Get(), src.Length() );
|
||||
}
|
||||
|
||||
void CUtlBinaryBlock::Get( void *pValue, int nLen ) const
|
||||
{
|
||||
Assert( nLen > 0 );
|
||||
if ( m_nActualLength < nLen )
|
||||
{
|
||||
nLen = m_nActualLength;
|
||||
}
|
||||
|
||||
if ( nLen > 0 )
|
||||
{
|
||||
memcpy( pValue, m_Memory.Base(), nLen );
|
||||
}
|
||||
}
|
||||
|
||||
void CUtlBinaryBlock::SetLength( int nLength )
|
||||
{
|
||||
Assert( !m_Memory.IsReadOnly() );
|
||||
|
||||
m_nActualLength = nLength;
|
||||
if ( nLength > m_Memory.NumAllocated() )
|
||||
{
|
||||
int nOverFlow = nLength - m_Memory.NumAllocated();
|
||||
m_Memory.Grow( nOverFlow );
|
||||
|
||||
// If the reallocation failed, clamp length
|
||||
if ( nLength > m_Memory.NumAllocated() )
|
||||
{
|
||||
m_nActualLength = m_Memory.NumAllocated();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ( m_Memory.NumAllocated() > m_nActualLength )
|
||||
{
|
||||
memset( ( ( char * )m_Memory.Base() ) + m_nActualLength, 0xEB, m_Memory.NumAllocated() - m_nActualLength );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CUtlBinaryBlock::Set( const void *pValue, int nLen )
|
||||
{
|
||||
Assert( !m_Memory.IsReadOnly() );
|
||||
|
||||
if ( !pValue )
|
||||
{
|
||||
nLen = 0;
|
||||
}
|
||||
|
||||
SetLength( nLen );
|
||||
|
||||
if ( m_nActualLength )
|
||||
{
|
||||
if ( ( ( const char * )m_Memory.Base() ) >= ( ( const char * )pValue ) + nLen ||
|
||||
( ( const char * )m_Memory.Base() ) + m_nActualLength <= ( ( const char * )pValue ) )
|
||||
{
|
||||
memcpy( m_Memory.Base(), pValue, m_nActualLength );
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove( m_Memory.Base(), pValue, m_nActualLength );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CUtlBinaryBlock &CUtlBinaryBlock::operator=( const CUtlBinaryBlock &src )
|
||||
{
|
||||
Assert( !m_Memory.IsReadOnly() );
|
||||
Set( src.Get(), src.Length() );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool CUtlBinaryBlock::operator==( const CUtlBinaryBlock &src ) const
|
||||
{
|
||||
if ( src.Length() != Length() )
|
||||
return false;
|
||||
|
||||
return !memcmp( src.Get(), Get(), Length() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Simple string class.
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlString::CUtlString()
|
||||
{
|
||||
}
|
||||
|
||||
CUtlString::CUtlString( const char *pString )
|
||||
{
|
||||
Set( pString );
|
||||
}
|
||||
|
||||
CUtlString::CUtlString( const CUtlString& string )
|
||||
{
|
||||
Set( string.Get() );
|
||||
}
|
||||
|
||||
// Attaches the string to external memory. Useful for avoiding a copy
|
||||
CUtlString::CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Storage( pMemory, nSizeInBytes, nInitialLength )
|
||||
{
|
||||
}
|
||||
|
||||
CUtlString::CUtlString( const void* pMemory, int nSizeInBytes ) : m_Storage( pMemory, nSizeInBytes )
|
||||
{
|
||||
}
|
||||
|
||||
void CUtlString::Set( const char *pValue )
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
int nLen = pValue ? Q_strlen(pValue) + 1 : 0;
|
||||
m_Storage.Set( pValue, nLen );
|
||||
}
|
||||
|
||||
// Returns strlen
|
||||
int CUtlString::Length() const
|
||||
{
|
||||
return m_Storage.Length() ? m_Storage.Length() - 1 : 0;
|
||||
}
|
||||
|
||||
// Sets the length (used to serialize into the buffer )
|
||||
void CUtlString::SetLength( int nLen )
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
|
||||
// Add 1 to account for the NULL
|
||||
m_Storage.SetLength( nLen > 0 ? nLen + 1 : 0 );
|
||||
}
|
||||
|
||||
const char *CUtlString::Get( ) const
|
||||
{
|
||||
if ( m_Storage.Length() == 0 )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return reinterpret_cast< const char* >( m_Storage.Get() );
|
||||
}
|
||||
|
||||
// Converts to c-strings
|
||||
CUtlString::operator const char*() const
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
char *CUtlString::Get()
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
|
||||
if ( m_Storage.Length() == 0 )
|
||||
{
|
||||
// In general, we optimise away small mallocs for empty strings
|
||||
// but if you ask for the non-const bytes, they must be writable
|
||||
// so we can't return "" here, like we do for the const version - jd
|
||||
m_Storage.SetLength( 1 );
|
||||
m_Storage[ 0 ] = '\0';
|
||||
}
|
||||
|
||||
return reinterpret_cast< char* >( m_Storage.Get() );
|
||||
}
|
||||
|
||||
CUtlString &CUtlString::operator=( const CUtlString &src )
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
m_Storage = src.m_Storage;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CUtlString &CUtlString::operator=( const char *src )
|
||||
{
|
||||
Assert( !m_Storage.IsReadOnly() );
|
||||
Set( src );
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CUtlString::operator==( const CUtlString &src ) const
|
||||
{
|
||||
return m_Storage == src.m_Storage;
|
||||
}
|
||||
|
||||
bool CUtlString::operator==( const char *src ) const
|
||||
{
|
||||
return ( strcmp( Get(), src ) == 0 );
|
||||
}
|
@ -6,17 +6,9 @@
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#if !defined _XBOX && defined _MSC_VER
|
||||
#pragma warning (disable:4514)
|
||||
#endif
|
||||
|
||||
#include "utlsymbol.h"
|
||||
#include "KeyValues.h"
|
||||
#include "tier0/threadtools.h"
|
||||
#include "tier0/memdbgon.h"
|
||||
#include "stringpool.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define INVALID_STRING_INDEX CStringPoolIndex( 0xFFFF, 0xFFFF )
|
||||
@ -27,7 +19,7 @@
|
||||
// globals
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CUtlSymbolTableMT* CUtlSymbol::s_pSymbolTable = 0;
|
||||
CUtlSymbolTable* CUtlSymbol::s_pSymbolTable = 0;
|
||||
bool CUtlSymbol::s_bAllowStaticSymbolTable = true;
|
||||
|
||||
|
||||
@ -40,17 +32,13 @@ void CUtlSymbol::Initialize()
|
||||
// If this assert fails, then the module that this call is in has chosen to disallow
|
||||
// use of the static symbol table. Usually, it's to prevent confusion because it's easy
|
||||
// to accidentally use the global symbol table when you really want to use a specific one.
|
||||
#ifndef _XBOX
|
||||
// xboxissue - need to isolate this concept per lib, otherwise
|
||||
// can't trap coding mistakes (i.e. unintended global symbol table usage)
|
||||
Assert( s_bAllowStaticSymbolTable );
|
||||
#endif
|
||||
|
||||
// necessary to allow us to create global symbols
|
||||
static bool symbolsInitialized = false;
|
||||
if (!symbolsInitialized)
|
||||
{
|
||||
s_pSymbolTable = new CUtlSymbolTableMT;
|
||||
s_pSymbolTable = new CUtlSymbolTable;
|
||||
symbolsInitialized = true;
|
||||
}
|
||||
}
|
||||
@ -70,7 +58,7 @@ public:
|
||||
|
||||
static CCleanupUtlSymbolTable g_CleanupSymbolTable;
|
||||
|
||||
CUtlSymbolTableMT* CUtlSymbol::CurrTable()
|
||||
CUtlSymbolTable* CUtlSymbol::CurrTable()
|
||||
{
|
||||
Initialize();
|
||||
return s_pSymbolTable;
|
||||
@ -122,21 +110,28 @@ inline const char* CUtlSymbolTable::StringFromIndex( const CStringPoolIndex &ind
|
||||
}
|
||||
|
||||
|
||||
bool CUtlSymbolTable::CLess::operator()( const CStringPoolIndex &i1, const CStringPoolIndex &i2 ) const
|
||||
bool CUtlSymbolTable::SymLess( CStringPoolIndex const& i1, CStringPoolIndex const& i2, void *pUserData )
|
||||
{
|
||||
// Need to do pointer math because CUtlSymbolTable is used in CUtlVectors, and hence
|
||||
// can be arbitrarily moved in memory on a realloc. Yes, this is portable. In reality,
|
||||
// right now at least, because m_LessFunc is the first member of CUtlRBTree, and m_Lookup
|
||||
// is the first member of CUtlSymbolTabke, this == pTable
|
||||
CUtlSymbolTable *pTable = (CUtlSymbolTable *)( (byte *)this - offsetof(CUtlSymbolTable::CTree, m_LessFunc) ) - offsetof(CUtlSymbolTable, m_Lookup );
|
||||
char const* str1 = (i1 == INVALID_STRING_INDEX) ? pTable->m_pUserSearchString :
|
||||
CUtlSymbolTable *pTable = (CUtlSymbolTable*)pUserData;
|
||||
|
||||
char const* str1 = (i1 == INVALID_STRING_INDEX) ? pTable->m_pLessCtxUserString :
|
||||
pTable->StringFromIndex( i1 );
|
||||
char const* str2 = (i2 == INVALID_STRING_INDEX) ? pTable->m_pUserSearchString :
|
||||
char const* str2 = (i2 == INVALID_STRING_INDEX) ? pTable->m_pLessCtxUserString :
|
||||
pTable->StringFromIndex( i2 );
|
||||
|
||||
if ( !pTable->m_bInsensitive )
|
||||
return strcmp( str1, str2 ) < 0;
|
||||
else
|
||||
}
|
||||
|
||||
|
||||
bool CUtlSymbolTable::SymLessi( CStringPoolIndex const& i1, CStringPoolIndex const& i2, void *pUserData )
|
||||
{
|
||||
CUtlSymbolTable *pTable = (CUtlSymbolTable*)pUserData;
|
||||
|
||||
char const* str1 = (i1 == INVALID_STRING_INDEX) ? pTable->m_pLessCtxUserString :
|
||||
pTable->StringFromIndex( i1 );
|
||||
char const* str2 = (i2 == INVALID_STRING_INDEX) ? pTable->m_pLessCtxUserString :
|
||||
pTable->StringFromIndex( i2 );
|
||||
|
||||
return strcmpi( str1, str2 ) < 0;
|
||||
}
|
||||
|
||||
@ -145,8 +140,12 @@ bool CUtlSymbolTable::CLess::operator()( const CStringPoolIndex &i1, const CStri
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CUtlSymbolTable::CUtlSymbolTable( int growSize, int initSize, bool caseInsensitive ) :
|
||||
m_Lookup( growSize, initSize ), m_bInsensitive( caseInsensitive ), m_StringPools( 8 )
|
||||
m_Lookup( growSize, initSize ), m_StringPools( 8 )
|
||||
{
|
||||
if ( caseInsensitive )
|
||||
m_Lookup.SetLessFunc( SymLessi );
|
||||
else
|
||||
m_Lookup.SetLessFunc( SymLess );
|
||||
}
|
||||
|
||||
CUtlSymbolTable::~CUtlSymbolTable()
|
||||
@ -162,16 +161,11 @@ CUtlSymbol CUtlSymbolTable::Find( char const* pString )
|
||||
return CUtlSymbol();
|
||||
|
||||
// Store a special context used to help with insertion
|
||||
m_pUserSearchString = pString;
|
||||
m_pLessCtxUserString = pString;
|
||||
|
||||
// Passing this special invalid symbol makes the comparison function
|
||||
// use the string passed in the context
|
||||
UtlSymId_t idx = m_Lookup.Find( INVALID_STRING_INDEX );
|
||||
|
||||
#ifdef _DEBUG
|
||||
m_pUserSearchString = NULL;
|
||||
#endif
|
||||
|
||||
UtlSymId_t idx = m_Lookup.Find( INVALID_STRING_INDEX, this );
|
||||
return CUtlSymbol( idx );
|
||||
}
|
||||
|
||||
@ -235,7 +229,7 @@ CUtlSymbol CUtlSymbolTable::AddString( char const* pString )
|
||||
index.m_iPool = iPool;
|
||||
index.m_iOffset = iStringOffset;
|
||||
|
||||
UtlSymId_t idx = m_Lookup.Insert( index );
|
||||
UtlSymId_t idx = m_Lookup.Insert( index, this );
|
||||
return CUtlSymbol( idx );
|
||||
}
|
||||
|
||||
@ -268,103 +262,3 @@ void CUtlSymbolTable::RemoveAll()
|
||||
m_StringPools.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pFileName -
|
||||
// Output : FileNameHandle_t
|
||||
//-----------------------------------------------------------------------------
|
||||
FileNameHandle_t CUtlFilenameSymbolTable::FindOrAddFileName( char const *pFileName )
|
||||
{
|
||||
if ( !pFileName )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Fix slashes and make lower case first..
|
||||
char fn[ MAX_PATH ];
|
||||
Q_strncpy( fn, pFileName, sizeof( fn ) );
|
||||
Q_FixSlashes( fn );
|
||||
#ifdef _WIN32
|
||||
strlwr( fn );
|
||||
#endif
|
||||
|
||||
// Split the fn into constituent parts
|
||||
char basepath[ MAX_PATH ];
|
||||
Q_ExtractFilePath( fn, basepath, sizeof( basepath ) );
|
||||
|
||||
char filename[ MAX_PATH ];
|
||||
Q_strncpy( filename, fn + Q_strlen( basepath ), sizeof( filename ) );
|
||||
|
||||
FileNameHandleInternal_t handle;
|
||||
handle.path = g_CountedStringPool.ReferenceStringHandle(basepath);
|
||||
handle.file = g_CountedStringPool.ReferenceStringHandle(filename );
|
||||
|
||||
void *h = &handle;
|
||||
return *reinterpret_cast<FileNameHandle_t *>(h);
|
||||
}
|
||||
|
||||
FileNameHandle_t CUtlFilenameSymbolTable::FindFileName( char const *pFileName )
|
||||
{
|
||||
if ( !pFileName )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Fix slashes and make lower case first..
|
||||
char fn[ MAX_PATH ];
|
||||
Q_strncpy( fn, pFileName, sizeof( fn ) );
|
||||
Q_FixSlashes( fn );
|
||||
#ifdef _WIN32
|
||||
strlwr( fn );
|
||||
#endif
|
||||
|
||||
// Split the fn into constituent parts
|
||||
char basepath[ MAX_PATH ];
|
||||
Q_ExtractFilePath( fn, basepath, sizeof( basepath ) );
|
||||
|
||||
char filename[ MAX_PATH ];
|
||||
Q_strncpy( filename, fn + Q_strlen( basepath ), sizeof( filename ) );
|
||||
|
||||
FileNameHandleInternal_t handle;
|
||||
handle.path = g_CountedStringPool.FindStringHandle(basepath);
|
||||
handle.file = g_CountedStringPool.FindStringHandle(filename);
|
||||
|
||||
if( handle.path == 0 || handle.file == 0 )
|
||||
return NULL;
|
||||
|
||||
void *h = &handle;
|
||||
return *reinterpret_cast<FileNameHandle_t *>(h);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : handle -
|
||||
// Output : char const
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CUtlFilenameSymbolTable::String( const FileNameHandle_t& handle, char *buf, int buflen )
|
||||
{
|
||||
buf[ 0 ] = 0;
|
||||
|
||||
FileNameHandleInternal_t *internal = ( FileNameHandleInternal_t * )&handle;
|
||||
if ( !internal )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char const *path = g_CountedStringPool.HandleToString(internal->path);
|
||||
if ( !path )
|
||||
return false;
|
||||
|
||||
Q_strncpy( buf, path, buflen );
|
||||
char const *fn = g_CountedStringPool.HandleToString(internal->file);
|
||||
if ( !fn )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_strncat( buf, fn, buflen, COPY_ALL_CHARACTERS );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,74 +0,0 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Stubs Xbox functions when compiling for other platforms
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef _XBOX
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#elif _LINUX
|
||||
#define ERROR_GEN_FAILURE 1
|
||||
#define GetTickCount() Plat_FloatTime()
|
||||
#else
|
||||
#error "implement me"
|
||||
#endif
|
||||
#include "xbox/xboxstubs.h"
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
void XBX_DebugString(xverbose_e verbose, COLORREF color, const char* format, ...)
|
||||
{
|
||||
}
|
||||
|
||||
void XBX_ProcessEvents( void )
|
||||
{
|
||||
}
|
||||
|
||||
void XInitDevices( DWORD dwPreallocTypeCount, PXDEVICE_PREALLOC_TYPE PreallocTypes )
|
||||
{
|
||||
}
|
||||
|
||||
DWORD XGetDevices(PXPP_DEVICE_TYPE DeviceType)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool XGetDeviceChanges(PXPP_DEVICE_TYPE DeviceType, DWORD *pdwInsertions, DWORD *pdwRemovals)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE XInputOpen(PXPP_DEVICE_TYPE DeviceType, DWORD dwPort, DWORD dwSlot, PXINPUT_POLLING_PARAMETERS pPollingParameters)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void XInputClose(HANDLE hDevice)
|
||||
{
|
||||
}
|
||||
|
||||
DWORD XInputSetState(HANDLE hDevice, PXINPUT_FEEDBACK pFeedback)
|
||||
{
|
||||
return ERROR_GEN_FAILURE;
|
||||
}
|
||||
|
||||
DWORD XInputGetState(HANDLE hDevice, PXINPUT_STATE pState)
|
||||
{
|
||||
return ERROR_GEN_FAILURE;
|
||||
}
|
||||
|
||||
DWORD XInputPoll(HANDLE hDevice)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int XBX_GetSystemTime( void )
|
||||
{
|
||||
return (unsigned int)GetTickCount();
|
||||
}
|
||||
|
||||
#endif // _XBOX
|
Loading…
Reference in New Issue
Block a user