diff --git a/addons/source-python/packages/source-python/cvars/__init__.py b/addons/source-python/packages/source-python/cvars/__init__.py
old mode 100644
new mode 100755
index 66177aede..516a2a380
--- a/addons/source-python/packages/source-python/cvars/__init__.py
+++ b/addons/source-python/packages/source-python/cvars/__init__.py
@@ -6,6 +6,8 @@
# >> IMPORTS
# =============================================================================
# Source.Python Imports
+# Core
+from core import AutoUnload
# Cvars
from _cvars import ConVar
from _cvars import _Cvar
@@ -24,5 +26,68 @@
# >> ALL DECLARATION
# =============================================================================
__all__ = ('ConVar',
+ 'ConVarChanged',
'cvar',
)
+
+
+# =============================================================================
+# >> CLASSES
+# =============================================================================
+class ConVarChanged(AutoUnload):
+ """ConVarChanged decorator class."""
+
+ def __init__(self, *convars):
+ """Store the convars."""
+ self._convars = ()
+ self.callback = None
+
+ # Validate convars
+ if not convars:
+ raise ValueError('At least one convar is required.')
+
+ _convars = []
+ for convar in convars:
+ if not isinstance(convar, (str, ConVar)):
+ raise ValueError('Given convar is not ConVar or ConVar name.')
+
+ elif isinstance(convar, str):
+ convar_name = convar
+ convar = cvar.find_var(convar_name)
+ if convar is None:
+ raise ValueError(
+ f'"{convar_name}" is not a valid ConVar name.')
+
+ _convars.append(convar)
+
+ self._convars = tuple(_convars)
+
+ def __call__(self, callback):
+ """Store the callback and add it to convars."""
+ # Is the callback callable?
+ if not callable(callback):
+ raise ValueError('Given callback is not callable.')
+
+ # Store the callback
+ self.callback = callback
+
+ # Loop through all convars
+ for convar in self._convars:
+
+ # Add the callback
+ convar.add_changed_callback(self.callback)
+
+ # Return the callback
+ return self.callback
+
+ def _unload_instance(self):
+ """Remove the callback from convars."""
+ # Was no callback registered?
+ if self.callback is None:
+ return
+
+ # Loop through all convars
+ for convar in self._convars:
+
+ # Remove the callback
+ convar.remove_changed_callback(self.callback)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
old mode 100644
new mode 100755
index 9bb21297a..889a15441
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -171,6 +171,7 @@ Set(SOURCEPYTHON_CVARS_MODULE_HEADERS
)
Set(SOURCEPYTHON_CVARS_MODULE_SOURCES
+ core/modules/cvars/cvars.cpp
core/modules/cvars/cvars_wrap.cpp
)
diff --git a/src/core/modules/cvars/cvars.cpp b/src/core/modules/cvars/cvars.cpp
new file mode 100755
index 000000000..0dc945a32
--- /dev/null
+++ b/src/core/modules/cvars/cvars.cpp
@@ -0,0 +1,217 @@
+/**
+* =============================================================================
+* Source Python
+* Copyright (C) 2012-2015 Source Python Development Team. All rights reserved.
+* =============================================================================
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License, version 3.0, as published by the
+* Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+* details.
+*
+* You should have received a copy of the GNU General Public License along with
+* this program. If not, see .
+*
+* As a special exception, the Source Python Team gives you permission
+* to link the code of this program (as well as its derivative works) to
+* "Half-Life 2," the "Source Engine," and any Game MODs that run on software
+* by the Valve Corporation. You must obey the GNU General Public License in
+* all respects for all other code used. Additionally, the Source.Python
+* Development Team grants this exception to all derivative works.
+*/
+
+//-----------------------------------------------------------------------------
+// Includes.
+//-----------------------------------------------------------------------------
+#include "cvars.h"
+
+
+//-----------------------------------------------------------------------------
+// Global ConVar changed callback mapping.
+//-----------------------------------------------------------------------------
+typedef std::vector