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.

975 lines
31 KiB

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