HomeNewsFeaturesLicensingDownloadsScreenshotsFAQRoadmap Contact Us
Search:
8 Online

Community

Discussion Topics Recent Postings User Contributions General Articles Example Documentation Credits

Licensed Developer

Programmer's Manual Artists Manual Tutorials and Articles

Programming: Game Code

Game Code Overview Server Side Game Code Client Side Game Code

Programming: System

Alphabetical Function List Renderer File System Collision & Ray Casting Low Level Audio Game Audio The Console Console Variable List Multiplayer Localisation Maths Library Memory Manager Model File Formats Texture Formats

Art: Overviews

Specifications Shaders Particle Systems Lens Flares Cipher console Cipher file types Tutorials Reference

Art: Tools

Shader Designer Particle Designer 3dsmax tools Model Conversion Font Generator

Cipher Engine
Game Development Search Engine
GameDev.net
You are not signed in - [sign in] [register]

C++ wrapper for console variables

Overview

Author: rikh
Date Submitted: 2004-02-16 08:09:11

Source Code

#define CVAR_INIT(name, def, flags) name(_T(#name), def, flags)
class CVar
{ 
	CVar(const CVar& _rOther)
	{
		*this = _rOther;
	}

	const CVar& operator =(const CVar& _rOther)
	{
		m_psName = _rOther.m_psName;
		m_sDefault = _rOther.m_sDefault;
		m_handle = m_handle;

		return *this;
	}

protected:
	const tchar_t const* m_psName;
	std::wstring m_sDefault;
	cvarhandle_t m_handle;

	void Set(const tchar_t* _psValue)
	{
		cipher_cvar_Set(m_psName, _psValue);
	}

	CVar(const tchar_t const* _psName, const tchar_t* _psDefault, uint_t _uFlags):
	m_psName(_psName),
		m_sDefault(_psDefault),
		m_handle(cipher_cvar_Get(_psName, _psDefault, _uFlags))
	{
	}

public: 
	void Reset()
	{
		cipher_cvar_Set(m_psName, m_sDefault.c_str());
	}

	const tchar_t* GetName() const
	{
		return m_psName;
	}

	operator const tchar_t* () const
	{
		tchar_t* psDest = common::GetStaticStringW(NULL);
		cipher_cvar_String(m_handle, psDest, MAX_STRING_SIZE);
		return psDest;
	}

	const tchar_t* GetTranslationKeyName(const tchar_t* _psDelimiter = _T("/")) const
	{
		return common::FormatStringW(_T("%ls%ls%ls"), m_psName, _psDelimiter, (const tchar_t*)(*this));
	} 
};


class CVarString : public CVar
{
	typedef CVar inherited;

public:
	CVarString(const tchar_t const* _psName, const tchar_t* _psDefault, uint_t _uFlags):
	  inherited(_psName, _psDefault, _uFlags)
	  {
	  }

	  const CVarString& operator =(const tchar_t* _psValue)
	  {
		  Set(_psValue);
		  return *this;
	  }

	  const CVarString& operator += (const CVarString& _rOther)
	  {
		  Set(common::FormatStringW(_T("%ls%ls"), (const tchar_t*)(*this), (const tchar_t*)(_rOther)));
		  return *this;
	  }
};


class CVarBoolean : public CVar
{
	typedef CVar inherited;

	void Set(const bool _bValue)
	{
		inherited::Set(common::FormatStringW(_T("%d"), _bValue ? 1 : 0));
	}

public:
	CVarBoolean(const tchar_t const* _psName, const bool _bDefault, uint_t _uFlags):
	  inherited(_psName, common::FormatStringW(_T("%d"), _bDefault ? 1 : 0), _uFlags)
	  {
	  }

	  const CVarBoolean& operator =(const bool _bValue)
	  {
		  Set(_bValue);
		  return *this;
	  }

	  const bool operator !() const
	  {
		  return (bool)(*this);
	  }

	  operator const bool() const
	  {
		  // rtrue and c++ boolean types are incompatible so I can not simply return the rbool
		  return (rtrue == cipher_cvar_Bool(m_handle) ? true : false);
	  }
};


class CVarInteger : public CVar
{
	typedef CVar inherited;

	void Set(const int _iValue)
	{
		inherited::Set(common::FormatStringW(_T("%d"), _iValue));
	}

public:
	CVarInteger(const tchar_t const* _psName, const int _iDefault, uint_t _uFlags):
	  inherited(_psName, common::FormatStringW(_T("%d"), _iDefault),  _uFlags)
	  {
	  }

	  const CVarInteger& operator =(const int _iValue)
	  {
		  Set(_iValue);
		  return *this;
	  }

