1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2024-12-23 01:59:43 +08:00

Update ICVar, IConVar, and ConVar from SDK 2013.

Includes minor fix-ups, such as not calling change callbacks when new
value matches old value.
This commit is contained in:
Nick Hastings 2018-05-05 10:01:15 -04:00
parent 1fca804cbd
commit 6e5b1bf250
5 changed files with 177 additions and 47 deletions

View File

@ -102,8 +102,91 @@ public:
#if defined( _X360 )
virtual void PublishToVXConsole( ) = 0;
#endif
virtual bool IsMaterialThreadSetAllowed( ) const = 0;
virtual void QueueMaterialThreadSetValue( ConVar *pConVar, const char *pValue ) = 0;
virtual void QueueMaterialThreadSetValue( ConVar *pConVar, int nValue ) = 0;
virtual void QueueMaterialThreadSetValue( ConVar *pConVar, float flValue ) = 0;
virtual bool HasQueuedMaterialThreadConVarSets() const = 0;
virtual int ProcessQueuedMaterialThreadConVarSets() = 0;
protected: class ICVarIteratorInternal;
public:
/// Iteration over all cvars.
/// (THIS IS A SLOW OPERATION AND YOU SHOULD AVOID IT.)
/// usage:
/// { ICVar::Iterator iter(g_pCVar);
/// for ( iter.SetFirst() ; iter.IsValid() ; iter.Next() )
/// {
/// ConCommandBase *cmd = iter.Get();
/// }
/// }
/// The Iterator class actually wraps the internal factory methods
/// so you don't need to worry about new/delete -- scope takes care
// of it.
/// We need an iterator like this because we can't simply return a
/// pointer to the internal data type that contains the cvars --
/// it's a custom, protected class with unusual semantics and is
/// prone to change.
class Iterator
{
public:
inline Iterator(ICvar *icvar);
inline ~Iterator(void);
inline void SetFirst( void );
inline void Next( void );
inline bool IsValid( void );
inline ConCommandBase *Get( void );
private:
ICVarIteratorInternal *m_pIter;
};
protected:
// internals for ICVarIterator
class ICVarIteratorInternal
{
public:
// warning: delete called on 'ICvar::ICVarIteratorInternal' that is abstract but has non-virtual destructor [-Wdelete-non-virtual-dtor]
virtual ~ICVarIteratorInternal() {}
virtual void SetFirst( void ) = 0;
virtual void Next( void ) = 0;
virtual bool IsValid( void ) = 0;
virtual ConCommandBase *Get( void ) = 0;
};
virtual ICVarIteratorInternal *FactoryInternalIterator( void ) = 0;
friend class Iterator;
};
inline ICvar::Iterator::Iterator(ICvar *icvar)
{
m_pIter = icvar->FactoryInternalIterator();
}
inline ICvar::Iterator::~Iterator( void )
{
delete m_pIter;
}
inline void ICvar::Iterator::SetFirst( void )
{
m_pIter->SetFirst();
}
inline void ICvar::Iterator::Next( void )
{
m_pIter->Next();
}
inline bool ICvar::Iterator::IsValid( void )
{
return m_pIter->IsValid();
}
inline ConCommandBase * ICvar::Iterator::Get( void )
{
return m_pIter->Get();
}
#define CVAR_INTERFACE_VERSION "VEngineCvar004"
@ -114,7 +197,7 @@ public:
// These are marked DLL_EXPORT for Linux.
DLL_EXPORT ICvar *cvar;
DLL_EXPORT ICvar *g_pCVar;
extern ICvar *g_pCVar;
#endif // ICVAR_H

View File

