mirrored earlier core native binding optimization to extensions as well. clarified note about pointer lifetime in AddNatives(), as it will be gaining a second version soon
authorDavid Anderson <dvander@alliedmods.net>
Wed Aug 29 05:44:29 2007 +0000 (2007-08-29)
changeset 1391ae2ae57ccccf
parent 1390 287480a3f664
child 1392 39c35bde9aa0
mirrored earlier core native binding optimization to extensions as well. clarified note about pointer lifetime in AddNatives(), as it will be gaining a second version soon
core/systems/ExtensionSys.cpp
core/systems/ExtensionSys.h
public/IShareSys.h
     1.1 --- a/core/systems/ExtensionSys.cpp	Wed Aug 29 05:22:47 2007 +0000
     1.2 +++ b/core/systems/ExtensionSys.cpp	Wed Aug 29 05:44:29 2007 +0000
     1.3 @@ -566,51 +566,54 @@
     1.4  
     1.5  void CExtensionManager::BindAllNativesToPlugin(IPlugin *pPlugin)
     1.6  {
     1.7 -	List<CExtension *>::iterator iter;
     1.8 -	CExtension *pExt;
     1.9  	IPluginContext *pContext = pPlugin->GetBaseContext();
    1.10 -	for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
    1.11 +
    1.12 +	List<CExtension *> exts;
    1.13 +
    1.14 +	uint32_t natives = pContext->GetNativesNum();
    1.15 +	sp_native_t *native;
    1.16 +	sm_extnative_t *x_native;
    1.17 +	for (uint32_t i=0; i<natives; i++)
    1.18  	{
    1.19 -		pExt = (*iter);
    1.20 -		if (!pExt->IsLoaded())
    1.21 +		/* Make sure the native is valid */
    1.22 +		if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
    1.23  		{
    1.24  			continue;
    1.25  		}
    1.26 -		if (!pExt->m_Natives.size())
    1.27 +		/* Make sure the native is not already bound */
    1.28 +		if (native->status == SP_NATIVE_BOUND)
    1.29 +		{
    1.30 +			continue;
    1.31 +		}
    1.32 +		/* See if we've got this native in our cache */
    1.33 +		if ((x_native = m_ExtNatives.retrieve(native->name)) == NULL)
    1.34  		{
    1.35  			continue;
    1.36  		}
    1.37 -		bool set = false;
    1.38 -		List<const sp_nativeinfo_t *>::iterator n_iter;
    1.39 -		const sp_nativeinfo_t *natives;
    1.40 -		for (n_iter = pExt->m_Natives.begin();
    1.41 -			 n_iter != pExt->m_Natives.end();
    1.42 -			 n_iter++)
    1.43 +		/* Try and bind it */
    1.44 +		if (pContext->BindNativeToIndex(i, x_native->info->func) != SP_ERROR_NONE)
    1.45 +		{
    1.46 +			continue;
    1.47 +		}
    1.48 +		/* See if it's optional */
    1.49 +		if (native->flags & SP_NTVFLAG_OPTIONAL)
    1.50  		{
    1.51 -			natives = (*n_iter);
    1.52 -			uint32_t idx;
    1.53 -			unsigned int i=0;
    1.54 -			while (natives[i].func != NULL && natives[i].name != NULL)
    1.55 -			{
    1.56 -				if (pContext->BindNative(&natives[i]) == SP_ERROR_NONE)
    1.57 -				{
    1.58 -					pContext->FindNativeByName(natives[i].name, &idx);
    1.59 -					if (!(pContext->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL))
    1.60 -					{
    1.61 -						set = true;
    1.62 -					} else {
    1.63 -						WeakNative wkn = WeakNative((CPlugin *)pPlugin, idx);
    1.64 -						pExt->m_WeakNatives.push_back(wkn);
    1.65 -					}
    1.66 -				}
    1.67 -				i++;
    1.68 -			}
    1.69 +			WeakNative wkn = WeakNative((CPlugin *)pPlugin, i);
    1.70 +			x_native->owner->m_WeakNatives.push_back(wkn);
    1.71 +		} else if (exts.find(x_native->owner) == exts.end()) {
    1.72 +			exts.push_back(x_native->owner);
    1.73  		}
    1.74 -		if (set && (pExt->m_Plugins.find(pPlugin) == pExt->m_Plugins.end()))
    1.75 +	}
    1.76 +
    1.77 +	List<CExtension *>::iterator iter;
    1.78 +	for (iter = exts.begin(); iter != exts.end(); iter++)
    1.79 +	{
    1.80 +		CExtension *pExt = (*iter);
    1.81 +		if (pExt->m_Plugins.find(pPlugin) != pExt->m_Plugins.end())
    1.82  		{
    1.83 -			/* For now, mark this plugin as a requirement.  Later we'll introduce native filtering. */
    1.84 -			pExt->m_Plugins.push_back(pPlugin);
    1.85 +			continue;
    1.86  		}
    1.87 +		pExt->m_Plugins.push_back(pPlugin);
    1.88  	}
    1.89  }
    1.90  
    1.91 @@ -704,6 +707,26 @@
    1.92  			}
    1.93  		}
    1.94  
    1.95 +		/* Unbind our natives from Core */
    1.96 +		List<const sp_nativeinfo_t *>::iterator native_iter;
    1.97 +		for (native_iter = pExt->m_Natives.begin();
    1.98 +			 native_iter != pExt->m_Natives.end();
    1.99 +			 native_iter++)
   1.100 +		{
   1.101 +			const sp_nativeinfo_t *natives = (*native_iter);
   1.102 +			sm_extnative_t *x_native;
   1.103 +			for (unsigned int n = 0;
   1.104 +				 natives[n].name != NULL && natives[n].func != NULL;
   1.105 +				 n++)
   1.106 +			{
   1.107 +				x_native = m_ExtNatives.retrieve(natives[n].name);
   1.108 +				if (x_native && x_native->owner == pExt)
   1.109 +				{
   1.110 +					m_ExtNatives.remove(natives[n].name);
   1.111 +				}
   1.112 +			}
   1.113 +		}
   1.114 +
   1.115  		/* Tell it to unload */
   1.116  		pAPI = pExt->GetAPI();
   1.117  		pAPI->OnExtensionUnload();
   1.118 @@ -743,6 +766,18 @@
   1.119  	CExtension *pExt = (CExtension *)pOwner;
   1.120  
   1.121  	pExt->m_Natives.push_back(natives);
   1.122 +
   1.123 +	for (unsigned int i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
   1.124 +	{
   1.125 +		if (m_ExtNatives.retrieve(natives[i].name) != NULL)
   1.126 +		{
   1.127 +			continue;
   1.128 +		}
   1.129 +		sm_extnative_t x_native;
   1.130 +		x_native.info = &natives[i];
   1.131 +		x_native.owner = pExt;
   1.132 +		m_ExtNatives.insert(natives[i].name, x_native);
   1.133 +	}
   1.134  }
   1.135  
   1.136  void CExtensionManager::MarkAllLoaded()
   1.137 @@ -1028,3 +1063,11 @@
   1.138  
   1.139  	return NULL;
   1.140  }
   1.141 +
   1.142 +CExtensionManager::CExtensionManager()
   1.143 +{
   1.144 +}
   1.145 +
   1.146 +CExtensionManager::~CExtensionManager()
   1.147 +{
   1.148 +}
     2.1 --- a/core/systems/ExtensionSys.h	Wed Aug 29 05:22:47 2007 +0000
     2.2 +++ b/core/systems/ExtensionSys.h	Wed Aug 29 05:44:29 2007 +0000
     2.3 @@ -36,6 +36,7 @@
     2.4  #include <ILibrarySys.h>
     2.5  #include <sh_list.h>
     2.6  #include <sh_string.h>
     2.7 +#include <sm_trie_tpl.h>
     2.8  #include "sm_globals.h"
     2.9  #include "ShareSys.h"
    2.10  #include <ISmmAPI.h>
    2.11 @@ -46,6 +47,14 @@
    2.12  using namespace SourceMod;
    2.13  using namespace SourceHook;
    2.14  
    2.15 +class CExtension;
    2.16 +
    2.17 +struct sm_extnative_t
    2.18 +{
    2.19 +	CExtension *owner;
    2.20 +	const sp_nativeinfo_t *info;
    2.21 +};
    2.22 +
    2.23  class CExtension : public IExtension
    2.24  {
    2.25  	friend class CExtensionManager;
    2.26 @@ -95,6 +104,9 @@
    2.27  	public IPluginsListener,
    2.28  	public IRootConsoleCommand
    2.29  {
    2.30 +public:
    2.31 +	CExtensionManager();
    2.32 +	~CExtensionManager();
    2.33  public: //SMGlobalClass
    2.34  	void OnSourceModAllInitialized();
    2.35  	void OnSourceModShutdown();
    2.36 @@ -127,6 +139,7 @@
    2.37  	CExtension *FindByOrder(unsigned int num);
    2.38  private:
    2.39  	List<CExtension *> m_Libs;
    2.40 +	KTrie<sm_extnative_t> m_ExtNatives;
    2.41  };
    2.42  
    2.43  extern CExtensionManager g_Extensions;
     3.1 --- a/public/IShareSys.h	Wed Aug 29 05:22:47 2007 +0000
     3.2 +++ b/public/IShareSys.h	Wed Aug 29 05:44:29 2007 +0000
     3.3 @@ -118,12 +118,18 @@
     3.4  										SMInterface **pIface) =0;
     3.5  
     3.6  		/**
     3.7 -		 * @brief Adds a list of natives to the global native pool, to be bound on plugin load.
     3.8 -		 * NOTE: Adding natives currently does not bind them to any loaded plugins.
     3.9 -		 * You must manually bind late natives.
    3.10 +		 * @brief Adds a list of natives to the global native pool, to be 
    3.11 +		 * bound on plugin load.
    3.12 +		 *
    3.13 +		 * Adding natives does not bind them to any loaded plugins; the 
    3.14 +		 * plugins must be reloaded for new natives to take effect.  
    3.15  		 * 
    3.16  		 * @param myself		Identity token of parent object.
    3.17 -		 * @param natives		Array of natives to add.  The last entry must have NULL members.
    3.18 +		 * @param natives		Array of natives to add.  The last entry in 
    3.19 +		 *						the array must be filled with NULLs to 
    3.20 +		 *						terminate the array.  The array must be static 
    3.21 +		 *						as Core will cache the pointer for the 
    3.22 +		 *						lifetime of the extension.
    3.23  		 */
    3.24  		virtual void AddNatives(IExtension *myself, const sp_nativeinfo_t *natives) =0;
    3.25