Added plugin dependencies to extensions
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40310
This commit is contained in:
		
							parent
							
								
									1857f29efc
								
							
						
					
					
						commit
						7b8c36cb79
					
				| @ -3,6 +3,7 @@ | |||||||
| #include "ShareSys.h" | #include "ShareSys.h" | ||||||
| #include "CLogger.h" | #include "CLogger.h" | ||||||
| #include "sourcemm_api.h" | #include "sourcemm_api.h" | ||||||
|  | #include "PluginSys.h" | ||||||
| 
 | 
 | ||||||
| CExtensionManager g_Extensions; | CExtensionManager g_Extensions; | ||||||
| IdentityType_t g_ExtType; | 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) | void CExtension::SetError(const char *error) | ||||||
| { | { | ||||||
| 	m_Error.assign(error); | 	m_Error.assign(error); | ||||||
| @ -197,10 +208,12 @@ void CExtension::AddInterface(SMInterface *pInterface) | |||||||
| void CExtensionManager::OnSourceModAllInitialized() | void CExtensionManager::OnSourceModAllInitialized() | ||||||
| { | { | ||||||
| 	g_ExtType = g_ShareSys.CreateIdentType("EXTENSION"); | 	g_ExtType = g_ShareSys.CreateIdentType("EXTENSION"); | ||||||
|  | 	g_PluginSys.AddPluginsListener(this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CExtensionManager::OnSourceModShutdown() | void CExtensionManager::OnSourceModShutdown() | ||||||
| { | { | ||||||
|  | 	g_PluginSys.RemovePluginsListener(this); | ||||||
| 	g_ShareSys.DestroyIdentType(g_ExtType); | 	g_ShareSys.DestroyIdentType(g_ExtType); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -217,7 +230,7 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path) | |||||||
| 
 | 
 | ||||||
| 	if (!p->IsLoaded()) | 	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); | 		p->SetError(error); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -316,6 +329,23 @@ void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface | |||||||
| 	pExt->AddInterface(pInterface); | 	pExt->AddInterface(pInterface); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void CExtensionManager::BindChildPlugin(IExtension *pParent, IPlugin *pPlugin) | ||||||
|  | { | ||||||
|  | 	CExtension *pExt = (CExtension *)pParent; | ||||||
|  | 
 | ||||||
|  | 	pExt->AddPlugin(pPlugin); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CExtensionManager::OnPluginDestroyed(IPlugin *plugin) | ||||||
|  | { | ||||||
|  | 	List<CExtension *>::iterator iter; | ||||||
|  | 
 | ||||||
|  | 	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++) | ||||||
|  | 	{ | ||||||
|  | 		(*iter)->RemovePlugin(plugin); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool CExtensionManager::UnloadExtension(IExtension *_pExt) | bool CExtensionManager::UnloadExtension(IExtension *_pExt) | ||||||
| { | { | ||||||
| 	if (!_pExt) | 	if (!_pExt) | ||||||
| @ -339,6 +369,15 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt) | |||||||
| 	/* Handle dependencies */ | 	/* Handle dependencies */ | ||||||
| 	if (pExt->IsLoaded()) | 	if (pExt->IsLoaded()) | ||||||
| 	{ | 	{ | ||||||
|  | 		/* Unload any dependent plugins */ | ||||||
|  | 		List<IPlugin *>::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 */ | 		/* Notify and/or unload all dependencies */ | ||||||
| 		List<CExtension *>::iterator c_iter; | 		List<CExtension *>::iterator c_iter; | ||||||
| 		CExtension *pDep; | 		CExtension *pDep; | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ | |||||||
| #include "sm_globals.h" | #include "sm_globals.h" | ||||||
| #include "ShareSys.h" | #include "ShareSys.h" | ||||||
| #include <ISmmAPI.h> | #include <ISmmAPI.h> | ||||||
|  | #include <IPluginSys.h> | ||||||
| 
 | 
 | ||||||
| using namespace SourceMod; | using namespace SourceMod; | ||||||
| using namespace SourceHook; | using namespace SourceHook; | ||||||
| @ -30,6 +31,8 @@ public: | |||||||
| 	void SetError(const char *error); | 	void SetError(const char *error); | ||||||
| 	void AddDependency(IfaceInfo *pInfo); | 	void AddDependency(IfaceInfo *pInfo); | ||||||
| 	void AddInterface(SMInterface *pInterface); | 	void AddInterface(SMInterface *pInterface); | ||||||
|  | 	void AddPlugin(IPlugin *pPlugin); | ||||||
|  | 	void RemovePlugin(IPlugin *pPlugin); | ||||||
| private: | private: | ||||||
| 	IdentityToken_t *m_pIdentToken; | 	IdentityToken_t *m_pIdentToken; | ||||||
| 	IExtensionInterface *m_pAPI; | 	IExtensionInterface *m_pAPI; | ||||||
| @ -38,12 +41,14 @@ private: | |||||||
| 	String m_Error; | 	String m_Error; | ||||||
| 	List<IfaceInfo> m_Deps; | 	List<IfaceInfo> m_Deps; | ||||||
| 	List<SMInterface *> m_Interfaces; | 	List<SMInterface *> m_Interfaces; | ||||||
|  | 	List<IPlugin *> m_Plugins; | ||||||
| 	PluginId m_PlId; | 	PluginId m_PlId; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class CExtensionManager :  | class CExtensionManager :  | ||||||
| 	public IExtensionManager, | 	public IExtensionManager, | ||||||
| 	public SMGlobalClass | 	public SMGlobalClass, | ||||||
|  | 	IPluginsListener | ||||||
| { | { | ||||||
| public: //SMGlobalClass
 | public: //SMGlobalClass
 | ||||||
| 	void OnSourceModAllInitialized(); | 	void OnSourceModAllInitialized(); | ||||||
| @ -56,10 +61,13 @@ public: //IExtensionManager | |||||||
| 	bool UnloadExtension(IExtension *pExt); | 	bool UnloadExtension(IExtension *pExt); | ||||||
| 	IExtension *FindExtensionByFile(const char *file); | 	IExtension *FindExtensionByFile(const char *file); | ||||||
| 	IExtension *FindExtensionByName(const char *ext); | 	IExtension *FindExtensionByName(const char *ext); | ||||||
|  | public: //IPluginsListener
 | ||||||
|  | 	void OnPluginDestroyed(IPlugin *plugin); | ||||||
| public: | public: | ||||||
| 	IExtension *LoadAutoExtension(const char *path); | 	IExtension *LoadAutoExtension(const char *path); | ||||||
| 	void BindDependency(IExtension *pOwner, IfaceInfo *pInfo); | 	void BindDependency(IExtension *pOwner, IfaceInfo *pInfo); | ||||||
| 	void AddInterface(IExtension *pOwner, SMInterface *pInterface); | 	void AddInterface(IExtension *pOwner, SMInterface *pInterface); | ||||||
|  | 	void BindChildPlugin(IExtension *pParent, IPlugin *pPlugin); | ||||||
| private: | private: | ||||||
| 	List<CExtension *> m_Libs; | 	List<CExtension *> m_Libs; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -588,11 +588,11 @@ void CPluginManager::LoadAll_FirstPass(const char *config, const char *basedir) | |||||||
| 	m_AllPluginsLoaded = false; | 	m_AllPluginsLoaded = false; | ||||||
| 	if ((err=g_TextParser.ParseFile_SMC(config, &m_PluginInfo, &line, &col)) != SMCParse_Okay) | 	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); | 		const char *err_msg = g_TextParser.GetSMCErrorString(err); | ||||||
| 		if (err_msg) | 		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]; | 		char error[256]; | ||||||
| 		g_LibSys.GetPlatformError(error, sizeof(error)); | 		g_LibSys.GetPlatformError(error, sizeof(error)); | ||||||
| 		g_Logger.LogError("[SOURCEMOD] Failure reading from plugins path: %s", localpath); | 		g_Logger.LogError("[SM] Failure reading from plugins path: %s", localpath); | ||||||
| 		g_Logger.LogError("[SOURCEMOD] Platform returned error: %s", error); | 		g_Logger.LogError("[SM] Platform returned error: %s", error); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -779,7 +779,7 @@ void CPluginManager::LoadAutoPlugin(const char *plugin) | |||||||
| 
 | 
 | ||||||
| 	if (!_LoadPlugin(&pl, plugin, false, PluginType_MapUpdated, error, sizeof(error))) | 	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); | 		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); | 				pExt = g_Extensions.LoadAutoExtension(path); | ||||||
| 			} | 			} | ||||||
|  | 			/* See if we can find a similar extension */ | ||||||
| 			if (ext->required && !pExt) | 			if (ext->required && !pExt) | ||||||
| 			{ | 			{ | ||||||
| 				if ((pExt = g_Extensions.FindExtensionByFile(path)) == NULL) | 				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); | 					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 (ext->required && (!pExt || !pExt->IsLoaded())) | ||||||
| 			{ | 			{ | ||||||
| 				if (error) | 				if (error) | ||||||
|  | |||||||
| @ -34,6 +34,9 @@ void ShareSystem::OnSourceModStartup(bool late) | |||||||
| 
 | 
 | ||||||
| 	/* Initialize our static identity handle */ | 	/* Initialize our static identity handle */ | ||||||
| 	m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL); | 	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() | void ShareSystem::OnSourceModShutdown() | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user