core/CConVarManager.cpp
author Scott Ehlert <ds@alliedmods.net>
Thu Feb 08 21:41:28 2007 +0000 (2007-02-08)
changeset 457 9b8a85bf4175
child 465 8856d2e7018d
permissions -rw-r--r--
Initial import of convar stuff
1) Natives to create, find, set, and get convars
2) "cvars" option added to sm menu
3) Some internal additions to CPlugin to store a convar list
Still some things left to do...
ds@457
     1
/**
ds@457
     2
* ===============================================================
ds@457
     3
* SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
ds@457
     4
* ===============================================================
ds@457
     5
*
ds@457
     6
* This file is not open source and may not be copied without explicit
ds@457
     7
* written permission of AlliedModders LLC.  This file may not be redistributed 
ds@457
     8
* in whole or significant part.
ds@457
     9
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
ds@457
    10
*
ds@457
    11
* Version: $Id$
ds@457
    12
*/
ds@457
    13
ds@457
    14
#include "CConVarManager.h"
ds@457
    15
#include "CLogger.h"
ds@457
    16
#include "PluginSys.h"
ds@457
    17
#include "sm_srvcmds.h"
ds@457
    18
ds@457
    19
CConVarManager g_ConVarManager;
ds@457
    20
ds@457
    21
CConVarManager::CConVarManager()
ds@457
    22
{
ds@457
    23
	m_ConVarType = 0;
ds@457
    24
	m_CvarCache = sm_trie_create();
ds@457
    25
}
ds@457
    26
ds@457
    27
CConVarManager::~CConVarManager()
ds@457
    28
{
ds@457
    29
	sm_trie_destroy(m_CvarCache);
ds@457
    30
}
ds@457
    31
ds@457
    32
void CConVarManager::OnSourceModAllInitialized()
ds@457
    33
{
ds@457
    34
	HandleAccess sec;
ds@457
    35
ds@457
    36
	sec.access[HandleAccess_Read] = 0;
ds@457
    37
	sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
ds@457
    38
	sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
ds@457
    39
ds@457
    40
	m_ConVarType = g_HandleSys.CreateType("ConVar", this, 0, NULL, &sec, g_pCoreIdent, NULL);
ds@457
    41
ds@457
    42
	g_RootMenu.AddRootConsoleCommand("cvars", "View convars associated with a plugin", this);
ds@457
    43
}
ds@457
    44
ds@457
    45
void CConVarManager::OnSourceModShutdown()
ds@457
    46
{
ds@457
    47
	g_RootMenu.RemoveRootConsoleCommand("cvars", this);
ds@457
    48
ds@457
    49
	g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent);
ds@457
    50
}
ds@457
    51
ds@457
    52
void CConVarManager::OnHandleDestroy(HandleType_t type, void *object)
ds@457
    53
{
ds@457
    54
	g_SMAPI->UnregisterConCmdBase(g_PLAPI, static_cast<ConCommandBase *>(object));
ds@457
    55
}
ds@457
    56
ds@457
    57
void CConVarManager::OnRootConsoleCommand(const char *command, unsigned int argcount)
ds@457
    58
{
ds@457
    59
	if (argcount >= 3)
ds@457
    60
	{
ds@457
    61
		int id = 1;
ds@457
    62
ds@457
    63
		int num = atoi(g_RootMenu.GetArgument(2));
ds@457
    64
		
ds@457
    65
		if (num < 1 || num > (int)g_PluginSys.GetPluginCount())
ds@457
    66
		{
ds@457
    67
			g_RootMenu.ConsolePrint("[SM] Plugin index not found.");
ds@457
    68
			return;
ds@457
    69
		}
ds@457
    70
ds@457
    71
		CPlugin *pl = g_PluginSys.GetPluginByOrder(num);
ds@457
    72
		int convarnum = pl->GetConVarCount();
ds@457
    73
ds@457
    74
		if (convarnum == 0)
ds@457
    75
		{
ds@457
    76
			g_RootMenu.ConsolePrint("[SM] No convars for \"%s\"", pl->GetPublicInfo()->name);
ds@457
    77
			return;
ds@457
    78
		}
ds@457
    79
ds@457
    80
		g_RootMenu.ConsolePrint("[SM] Displaying convars for \"%s\":", pl->GetPublicInfo()->name);
ds@457
    81
ds@457
    82
		for (int i = 0; i < convarnum; i++, id++)
ds@457
    83
		{
ds@457
    84
			ConVar *cvar = pl->GetConVarByIndex(i);
ds@457
    85
			g_RootMenu.ConsolePrint("  %02d \"%s\" = \"%s\"", id, cvar->GetName(), cvar->GetString()); 
ds@457
    86
		}
ds@457
    87
ds@457
    88
		return;
ds@457
    89
	}
ds@457
    90
ds@457
    91
	g_RootMenu.ConsolePrint("[SM] Usage: sm cvars <#>");
ds@457
    92
}
ds@457
    93
