ds@2400: //===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// ds@2400: // ds@2400: // Purpose: ds@2400: // ds@2400: // $Workfile: $ ds@2400: // $Date: $ ds@2400: // ds@2400: //----------------------------------------------------------------------------- ds@2400: // $NoKeywords: $ ds@2400: //===========================================================================// ds@2400: ds@2400: #ifndef CONVAR_H ds@2400: #define CONVAR_H ds@2400: ds@2400: #if _WIN32 ds@2400: #pragma once ds@2400: #endif ds@2400: ds@2400: #include "tier0/dbg.h" ds@2400: #include "tier1/iconvar.h" ds@2400: #include "tier1/utlvector.h" ds@2400: #include "tier1/utlstring.h" ds@2400: #include "icvar.h" ds@2400: ds@2400: #ifdef _WIN32 ds@2400: #define FORCEINLINE_CVAR FORCEINLINE ds@3138: #elif defined _LINUX || defined __APPLE__ ds@2400: #define FORCEINLINE_CVAR inline ds@2400: #else ds@2400: #error "implement me" ds@2400: #endif ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Forward declarations ds@2400: //----------------------------------------------------------------------------- ds@2400: class ConVar; ds@2400: class CCommand; ds@2400: class ConCommand; ds@2400: class ConCommandBase; ds@2400: struct characterset_t; ds@2400: ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Any executable that wants to use ConVars need to implement one of ds@2400: // these to hook up access to console variables. ds@2400: //----------------------------------------------------------------------------- ds@2400: class IConCommandBaseAccessor ds@2400: { ds@2400: public: ds@2400: // Flags is a combination of FCVAR flags in cvar.h. ds@2400: // hOut is filled in with a handle to the variable. ds@2400: virtual bool RegisterConCommandBase( ConCommandBase *pVar ) = 0; ds@2400: }; ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Helper method for console development ds@2400: //----------------------------------------------------------------------------- ds@2400: #if defined( _X360 ) && !defined( _RETAIL ) ds@2400: void ConVar_PublishToVXConsole(); ds@2400: #endif ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Called when a ConCommand needs to execute ds@2400: //----------------------------------------------------------------------------- ds@2400: typedef void ( *FnCommandCallbackV1_t )( void ); ds@2400: typedef void ( *FnCommandCallback_t )( const CCommand &command ); ds@2400: ds@2400: #define COMMAND_COMPLETION_MAXITEMS 64 ds@2400: #define COMMAND_COMPLETION_ITEM_LENGTH 64 ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings ds@2400: //----------------------------------------------------------------------------- ds@2400: typedef int ( *FnCommandCompletionCallback )( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] ); ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Interface version ds@2400: //----------------------------------------------------------------------------- ds@2400: class ICommandCallback ds@2400: { ds@2400: public: ds@2400: virtual void CommandCallback( const CCommand &command ) = 0; ds@2400: }; ds@2400: ds@2400: class ICommandCompletionCallback ds@2400: { ds@2400: public: ds@2400: virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0; ds@2400: }; ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: The base console invoked command/cvar interface ds@2400: //----------------------------------------------------------------------------- ds@2400: class ConCommandBase ds@2400: { ds@2400: friend class CCvar; ds@2400: friend class ConVar; ds@2400: friend class ConCommand; ds@2400: friend void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor ); ds@2400: friend void ConVar_PublishToVXConsole(); ds@2400: ds@2400: // FIXME: Remove when ConVar changes are done ds@2400: friend class CDefaultCvar; ds@2400: ds@2400: public: ds@2400: ConCommandBase( void ); ds@2400: ConCommandBase( const char *pName, const char *pHelpString = 0, ds@2400: int flags = 0 ); ds@2400: ds@2400: virtual ~ConCommandBase( void ); ds@2400: ds@2400: virtual bool IsCommand( void ) const; ds@2400: ds@2400: // Check flag ds@2400: virtual bool IsFlagSet( int flag ) const; ds@2400: // Set flag ds@2400: virtual void AddFlags( int flags ); ds@2400: // Remove flag ds@2400: virtual void RemoveFlags( int flags ); ds@2400: // Get flags ds@2400: virtual int GetFlags( void ) const; ds@2400: ds@2400: // Return name of cvar ds@2400: virtual const char *GetName( void ) const; ds@2400: ds@2400: // Return help text for cvar ds@2400: virtual const char *GetHelpText( void ) const; ds@2400: ds@2400: // Deal with next pointer ds@2400: const ConCommandBase *GetNext( void ) const; ds@2400: ConCommandBase *GetNext( void ); ds@2400: ds@2400: inline void SetNext(ConCommandBase *pBase) ds@2400: { ds@2400: m_pNext = pBase; ds@2400: } ds@2400: ds@2400: virtual bool IsRegistered( void ) const; ds@2400: ds@2400: // Returns the DLL identifier ds@2400: virtual CVarDLLIdentifier_t GetDLLIdentifier() const; ds@2400: ds@2400: protected: ds@2400: virtual void Create( const char *pName, const char *pHelpString = 0, ds@2400: int flags = 0 ); ds@2400: ds@2400: // Used internally by OneTimeInit to initialize/shutdown ds@2400: virtual void Init(); ds@2400: void Shutdown(); ds@2400: ds@2400: // Internal copy routine ( uses new operator from correct module ) ds@2400: char *CopyString( const char *from ); ds@2400: ds@2400: private: ds@2400: // Next ConVar in chain ds@2400: // Prior to register, it points to the next convar in the DLL. ds@2400: // Once registered, though, m_pNext is reset to point to the next ds@2400: // convar in the global list ds@2400: ConCommandBase *m_pNext; ds@2400: ds@2400: // Has the cvar been added to the global list? ds@2400: bool m_bRegistered; ds@2400: ds@2400: // Static data ds@2400: const char *m_pszName; ds@2400: const char *m_pszHelpString; ds@2400: ds@2400: // ConVar flags ds@2400: int m_nFlags; ds@2400: ds@2400: protected: ds@2400: // ConVars add themselves to this list for the executable. ds@2400: // Then ConVar_Register runs through all the console variables ds@2400: // and registers them into a global list stored in vstdlib.dll ds@2400: static ConCommandBase *s_pConCommandBases; ds@2400: ds@2400: // ConVars in this executable use this 'global' to access values. ds@2400: static IConCommandBaseAccessor *s_pAccessor; ds@2400: public: ds@2400: inline void SetFlags(int flags) ds@2400: { ds@2400: m_nFlags = flags; ds@2400: } ds@2400: }; ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Command tokenizer ds@2400: //----------------------------------------------------------------------------- ds@2400: class CCommand ds@2400: { ds@2400: public: ds@2400: CCommand(); ds@2400: CCommand( int nArgC, const char **ppArgV ); ds@2400: bool Tokenize( const char *pCommand, characterset_t *pBreakSet = NULL ); ds@2400: void Reset(); ds@2400: ds@2400: int ArgC() const; ds@2400: const char **ArgV() const; ds@2400: const char *ArgS() const; // All args that occur after the 0th arg, in string form ds@2400: const char *GetCommandString() const; // The entire command in string form, including the 0th arg ds@2400: const char *operator[]( int nIndex ) const; // Gets at arguments ds@2400: const char *Arg( int nIndex ) const; // Gets at arguments ds@2400: ds@2400: // Helper functions to parse arguments to commands. ds@2400: const char* FindArg( const char *pName ) const; ds@2400: int FindArgInt( const char *pName, int nDefaultVal ) const; ds@2400: ds@2400: static int MaxCommandLength(); ds@2400: static characterset_t* DefaultBreakSet(); ds@2400: ds@2400: private: ds@2400: enum ds@2400: { ds@2400: COMMAND_MAX_ARGC = 64, ds@2400: COMMAND_MAX_LENGTH = 512, ds@2400: }; ds@2400: ds@2400: int m_nArgc; ds@2400: int m_nArgv0Size; ds@2400: char m_pArgSBuffer[ COMMAND_MAX_LENGTH ]; ds@2400: char m_pArgvBuffer[ COMMAND_MAX_LENGTH ]; ds@2400: const char* m_ppArgv[ COMMAND_MAX_ARGC ]; ds@2400: }; ds@2400: ds@2400: inline int CCommand::MaxCommandLength() ds@2400: { ds@2400: return COMMAND_MAX_LENGTH - 1; ds@2400: } ds@2400: ds@2400: inline int CCommand::ArgC() const ds@2400: { ds@2400: return m_nArgc; ds@2400: } ds@2400: ds@2400: inline const char **CCommand::ArgV() const ds@2400: { ds@2400: return m_nArgc ? (const char**)m_ppArgv : NULL; ds@2400: } ds@2400: ds@2400: inline const char *CCommand::ArgS() const ds@2400: { ds@2400: return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : ""; ds@2400: } ds@2400: ds@2400: inline const char *CCommand::GetCommandString() const ds@2400: { ds@2400: return m_nArgc ? m_pArgSBuffer : ""; ds@2400: } ds@2400: ds@2400: inline const char *CCommand::Arg( int nIndex ) const ds@2400: { ds@2400: // FIXME: Many command handlers appear to not be particularly careful ds@2400: // about checking for valid argc range. For now, we're going to ds@2400: // do the extra check and return an empty string if it's out of range ds@2400: if ( nIndex < 0 || nIndex >= m_nArgc ) ds@2400: return ""; ds@2400: return m_ppArgv[nIndex]; ds@2400: } ds@2400: ds@2400: inline const char *CCommand::operator[]( int nIndex ) const ds@2400: { ds@2400: return Arg( nIndex ); ds@2400: } ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: The console invoked command ds@2400: //----------------------------------------------------------------------------- ds@2400: class ConCommand : public ConCommandBase ds@2400: { ds@2400: friend class CCvar; ds@2400: ds@2400: public: ds@2400: typedef ConCommandBase BaseClass; ds@2400: ds@2400: ConCommand( const char *pName, FnCommandCallbackV1_t callback, ds@2400: const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); ds@2400: ConCommand( const char *pName, FnCommandCallback_t callback, ds@2400: const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); ds@2400: ConCommand( const char *pName, ICommandCallback *pCallback, ds@2400: const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 ); ds@2400: ds@2400: virtual ~ConCommand( void ); ds@2400: ds@2400: virtual bool IsCommand( void ) const; ds@2400: ds@2400: virtual int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands ); ds@2400: ds@2400: virtual bool CanAutoComplete( void ); ds@2400: ds@2400: // Invoke the function ds@2400: virtual void Dispatch( const CCommand &command ); ds@2400: ds@2400: private: ds@2400: // NOTE: To maintain backward compat, we have to be very careful: ds@2400: // All public virtual methods must appear in the same order always ds@2400: // since engine code will be calling into this code, which *does not match* ds@2400: // in the mod code; it's using slightly different, but compatible versions ds@2400: // of this class. Also: Be very careful about adding new fields to this class. ds@2400: // Those fields will not exist in the version of this class that is instanced ds@2400: // in mod code. ds@2400: ds@2400: // Call this function when executing the command ds@2400: union ds@2400: { ds@2400: FnCommandCallbackV1_t m_fnCommandCallbackV1; ds@2400: FnCommandCallback_t m_fnCommandCallback; ds@2400: ICommandCallback *m_pCommandCallback; ds@2400: }; ds@2400: ds@2400: union ds@2400: { ds@2400: FnCommandCompletionCallback m_fnCompletionCallback; ds@2400: ICommandCompletionCallback *m_pCommandCompletionCallback; ds@2400: }; ds@2400: ds@2400: bool m_bHasCompletionCallback : 1; ds@2400: bool m_bUsingNewCommandCallback : 1; ds@2400: bool m_bUsingCommandCallbackInterface : 1; ds@2400: public: ds@2400: inline FnCommandCallback_t GetCallback() const ds@2400: { ds@2400: return m_fnCommandCallback; ds@2400: } ds@2400: }; ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: A console variable ds@2400: //----------------------------------------------------------------------------- ds@2400: class ConVar : public ConCommandBase, public IConVar ds@2400: { ds@2400: friend class CCvar; ds@2400: friend class ConVarRef; ds@2400: ds@2400: public: ds@2400: typedef ConCommandBase BaseClass; ds@2400: ds@2400: ConVar( const char *pName, const char *pDefaultValue, int flags = 0); ds@2400: ds@2400: ConVar( const char *pName, const char *pDefaultValue, int flags, ds@2400: const char *pHelpString ); ds@2400: ConVar( const char *pName, const char *pDefaultValue, int flags, ds@2400: const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax ); ds@2400: ConVar( const char *pName, const char *pDefaultValue, int flags, ds@2400: const char *pHelpString, FnChangeCallback_t callback ); ds@2400: ConVar( const char *pName, const char *pDefaultValue, int flags, ds@2400: const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax, ds@2400: FnChangeCallback_t callback ); ds@2400: ds@2400: virtual ~ConVar( void ); ds@2400: ds@2400: virtual bool IsCommand( void ) const; ds@2400: virtual bool IsFlagSet( int flag ) const; ds@2400: virtual void AddFlags( int flags ); ds@2400: virtual int GetFlags( void ) const; ds@2400: virtual const char *GetName( void ) const; ds@2400: virtual const char* GetHelpText( void ) const; ds@2400: virtual bool IsRegistered( void ) const; ds@2400: ds@2400: // Install a change callback (there shouldn't already be one....) ds@2400: void InstallChangeCallback( FnChangeCallback_t callback ); ds@2400: ds@2400: // Retrieve value ds@2400: FORCEINLINE_CVAR float GetFloat( void ) const; ds@2400: FORCEINLINE_CVAR int GetInt( void ) const; ds@2400: FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); } ds@2400: FORCEINLINE_CVAR char const *GetString( void ) const; ds@2400: ds@2400: // Used internally by OneTimeInit to initialize. ds@2400: virtual void Init(); ds@2400: ds@2400: virtual const char *GetBaseName( void ) const; ds@2400: virtual int GetSplitScreenPlayerSlot ( void ) const; ds@2400: ds@2400: // Any function that allocates/frees memory needs to be virtual or else you'll have crashes ds@2400: // from alloc/free across dll/exe boundaries. ds@2400: ds@2400: // These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue). ds@2400: virtual void SetValue( const char *value ); ds@2400: virtual void SetValue( float value ); ds@2400: virtual void SetValue( int value ); skamonkey@3961: #if SOURCE_ENGINE >= SE_NUCLEARDAWN pred@2850: virtual void SetValue( Color value ); pred@2850: #endif ds@2400: ds@2400: // Reset to default value ds@2400: void Revert( void ); ds@2400: ds@2400: // True if it has a min/max setting ds@2400: bool GetMin( float& minVal ) const; ds@2400: bool GetMax( float& maxVal ) const; ds@2400: const char *GetDefault( void ) const; ds@2400: ds@2400: private: ds@2400: // Called by CCvar when the value of a var is changing. ds@2400: virtual void InternalSetValue(const char *value); ds@2400: // For CVARs marked FCVAR_NEVER_AS_STRING ds@2400: virtual void InternalSetFloatValue( float fNewValue ); ds@2400: virtual void InternalSetIntValue( int nValue ); ds@3099: #if SOURCE_ENGINE >= SE_LEFT4DEAD2 ds@3099: virtual void InternalSetColorValue( Color value ); ds@3099: #endif ds@2400: ds@2400: virtual bool ClampValue( float& value ); ds@2400: virtual void ChangeStringValue( const char *tempVal, float flOldValue ); ds@2400: ds@2400: virtual void Create( const char *pName, const char *pDefaultValue, int flags = 0, ds@2400: const char *pHelpString = 0, bool bMin = false, float fMin = 0.0, ds@2400: bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 ); ds@2400: ds@2400: private: ds@2400: ds@2400: // This either points to "this" or it points to the original declaration of a ConVar. ds@2400: // This allows ConVars to exist in separate modules, and they all use the first one to be declared. ds@2400: // m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar). ds@2400: ConVar *m_pParent; ds@2400: ds@2400: // Static data ds@2400: const char *m_pszDefaultValue; ds@2400: ds@2400: // Value ds@2400: // Dynamically allocated ds@2400: char *m_pszString; ds@2400: int m_StringLength; ds@2400: ds@2400: // Values ds@2400: float m_fValue; ds@2400: int m_nValue; ds@2400: ds@2400: // Min/Max values ds@2400: bool m_bHasMin; ds@2400: float m_fMinVal; ds@2400: bool m_bHasMax; ds@2400: float m_fMaxVal; ds@2400: ds@2400: // Call this function when ConVar changes ds@2400: FnChangeCallback_t m_fnChangeCallback; ds@2400: public: ds@2400: inline FnChangeCallback_t GetCallback() const ds@2400: { ds@2400: return m_fnChangeCallback; ds@2400: } ds@2400: inline void SetMin(bool set, float min=0.0) ds@2400: { ds@2400: m_bHasMin = set; ds@2400: m_fMinVal = min; ds@2400: } ds@2400: inline void SetMax(bool set, float max=0.0) ds@2400: { ds@2400: m_bHasMax = set; ds@2400: m_fMaxVal = max; ds@2400: } ds@2400: }; ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: Return ConVar value as a float ds@2400: // Output : float ds@2400: //----------------------------------------------------------------------------- ds@2400: FORCEINLINE_CVAR float ConVar::GetFloat( void ) const ds@2400: { ds@2400: return m_pParent->m_fValue; ds@2400: } ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: Return ConVar value as an int ds@2400: // Output : int ds@2400: //----------------------------------------------------------------------------- ds@2400: FORCEINLINE_CVAR int ConVar::GetInt( void ) const ds@2400: { ds@2400: return m_pParent->m_nValue; ds@2400: } ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. ds@2400: // Output : const char * ds@2400: //----------------------------------------------------------------------------- ds@2400: FORCEINLINE_CVAR const char *ConVar::GetString( void ) const ds@2400: { ds@2400: if ( m_nFlags & FCVAR_NEVER_AS_STRING ) ds@2400: return "FCVAR_NEVER_AS_STRING"; ds@2400: ds@2400: return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : ""; ds@2400: } ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Used to read/write convars that already exist (replaces the FindVar method) ds@2400: //----------------------------------------------------------------------------- ds@2400: class ConVarRef ds@2400: { ds@2400: public: ds@2400: ConVarRef( const char *pName ); ds@2400: ConVarRef( const char *pName, bool bIgnoreMissing ); ds@2400: ConVarRef( IConVar *pConVar ); ds@2400: ds@2400: void Init( const char *pName, bool bIgnoreMissing ); ds@2400: bool IsValid() const; ds@2400: bool IsFlagSet( int nFlags ) const; ds@2400: IConVar *GetLinkedConVar(); ds@2400: ds@2400: // Get/Set value ds@2400: float GetFloat( void ) const; ds@2400: int GetInt( void ) const; ds@2400: bool GetBool() const { return !!GetInt(); } ds@2400: const char *GetString( void ) const; ds@2400: ds@2400: void SetValue( const char *pValue ); ds@2400: void SetValue( float flValue ); ds@2400: void SetValue( int nValue ); ds@2400: void SetValue( bool bValue ); ds@2400: ds@2400: const char *GetName() const; ds@2400: ds@2400: const char *GetDefault() const; ds@2400: ds@2400: private: ds@2400: // High-speed method to read convar data ds@2400: IConVar *m_pConVar; ds@2400: ConVar *m_pConVarState; ds@2400: }; ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Did we find an existing convar of that name? ds@2400: //----------------------------------------------------------------------------- ds@2400: FORCEINLINE_CVAR bool ConVarRef::IsFlagSet( int nFlags ) const ds@2400: { ds@2400: return ( m_pConVar->IsFlagSet( nFlags ) != 0 ); ds@2400: } ds@2400: ds@2400: FORCEINLINE_CVAR IConVar *ConVarRef::GetLinkedConVar() ds@2400: { ds@2400: return m_pConVar; ds@2400: } ds@2400: ds@2400: FORCEINLINE_CVAR const char *ConVarRef::GetName() const ds@2400: { ds@2400: return m_pConVar->GetName(); ds@2400: } ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: Return ConVar value as a float ds@2400: //----------------------------------------------------------------------------- ds@2400: FORCEINLINE_CVAR float ConVarRef::GetFloat( void ) const ds@2400: { ds@2400: return m_pConVarState->m_fValue; ds@2400: } ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: Return ConVar value as an int ds@2400: //----------------------------------------------------------------------------- ds@2400: FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const ds@2400: { ds@2400: return m_pConVarState->m_nValue; ds@2400: } ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. ds@2400: //----------------------------------------------------------------------------- ds@2400: FORCEINLINE_CVAR const char *ConVarRef::GetString( void ) const ds@2400: { ds@2400: Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) ); ds@2400: return m_pConVarState->m_pszString; ds@2400: } ds@2400: ds@2400: ds@2400: FORCEINLINE_CVAR void ConVarRef::SetValue( const char *pValue ) ds@2400: { ds@2400: m_pConVar->SetValue( pValue ); ds@2400: } ds@2400: ds@2400: FORCEINLINE_CVAR void ConVarRef::SetValue( float flValue ) ds@2400: { ds@2400: m_pConVar->SetValue( flValue ); ds@2400: } ds@2400: ds@2400: FORCEINLINE_CVAR void ConVarRef::SetValue( int nValue ) ds@2400: { ds@2400: m_pConVar->SetValue( nValue ); ds@2400: } ds@2400: ds@2400: FORCEINLINE_CVAR void ConVarRef::SetValue( bool bValue ) ds@2400: { ds@2400: m_pConVar->SetValue( bValue ? 1 : 0 ); ds@2400: } ds@2400: ds@2400: FORCEINLINE_CVAR const char *ConVarRef::GetDefault() const ds@2400: { ds@2400: return m_pConVarState->m_pszDefaultValue; ds@2400: } ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Called by the framework to register ConCommands with the ICVar ds@2400: //----------------------------------------------------------------------------- ds@2400: void ConVar_Register( int nCVarFlag = 0, IConCommandBaseAccessor *pAccessor = NULL ); ds@2400: void ConVar_Unregister( ); ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Utility methods ds@2400: //----------------------------------------------------------------------------- ds@2400: void ConVar_PrintFlags( const ConCommandBase *var ); ds@2400: void ConVar_PrintDescription( const ConCommandBase *pVar ); ds@2400: ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: Utility class to quickly allow ConCommands to call member methods ds@2400: //----------------------------------------------------------------------------- ds@2400: #ifdef _MSC_VER ds@2400: #pragma warning (disable : 4355 ) ds@2400: #endif ds@2400: ds@2400: template< class T > ds@2400: class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback ds@2400: { ds@2400: typedef ConCommand BaseClass; ds@2400: typedef void ( T::*FnMemberCommandCallback_t )( const CCommand &command ); ds@2400: typedef int ( T::*FnMemberCommandCompletionCallback_t )( const char *pPartial, CUtlVector< CUtlString > &commands ); ds@2400: ds@2400: public: ds@2400: CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0, ds@2400: int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) : ds@2400: BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL ) ds@2400: { ds@2400: m_pOwner = pOwner; ds@2400: m_Func = callback; ds@2400: m_CompletionFunc = completionFunc; ds@2400: } ds@2400: ds@2400: ~CConCommandMemberAccessor() ds@2400: { ds@2400: Shutdown(); ds@2400: } ds@2400: ds@2400: void SetOwner( T* pOwner ) ds@2400: { ds@2400: m_pOwner = pOwner; ds@2400: } ds@2400: ds@2400: virtual void CommandCallback( const CCommand &command ) ds@2400: { ds@2400: Assert( m_pOwner && m_Func ); ds@2400: (m_pOwner->*m_Func)( command ); ds@2400: } ds@2400: ds@2400: virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) ds@2400: { ds@2400: Assert( m_pOwner && m_CompletionFunc ); ds@2400: return (m_pOwner->*m_CompletionFunc)( pPartial, commands ); ds@2400: } ds@2400: ds@2400: private: ds@2400: T* m_pOwner; ds@2400: FnMemberCommandCallback_t m_Func; ds@2400: FnMemberCommandCompletionCallback_t m_CompletionFunc; ds@2400: }; ds@2400: ds@2400: #ifdef _MSC_VER ds@2400: #pragma warning ( default : 4355 ) ds@2400: #endif ds@2400: ds@2400: //----------------------------------------------------------------------------- ds@2400: // Purpose: Utility macros to quicky generate a simple console command ds@2400: //----------------------------------------------------------------------------- ds@2400: #define CON_COMMAND( name, description ) \ ds@2400: static void name( const CCommand &args ); \ ds@2400: static ConCommand name##_command( #name, name, description ); \ ds@2400: static void name( const CCommand &args ) ds@2400: ds@2400: #define CON_COMMAND_F( name, description, flags ) \ ds@2400: static void name( const CCommand &args ); \ ds@2400: static ConCommand name##_command( #name, name, description, flags ); \ ds@2400: static void name( const CCommand &args ) ds@2400: ds@2400: #define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \ ds@2400: static void name( const CCommand &args ); \ ds@2400: static ConCommand name##_command( #name, name, description, flags, completion ); \ ds@2400: static void name( const CCommand &args ) ds@2400: ds@2400: #define CON_COMMAND_EXTERN( name, _funcname, description ) \ ds@2400: void _funcname( const CCommand &args ); \ ds@2400: static ConCommand name##_command( #name, _funcname, description ); \ ds@2400: void _funcname( const CCommand &args ) ds@2400: ds@2400: #define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \ ds@2400: void _funcname( const CCommand &args ); \ ds@2400: static ConCommand name##_command( #name, _funcname, description, flags ); \ ds@2400: void _funcname( const CCommand &args ) ds@2400: ds@2400: #define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \ ds@2400: void _funcname( const CCommand &args ); \ ds@2400: friend class CCommandMemberInitializer_##_funcname; \ ds@2400: class CCommandMemberInitializer_##_funcname \ ds@2400: { \ ds@2400: public: \ ds@2400: CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags ) \ ds@2400: { \ ds@2400: m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) ); \ ds@2400: } \ ds@2400: private: \ ds@2400: CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor; \ ds@2400: }; \ ds@2400: \ ds@2400: CCommandMemberInitializer_##_funcname m_##_funcname##_register; \ ds@2400: ds@2400: ds@2400: #endif // CONVAR_H