Remove memtables from ConCmdManager (bug 5899 part 3, r=fyren).

This commit is contained in:
David Anderson 2013-08-31 19:50:15 -07:00
parent ba927964c8
commit 67ce8aff61
3 changed files with 52 additions and 39 deletions

View File

@ -38,6 +38,8 @@
#include "ChatTriggers.h" #include "ChatTriggers.h"
#include "logic_bridge.h" #include "logic_bridge.h"
using namespace ke;
ConCmdManager g_ConCmds; ConCmdManager g_ConCmds;
#if SOURCE_ENGINE == SE_DOTA #if SOURCE_ENGINE == SE_DOTA
@ -53,7 +55,7 @@ SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int
typedef ke::LinkedList<CmdHook *> PluginHookList; typedef ke::LinkedList<CmdHook *> PluginHookList;
void RegisterInPlugin(CmdHook *hook); void RegisterInPlugin(CmdHook *hook);
ConCmdManager::ConCmdManager() : m_Strings(1024) ConCmdManager::ConCmdManager()
{ {
m_CmdClient = 0; m_CmdClient = 0;
} }
@ -105,6 +107,9 @@ void ConCmdManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *na
} }
} }
if (hook->admin)
hook->admin->group->hooks.remove(hook);
iter = pInfo->hooks.erase(iter); iter = pInfo->hooks.erase(iter);
delete hook; delete hook;
} }
@ -124,6 +129,8 @@ void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
CmdHook *hook = *iter; CmdHook *hook = *iter;
hook->info->hooks.remove(hook); hook->info->hooks.remove(hook);
if (hook->admin)
hook->admin->group->hooks.remove(hook);
if (hook->info->hooks.empty()) if (hook->info->hooks.empty())
RemoveConCmd(hook->info, hook->info->pCmd->GetName(), true, true); RemoveConCmd(hook->info, hook->info->pCmd->GetName(), true, true);
@ -450,19 +457,17 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
if (!pInfo) if (!pInfo)
return false; return false;
CmdHook *pHook = new CmdHook(CmdHook::Client, pInfo, pFunction, description); GroupMap::Insert i = m_CmdGrps.findForAdd(group);
if (!i.found())
pHook->admin = new AdminCmdInfo();
int grpid;
if (!m_CmdGrps.retrieve(group, &grpid))
{ {
grpid = m_Strings.AddString(group); if (!m_CmdGrps.add(i, group))
m_CmdGrps.insert(group, grpid); return false;
i->value = NoAddRef(new CommandGroup());
} }
Ref<CommandGroup> cmdgroup = i->value;
pHook->admin->cmdGrpId = grpid; CmdHook *pHook = new CmdHook(CmdHook::Client, pInfo, pFunction, description);
pHook->admin->flags = adminflags; pHook->admin = new AdminCmdInfo(cmdgroup, adminflags);
/* First get the command group override, if any */ /* First get the command group override, if any */
bool override = g_Admins.GetCommandOverride(group, bool override = g_Admins.GetCommandOverride(group,
@ -482,6 +487,7 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
pHook->admin->eflags = pHook->admin->flags; pHook->admin->eflags = pHook->admin->flags;
pInfo->eflags = pHook->admin->eflags; pInfo->eflags = pHook->admin->eflags;
cmdgroup->hooks.append(pHook);
pInfo->hooks.append(pHook); pInfo->hooks.append(pHook);
RegisterInPlugin(pHook); RegisterInPlugin(pHook);
return true; return true;
@ -586,27 +592,20 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
} }
else if (type == Override_CommandGroup) else if (type == Override_CommandGroup)
{ {
int grpid; GroupMap::Result r = m_CmdGrps.find(cmd);
if (!m_CmdGrps.retrieve(cmd, &grpid)) if (!r.found())
return; return;
/* This is bad :( loop through all commands */ Ref<CommandGroup> group(r->value);
List<ConCmdInfo *>::iterator iter;
for (iter=m_CmdList.begin(); iter!=m_CmdList.end(); iter++)
{
ConCmdInfo *pInfo = *iter;
for (CmdHookList::iterator citer = pInfo->hooks.begin(); citer != pInfo->hooks.end(); citer++)
{
CmdHook *hook = (*citer);
if (!hook->admin || hook->admin->cmdGrpId != grpid)
continue;
for (PluginHookList::iterator iter = group->hooks.begin(); iter != group->hooks.end(); iter++)
{
CmdHook *hook = *iter;
if (remove) if (remove)
hook->admin->eflags = bits; hook->admin->eflags = bits;
else else
hook->admin->eflags = hook->admin->flags; hook->admin->eflags = hook->admin->flags;
pInfo->eflags = hook->admin->eflags; hook->info->eflags = hook->admin->eflags;
}
} }
} }
} }

