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