Skip to content

Commit

Permalink
Re-introduced memory leaks. 😖 (Fixes #430)
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanbriere committed Dec 3, 2021
1 parent a2dd2ff commit 312ecba
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,8 @@ def _unregister_command(self, name, callback):
:param callable callback:
The callback that is assigned to the command.
"""
self._get_command(name).remove_callback(callback)
try:
self._get_command(name).remove_callback(callback)
except ValueError:
# Command was not registered
pass
42 changes: 18 additions & 24 deletions src/core/modules/commands/commands_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,6 @@ CServerCommandManager* GetServerCommand(const char* szName,
return manager;
}

//-----------------------------------------------------------------------------
// Removes a CServerCommandManager instance for the given name.
//-----------------------------------------------------------------------------
void RemoveCServerCommandManager(const char* szName)
{
ServerCommandMap::iterator iter;
if (find_manager<ServerCommandMap, ServerCommandMap::iterator>(g_ServerCommandMap, szName, iter))
{
delete iter->second;
g_ServerCommandMap.erase(iter);
}
}

//-----------------------------------------------------------------------------
// Returns a CServerCommandManager instance.
//-----------------------------------------------------------------------------
Expand All @@ -121,8 +108,17 @@ CServerCommandManager* CServerCommandManager::CreateCommand(const char* szName,
char* szNameCopy = strdup(szName);
char* szHelpTextCopy = NULL;

// FInd if the command already exists
ConCommandBase* pConCommand = g_pCVar->FindCommandBase(szName);
// Find if the command already exists
ConCommandBase* pBase = g_pCVar->FindCommandBase(szName);
if (pBase && !pBase->IsCommand()) {
BOOST_RAISE_EXCEPTION(
PyExc_ValueError,
"Failed to create ConCommand(\"%s\") because a ConVar with the same name already exists.",
szName
)
}

ConCommand *pConCommand = static_cast<ConCommand *>(pBase);
if( pConCommand )
{
// Store the current command's help text and flags
Expand All @@ -147,7 +143,7 @@ CServerCommandManager* CServerCommandManager::CreateCommand(const char* szName,
//-----------------------------------------------------------------------------
// CServerCommandManager constructor.
//-----------------------------------------------------------------------------
CServerCommandManager::CServerCommandManager(ConCommandBase* pConCommand,
CServerCommandManager::CServerCommandManager(ConCommand* pConCommand,
const char* szName, const char* szHelpText, int iFlags):
ConCommand(szName, (FnCommandCallback_t)NULL, szHelpText, iFlags),
m_pOldCommand(pConCommand)
Expand Down Expand Up @@ -209,17 +205,18 @@ void CServerCommandManager::RemoveCallback( PyObject* pCallable, HookType_t type
{
object oCallable = object(handle<>(borrowed(pCallable)));
m_vecCallables[type]->UnregisterListener(pCallable);
if( !m_vecCallables[HOOKTYPE_PRE]->GetCount() && !m_vecCallables[HOOKTYPE_POST]->GetCount() )
{
RemoveCServerCommandManager(m_Name);
}
}

//-----------------------------------------------------------------------------
// Calls all callables for the command when it is called on the server.
//-----------------------------------------------------------------------------
void CServerCommandManager::Dispatch( const CCommand& command )
{
if (!m_vecCallables[HOOKTYPE_PRE]->GetCount() && !m_vecCallables[HOOKTYPE_POST]->GetCount() && !m_pOldCommand) {
Msg("Unknown command \"%s\"\n", m_Name);
return;
}

bool block = false;

// Pre hook callbacks
Expand All @@ -240,10 +237,7 @@ void CServerCommandManager::Dispatch( const CCommand& command )
if(m_pOldCommand)
{
if (m_pOldCommand->IsCommand()) {
static_cast<ConCommand *>(m_pOldCommand)->Dispatch(command);
}
else {
static_cast<ConVar *>(m_pOldCommand)->SetValue(command.ArgS());
m_pOldCommand->Dispatch(command);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/modules/commands/commands_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ class CServerCommandManager : public ConCommand
void Dispatch( const CCommand& command);

public:
CServerCommandManager(ConCommandBase* pConCommand, const char* szName, const char* szHelpString = 0, int iFlags = 0);
CServerCommandManager(ConCommand* pConCommand, const char* szName, const char* szHelpString = 0, int iFlags = 0);
std::map< HookType_t, CListenerManager* > m_vecCallables;
const char* m_Name;
ConCommandBase* m_pOldCommand;
ConCommand* m_pOldCommand;
};

#endif // _COMMANDS_SERVER_H
56 changes: 11 additions & 45 deletions src/core/modules/cvars/cvars.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,33 +36,6 @@
#include "modules/commands/commands_server.h"


//-----------------------------------------------------------------------------
// ICvar shared extension class.
//-----------------------------------------------------------------------------
class ICVarSharedExt
{
public:
static ConVar *FindVar(ICvar *pCVar, const char *szName)
{
ConCommandBase *pBase = pCVar->FindCommandBase(szName);
if (pBase)
{
if (pBase->IsCommand()) {
CServerCommandManager *pManager = dynamic_cast<CServerCommandManager *>(pBase);
if (pManager && pManager->m_pOldCommand && !pManager->m_pOldCommand->IsCommand()) {
return static_cast<ConVar *>(pManager->m_pOldCommand);
}
}
else {
return static_cast<ConVar *>(pBase);
}
}

return NULL;
};
};


//-----------------------------------------------------------------------------
// ConVar extension class.
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -92,34 +65,27 @@ class ConVarExt
PyErr_Clear();
}

ConVar *pConVar = ICVarSharedExt::FindVar(g_pCVar, name);
ConCommandBase *pBase = g_pCVar->FindCommandBase(name);
if (pBase && pBase->IsCommand()) {
BOOST_RAISE_EXCEPTION(
PyExc_ValueError,
"Failed to create ConVar(\"%s\") because a ConCommand with the same name already exists.",
name
)
}

ConVar *pConVar = static_cast<ConVar *>(pBase);
if (!pConVar)
{
ConVar* pConVar = new ConVar(strdup(name), strdup(value), flags,
strdup(description), !min_value.is_none(), fMin, !max_value.is_none(), fMax);

return boost::shared_ptr<ConVar>(pConVar, &Deleter);
return boost::shared_ptr<ConVar>(pConVar, &NeverDeleteDeleter<ConVar *>);
}

return boost::shared_ptr<ConVar>(pConVar, &NeverDeleteDeleter<ConVar *>);
}

static void Deleter(ConVar *pConVar)
{
ConCommandBase *pBase = g_pCVar->FindCommandBase(pConVar->GetName());
if (pBase) {
CServerCommandManager *pManager = dynamic_cast<CServerCommandManager *>(pBase);
if (pManager && pManager->m_pOldCommand == pConVar) {
pManager->m_pOldCommand = NULL;
}
else if (pBase == pConVar) {
g_pCVar->UnregisterConCommand(pConVar);
}
}

delete pConVar;
}

static bool HasMin(ConVar* pConVar)
{
float fMin;
Expand Down
2 changes: 1 addition & 1 deletion src/core/modules/cvars/cvars_wrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void export_cvar_interface(scope _cvars)
)

.def("find_var",
&ICVarSharedExt::FindVar,
GET_METHOD(ConVar*, ICvar, FindVar, const char *),
"Find the ConVar instance of console variable.\n\n"
":return: Return ``None`` if the console variable was not found.\n"
":rtype: ConVar",
Expand Down

0 comments on commit 312ecba

Please sign in to comment.