View File

@ -35,7 +35,6 @@
#include "sm_globals.h" #include "sm_globals.h"
#include "sourcemm_api.h" #include "sourcemm_api.h"
#include "ForwardSys.h" #include "ForwardSys.h"
#include "sm_memtable.h"
#include <sh_list.h> #include <sh_list.h>
#include <sh_string.h> #include <sh_string.h>
#include <IRootConsoleMenu.h> #include <IRootConsoleMenu.h>
@ -45,24 +44,31 @@
#include <am-utility.h> #include <am-utility.h>
#include <am-inlinelist.h> #include <am-inlinelist.h>
#include <am-linkedlist.h> #include <am-linkedlist.h>
#include <am-refcounting.h>
using namespace SourceHook; using namespace SourceHook;
struct CmdHook;
struct ConCmdInfo;
struct CommandGroup : public ke::Refcounted<CommandGroup>
{
ke::LinkedList<CmdHook *> hooks;
};
struct AdminCmdInfo struct AdminCmdInfo
{ {
AdminCmdInfo() AdminCmdInfo(const ke::Ref<CommandGroup> &group, FlagBits flags)
: group(group),
flags(flags),
eflags(0)
{ {
cmdGrpId = -1;
flags = 0;
eflags = 0;
} }
int cmdGrpId; /* index into cmdgroup string table */ ke::Ref<CommandGroup> group;
FlagBits flags; /* default flags */ FlagBits flags; /* default flags */
FlagBits eflags; /* effective flags */ FlagBits eflags; /* effective flags */
}; };
struct ConCmdInfo;
struct CmdHook : public ke::InlineListNode<CmdHook> struct CmdHook : public ke::InlineListNode<CmdHook>
{ {
enum Type { enum Type {
@ -166,11 +172,12 @@ public:
return m_CmdList; return m_CmdList;
} }
private: private:
typedef StringHashMap<ke::Ref<CommandGroup> > GroupMap;
StringHashMap<ConCmdInfo *> m_Cmds; /* command lookup */ StringHashMap<ConCmdInfo *> m_Cmds; /* command lookup */
StringHashMap<int> m_CmdGrps; /* command group lookup */ GroupMap m_CmdGrps; /* command group map */
ConCmdList m_CmdList; /* command list */ ConCmdList m_CmdList; /* command list */
int m_CmdClient; /* current client */ int m_CmdClient; /* current client */
BaseStringTable m_Strings; /* string table */
}; };
extern ConCmdManager g_ConCmds; extern ConCmdManager g_ConCmds;

View File

@ -58,6 +58,13 @@ class Newborn
mutable T *thing_; mutable T *thing_;
}; };
template <typename T>
static inline Newborn<T>
NoAddRef(T *t)
{
return Newborn<T>(t);
}
// When returning a value, we'd rather not be needlessly changing the refcount, // When returning a value, we'd rather not be needlessly changing the refcount,
// so we have a special type to use for returns. // so we have a special type to use for returns.
template <typename T> template <typename T>