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