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
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401397
This commit is contained in:
parent
77cc895151
commit
e5d81cf621
@ -566,51 +566,54 @@ CExtension *CExtensionManager::FindByOrder(unsigned int num)
|
|||||||
|
|
||||||
void CExtensionManager::BindAllNativesToPlugin(IPlugin *pPlugin)
|
void CExtensionManager::BindAllNativesToPlugin(IPlugin *pPlugin)
|
||||||
{
|
{
|
||||||
List<CExtension *>::iterator iter;
|
|
||||||
CExtension *pExt;
|
|
||||||
IPluginContext *pContext = pPlugin->GetBaseContext();
|
IPluginContext *pContext = pPlugin->GetBaseContext();
|
||||||
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
|
|
||||||
|
List<CExtension *> exts;
|
||||||
|
|
||||||
|
uint32_t natives = pContext->GetNativesNum();
|
||||||
|
sp_native_t *native;
|
||||||
|
sm_extnative_t *x_native;
|
||||||
|
for (uint32_t i=0; i<natives; i++)
|
||||||
{
|
{
|
||||||
pExt = (*iter);
|
/* Make sure the native is valid */
|
||||||
if (!pExt->IsLoaded())
|
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!pExt->m_Natives.size())
|
/* Make sure the native is not already bound */
|
||||||
|
if (native->status == SP_NATIVE_BOUND)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool set = false;
|
/* See if we've got this native in our cache */
|
||||||
List<const sp_nativeinfo_t *>::iterator n_iter;
|
if ((x_native = m_ExtNatives.retrieve(native->name)) == NULL)
|
||||||
const sp_nativeinfo_t *natives;
|
|
||||||
for (n_iter = pExt->m_Natives.begin();
|
|
||||||
n_iter != pExt->m_Natives.end();
|
|
||||||
n_iter++)
|
|
||||||
{
|
{
|
||||||
natives = (*n_iter);
|
continue;
|
||||||
uint32_t idx;
|
|
||||||
unsigned int i=0;
|
|
||||||
while (natives[i].func != NULL && natives[i].name != NULL)
|
|
||||||
{
|
|
||||||
if (pContext->BindNative(&natives[i]) == SP_ERROR_NONE)
|
|
||||||
{
|
|
||||||
pContext->FindNativeByName(natives[i].name, &idx);
|
|
||||||
if (!(pContext->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL))
|
|
||||||
{
|
|
||||||
set = true;
|
|
||||||
} else {
|
|
||||||
WeakNative wkn = WeakNative((CPlugin *)pPlugin, idx);
|
|
||||||
pExt->m_WeakNatives.push_back(wkn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (set && (pExt->m_Plugins.find(pPlugin) == pExt->m_Plugins.end()))
|
/* Try and bind it */
|
||||||
|
if (pContext->BindNativeToIndex(i, x_native->info->func) != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
/* For now, mark this plugin as a requirement. Later we'll introduce native filtering. */
|
continue;
|
||||||
pExt->m_Plugins.push_back(pPlugin);
|
|
||||||
}
|
}
|
||||||
|
/* See if it's optional */
|
||||||
|
if (native->flags & SP_NTVFLAG_OPTIONAL)
|
||||||
|
{
|
||||||
|
WeakNative wkn = WeakNative((CPlugin *)pPlugin, i);
|
||||||
|
x_native->owner->m_WeakNatives.push_back(wkn);
|
||||||
|
} else if (exts.find(x_native->owner) == exts.end()) {
|
||||||
|
exts.push_back(x_native->owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CExtension *>::iterator iter;
|
||||||
|
for (iter = exts.begin(); iter != exts.end(); iter++)
|
||||||
|
{
|
||||||
|
CExtension *pExt = (*iter);
|
||||||
|
if (pExt->m_Plugins.find(pPlugin) != pExt->m_Plugins.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pExt->m_Plugins.push_back(pPlugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,6 +707,26 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unbind our natives from Core */
|
||||||
|
List<const sp_nativeinfo_t *>::iterator native_iter;
|
||||||
|
for (native_iter = pExt->m_Natives.begin();
|
||||||
|
native_iter != pExt->m_Natives.end();
|
||||||
|
native_iter++)
|
||||||
|
{
|
||||||
|
const sp_nativeinfo_t *natives = (*native_iter);
|
||||||
|
sm_extnative_t *x_native;
|
||||||
|
for (unsigned int n = 0;
|
||||||
|
natives[n].name != NULL && natives[n].func != NULL;
|
||||||
|
n++)
|
||||||
|
{
|
||||||
|
x_native = m_ExtNatives.retrieve(natives[n].name);
|
||||||
|
if (x_native && x_native->owner == pExt)
|
||||||
|
{
|
||||||
|
m_ExtNatives.remove(natives[n].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Tell it to unload */
|
/* Tell it to unload */
|
||||||
pAPI = pExt->GetAPI();
|
pAPI = pExt->GetAPI();
|
||||||
pAPI->OnExtensionUnload();
|
pAPI->OnExtensionUnload();
|
||||||
@ -743,6 +766,18 @@ void CExtensionManager::AddNatives(IExtension *pOwner, const sp_nativeinfo_t *na
|
|||||||
CExtension *pExt = (CExtension *)pOwner;
|
CExtension *pExt = (CExtension *)pOwner;
|
||||||
|
|
||||||
pExt->m_Natives.push_back(natives);
|
pExt->m_Natives.push_back(natives);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
|
||||||
|
{
|
||||||
|
if (m_ExtNatives.retrieve(natives[i].name) != NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sm_extnative_t x_native;
|
||||||
|
x_native.info = &natives[i];
|
||||||
|
x_native.owner = pExt;
|
||||||
|
m_ExtNatives.insert(natives[i].name, x_native);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CExtensionManager::MarkAllLoaded()
|
void CExtensionManager::MarkAllLoaded()
|
||||||
@ -1028,3 +1063,11 @@ CExtension *CExtensionManager::GetExtensionFromIdent(IdentityToken_t *ptr)
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CExtensionManager::CExtensionManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CExtensionManager::~CExtensionManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <ILibrarySys.h>
|
#include <ILibrarySys.h>
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
|
#include <sm_trie_tpl.h>
|
||||||
#include "sm_globals.h"
|
#include "sm_globals.h"
|
||||||
#include "ShareSys.h"
|
#include "ShareSys.h"
|
||||||
#include <ISmmAPI.h>
|
#include <ISmmAPI.h>
|
||||||
@ -46,6 +47,14 @@
|
|||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
|
|
||||||
|
class CExtension;
|
||||||
|
|
||||||
|
struct sm_extnative_t
|
||||||
|
{
|
||||||
|
CExtension *owner;
|
||||||
|
const sp_nativeinfo_t *info;
|
||||||
|
};
|
||||||
|
|
||||||
class CExtension : public IExtension
|
class CExtension : public IExtension
|
||||||
{
|
{
|
||||||
friend class CExtensionManager;
|
friend class CExtensionManager;
|
||||||
@ -95,6 +104,9 @@ class CExtensionManager :
|
|||||||
public IPluginsListener,
|
public IPluginsListener,
|
||||||
public IRootConsoleCommand
|
public IRootConsoleCommand
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
CExtensionManager();
|
||||||
|
~CExtensionManager();
|
||||||
public: //SMGlobalClass
|
public: //SMGlobalClass
|
||||||
void OnSourceModAllInitialized();
|
void OnSourceModAllInitialized();
|
||||||
void OnSourceModShutdown();
|
void OnSourceModShutdown();
|
||||||
@ -127,6 +139,7 @@ private:
|
|||||||
CExtension *FindByOrder(unsigned int num);
|
CExtension *FindByOrder(unsigned int num);
|
||||||
private:
|
private:
|
||||||
List<CExtension *> m_Libs;
|
List<CExtension *> m_Libs;
|
||||||
|
KTrie<sm_extnative_t> m_ExtNatives;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CExtensionManager g_Extensions;
|
extern CExtensionManager g_Extensions;
|
||||||
|
@ -118,12 +118,18 @@ namespace SourceMod
|
|||||||
SMInterface **pIface) =0;
|
SMInterface **pIface) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds a list of natives to the global native pool, to be bound on plugin load.
|
* @brief Adds a list of natives to the global native pool, to be
|
||||||
* NOTE: Adding natives currently does not bind them to any loaded plugins.
|
* bound on plugin load.
|
||||||
* You must manually bind late natives.
|
*
|
||||||
|
* Adding natives does not bind them to any loaded plugins; the
|
||||||
|
* plugins must be reloaded for new natives to take effect.
|
||||||
*
|
*
|
||||||
* @param myself Identity token of parent object.
|
* @param myself Identity token of parent object.
|
||||||
* @param natives Array of natives to add. The last entry must have NULL members.
|
* @param natives Array of natives to add. The last entry in
|
||||||
|
* the array must be filled with NULLs to
|
||||||
|
* terminate the array. The array must be static
|
||||||
|
* as Core will cache the pointer for the
|
||||||
|
* lifetime of the extension.
|
||||||
*/
|
*/
|
||||||
virtual void AddNatives(IExtension *myself, const sp_nativeinfo_t *natives) =0;
|
virtual void AddNatives(IExtension *myself, const sp_nativeinfo_t *natives) =0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user