diff --git a/public/icvar.h b/public/icvar.h index c70c4f49..1a15cd7e 100644 --- a/public/icvar.h +++ b/public/icvar.h @@ -185,6 +185,7 @@ public: struct CConVarChangeCallbackNode_t { + FnGenericChangeCallback_t m_pProviderCallBack; FnGenericChangeCallback_t m_pCallback; // Register index of cvar which change cb comes from @@ -215,7 +216,7 @@ public: CUtlLinkedList m_ConVarList; CUtlHashtable m_ConVarHashes; - CUtlLinkedList m_ConVarChangeCBList; + CUtlLinkedList m_ConVarChangeCBList; int m_ConVarCount; CUtlVector m_CvarCreationListeners; diff --git a/public/tier1/convar.h b/public/tier1/convar.h index 5b779578..8afa9c5e 100644 --- a/public/tier1/convar.h +++ b/public/tier1/convar.h @@ -607,7 +607,16 @@ private: void Destroy( ); }; -using FnGenericChangeCallback_t = void(*)(ConVarRefAbstract* ref, CSplitScreenSlot nSlot, const CVValue_t* pNewValue, const CVValue_t* pOldValue); +template +class CConVar; + +template +using FnTypedChangeCallback_t = void (*)(CConVar *cvar, CSplitScreenSlot nSlot, const T *pNewValue, const T *pOldValue); +template +using FnTypedChangeCallbackProvider_t = void(*)(CConVar *cvar, CSplitScreenSlot slot, const T *pNewValue, const T *pOldValue, FnTypedChangeCallback_t cb); + +using FnGenericChangeCallback_t = void(*)(ConVarRefAbstract *ref, CSplitScreenSlot nSlot, const CVValue_t *pNewValue, const CVValue_t *pOldValue); +using FnGenericChangeCallbackProvider_t = void(*)(ConVarRefAbstract *ref, CSplitScreenSlot nSlot, const CVValue_t *pNewValue, const CVValue_t *pOldValue, FnGenericChangeCallback_t cb); struct ConVarValueInfo_t { @@ -619,31 +628,45 @@ struct ConVarValueInfo_t m_defaultValue {}, m_minValue {}, m_maxValue {}, - m_fnCallBack(), + m_fnProviderCallBack( nullptr ), + m_fnCallBack( nullptr ), m_eVarType( type ) {} - template + template void SetDefaultValue( const T &value ) { m_bHasDefault = true; *reinterpret_cast(m_defaultValue) = value; } - template + template void SetMinValue( const T &min ) { m_bHasMin = true; *reinterpret_cast(m_minValue) = min; } - template + template void SetMaxValue( const T &max ) { m_bHasMax = true; *reinterpret_cast(m_maxValue) = max; } + template + void SetCallback( FnTypedChangeCallback_t cb ) + { + if(cb) + { + m_fnProviderCallBack = []( ConVarRefAbstract *ref, CSplitScreenSlot nSlot, const CVValue_t *pNewValue, const CVValue_t *pOldValue, FnGenericChangeCallback_t cb ) { + reinterpret_cast>(cb)(reinterpret_cast *>(ref), nSlot, reinterpret_cast(pNewValue), reinterpret_cast(pOldValue)); + }; + + m_fnCallBack = reinterpret_cast(cb); + } + } + int32 m_Version; bool m_bHasDefault; @@ -657,7 +680,9 @@ private: uint8 m_maxValue[sizeof( CVValue_t )]; public: + FnGenericChangeCallbackProvider_t m_fnProviderCallBack; FnGenericChangeCallback_t m_fnCallBack; + EConVarType m_eVarType; }; @@ -1211,9 +1236,7 @@ class CConVar : public CConVarRef public: typedef CConVarRef BaseClass; - using FnChangeCallback_t = void(*)(CConVar *ref, CSplitScreenSlot nSlot, const T *pNewValue, const T *pOldValue); - - CConVar( const char *name, uint64 flags, const char *help_string, const T &default_value, FnChangeCallback_t cb = nullptr ) + CConVar( const char *name, uint64 flags, const char *help_string, const T &default_value, FnTypedChangeCallback_t cb = nullptr ) : BaseClass() { Assert( name ); @@ -1222,12 +1245,12 @@ public: ConVarValueInfo_t value_info( TranslateConVarType() ); value_info.SetDefaultValue( default_value ); - value_info.m_fnCallBack = reinterpret_cast(cb); + value_info.SetCallback( cb ); BaseClass::Register( name, flags, help_string, value_info ); } - CConVar( const char *name, uint64 flags, const char *help_string, const T &default_value, bool min, const T &minValue, bool max, const T &maxValue, FnChangeCallback_t cb = nullptr ) + CConVar( const char *name, uint64 flags, const char *help_string, const T &default_value, bool min, const T &minValue, bool max, const T &maxValue, FnTypedChangeCallback_t cb = nullptr ) : BaseClass() { Assert( name ); @@ -1243,7 +1266,7 @@ public: if(max) value_info.SetMaxValue( maxValue ); - value_info.m_fnCallBack = reinterpret_cast(cb); + value_info.SetCallback( cb ); BaseClass::Register( name, flags, help_string, value_info ); }