From 7b8c36cb79800eda60cb7e3580407316ed53e57a Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 17 Jan 2007 06:48:11 +0000 Subject: [PATCH] Added plugin dependencies to extensions --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40310 --- core/systems/ExtensionSys.cpp | 41 ++++++++++++++++++++++++++++++++++- core/systems/ExtensionSys.h | 10 ++++++++- core/systems/PluginSys.cpp | 17 ++++++++++----- core/systems/ShareSys.cpp | 3 +++ 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/core/systems/ExtensionSys.cpp b/core/systems/ExtensionSys.cpp index 3d9375ce..ae223b57 100644 --- a/core/systems/ExtensionSys.cpp +++ b/core/systems/ExtensionSys.cpp @@ -3,6 +3,7 @@ #include "ShareSys.h" #include "CLogger.h" #include "sourcemm_api.h" +#include "PluginSys.h" CExtensionManager g_Extensions; IdentityType_t g_ExtType; @@ -94,6 +95,16 @@ CExtension::~CExtension() } } +void CExtension::AddPlugin(IPlugin *pPlugin) +{ + m_Plugins.push_back(pPlugin); +} + +void CExtension::RemovePlugin(IPlugin *pPlugin) +{ + m_Plugins.remove(pPlugin); +} + void CExtension::SetError(const char *error) { m_Error.assign(error); @@ -197,10 +208,12 @@ void CExtension::AddInterface(SMInterface *pInterface) void CExtensionManager::OnSourceModAllInitialized() { g_ExtType = g_ShareSys.CreateIdentType("EXTENSION"); + g_PluginSys.AddPluginsListener(this); } void CExtensionManager::OnSourceModShutdown() { + g_PluginSys.RemovePluginsListener(this); g_ShareSys.DestroyIdentType(g_ExtType); } @@ -217,7 +230,7 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path) if (!p->IsLoaded()) { - g_Logger.LogError("[SOURCEMOD] Unable to load extension \"%s\": %s", path, error); + g_Logger.LogError("[SM] Unable to load extension \"%s\": %s", path, error); p->SetError(error); } @@ -316,6 +329,23 @@ void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface pExt->AddInterface(pInterface); } +void CExtensionManager::BindChildPlugin(IExtension *pParent, IPlugin *pPlugin) +{ + CExtension *pExt = (CExtension *)pParent; + + pExt->AddPlugin(pPlugin); +} + +void CExtensionManager::OnPluginDestroyed(IPlugin *plugin) +{ + List::iterator iter; + + for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++) + { + (*iter)->RemovePlugin(plugin); + } +} + bool CExtensionManager::UnloadExtension(IExtension *_pExt) { if (!_pExt) @@ -339,6 +369,15 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt) /* Handle dependencies */ if (pExt->IsLoaded()) { + /* Unload any dependent plugins */ + List::iterator p_iter = pExt->m_Plugins.begin(); + while (p_iter != pExt->m_Plugins.end()) + { + g_PluginSys.UnloadPlugin((*p_iter)); + /* It should already have been removed! */ + assert(pExt->m_Plugins.find((*p_iter)) != pExt->m_Plugins.end()); + } + /* Notify and/or unload all dependencies */ List::iterator c_iter; CExtension *pDep; diff --git a/core/systems/ExtensionSys.h b/core/systems/ExtensionSys.h index 7bf05f1c..2e946406 100644 --- a/core/systems/ExtensionSys.h +++ b/core/systems/ExtensionSys.h @@ -8,6 +8,7 @@ #include "sm_globals.h" #include "ShareSys.h" #include +#include using namespace SourceMod; using namespace SourceHook; @@ -30,6 +31,8 @@ public: void SetError(const char *error); void AddDependency(IfaceInfo *pInfo); void AddInterface(SMInterface *pInterface); + void AddPlugin(IPlugin *pPlugin); + void RemovePlugin(IPlugin *pPlugin); private: IdentityToken_t *m_pIdentToken; IExtensionInterface *m_pAPI; @@ -38,12 +41,14 @@ private: String m_Error; List m_Deps; List m_Interfaces; + List m_Plugins; PluginId m_PlId; }; class CExtensionManager : public IExtensionManager, - public SMGlobalClass + public SMGlobalClass, + IPluginsListener { public: //SMGlobalClass void OnSourceModAllInitialized(); @@ -56,10 +61,13 @@ public: //IExtensionManager bool UnloadExtension(IExtension *pExt); IExtension *FindExtensionByFile(const char *file); IExtension *FindExtensionByName(const char *ext); +public: //IPluginsListener + void OnPluginDestroyed(IPlugin *plugin); public: IExtension *LoadAutoExtension(const char *path); void BindDependency(IExtension *pOwner, IfaceInfo *pInfo); void AddInterface(IExtension *pOwner, SMInterface *pInterface); + void BindChildPlugin(IExtension *pParent, IPlugin *pPlugin); private: List m_Libs; }; diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp index 627c4f9a..9e83688b 100644 --- a/core/systems/PluginSys.cpp +++ b/core/systems/PluginSys.cpp @@ -588,11 +588,11 @@ void CPluginManager::LoadAll_FirstPass(const char *config, const char *basedir) m_AllPluginsLoaded = false; if ((err=g_TextParser.ParseFile_SMC(config, &m_PluginInfo, &line, &col)) != SMCParse_Okay) { - g_Logger.LogError("[SOURCEMOD] Encountered fatal error parsing file \"%s\"", config); + g_Logger.LogError("[SM] Encountered fatal error parsing file \"%s\"", config); const char *err_msg = g_TextParser.GetSMCErrorString(err); if (err_msg) { - g_Logger.LogError("[SOURCEMOD] Parse error encountered: \"%s\"", err_msg); + g_Logger.LogError("[SM] Parse error encountered: \"%s\"", err_msg); } } @@ -617,8 +617,8 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa { char error[256]; g_LibSys.GetPlatformError(error, sizeof(error)); - g_Logger.LogError("[SOURCEMOD] Failure reading from plugins path: %s", localpath); - g_Logger.LogError("[SOURCEMOD] Platform returned error: %s", error); + g_Logger.LogError("[SM] Failure reading from plugins path: %s", localpath); + g_Logger.LogError("[SM] Platform returned error: %s", error); return; } @@ -779,7 +779,7 @@ void CPluginManager::LoadAutoPlugin(const char *plugin) if (!_LoadPlugin(&pl, plugin, false, PluginType_MapUpdated, error, sizeof(error))) { - g_Logger.LogError("[SOURCEMOD] Failed to load plugin \"%s\": %s", plugin, error); + g_Logger.LogError("[SM] Failed to load plugin \"%s\": %s", plugin, error); pl->SetErrorState(Plugin_Failed, "%s", error); } @@ -864,6 +864,7 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng { pExt = g_Extensions.LoadAutoExtension(path); } + /* See if we can find a similar extension */ if (ext->required && !pExt) { if ((pExt = g_Extensions.FindExtensionByFile(path)) == NULL) @@ -871,6 +872,12 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng pExt = g_Extensions.FindExtensionByName(name); } } + /* If we're requiring and got an extension and it's loaded, bind it */ + if (ext->required && pExt && pExt->IsLoaded()) + { + g_Extensions.BindChildPlugin(pExt, pPlugin); + } + /* If we're requiring and we didn't get an extension or it's not loaded, error */ if (ext->required && (!pExt || !pExt->IsLoaded())) { if (error) diff --git a/core/systems/ShareSys.cpp b/core/systems/ShareSys.cpp index bf91c851..4d96b3f8 100644 --- a/core/systems/ShareSys.cpp +++ b/core/systems/ShareSys.cpp @@ -34,6 +34,9 @@ void ShareSystem::OnSourceModStartup(bool late) /* Initialize our static identity handle */ m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL); + + /* Add the Handle System... it's too innocent and pure to do it itself */ + AddInterface(NULL, &g_HandleSys); } void ShareSystem::OnSourceModShutdown()