@ -66,7 +66,7 @@ void ConVar_PublishToVXConsole();
//-----------------------------------------------------------------------------
// Called when a ConCommand needs to execute
//-----------------------------------------------------------------------------
typedef void ( *FnCommandCallbackV1_t )( void );
typedef void ( *FnCommandCallbackVoid_t )( void );
typedef void ( *FnCommandCallback_t )( const CCommand &command );
#define COMMAND_COMPLETION_MAXITEMS 64
@ -142,7 +142,7 @@ public:
virtual CVarDLLIdentifier_t GetDLLIdentifier() const;
protected:
virtual void Create( const char *pName, const char *pHelpString = 0,
virtual void CreateBase( const char *pName, const char *pHelpString = 0,
int flags = 0 );
// Used internally by OneTimeInit to initialize/shutdown
@ -270,7 +270,7 @@ friend class CCvar;
public:
typedef ConCommandBase BaseClass;
ConCommand( const char *pName, FnCommandCallbackV1_t callback,
ConCommand( const char *pName, FnCommandCallbackVoid_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
ConCommand( const char *pName, FnCommandCallback_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
@ -300,7 +300,7 @@ private:
// Call this function when executing the command
union
{
FnCommandCallbackV1_t m_fnCommandCallbackV1;
FnCommandCallbackVoid_t m_fnCommandCallbackV1;
FnCommandCallback_t m_fnCommandCallback;
ICommandCallback *m_pCommandCallback;
};
@ -373,6 +373,7 @@ public:
bool GetMin( float& minVal ) const;
bool GetMax( float& maxVal ) const;
const char *GetDefault( void ) const;
void SetDefault( const char *pszDefault );
private:
// Called by CCvar when the value of a var is changing.
@ -390,7 +391,7 @@ private:
// Used internally by OneTimeInit to initialize.
virtual void Init();
int GetFlags() { return m_pParent->m_nFlags; }
private:
// This either points to "this" or it points to the original declaration of a ConVar.

View File

@ -62,11 +62,15 @@ class CCommand;
#define FCVAR_REPLICATED (1<<13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time
#define FCVAR_DEMO (1<<16) // record this cvar when starting a demo file
#define FCVAR_DONTRECORD (1<<17) // don't record these command in demofiles
#define FCVAR_RELOAD_MATERIALS (1<<20) // If this cvar changes, it forces a material reload
#define FCVAR_RELOAD_TEXTURES (1<<21) // If this cvar changes, if forces a texture reload
#define FCVAR_NOT_CONNECTED (1<<22) // cvar cannot be changed by a client that is connected to a server
#define FCVAR_MATERIAL_SYSTEM_THREAD (1<<23) // Indicates this cvar is read from the material system thread
#define FCVAR_ARCHIVE_XBOX (1<<24) // cvar written to config.cfg on the Xbox
#define FCVAR_ACCESSIBLE_FROM_THREADS (1<<25) // used as a debugging tool necessary to check material system thread convars
#define FCVAR_SERVER_CAN_EXECUTE (1<<28)// the server is allowed to execute this command on clients via ClientCommand/NET_StringCmd/CBaseClientState::ProcessStringCmd.
#define FCVAR_SERVER_CANNOT_QUERY (1<<29)// If this is set, then the server is not allowed to query this cvar's value (via IServerPluginHelpers::StartQueryCvarValue).
#define FCVAR_CLIENTCMD_CAN_EXECUTE (1<<30) // IVEngineClient::ClientCmd is allowed to execute this command.
@ -78,11 +82,11 @@ class CCommand;
// #define FCVAR_AVAILABLE (1<<20)
// #define FCVAR_AVAILABLE (1<<21)
// #define FCVAR_AVAILABLE (1<<23)
// #define FCVAR_AVAILABLE (1<<25)
// #define FCVAR_AVAILABLE (1<<26)
// #define FCVAR_AVAILABLE (1<<27)
// #define FCVAR_AVAILABLE (1<<31)
#define FCVAR_MATERIAL_THREAD_MASK ( FCVAR_RELOAD_MATERIALS | FCVAR_RELOAD_TEXTURES | FCVAR_MATERIAL_SYSTEM_THREAD )
//-----------------------------------------------------------------------------
// Called when a ConVar changes value

View File

@ -32,7 +32,7 @@ class IProcessUtils;
// These are marked DLL_EXPORT for Linux.
DLL_EXPORT ICvar *cvar;
DLL_EXPORT ICvar *g_pCVar;
extern ICvar *g_pCVar;
extern IProcessUtils *g_pProcessUtils;

View File

@ -24,9 +24,10 @@
#endif
#include "tier0/memdbgon.h"
#ifndef NDEBUG
// Comment this out when we release.
//#define ALLOW_DEVELOPMENT_CVARS
#define ALLOW_DEVELOPMENT_CVARS
#endif
@ -78,6 +79,7 @@ void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor )
pCur = pNext;
}
g_pCVar->ProcessQueuedMaterialThreadConVarSets();
ConCommandBase::s_pConCommandBases = NULL;
}
@ -114,7 +116,7 @@ ConCommandBase::ConCommandBase( void )
//-----------------------------------------------------------------------------
ConCommandBase::ConCommandBase( const char *pName, const char *pHelpString /*=0*/, int flags /*= 0*/ )
{
Create( pName, pHelpString, flags );
CreateBase( pName, pHelpString, flags );
}
//-----------------------------------------------------------------------------
@ -151,16 +153,14 @@ CVarDLLIdentifier_t ConCommandBase::GetDLLIdentifier() const
// *pHelpString -
// flags -
//-----------------------------------------------------------------------------
void ConCommandBase::Create( const char *pName, const char *pHelpString /*= 0*/, int flags /*= 0*/ )
void ConCommandBase::CreateBase( const char *pName, const char *pHelpString /*= 0*/, int flags /*= 0*/ )
{
static const char *empty_string = "";
m_bRegistered = false;
// Name should be static data
Assert( pName );
m_pszName = pName;
m_pszHelpString = pHelpString ? pHelpString : empty_string;
m_pszHelpString = pHelpString ? pHelpString : "";
m_nFlags = flags;
@ -267,7 +267,7 @@ char *ConCommandBase::CopyString( const char *from )
int len;
char *to;
len = strlen( from );
len = V_strlen( from );
if ( len <= 0 )
{
to = new char[1];
@ -505,7 +505,7 @@ int DefaultCompletionFunc( const char *partial, char commands[ COMMAND_COMPLETIO
// m_bIsNewConCommand = true;
//}
ConCommand::ConCommand( const char *pName, FnCommandCallbackV1_t callback, const char *pHelpString /*= 0*/, int flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ )
ConCommand::ConCommand( const char *pName, FnCommandCallbackVoid_t callback, const char *pHelpString /*= 0*/, int flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ )
{
// Set the callback
m_fnCommandCallbackV1 = callback;
@ -515,7 +515,7 @@ ConCommand::ConCommand( const char *pName, FnCommandCallbackV1_t callback, const
m_bHasCompletionCallback = completionFunc != 0 ? true : false;
// Setup the rest
BaseClass::Create( pName, pHelpString, flags );
BaseClass::CreateBase( pName, pHelpString, flags );
}
ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const char *pHelpString /*= 0*/, int flags /*= 0*/, FnCommandCompletionCallback completionFunc /*= 0*/ )
@ -528,7 +528,7 @@ ConCommand::ConCommand( const char *pName, FnCommandCallback_t callback, const c
m_bUsingCommandCallbackInterface = false;
// Setup the rest
BaseClass::Create( pName, pHelpString, flags );
BaseClass::CreateBase( pName, pHelpString, flags );
}
ConCommand::ConCommand( const char *pName, ICommandCallback *pCallback, const char *pHelpString /*= 0*/, int flags /*= 0*/, ICommandCompletionCallback *pCompletionCallback /*= 0*/ )
@ -541,7 +541,7 @@ ConCommand::ConCommand( const char *pName, ICommandCallback *pCallback, const ch
m_bUsingCommandCallbackInterface = true;
// Setup the rest
BaseClass::Create( pName, pHelpString, flags );
BaseClass::CreateBase( pName, pHelpString, flags );
}
//-----------------------------------------------------------------------------
@ -592,7 +592,7 @@ void ConCommand::Dispatch( const CCommand &command )
}
// Command without callback!!!
AssertMsg( 0, ( "Encountered ConCommand without a callback!\n" ) );
AssertMsg( 0, "Encountered ConCommand '%s' without a callback!\n", GetName() );
}
@ -749,6 +749,15 @@ void ConVar::Init()
//-----------------------------------------------------------------------------
void ConVar::InternalSetValue( const char *value )
{
if ( IsFlagSet( FCVAR_MATERIAL_THREAD_MASK ) )
{
if ( g_pCVar && !g_pCVar->IsMaterialThreadSetAllowed() )
{
g_pCVar->QueueMaterialThreadSetValue( this, value );
return;
}
}
float fNewValue;
char tempVal[ 32 ];
char *val;
@ -758,17 +767,20 @@ void ConVar::InternalSetValue( const char *value )
float flOldValue = m_fValue;
val = (char *)value;
fNewValue = ( float )atof( value );
if ( !value )
fNewValue = 0.0f;
else
fNewValue = ( float )atof( value );
if ( ClampValue( fNewValue ) )
{
Q_snprintf( tempVal,sizeof(tempVal), "%f", fNewValue );
val = tempVal;
}
// Redetermine value
m_fValue = fNewValue;
m_nValue = ( int )( m_fValue );
m_nValue = ( int )( fNewValue );
if ( !( m_nFlags & FCVAR_NEVER_AS_STRING ) )
{
@ -787,28 +799,39 @@ void ConVar::ChangeStringValue( const char *tempVal, float flOldValue )
char* pszOldValue = (char*)stackalloc( m_StringLength );
memcpy( pszOldValue, m_pszString, m_StringLength );
int len = Q_strlen(tempVal) + 1;
if ( len > m_StringLength)
if ( tempVal )
{
if (m_pszString)
int len = Q_strlen(tempVal) + 1;
if ( len > m_StringLength)
{
delete[] m_pszString;
if (m_pszString)
{
delete[] m_pszString;
}
m_pszString = new char[len];
m_StringLength = len;
}
m_pszString = new char[len];
m_StringLength = len;
memcpy( m_pszString, tempVal, len );
}
memcpy( m_pszString, tempVal, len );
// Invoke any necessary callback function
if ( m_fnChangeCallback )
else
{
m_fnChangeCallback( this, pszOldValue, flOldValue );
*m_pszString = 0;
}
g_pCVar->CallGlobalChangeCallbacks( this, pszOldValue, flOldValue );
// If nothing has changed, don't do the callbacks.
if (V_strcmp(pszOldValue, m_pszString) != 0)
{
// Invoke any necessary callback function
if ( m_fnChangeCallback )
{
m_fnChangeCallback( this, pszOldValue, flOldValue );
}
g_pCVar->CallGlobalChangeCallbacks( this, pszOldValue, flOldValue );
}
stackfree( pszOldValue );
}
@ -844,6 +867,15 @@ void ConVar::InternalSetFloatValue( float fNewValue )
if ( fNewValue == m_fValue )
return;
if ( IsFlagSet( FCVAR_MATERIAL_THREAD_MASK ) )
{
if ( g_pCVar && !g_pCVar->IsMaterialThreadSetAllowed() )
{
g_pCVar->QueueMaterialThreadSetValue( this, fNewValue );
return;
}
}
Assert( m_pParent == this ); // Only valid for root convars.
// Check bounds
@ -875,6 +907,15 @@ void ConVar::InternalSetIntValue( int nValue )
if ( nValue == m_nValue )
return;
if ( IsFlagSet( FCVAR_MATERIAL_THREAD_MASK ) )
{
if ( g_pCVar && !g_pCVar->IsMaterialThreadSetAllowed() )
{
g_pCVar->QueueMaterialThreadSetValue( this, nValue );
return;
}
}
Assert( m_pParent == this ); // Only valid for root convars.
float fValue = (float)nValue;
@ -907,15 +948,12 @@ void ConVar::Create( const char *pName, const char *pDefaultValue, int flags /*=
const char *pHelpString /*= NULL*/, bool bMin /*= false*/, float fMin /*= 0.0*/,
bool bMax /*= false*/, float fMax /*= false*/, FnChangeCallback_t callback /*= NULL*/ )
{
static const char *empty_string = "";
m_pParent = this;
// Name should be static data
m_pszDefaultValue = pDefaultValue ? pDefaultValue : empty_string;
Assert( m_pszDefaultValue );
SetDefault( pDefaultValue );
m_StringLength = strlen( m_pszDefaultValue ) + 1;
m_StringLength = V_strlen( m_pszDefaultValue ) + 1;
m_pszString = new char[m_StringLength];
memcpy( m_pszString, m_pszDefaultValue, m_StringLength );
@ -927,6 +965,7 @@ void ConVar::Create( const char *pName, const char *pDefaultValue, int flags /*=
m_fnChangeCallback = callback;
m_fValue = ( float )atof( m_pszString );
m_nValue = atoi( m_pszString ); // dont convert from float to int and lose bits
// Bounds Check, should never happen, if it does, no big deal
if ( m_bHasMin && ( m_fValue < m_fMinVal ) )
@ -939,9 +978,7 @@ void ConVar::Create( const char *pName, const char *pDefaultValue, int flags /*=
Assert( 0 );
}
m_nValue = ( int )m_fValue;
BaseClass::Create( pName, pHelpString, flags );
BaseClass::CreateBase( pName, pHelpString, flags );
}
//-----------------------------------------------------------------------------
@ -1014,6 +1051,11 @@ const char *ConVar::GetDefault( void ) const
return m_pParent->m_pszDefaultValue;
}
void ConVar::SetDefault( const char *pszDefault )
{
m_pszDefaultValue = pszDefault ? pszDefault : "";
Assert( m_pszDefaultValue );
}
//-----------------------------------------------------------------------------
// This version is simply used to make reading convars simpler.