Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

725 lines
23 KiB

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