Seaside/SpyCustom/convar.h
2021-06-16 16:08:23 +03:00

541 lines
14 KiB
C++

#ifndef CONVAR_H
#define CONVAR_H
#if _WIN32
#pragma once
#endif
#include "dbg.h"
#include "iconvar.h"
#include "utlvector.h"
#include "utlstring.h"
#include "icvar.h"
#ifdef _WIN32
#define FORCEINLINE_CVAR FORCEINLINE
#elif POSIX
#define FORCEINLINE_CVAR inline
#else
#error "implement me"
#endif
typedef unsigned int uint32_t;
class ConVar;
class CCommand;
class ConCommand;
class ConCommandBase;
struct characterset_t;
class IConCommandBaseAccessor
{
public:
virtual bool RegisterConCommandBase(ConCommandBase* pVar) = 0;
};
#if defined( _X360 ) && !defined( _RETAIL )
void ConVar_PublishToVXConsole();
#endif
typedef void (*FnCommandCallbackVoid_t)(void);
typedef void (*FnCommandCallback_t)(const CCommand& command);
#define COMMAND_COMPLETION_MAXITEMS 64
#define COMMAND_COMPLETION_ITEM_LENGTH 64
typedef int (*FnCommandCompletionCallback)(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
class ICommandCallback
{
public:
virtual void CommandCallback(const CCommand& command) = 0;
};
class ICommandCompletionCallback
{
public:
virtual int CommandCompletionCallback(const char* pPartial, CUtlVector< CUtlString >& commands) = 0;
};
class ConCommandBase
{
friend class CCvar;
friend class ConVar;
friend class ConCommand;
friend void ConVar_Register(int nCVarFlag, IConCommandBaseAccessor* pAccessor);
friend class CDefaultCvar;
public:
ConCommandBase(void);
ConCommandBase(const char* pName, const char* pHelpString = 0,
int flags = 0);
virtual ~ConCommandBase(void);
virtual bool IsCommand(void) const;
virtual bool IsFlagSet(int flag) const;
virtual void AddFlags(int flags);
virtual void RemoveFlags(int flags);
virtual int GetFlags() const;
virtual const char* GetName(void) const;
virtual const char* GetHelpText(void) const;
const ConCommandBase* GetNext(void) const;
ConCommandBase* GetNext(void);
virtual bool IsRegistered(void) const;
virtual CVarDLLIdentifier_t GetDLLIdentifier() const;
virtual void Create(const char* pName, const char* pHelpString = 0,
int flags = 0);
virtual void Init();
void Shutdown();
char* CopyString(const char* from);
ConCommandBase* m_pNext;
bool m_bRegistered;
const char* m_pszName;
const char* m_pszHelpString;
int m_nFlags;
protected:
static ConCommandBase* s_pConCommandBases;
static IConCommandBaseAccessor* s_pAccessor;
};
class CCommand
{
public:
CCommand();
CCommand(int nArgC, const char** ppArgV);
bool Tokenize(const char* pCommand, characterset_t* pBreakSet = NULL);
void Reset();
int ArgC() const;
const char** ArgV() const;
const char* ArgS() const;
const char* GetCommandString() const;
const char* operator[](int nIndex) const;
const char* Arg(int nIndex) const;
const char* FindArg(const char* pName) const;
int FindArgInt(const char* pName, int nDefaultVal) const;
static int MaxCommandLength();
static characterset_t* DefaultBreakSet();
private:
enum
{
COMMAND_MAX_ARGC = 64,
COMMAND_MAX_LENGTH = 512,
};
int m_nArgc;
int m_nArgv0Size;
char m_pArgSBuffer[COMMAND_MAX_LENGTH];
char m_pArgvBuffer[COMMAND_MAX_LENGTH];
const char* m_ppArgv[COMMAND_MAX_ARGC];
};
inline int CCommand::MaxCommandLength()
{
return COMMAND_MAX_LENGTH - 1;
}
inline int CCommand::ArgC() const
{
return m_nArgc;
}
inline const char** CCommand::ArgV() const
{
return m_nArgc ? (const char**)m_ppArgv : NULL;
}
inline const char* CCommand::ArgS() const
{
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
}
inline const char* CCommand::GetCommandString() const
{
return m_nArgc ? m_pArgSBuffer : "";
}
inline const char* CCommand::Arg(int nIndex) const
{
if (nIndex < 0 || nIndex >= m_nArgc)
return "";
return m_ppArgv[nIndex];
}
inline const char* CCommand::operator[](int nIndex) const
{
return Arg(nIndex);
}
class ConCommand : public ConCommandBase
{
friend class CCvar;
public:
typedef ConCommandBase BaseClass;
ConCommand(const char* pName, FnCommandCallbackVoid_t callback,
const char* pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0);
ConCommand(const char* pName, FnCommandCallback_t callback,
const char* pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0);
ConCommand(const char* pName, ICommandCallback* pCallback,
const char* pHelpString = 0, int flags = 0, ICommandCompletionCallback* pCommandCompletionCallback = 0);
virtual ~ConCommand(void);
virtual bool IsCommand(void) const;
virtual int AutoCompleteSuggest(const char* partial, CUtlVector< CUtlString >& commands);
virtual bool CanAutoComplete(void);
virtual void Dispatch(const CCommand& command);
private:
union
{
FnCommandCallbackVoid_t m_fnCommandCallbackV1;
FnCommandCallback_t m_fnCommandCallback;
ICommandCallback* m_pCommandCallback;
};
union
{
FnCommandCompletionCallback m_fnCompletionCallback;
ICommandCompletionCallback* m_pCommandCompletionCallback;
};
bool m_bHasCompletionCallback : 1;
bool m_bUsingNewCommandCallback : 1;
bool m_bUsingCommandCallbackInterface : 1;
};
class ConVar : public ConCommandBase, public IConVar
{
friend class CCvar;
friend class ConVarRef;
public:
typedef ConCommandBase BaseClass;
ConVar(const char* pName, const char* pDefaultValue, int flags = 0);
ConVar(const char* pName, const char* pDefaultValue, int flags,
const char* pHelpString);
ConVar(const char* pName, const char* pDefaultValue, int flags,
const char* pHelpString, bool bMin, float fMin, bool bMax, float fMax);
ConVar(const char* pName, const char* pDefaultValue, int flags,
const char* pHelpString, FnChangeCallback_t callback);
ConVar(const char* pName, const char* pDefaultValue, int flags,
const char* pHelpString, bool bMin, float fMin, bool bMax, float fMax,
FnChangeCallback_t callback);
virtual ~ConVar(void);
virtual bool IsFlagSet(int flag) const;
virtual const char* GetHelpText(void) const;
virtual bool IsRegistered(void) const;
virtual const char* GetName(void) const;
virtual const char* GetBaseName(void) const;
virtual int GetSplitScreenPlayerSlot() const;
virtual void AddFlags(int flags);
virtual int GetFlags() const;
virtual bool IsCommand(void) const;
void InstallChangeCallback(FnChangeCallback_t callback, bool bInvoke = true);
void RemoveChangeCallback(FnChangeCallback_t callbackToRemove);
int GetChangeCallbackCount() const { return m_pParent->m_fnChangeCallbacks.Count(); }
FnChangeCallback_t GetChangeCallback(int slot) const { return m_pParent->m_fnChangeCallbacks[slot]; }
FORCEINLINE_CVAR float GetFloat(void) const;
FORCEINLINE_CVAR int GetInt(void) const;
FORCEINLINE_CVAR Color GetColor(void) const;
FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); }
FORCEINLINE_CVAR char const* GetString(void) const;
template <typename T> T Get(void) const;
template <typename T> T Get(T*) const;
virtual void SetValue(const char* value);
virtual void SetValue(float value);
virtual void SetValue(int value);
virtual void SetValue(Color value);
void Revert(void);
bool HasMin() const;
bool HasMax() const;
struct CVValue_t
{
char* m_pszString;
int m_StringLength;
float m_fValue;
int m_nValue;
};
bool GetMin(float& minVal) const;
bool GetMax(float& maxVal) const;
float GetMinValue() const;
float GetMaxValue() const;
const char* GetDefault(void) const;
FORCEINLINE_CVAR CVValue_t& GetRawValue()
{
return m_Value;
}
FORCEINLINE_CVAR const CVValue_t& GetRawValue() const
{
return m_Value;
}
bool InternalSetColorFromString(const char* value);
virtual void InternalSetValue(const char* value);
virtual void InternalSetFloatValue(float fNewValue);
virtual void InternalSetIntValue(int nValue);
virtual void InternalSetColorValue(Color value);
virtual bool ClampValue(float& value);
virtual void ChangeStringValue(const char* tempVal, float flOldValue);
virtual void Create(const char* pName, const char* pDefaultValue, int flags = 0,
const char* pHelpString = 0, bool bMin = false, float fMin = 0.0,
bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0);
virtual void Init();
int GetFlags() { return m_pParent->m_nFlags; }
public:
ConVar* m_pParent;
const char* m_pszDefaultValue;
CVValue_t m_Value;
bool m_bHasMin;
float m_fMinVal;
bool m_bHasMax;
float m_fMaxVal;
CUtlVector<FnChangeCallback_t> m_fnChangeCallbacks;
};
FORCEINLINE_CVAR float ConVar::GetFloat(void) const
{
uint32_t xored = *(uint32_t*)&m_pParent->m_Value.m_fValue ^ (uint32_t)this;
return *(float*)&xored;
}
FORCEINLINE_CVAR int ConVar::GetInt(void) const
{
return (int)(m_pParent->m_Value.m_nValue ^ (int)this);
}
FORCEINLINE_CVAR const char* ConVar::GetString(void) const
{
if (m_nFlags & FCVAR_NEVER_AS_STRING)
return "FCVAR_NEVER_AS_STRING";
char const* str = m_pParent->m_Value.m_pszString;
return str ? str : "";
}
class ConVarRef
{
public:
ConVarRef(const char* pName);
ConVarRef(const char* pName, bool bIgnoreMissing);
ConVarRef(IConVar* pConVar);
void Init(const char* pName, bool bIgnoreMissing);
bool IsValid() const;
bool IsFlagSet(int nFlags) const;
IConVar* GetLinkedConVar();
float GetFloat(void) const;
int GetInt(void) const;
bool GetBool() const { return !!GetInt(); }
const char* GetString(void) const;
void SetValue(const char* pValue);
void SetValue(float flValue);
void SetValue(int nValue);
void SetValue(bool bValue);
const char* GetName() const;
const char* GetDefault() const;
private:
IConVar* m_pConVar;
ConVar* m_pConVarState;
};
FORCEINLINE_CVAR bool ConVarRef::IsFlagSet(int nFlags) const
{
return (m_pConVar->IsFlagSet(nFlags) != 0);
}
FORCEINLINE_CVAR IConVar* ConVarRef::GetLinkedConVar()
{
return m_pConVar;
}
FORCEINLINE_CVAR const char* ConVarRef::GetName() const
{
return m_pConVar->GetName();
}
FORCEINLINE_CVAR void ConVarRef::SetValue(const char* pValue)
{
m_pConVar->SetValue(pValue);
}
FORCEINLINE_CVAR void ConVarRef::SetValue(float flValue)
{
m_pConVar->SetValue(flValue);
}
FORCEINLINE_CVAR void ConVarRef::SetValue(int nValue)
{
m_pConVar->SetValue(nValue);
}
FORCEINLINE_CVAR void ConVarRef::SetValue(bool bValue)
{
m_pConVar->SetValue(bValue ? 1 : 0);
}
FORCEINLINE_CVAR const char* ConVarRef::GetDefault() const
{
return m_pConVarState->m_pszDefaultValue;
}
void ConVar_Register(int nCVarFlag = 0, IConCommandBaseAccessor* pAccessor = NULL);
void ConVar_Unregister();
void ConVar_PrintFlags(const ConCommandBase* var);
void ConVar_PrintDescription(const ConCommandBase* pVar);
#pragma warning (disable : 4355 )
template< class T >
class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback
{
typedef ConCommand BaseClass;
typedef void (T::* FnMemberCommandCallback_t)(const CCommand& command);
typedef int (T::* FnMemberCommandCompletionCallback_t)(const char* pPartial, CUtlVector< CUtlString >& commands);
public:
CConCommandMemberAccessor(T* pOwner, const char* pName, FnMemberCommandCallback_t callback, const char* pHelpString = 0,
int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0) :
BaseClass(pName, this, pHelpString, flags, (completionFunc != 0) ? this : NULL)
{
m_pOwner = pOwner;
m_Func = callback;
m_CompletionFunc = completionFunc;
}
~CConCommandMemberAccessor()
{
Shutdown();
}
void SetOwner(T* pOwner)
{
m_pOwner = pOwner;
}
virtual void CommandCallback(const CCommand& command)
{
Assert(m_pOwner && m_Func);
(m_pOwner->*m_Func)(command);
}
virtual int CommandCompletionCallback(const char* pPartial, CUtlVector< CUtlString >& commands)
{
Assert(m_pOwner && m_CompletionFunc);
return (m_pOwner->*m_CompletionFunc)(pPartial, commands);
}
private:
T* m_pOwner;
FnMemberCommandCallback_t m_Func;
FnMemberCommandCompletionCallback_t m_CompletionFunc;
};
#pragma warning ( default : 4355 )
#define CON_COMMAND( name, description ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description ); \
static void name( const CCommand &args )
#define CON_COMMAND_F( name, description, flags ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description, flags ); \
static void name( const CCommand &args )
#define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description, flags, completion ); \
static void name( const CCommand &args )
#define CON_COMMAND_EXTERN( name, _funcname, description ) \
void _funcname( const CCommand &args ); \
static ConCommand name##_command( #name, _funcname, description ); \
void _funcname( const CCommand &args )
#define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \
void _funcname( const CCommand &args ); \
static ConCommand name##_command( #name, _funcname, description, flags ); \
void _funcname( const CCommand &args )
#define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \
void _funcname( const CCommand &args ); \
friend class CCommandMemberInitializer_##_funcname; \
class CCommandMemberInitializer_##_funcname \
{ \
public: \
CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags ) \
{ \
m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) ); \
} \
private: \
CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor; \
}; \
\
CCommandMemberInitializer_##_funcname m_##_funcname##_register; \
#endif