core/convar_sm_ob.h
author Drifter <rgr_02@comcast.net>
Wed May 30 23:00:16 2012 -0400 (2012-05-30)
changeset 3543 9287a18e9a33
parent 2993 76da4d93e0d6
permissions -rw-r--r--
Fix for SDKTools TeamScore natives crash on CS:GO (bug 5319, r=psychonic).
     1 //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
     2 //
     3 // Purpose: 
     4 //
     5 // $Workfile:     $
     6 // $Date:         $
     7 //
     8 //-----------------------------------------------------------------------------
     9 // $NoKeywords: $
    10 //===========================================================================//
    11 
    12 #ifndef CONVAR_H
    13 #define CONVAR_H
    14 
    15 #if _WIN32
    16 #pragma once
    17 #endif
    18 
    19 #include "tier0/dbg.h"
    20 #include "tier1/iconvar.h"
    21 #include "tier1/utlvector.h"
    22 #include "tier1/utlstring.h"
    23 #include "icvar.h"
    24 
    25 #ifdef _WIN32
    26 #define FORCEINLINE_CVAR FORCEINLINE
    27 #elif defined _LINUX || defined __APPLE__
    28 #define FORCEINLINE_CVAR inline
    29 #else
    30 #error "implement me"
    31 #endif
    32 
    33 
    34 //-----------------------------------------------------------------------------
    35 // Forward declarations
    36 //-----------------------------------------------------------------------------
    37 class ConVar;
    38 class CCommand;
    39 class ConCommand;
    40 class ConCommandBase;
    41 struct characterset_t;
    42 
    43 
    44 
    45 //-----------------------------------------------------------------------------
    46 // Any executable that wants to use ConVars need to implement one of
    47 // these to hook up access to console variables.
    48 //-----------------------------------------------------------------------------
    49 class IConCommandBaseAccessor
    50 {
    51 public:
    52 	// Flags is a combination of FCVAR flags in cvar.h.
    53 	// hOut is filled in with a handle to the variable.
    54 	virtual bool RegisterConCommandBase( ConCommandBase *pVar ) = 0;
    55 };
    56 
    57 
    58 //-----------------------------------------------------------------------------
    59 // Helper method for console development
    60 //-----------------------------------------------------------------------------
    61 #if defined( _X360 ) && !defined( _RETAIL )
    62 void ConVar_PublishToVXConsole();
    63 #endif
    64 
    65 
    66 //-----------------------------------------------------------------------------
    67 // Called when a ConCommand needs to execute
    68 //-----------------------------------------------------------------------------
    69 typedef void ( *FnCommandCallbackV1_t )( void );
    70 typedef void ( *FnCommandCallback_t )( const CCommand &command );
    71 
    72 #define COMMAND_COMPLETION_MAXITEMS		64
    73 #define COMMAND_COMPLETION_ITEM_LENGTH	64
    74 
    75 //-----------------------------------------------------------------------------
    76 // Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
    77 //-----------------------------------------------------------------------------
    78 typedef int  ( *FnCommandCompletionCallback )( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
    79 
    80 
    81 //-----------------------------------------------------------------------------
    82 // Interface version
    83 //-----------------------------------------------------------------------------
    84 class ICommandCallback
    85 {
    86 public:
    87 	virtual void CommandCallback( const CCommand &command ) = 0;
    88 };
    89 
    90 class ICommandCompletionCallback
    91 {
    92 public:
    93 	virtual int  CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0;
    94 };
    95 
    96 //-----------------------------------------------------------------------------
    97 // Purpose: The base console invoked command/cvar interface
    98 //-----------------------------------------------------------------------------
    99 class ConCommandBase
   100 {
   101 	friend class CCvar;
   102 	friend class ConVar;
   103 	friend class ConCommand;
   104 	friend void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor );
   105 	friend void ConVar_PublishToVXConsole();
   106 
   107 	// FIXME: Remove when ConVar changes are done
   108 	friend class CDefaultCvar;
   109 
   110 public:
   111 								ConCommandBase( void );
   112 								ConCommandBase( const char *pName, const char *pHelpString = 0, 
   113 									int flags = 0 );
   114 
   115 	virtual						~ConCommandBase( void );
   116 
   117 	virtual	bool				IsCommand( void ) const;
   118 
   119 	// Check flag
   120 	virtual bool				IsFlagSet( int flag ) const;
   121 	// Set flag
   122 	virtual void				AddFlags( int flags );
   123 
   124 	// Return name of cvar
   125 	virtual const char			*GetName( void ) const;
   126 
   127 	// Return help text for cvar
   128 	virtual const char			*GetHelpText( void ) const;
   129 
   130 	// Deal with next pointer
   131 	const ConCommandBase		*GetNext( void ) const;
   132 	ConCommandBase				*GetNext( void );
   133 
   134 	void SetNext(ConCommandBase *pBase)
   135 	{
   136 		m_pNext = pBase;
   137 	}
   138 	
   139 	virtual bool				IsRegistered( void ) const;
   140 
   141 	// Returns the DLL identifier
   142 	virtual CVarDLLIdentifier_t	GetDLLIdentifier() const;
   143 
   144 protected:
   145 	virtual void				Create( const char *pName, const char *pHelpString = 0, 
   146 									int flags = 0 );
   147 
   148 	// Used internally by OneTimeInit to initialize/shutdown
   149 	virtual void				Init();
   150 	void						Shutdown();
   151 
   152 	// Internal copy routine ( uses new operator from correct module )
   153 	char						*CopyString( const char *from );
   154 
   155 private:
   156 	// Next ConVar in chain
   157 	// Prior to register, it points to the next convar in the DLL.
   158 	// Once registered, though, m_pNext is reset to point to the next
   159 	// convar in the global list
   160 	ConCommandBase				*m_pNext;
   161 
   162 	// Has the cvar been added to the global list?
   163 	bool						m_bRegistered;
   164 
   165 	// Static data
   166 	const char 					*m_pszName;
   167 	const char 					*m_pszHelpString;
   168 	
   169 	// ConVar flags
   170 	int							m_nFlags;
   171 
   172 protected:
   173 	// ConVars add themselves to this list for the executable. 
   174 	// Then ConVar_Register runs through  all the console variables 
   175 	// and registers them into a global list stored in vstdlib.dll
   176 	static ConCommandBase		*s_pConCommandBases;
   177 
   178 	// ConVars in this executable use this 'global' to access values.
   179 	static IConCommandBaseAccessor	*s_pAccessor;
   180 public: // Hackalicous
   181 	inline int GetFlags() const
   182 	{
   183 		return m_nFlags;
   184 	}
   185 	inline void SetFlags(int flags)	
   186 	{ 
   187 		m_nFlags = flags; 
   188 	}
   189 };
   190 
   191 
   192 //-----------------------------------------------------------------------------
   193 // Command tokenizer
   194 //-----------------------------------------------------------------------------
   195 class CCommand
   196 {
   197 public:
   198 	CCommand();
   199 	CCommand( int nArgC, const char **ppArgV );
   200 	bool Tokenize( const char *pCommand, characterset_t *pBreakSet = NULL );
   201 	void Reset();
   202 
   203 	int ArgC() const;
   204 	const char **ArgV() const;
   205 	const char *ArgS() const;					// All args that occur after the 0th arg, in string form
   206 	const char *GetCommandString() const;		// The entire command in string form, including the 0th arg
   207 	const char *operator[]( int nIndex ) const;	// Gets at arguments
   208 	const char *Arg( int nIndex ) const;		// Gets at arguments
   209 	
   210 	// Helper functions to parse arguments to commands.
   211 	const char* FindArg( const char *pName ) const;
   212 	int FindArgInt( const char *pName, int nDefaultVal ) const;
   213 
   214 	static int MaxCommandLength();
   215 	static characterset_t* DefaultBreakSet();
   216 
   217 private:
   218 	enum
   219 	{
   220 		COMMAND_MAX_ARGC = 64,
   221 		COMMAND_MAX_LENGTH = 512,
   222 	};
   223 
   224 	int		m_nArgc;
   225 	int		m_nArgv0Size;
   226 	char	m_pArgSBuffer[ COMMAND_MAX_LENGTH ];
   227 	char	m_pArgvBuffer[ COMMAND_MAX_LENGTH ];
   228 	const char*	m_ppArgv[ COMMAND_MAX_ARGC ];
   229 };
   230 
   231 inline int CCommand::MaxCommandLength()
   232 {
   233 	return COMMAND_MAX_LENGTH - 1;
   234 }
   235 
   236 inline int CCommand::ArgC() const
   237 {
   238 	return m_nArgc;
   239 }
   240 
   241 inline const char **CCommand::ArgV() const
   242 {
   243 	return m_nArgc ? (const char**)m_ppArgv : NULL;
   244 }
   245 
   246 inline const char *CCommand::ArgS() const
   247 {
   248 	return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
   249 }
   250 
   251 inline const char *CCommand::GetCommandString() const
   252 {
   253 	return m_nArgc ? m_pArgSBuffer : "";
   254 }
   255 
   256 inline const char *CCommand::Arg( int nIndex ) const
   257 {
   258 	// FIXME: Many command handlers appear to not be particularly careful
   259 	// about checking for valid argc range. For now, we're going to
   260 	// do the extra check and return an empty string if it's out of range
   261 	if ( nIndex < 0 || nIndex >= m_nArgc )
   262 		return "";
   263 	return m_ppArgv[nIndex];
   264 }
   265 
   266 inline const char *CCommand::operator[]( int nIndex ) const
   267 {
   268 	return Arg( nIndex );
   269 }
   270 
   271 
   272 //-----------------------------------------------------------------------------
   273 // Purpose: The console invoked command
   274 //-----------------------------------------------------------------------------
   275 class ConCommand : public ConCommandBase
   276 {
   277 friend class CCvar;
   278 
   279 public:
   280 	typedef ConCommandBase BaseClass;
   281 
   282 	ConCommand( const char *pName, FnCommandCallbackV1_t callback, 
   283 		const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
   284 	ConCommand( const char *pName, FnCommandCallback_t callback, 
   285 		const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
   286 	ConCommand( const char *pName, ICommandCallback *pCallback, 
   287 		const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 );
   288 
   289 	virtual ~ConCommand( void );
   290 
   291 	virtual	bool IsCommand( void ) const;
   292 
   293 	virtual int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands );
   294 
   295 	virtual bool CanAutoComplete( void );
   296 
   297 	// Invoke the function
   298 	virtual void Dispatch( const CCommand &command );
   299 
   300 private:
   301 	// NOTE: To maintain backward compat, we have to be very careful:
   302 	// All public virtual methods must appear in the same order always
   303 	// since engine code will be calling into this code, which *does not match*
   304 	// in the mod code; it's using slightly different, but compatible versions
   305 	// of this class. Also: Be very careful about adding new fields to this class.
   306 	// Those fields will not exist in the version of this class that is instanced
   307 	// in mod code.
   308 
   309 	// Call this function when executing the command
   310 	union
   311 	{
   312 		FnCommandCallbackV1_t m_fnCommandCallbackV1;
   313 		FnCommandCallback_t m_fnCommandCallback;
   314 		ICommandCallback *m_pCommandCallback; 
   315 	};
   316 
   317 	union
   318 	{
   319 		FnCommandCompletionCallback	m_fnCompletionCallback;
   320 		ICommandCompletionCallback *m_pCommandCompletionCallback;
   321 	};
   322 
   323 	bool m_bHasCompletionCallback : 1;
   324 	bool m_bUsingNewCommandCallback : 1;
   325 	bool m_bUsingCommandCallbackInterface : 1;
   326 public: // Hackalicous
   327 	inline FnCommandCallback_t GetCallback() const
   328 	{ 
   329 		return m_fnCommandCallback; 
   330 	}
   331 };
   332 
   333 
   334 //-----------------------------------------------------------------------------
   335 // Purpose: A console variable
   336 //-----------------------------------------------------------------------------
   337 class ConVar : public ConCommandBase, public IConVar
   338 {
   339 friend class CCvar;
   340 friend class ConVarRef;
   341 
   342 public:
   343 	typedef ConCommandBase BaseClass;
   344 
   345 								ConVar( const char *pName, const char *pDefaultValue, int flags = 0);
   346 
   347 								ConVar( const char *pName, const char *pDefaultValue, int flags, 
   348 									const char *pHelpString );
   349 								ConVar( const char *pName, const char *pDefaultValue, int flags, 
   350 									const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax );
   351 								ConVar( const char *pName, const char *pDefaultValue, int flags, 
   352 									const char *pHelpString, FnChangeCallback_t callback );
   353 								ConVar( const char *pName, const char *pDefaultValue, int flags, 
   354 									const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax,
   355 									FnChangeCallback_t callback );
   356 
   357 	virtual						~ConVar( void );
   358 
   359 	virtual bool				IsFlagSet( int flag ) const;
   360 	virtual const char*			GetHelpText( void ) const;
   361 	virtual bool				IsRegistered( void ) const;
   362 	virtual const char			*GetName( void ) const;
   363 	virtual void				AddFlags( int flags );
   364 	virtual	bool				IsCommand( void ) const;
   365 
   366 	// Install a change callback (there shouldn't already be one....)
   367 	void InstallChangeCallback( FnChangeCallback_t callback );
   368 
   369 	// Retrieve value
   370 	FORCEINLINE_CVAR float			GetFloat( void ) const;
   371 	FORCEINLINE_CVAR int			GetInt( void ) const;
   372 	FORCEINLINE_CVAR bool			GetBool() const {  return !!GetInt(); }
   373 	FORCEINLINE_CVAR char const	   *GetString( void ) const;
   374 
   375 	// Any function that allocates/frees memory needs to be virtual or else you'll have crashes
   376 	//  from alloc/free across dll/exe boundaries.
   377 	
   378 	// These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue).
   379 	virtual void				SetValue( const char *value );
   380 	virtual void				SetValue( float value );
   381 	virtual void				SetValue( int value );
   382 	
   383 	// Reset to default value
   384 	void						Revert( void );
   385 
   386 	// True if it has a min/max setting
   387 	bool						GetMin( float& minVal ) const;
   388 	bool						GetMax( float& maxVal ) const;
   389 	const char					*GetDefault( void ) const;
   390 
   391 private:
   392 	// Called by CCvar when the value of a var is changing.
   393 	virtual void				InternalSetValue(const char *value);
   394 	// For CVARs marked FCVAR_NEVER_AS_STRING
   395 	virtual void				InternalSetFloatValue( float fNewValue );
   396 	virtual void				InternalSetIntValue( int nValue );
   397 
   398 	virtual bool				ClampValue( float& value );
   399 	virtual void				ChangeStringValue( const char *tempVal, float flOldValue );
   400 
   401 	virtual void				Create( const char *pName, const char *pDefaultValue, int flags = 0,
   402 									const char *pHelpString = 0, bool bMin = false, float fMin = 0.0,
   403 									bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 );
   404 
   405 	// Used internally by OneTimeInit to initialize.
   406 	virtual void				Init();
   407 
   408 private:
   409 
   410 	// This either points to "this" or it points to the original declaration of a ConVar.
   411 	// This allows ConVars to exist in separate modules, and they all use the first one to be declared.
   412 	// m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar).
   413 	ConVar						*m_pParent;
   414 
   415 	// Static data
   416 	const char					*m_pszDefaultValue;
   417 	
   418 	// Value
   419 	// Dynamically allocated
   420 	char						*m_pszString;
   421 	int							m_StringLength;
   422 
   423 	// Values
   424 	float						m_fValue;
   425 	int							m_nValue;
   426 
   427 	// Min/Max values
   428 	bool						m_bHasMin;
   429 	float						m_fMinVal;
   430 	bool						m_bHasMax;
   431 	float						m_fMaxVal;
   432 	
   433 	// Call this function when ConVar changes
   434 	FnChangeCallback_t			m_fnChangeCallback;
   435 public: // Hackalicous
   436 	inline FnChangeCallback_t GetCallback() const
   437 	{
   438 		return m_fnChangeCallback;
   439 	}
   440 	inline void SetMin(bool set, float min=0.0)
   441 	{ 
   442 		m_bHasMin = set; 
   443 		m_fMinVal = min; 
   444 	}
   445 	inline void SetMax(bool set, float max=0.0)
   446 	{
   447 		m_bHasMax = set;
   448 		m_fMaxVal = max; 
   449 	}
   450 };
   451 
   452 
   453 //-----------------------------------------------------------------------------
   454 // Purpose: Return ConVar value as a float
   455 // Output : float
   456 //-----------------------------------------------------------------------------
   457 FORCEINLINE_CVAR float ConVar::GetFloat( void ) const
   458 {
   459 	return m_pParent->m_fValue;
   460 }
   461 
   462 //-----------------------------------------------------------------------------
   463 // Purpose: Return ConVar value as an int
   464 // Output : int
   465 //-----------------------------------------------------------------------------
   466 FORCEINLINE_CVAR int ConVar::GetInt( void ) const 
   467 {
   468 	return m_pParent->m_nValue;
   469 }
   470 
   471 
   472 //-----------------------------------------------------------------------------
   473 // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
   474 // Output : const char *
   475 //-----------------------------------------------------------------------------
   476 FORCEINLINE_CVAR const char *ConVar::GetString( void ) const 
   477 {
   478 	if ( m_nFlags & FCVAR_NEVER_AS_STRING )
   479 		return "FCVAR_NEVER_AS_STRING";
   480 
   481 	return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : "";
   482 }
   483 
   484 
   485 //-----------------------------------------------------------------------------
   486 // Used to read/write convars that already exist (replaces the FindVar method)
   487 //-----------------------------------------------------------------------------
   488 class ConVarRef
   489 {
   490 public:
   491 	ConVarRef( const char *pName );
   492 	ConVarRef( const char *pName, bool bIgnoreMissing );
   493 	ConVarRef( IConVar *pConVar );
   494 
   495 	void Init( const char *pName, bool bIgnoreMissing );
   496 	bool IsValid() const;
   497 	bool IsFlagSet( int nFlags ) const;
   498 	IConVar *GetLinkedConVar();
   499 
   500 	// Get/Set value
   501 	float GetFloat( void ) const;
   502 	int GetInt( void ) const;
   503 	bool GetBool() const { return !!GetInt(); }
   504 	const char *GetString( void ) const;
   505 
   506 	void SetValue( const char *pValue );
   507 	void SetValue( float flValue );
   508 	void SetValue( int nValue );
   509 	void SetValue( bool bValue );
   510 
   511 	const char *GetName() const;
   512 
   513 	const char *GetDefault() const;
   514 
   515 private:
   516 	// High-speed method to read convar data
   517 	IConVar *m_pConVar;
   518 	ConVar *m_pConVarState;
   519 };
   520 
   521 
   522 //-----------------------------------------------------------------------------
   523 // Did we find an existing convar of that name?
   524 //-----------------------------------------------------------------------------
   525 FORCEINLINE_CVAR bool ConVarRef::IsFlagSet( int nFlags ) const
   526 {
   527 	return ( m_pConVar->IsFlagSet( nFlags ) != 0 );
   528 }
   529 
   530 FORCEINLINE_CVAR IConVar *ConVarRef::GetLinkedConVar()
   531 {
   532 	return m_pConVar;
   533 }
   534 
   535 FORCEINLINE_CVAR const char *ConVarRef::GetName() const
   536 {
   537 	return m_pConVar->GetName();
   538 }
   539 
   540 
   541 //-----------------------------------------------------------------------------
   542 // Purpose: Return ConVar value as a float
   543 //-----------------------------------------------------------------------------
   544 FORCEINLINE_CVAR float ConVarRef::GetFloat( void ) const
   545 {
   546 	return m_pConVarState->m_fValue;
   547 }
   548 
   549 //-----------------------------------------------------------------------------
   550 // Purpose: Return ConVar value as an int
   551 //-----------------------------------------------------------------------------
   552 FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const 
   553 {
   554 	return m_pConVarState->m_nValue;
   555 }
   556 
   557 //-----------------------------------------------------------------------------
   558 // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
   559 //-----------------------------------------------------------------------------
   560 FORCEINLINE_CVAR const char *ConVarRef::GetString( void ) const 
   561 {
   562 	Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) );
   563 	return m_pConVarState->m_pszString;
   564 }
   565 
   566 
   567 FORCEINLINE_CVAR void ConVarRef::SetValue( const char *pValue )
   568 {
   569 	m_pConVar->SetValue( pValue );
   570 }
   571 
   572 FORCEINLINE_CVAR void ConVarRef::SetValue( float flValue )
   573 {
   574 	m_pConVar->SetValue( flValue );
   575 }
   576 
   577 FORCEINLINE_CVAR void ConVarRef::SetValue( int nValue )
   578 {
   579 	m_pConVar->SetValue( nValue );
   580 }
   581 
   582 FORCEINLINE_CVAR void ConVarRef::SetValue( bool bValue )
   583 {
   584 	m_pConVar->SetValue( bValue ? 1 : 0 );
   585 }
   586 
   587 FORCEINLINE_CVAR const char *ConVarRef::GetDefault() const
   588 {
   589 	return m_pConVarState->m_pszDefaultValue;
   590 }
   591 
   592 
   593 //-----------------------------------------------------------------------------
   594 // Called by the framework to register ConCommands with the ICVar
   595 //-----------------------------------------------------------------------------
   596 void ConVar_Register( int nCVarFlag = 0, IConCommandBaseAccessor *pAccessor = NULL );
   597 void ConVar_Unregister( );
   598 
   599 
   600 //-----------------------------------------------------------------------------
   601 // Utility methods 
   602 //-----------------------------------------------------------------------------
   603 void ConVar_PrintFlags( const ConCommandBase *var );
   604 void ConVar_PrintDescription( const ConCommandBase *pVar );
   605 
   606 
   607 //-----------------------------------------------------------------------------
   608 // Purpose: Utility class to quickly allow ConCommands to call member methods
   609 //-----------------------------------------------------------------------------
   610 #if defined _MSC_VER
   611 #pragma warning (disable : 4355 )
   612 #endif
   613 
   614 template< class T >
   615 class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback
   616 {
   617 	typedef ConCommand BaseClass;
   618 	typedef void ( T::*FnMemberCommandCallback_t )( const CCommand &command );
   619 	typedef int  ( T::*FnMemberCommandCompletionCallback_t )( const char *pPartial, CUtlVector< CUtlString > &commands );
   620 
   621 public:
   622 	CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0,
   623 		int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) :
   624 		BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL )
   625 	{
   626 		m_pOwner = pOwner;
   627 		m_Func = callback;
   628 		m_CompletionFunc = completionFunc;
   629 	}
   630 
   631 	~CConCommandMemberAccessor()
   632 	{
   633 		Shutdown();
   634 	}
   635 
   636 	void SetOwner( T* pOwner )
   637 	{
   638 		m_pOwner = pOwner;
   639 	}
   640 
   641 	virtual void CommandCallback( const CCommand &command )
   642 	{
   643 		Assert( m_pOwner && m_Func );
   644 		(m_pOwner->*m_Func)( command );
   645 	}
   646 
   647 	virtual int  CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands )
   648 	{
   649 		Assert( m_pOwner && m_CompletionFunc );
   650 		return (m_pOwner->*m_CompletionFunc)( pPartial, commands );
   651 	}
   652 
   653 private:
   654 	T* m_pOwner;
   655 	FnMemberCommandCallback_t m_Func;
   656 	FnMemberCommandCompletionCallback_t m_CompletionFunc;
   657 };
   658 
   659 #if defined _MSC_VER
   660 #pragma warning ( default : 4355 )
   661 #endif
   662 
   663 
   664 //-----------------------------------------------------------------------------
   665 // Purpose: Utility macros to quicky generate a simple console command
   666 //-----------------------------------------------------------------------------
   667 #define CON_COMMAND( name, description ) \
   668    static void name( const CCommand &args ); \
   669    static ConCommand name##_command( #name, name, description ); \
   670    static void name( const CCommand &args )
   671 
   672 #define CON_COMMAND_F( name, description, flags ) \
   673    static void name( const CCommand &args ); \
   674    static ConCommand name##_command( #name, name, description, flags ); \
   675    static void name( const CCommand &args )
   676 
   677 #define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \
   678 	static void name( const CCommand &args ); \
   679 	static ConCommand name##_command( #name, name, description, flags, completion ); \
   680 	static void name( const CCommand &args )
   681 
   682 #define CON_COMMAND_EXTERN( name, _funcname, description ) \
   683 	void _funcname( const CCommand &args ); \
   684 	static ConCommand name##_command( #name, _funcname, description ); \
   685 	void _funcname( const CCommand &args )
   686 
   687 #define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \
   688 	void _funcname( const CCommand &args ); \
   689 	static ConCommand name##_command( #name, _funcname, description, flags ); \
   690 	void _funcname( const CCommand &args )
   691 
   692 #define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \
   693 	void _funcname( const CCommand &args );						\
   694 	friend class CCommandMemberInitializer_##_funcname;			\
   695 	class CCommandMemberInitializer_##_funcname					\
   696 	{															\
   697 	public:														\
   698 		CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags )	\
   699 		{														\
   700 			m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) );	\
   701 		}														\
   702 	private:													\
   703 		CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor;	\
   704 	};															\
   705 																\
   706 	CCommandMemberInitializer_##_funcname m_##_funcname##_register;		\
   707 
   708 
   709 #endif // CONVAR_H