ds@457
    94
Handle_t CConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *helpText, int flags, bool hasMin, float min, bool hasMax, float max)
ds@457
    95
{
ds@457
    96
	ConVar *cvar = NULL;
ds@457
    97
	void *temp = NULL;
ds@457
    98
	Handle_t hndl = 0;
ds@457
    99
ds@457
   100
	// Find out if the convar exists already
ds@457
   101
	cvar = icvar->FindVar(name);
ds@457
   102
ds@457
   103
	// If the convar already exists...
ds@457
   104
	if (cvar != NULL)
ds@457
   105
	{
ds@457
   106
		IPlugin *pl = g_PluginSys.FindPluginByContext(pContext->GetContext());
ds@457
   107
ds@457
   108
		// This isn't a fatal error because we can handle it, but user should be warned anyways
ds@457
   109
		g_Logger.LogError("[SM] Warning: Plugin \"%s\" has attempted to create already existing convar \"%s\"", pl->GetFilename(), name);
ds@457
   110
ds@457
   111
		// First check if we already have a handle to it
ds@457
   112
		if (sm_trie_retrieve(m_CvarCache, name, &temp))
ds@457
   113
		{
ds@457
   114
			// If we do, then return that handle
ds@457
   115
			return reinterpret_cast<Handle_t>(temp);
ds@457
   116
		} else {
ds@457
   117
			// If we don't, then create a new handle from the convar and return it
ds@457
   118
			return g_HandleSys.CreateHandle(m_ConVarType, cvar, NULL, g_pCoreIdent, NULL);
ds@457
   119
		}
ds@457
   120
	}
ds@457
   121
ds@457
   122
	// Since we didn't find an existing convar, now we can create it
ds@457
   123
	cvar = new ConVar(name, defaultVal, flags, helpText, hasMin, min, hasMax, max);
ds@457
   124
ds@457
   125
	// Add new convar to plugin's list
ds@457
   126
	g_PluginSys.GetPluginByCtx(pContext->GetContext())->AddConVar(cvar);
ds@457
   127
ds@457
   128
	// Create a new handle from the convar
ds@457
   129
	hndl = g_HandleSys.CreateHandle(m_ConVarType, cvar, NULL, g_pCoreIdent, NULL);
ds@457
   130
ds@457
   131
	// Insert the handle into our cache
ds@457
   132
	sm_trie_insert(m_CvarCache, name, reinterpret_cast<void *>(hndl));
ds@457
   133
ds@457
   134
	return hndl;
ds@457
   135
}
ds@457
   136
ds@457
   137
Handle_t CConVarManager::FindConVar(const char *name)
ds@457
   138
{
ds@457
   139
	ConVar *cvar = NULL;
ds@457
   140
	void *temp = NULL;
ds@457
   141
ds@457
   142
	// Search for convar
ds@457
   143
	cvar = icvar->FindVar(name);
ds@457
   144
ds@457
   145
	// If it doesn't exist, then return an invalid handle
ds@457
   146
	if (cvar == NULL)
ds@457
   147
	{
ds@457
   148
		return BAD_HANDLE;
ds@457
   149
	}
ds@457
   150
ds@457
   151
	// At this point, convar exists, so find out if we already have a handle for it
ds@457
   152
	if (sm_trie_retrieve(m_CvarCache, name, &temp))
ds@457
   153
	{
ds@457
   154
		// If we do, then return that handle
ds@457
   155
		return reinterpret_cast<Handle_t>(temp);
ds@457
   156
	}
ds@457
   157
ds@457
   158
	// If we don't, then create a new handle from the convar and return it
ds@457
   159
	return g_HandleSys.CreateHandle(m_ConVarType, cvar, NULL, g_pCoreIdent, NULL);
ds@457
   160
}