	  const CVarInteger& operator =(const unsigned int _iValue)
	  {
		  Set((int)_iValue);
		  return *this;
	  }

	  operator const int() const
	  {
		  return cipher_cvar_Int(m_handle);
	  }

	  operator const unsigned int() const
	  {
		  return cipher_cvar_Int(m_handle);
	  }

	  const CVarInteger& operator +=(const int _iValue)
	  {
		  Set(((int)(*this) + _iValue));
		  return *this;
	  }

	  const CVarInteger& operator +=(const CVarInteger& _rOther)
	  {
		  Set(((int)(*this) + (int)_rOther));
		  return *this;
	  }

	  const CVarInteger& operator -=(const CVarInteger& _rOther)
	  {
		  Set(((int)(*this) - (int)_rOther));
		  return *this;
	  }


	  const CVarInteger& operator -=(const int _iValue)
	  {
		  Set(((int)(*this) - _iValue));
		  return *this;
	  }
};


class CVarFloat : public CVar
{ 
	typedef CVar inherited;

	void Set(const float _fValue)
	{
		inherited::Set(common::FormatStringW(_T("%f"), _fValue));
	}

public:
	CVarFloat(const tchar_t const* _psName, const float _fDefault, uint_t _uFlags):
	  inherited(_psName, common::FormatStringW(_T("%f"), _fDefault), _uFlags)
	  {
	  }

	  operator const float() const
	  {
		  return cipher_cvar_Float(m_handle);
	  } 

	  const CVarFloat& operator +=(const float _fValue)
	  {
		  Set(((float)(*this) + _fValue));
		  return *this;
	  }

	  const CVarFloat& operator -=(const float _fValue)
	  {
		  Set(((float)(*this) - _fValue));
		  return *this;
	  }

	  const CVarFloat& operator +=(const CVarFloat& _rOther)
	  {
		  Set(((float)(*this) + (float)_rOther));
		  return *this;
	  }

	  const CVarFloat& operator -=(const CVarFloat& _rOther)
	  {
		  Set(((float)(*this) - (float)_rOther));
		  return *this;
	  }

	  const CVarFloat& operator =(const float _fValue)
	  {
		  Set(_fValue);
		  return *this;
	  }
};

namespace common 
{

	wchar_t* 
		GetStaticStringW(const wchar_t* _psString/* = NULL*/)
	{
		// Make this buffer safe someday
		static wchar_t sBuffer[16][16384];
		static int iBuffer = 0;

		wchar_t* psBuffer = sBuffer[iBuffer];
		iBuffer = (iBuffer + 1) & 15;

		*psBuffer = 0;
		if (_psString)
		{
			com_strncpy(psBuffer, _psString, dimof(sBuffer[0]));
		}

		return psBuffer;
	}


	const wchar_t*
		FormatStringArgsW(const wchar_t* _psFormat, com_va_list _pArgs)
	{
		// Make this buffer safe someday
		static wchar_t sBuffer[16][16384];
		static int iBuffer = 0;

		wchar_t* psBuffer = sBuffer[iBuffer];

		iBuffer = (iBuffer + 1) & 15;

		com_vsnwprintf(psBuffer, dimof(sBuffer[0]), _psFormat, _pArgs);

		return psBuffer;
	}


	const wchar_t*
		FormatStringW(const wchar_t* _psFormat, ...)
	{
		com_va_list pArgs;
		com_va_start(pArgs, _psFormat);
		const wchar_t* psText = FormatStringArgsW(_psFormat, pArgs);
		com_va_end(pArgs);

		return psText;
	}

} // namespace common


Description

C++ users should take advantage of the features the language provides. Operator overloading is the key for this task.

I have written a wrapper arround the cipher_cvar_??? functions to make my code easier to write and read.

First I had a single class "CVar" that had all operators overloaded. But I decided later that for even better typechecking to split it up into different CVar classes for each available type.
Now the compiler warns you if you want compare a string CVar to an integer CVar.

Example of use:

CVarBoolean CVAR_INIT(cg_showfps, false, CVAR_ARCHIVE);

That would create a boolean cvar named "cg_showfps"
In your code you just have to write:
if (true == cg_showfps) DrawFPS();


You can even do simple mathematical operations with the CVarInteger implementation and always extend it to your needs.
One future implementation could include a string compare operator. I'll leave that as an exercise to the user :)

The helper functions from the
common
namespace I have also included into this posting.

I hope you find this usefull. Feel free to express your thoughts or to ask questions you might have.

Happy (c++) coding,
Phil

[Recent Contributions] [Recent Source Code]

User Contributed Comments

rikh 16th February, 2004 08:10
Please note, this contribution is from philk, though due to some technical problems I ended up posting it for him.




Register and Sign In to discuss this article