Added custom gamedata section parsing to GameConfigs.

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402429
This commit is contained in:
Matt Woodrow 2008-07-30 00:03:10 +00:00
parent 8182bdb476
commit 3c0b289694
3 changed files with 99 additions and 2 deletions

View File

@ -65,6 +65,7 @@ char g_GameName[256] = {'$', '\0'};
#define PSTATE_GAMEDEFS_SIGNATURES_SIG 8
#define PSTATE_GAMEDEFS_CRC 9
#define PSTATE_GAMEDEFS_CRC_BINARY 10
#define PSTATE_GAMEDEFS_CUSTOM 11
#if defined PLATFORM_WINDOWS
#define PLATFORM_NAME "windows"
@ -96,6 +97,9 @@ CGameConfig::CGameConfig(const char *file)
m_pSigs = sm_trie_create();
m_pStrings = new BaseStringTable(512);
m_RefCount = 0;
m_CustomLevel = 0;
m_CustomHandler = NULL;
}
CGameConfig::~CGameConfig()
@ -172,6 +176,17 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
}
else
{
ITextListener_SMC **pListen = g_GameConfigs.m_customHandlers.retrieve(name);
if (pListen != NULL)
{
m_CustomLevel = 0;
m_ParseState = PSTATE_GAMEDEFS_CUSTOM;
m_CustomHandler = *pListen;
m_CustomHandler->ReadSMC_ParseStart();
break;
}
m_IgnoreLevel++;
}
break;
@ -233,6 +248,12 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
}
break;
}
case PSTATE_GAMEDEFS_CUSTOM:
{
m_CustomLevel++;
return m_CustomHandler->ReadSMC_NewSection(states, name);
break;
}
/* No sub-sections allowed:
case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
case PSTATE_GAMEDEFS_KEYS:
@ -300,6 +321,8 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
bShouldBeReadingDefault = true;
}
}
} else if (m_ParseState == PSTATE_GAMEDEFS_CUSTOM) {
return m_CustomHandler->ReadSMC_KeyValue(states, key, value);
}
return SMCResult_Continue;
@ -313,6 +336,13 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
return SMCResult_Continue;
}
if (m_CustomLevel)
{
m_CustomLevel--;
m_CustomHandler->ReadSMC_LeavingSection(states);
return SMCResult_Continue;
}
switch (m_ParseState)
{
case PSTATE_GAMES:
@ -325,6 +355,12 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
m_ParseState = PSTATE_GAMES;
break;
}
case PSTATE_GAMEDEFS_CUSTOM:
{
m_ParseState = PSTATE_GAMEDEFS;
m_CustomHandler->ReadSMC_ParseEnd(false, false);
break;
}
case PSTATE_GAMEDEFS_KEYS:
case PSTATE_GAMEDEFS_OFFSETS:
{
@ -523,6 +559,15 @@ bool CGameConfig::Reparse(char *error, size_t maxlength)
state.line,
state.col,
msg ? msg : "Unknown error");
if (m_ParseState == PSTATE_GAMEDEFS_CUSTOM)
{
//error occurred while parsing a custom section
m_CustomHandler->ReadSMC_ParseEnd(true, true);
m_CustomHandler = NULL;
m_CustomLevel = 0;
}
return false;
}
@ -692,3 +737,27 @@ IGameConfig *GameConfigManager::ReadHandle(Handle_t hndl, IdentityToken_t *ident
return conf;
}
void GameConfigManager::AddUserConfigHook( const char *sectionname, ITextListener_SMC *listener )
{
m_customHandlers.insert(sectionname, listener);
}
void GameConfigManager::RemoveUserConfigHook( const char *sectionname, ITextListener_SMC *listener )
{
ITextListener_SMC **pListener = m_customHandlers.retrieve(sectionname);
if (pListener == NULL)
{
return;
}
if (*pListener != listener)
{
return;
}
m_customHandlers.remove(sectionname);
return;
}

View File

@ -38,6 +38,7 @@
#include "sm_trie.h"
#include "sm_globals.h"
#include "sm_memtable.h"
#include "sm_trie_tpl.h"
using namespace SourceMod;
using namespace SourceHook;
@ -82,6 +83,10 @@ private:
char m_offset[64];
char m_Game[256];
bool bShouldBeReadingDefault;
/* Custom Sections */
unsigned int m_CustomLevel;
ITextListener_SMC *m_CustomHandler;
};
class GameConfigManager :
@ -97,6 +102,8 @@ public: //IGameConfigManager
IGameConfig *ReadHandle(Handle_t hndl,
IdentityToken_t *ident,
HandleError *err);
void AddUserConfigHook(const char *sectionname, ITextListener_SMC *listener);
void RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener);
public: //SMGlobalClass
void OnSourceModStartup(bool late);
void OnSourceModAllInitialized();
@ -104,6 +111,8 @@ public: //SMGlobalClass
private:
List<CGameConfig *> m_cfgs;
Trie *m_pLookup;
public:
KTrie<ITextListener_SMC *> m_customHandlers;
};
extern GameConfigManager g_GameConfigs;

View File

@ -34,6 +34,7 @@
#include <IShareSys.h>
#include <IHandleSys.h>
#include <ITextParsers.h>
/**
* @file IGameConfigs.h
@ -41,7 +42,7 @@
*/
#define SMINTERFACE_GAMECONFIG_NAME "IGameConfigManager"
#define SMINTERFACE_GAMECONFIG_VERSION 3
#define SMINTERFACE_GAMECONFIG_VERSION 4
class SendProp;
@ -141,7 +142,25 @@ namespace SourceMod
*/
virtual IGameConfig *ReadHandle(Handle_t hndl,
IdentityToken_t *ident,
HandleError *err) =0;
HandleError *err) =0;
/**
* @brief Adds a custom gamedata section hook.
*
* @param sectionname Section name to hook.
* @param listener Listener callback.
* @noreturn
*/
virtual void AddUserConfigHook(const char *sectionname, ITextListener_SMC *listener) =0;
/**
* @brief Removes a custom gamedata section hook.
*
* @param sectionname Section name to unhook.
* @param listener Listener callback.
* @noreturn
*/
virtual void RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener) =0;
};
}