Added extension loading/unloading
Extended SDK for interface sharing Completed Metamod extension support --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40309
This commit is contained in:
parent
b7e10b111f
commit
1857f29efc
@ -7,6 +7,7 @@
|
||||
namespace SourceMod
|
||||
{
|
||||
class IExtensionInterface;
|
||||
typedef void * ITERATOR;
|
||||
|
||||
/**
|
||||
* @brief Encapsulates an IExtension.
|
||||
@ -40,6 +41,32 @@ namespace SourceMod
|
||||
* @return An IdentityToken_t pointer.
|
||||
*/
|
||||
virtual IdentityToken_t *GetIdentity() =0;
|
||||
|
||||
/**
|
||||
* @brief Retrieves the extension dependency list for this extension.
|
||||
*
|
||||
* @param pOwner Optional pointer to store the first interface's owner.
|
||||
* @param pInterface Optional pointer to store the first interface.
|
||||
* @return An ITERATOR pointer for the results, or NULL if no results at all.
|
||||
*/
|
||||
virtual ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface) =0;
|
||||
|
||||
/**
|
||||
* @brief Finds the next dependency in the dependency list.
|
||||
*
|
||||
* @param iter Pointer to iterator from FindFirstDependency.
|
||||
* @param pOwner Optional pointer to store the interface's owner.
|
||||
* @param pInterface Optional pointer to store the interface.
|
||||
* @return True if there are more results after this, false otherwise.
|
||||
*/
|
||||
virtual bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface) =0;
|
||||
|
||||
/**
|
||||
* @brief Frees an ITERATOR handle from FindFirstDependency.
|
||||
*
|
||||
* @param iter Pointer to iterator to free.
|
||||
*/
|
||||
virtual void FreeDependencyIterator(ITERATOR *iter) =0;
|
||||
};
|
||||
|
||||
#define SMINTERFACE_EXTENSIONAPI_VERSION 1
|
||||
@ -49,6 +76,11 @@ namespace SourceMod
|
||||
*/
|
||||
class IExtensionInterface
|
||||
{
|
||||
public:
|
||||
virtual unsigned int GetExtensionVersion()
|
||||
{
|
||||
return SMINTERFACE_EXTENSIONAPI_VERSION;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* @brief Called when the extension is loaded.
|
||||
@ -84,16 +116,29 @@ namespace SourceMod
|
||||
*/
|
||||
virtual void OnExtensionPauseChange(bool pause) =0;
|
||||
|
||||
virtual unsigned int GetExtensionVersion()
|
||||
/**
|
||||
* @brief Asks the extension whether it's safe to remove an external interface it's using.
|
||||
* If it's not safe, return false, and the extension will be unloaded afterwards.
|
||||
* NOTE: It is important to also hook NotifyInterfaceDrop() in order to clean up resources.
|
||||
*
|
||||
* @param pInterface Pointer to interface being dropped.
|
||||
* @return True to continue, false to unload this extension afterwards.
|
||||
*/
|
||||
virtual bool QueryInterfaceDrop(SMInterface *pInterface)
|
||||
{
|
||||
return SMINTERFACE_EXTENSIONAPI_VERSION;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the extension is Metamod-dependent.
|
||||
* @brief Notifies the extension that an external interface it uses is being removed.
|
||||
*
|
||||
* @param pInterface Pointer to interface being dropped.
|
||||
*/
|
||||
virtual bool IsMetamodExtension() =0;
|
||||
virtual void NotifyInterfaceDrop(SMInterface *pInterface)
|
||||
{
|
||||
}
|
||||
public:
|
||||
virtual bool IsMetamodExtension() =0;
|
||||
virtual const char *GetExtensionName() =0;
|
||||
virtual const char *GetExtensionURL() =0;
|
||||
virtual const char *GetExtensionTag() =0;
|
||||
@ -138,25 +183,6 @@ namespace SourceMod
|
||||
char *error,
|
||||
size_t err_max) =0;
|
||||
|
||||
/**
|
||||
* @brief Returns the number of plugins that will be unloaded when this
|
||||
* module is unloaded.
|
||||
*
|
||||
* @param pExt IExtension pointer.
|
||||
* @param optional Optional pointer to be filled with # of plugins that
|
||||
* are dependent, but will continue safely. NOT YET USED.
|
||||
* @return Total number of dependent plugins.
|
||||
*/
|
||||
virtual unsigned int NumberOfPluginDependents(IExtension *pExt, unsigned int *optional) =0;
|
||||
|
||||
/**
|
||||
* @brief Returns whether or not the extension can be unloaded.
|
||||
*
|
||||
* @param pExt IExtension pointer.
|
||||
* @return True if unloading is possible, false otherwise.
|
||||
*/
|
||||
virtual bool IsExtensionUnloadable(IExtension *pExtension) =0;
|
||||
|
||||
/**
|
||||
* @brief Attempts to unload a module.
|
||||
*
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
class IExtension;
|
||||
struct IdentityToken_t;
|
||||
typedef unsigned int HandleType_t;
|
||||
typedef HandleType_t IdentityType_t;
|
||||
@ -53,11 +54,11 @@ namespace SourceMod
|
||||
/**
|
||||
* @brief Adds an interface to the global interface system.
|
||||
*
|
||||
* @param myself Object adding this interface, in order to track dependencies.
|
||||
* @param iface Interface pointer (must be unique).
|
||||
* @param token Parent token of the module/interface.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
virtual bool AddInterface(SMInterface *iface, IdentityToken_t *token) =0;
|
||||
virtual bool AddInterface(IExtension *myself, SMInterface *iface) =0;
|
||||
|
||||
/**
|
||||
* @brief Requests an interface from the global interface system.
|
||||
@ -65,12 +66,12 @@ namespace SourceMod
|
||||
*
|
||||
* @param iface_name Interface name.
|
||||
* @param iface_vers Interface version to attempt to match.
|
||||
* @param token Object requesting this interface, in order to track dependencies.
|
||||
* @param myself Object requesting this interface, in order to track dependencies.
|
||||
* @param pIface Pointer to store the return value in.
|
||||
*/
|
||||
virtual bool RequestInterface(const char *iface_name,
|
||||
unsigned int iface_vers,
|
||||
IdentityToken_t *token,
|
||||
IExtension *myself,
|
||||
SMInterface **pIface) =0;
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,7 @@ SourceMod_Core g_SourceMod_Core;
|
||||
IVEngineServer *engine = NULL;
|
||||
IServerGameDLL *gamedll = NULL;
|
||||
IServerGameClients *serverClients = NULL;
|
||||
ISmmPluginManager *g_pMMPlugins = NULL;
|
||||
|
||||
PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core);
|
||||
|
||||
@ -18,6 +19,15 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
|
||||
GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
|
||||
GET_V_IFACE_CURRENT(serverFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS);
|
||||
|
||||
if ((g_pMMPlugins = (ISmmPluginManager *)g_SMAPI->MetaFactory(MMIFACE_PLMANAGER, NULL, NULL)) == NULL)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
snprintf(error, maxlen, "Unable to find interface %s", MMIFACE_PLMANAGER);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return g_SourceMod.InitializeSourceMod(error, maxlen, late);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ extern SourceMod_Core g_SourceMod_Core;
|
||||
extern IVEngineServer *engine;
|
||||
extern IServerGameDLL *gamedll;
|
||||
extern IServerGameClients *serverClients;
|
||||
extern ISmmPluginManager *g_pMMPlugins;
|
||||
|
||||
PLUGIN_GLOBALVARS();
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "LibrarySys.h"
|
||||
#include "ShareSys.h"
|
||||
#include "CLogger.h"
|
||||
#include "sourcemm_api.h"
|
||||
|
||||
CExtensionManager g_Extensions;
|
||||
IdentityType_t g_ExtType;
|
||||
@ -11,6 +12,7 @@ CExtension::CExtension(const char *filename, char *error, size_t err_max)
|
||||
m_File.assign(filename);
|
||||
m_pAPI = NULL;
|
||||
m_pIdentToken = NULL;
|
||||
m_PlId = 0;
|
||||
|
||||
char path[PLATFORM_MAX_PATH+1];
|
||||
g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s/extensions/%s", g_SourceMod.GetSMBaseDir(), filename);
|
||||
@ -44,7 +46,8 @@ CExtension::CExtension(const char *filename, char *error, size_t err_max)
|
||||
|
||||
if (m_pAPI->IsMetamodExtension())
|
||||
{
|
||||
/* :TODO: STUFF */
|
||||
bool already;
|
||||
m_PlId = g_pMMPlugins->Load(path, g_PLID, already, error, err_max);
|
||||
}
|
||||
|
||||
m_pIdentToken = g_ShareSys.CreateIdentity(g_ExtType);
|
||||
@ -53,7 +56,12 @@ CExtension::CExtension(const char *filename, char *error, size_t err_max)
|
||||
{
|
||||
if (m_pAPI->IsMetamodExtension())
|
||||
{
|
||||
/* :TODO: stuff */
|
||||
if (m_PlId)
|
||||
{
|
||||
char dummy[255];
|
||||
g_pMMPlugins->Unload(m_PlId, true, dummy, sizeof(dummy));
|
||||
m_PlId = 0;
|
||||
}
|
||||
}
|
||||
m_pAPI = NULL;
|
||||
m_pLib->CloseLibrary();
|
||||
@ -69,6 +77,10 @@ CExtension::~CExtension()
|
||||
if (m_pAPI)
|
||||
{
|
||||
m_pAPI->OnExtensionUnload();
|
||||
if (m_PlId)
|
||||
{
|
||||
g_pMMPlugins->Unload(m_PlId, true, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pIdentToken)
|
||||
@ -107,6 +119,81 @@ bool CExtension::IsLoaded()
|
||||
return (m_pLib != NULL);
|
||||
}
|
||||
|
||||
void CExtension::AddDependency(IfaceInfo *pInfo)
|
||||
{
|
||||
m_Deps.push_back(*pInfo);
|
||||
}
|
||||
|
||||
ITERATOR *CExtension::FindFirstDependency(IExtension **pOwner, SMInterface **pInterface)
|
||||
{
|
||||
List<IfaceInfo>::iterator iter = m_Deps.begin();
|
||||
|
||||
if (iter == m_Deps.end())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pOwner)
|
||||
{
|
||||
*pOwner = (*iter).owner;
|
||||
}
|
||||
if (pInterface)
|
||||
{
|
||||
*pInterface = (*iter).iface;
|
||||
}
|
||||
|
||||
List<IfaceInfo>::iterator *pIter = new List<IfaceInfo>::iterator(iter);
|
||||
|
||||
return (ITERATOR *)pIter;
|
||||
}
|
||||
|
||||
bool CExtension::FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface)
|
||||
{
|
||||
List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
|
||||
List<IfaceInfo>::iterator _iter;
|
||||
|
||||
if (_iter == m_Deps.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_iter++;
|
||||
|
||||
if (pOwner)
|
||||
{
|
||||
*pOwner = (*_iter).owner;
|
||||
}
|
||||
if (pInterface)
|
||||
{
|
||||
*pInterface = (*_iter).iface;
|
||||
}
|
||||
|
||||
*pIter = _iter;
|
||||
|
||||
if (_iter == m_Deps.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CExtension::FreeDependencyIterator(ITERATOR *iter)
|
||||
{
|
||||
List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
|
||||
|
||||
delete pIter;
|
||||
}
|
||||
|
||||
void CExtension::AddInterface(SMInterface *pInterface)
|
||||
{
|
||||
m_Interfaces.push_back(pInterface);
|
||||
}
|
||||
|
||||
/*********************
|
||||
* EXTENSION MANAGER *
|
||||
*********************/
|
||||
|
||||
void CExtensionManager::OnSourceModAllInitialized()
|
||||
{
|
||||
g_ExtType = g_ShareSys.CreateIdentType("EXTENSION");
|
||||
@ -119,6 +206,12 @@ void CExtensionManager::OnSourceModShutdown()
|
||||
|
||||
IExtension *CExtensionManager::LoadAutoExtension(const char *path)
|
||||
{
|
||||
IExtension *pAlready;
|
||||
if ((pAlready=FindExtensionByFile(path)) != NULL)
|
||||
{
|
||||
return pAlready;
|
||||
}
|
||||
|
||||
char error[256];
|
||||
CExtension *p = new CExtension(path, error, sizeof(error));
|
||||
|
||||
@ -188,6 +281,12 @@ IExtension *CExtensionManager::FindExtensionByName(const char *ext)
|
||||
|
||||
IExtension *CExtensionManager::LoadExtension(const char *file, ExtensionLifetime lifetime, char *error, size_t err_max)
|
||||
{
|
||||
IExtension *pAlready;
|
||||
if ((pAlready=FindExtensionByFile(file)) != NULL)
|
||||
{
|
||||
return pAlready;
|
||||
}
|
||||
|
||||
CExtension *pExt = new CExtension(file, error, err_max);
|
||||
|
||||
/* :NOTE: lifetime is currently ignored */
|
||||
@ -203,20 +302,80 @@ IExtension *CExtensionManager::LoadExtension(const char *file, ExtensionLifetime
|
||||
return pExt;
|
||||
}
|
||||
|
||||
bool CExtensionManager::UnloadExtension(IExtension *pExt)
|
||||
void CExtensionManager::BindDependency(IExtension *pOwner, IfaceInfo *pInfo)
|
||||
{
|
||||
/* :TODO: implement */
|
||||
return true;
|
||||
CExtension *pExt = (CExtension *)pOwner;
|
||||
|
||||
pExt->AddDependency(pInfo);
|
||||
}
|
||||
|
||||
unsigned int CExtensionManager::NumberOfPluginDependents(IExtension *pExt, unsigned int *optional)
|
||||
void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface)
|
||||
{
|
||||
/* :TODO: implement */
|
||||
return 0;
|
||||
CExtension *pExt = (CExtension *)pOwner;
|
||||
|
||||
pExt->AddInterface(pInterface);
|
||||
}
|
||||
|
||||
bool CExtensionManager::IsExtensionUnloadable(IExtension *pExtension)
|
||||
bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
||||
{
|
||||
/* :TODO: implement */
|
||||
if (!_pExt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CExtension *pExt = (CExtension *)_pExt;
|
||||
|
||||
if (m_Libs.find(pExt) == m_Libs.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* First remove us from internal lists */
|
||||
g_ShareSys.RemoveInterfaces(_pExt);
|
||||
m_Libs.remove(pExt);
|
||||
|
||||
List<CExtension *> UnloadQueue;
|
||||
|
||||
/* Handle dependencies */
|
||||
if (pExt->IsLoaded())
|
||||
{
|
||||
/* Notify and/or unload all dependencies */
|
||||
List<CExtension *>::iterator c_iter;
|
||||
CExtension *pDep;
|
||||
IExtensionInterface *pAPI;
|
||||
for (c_iter = m_Libs.begin(); c_iter != m_Libs.end(); c_iter++)
|
||||
{
|
||||
pDep = (*c_iter);
|
||||
if ((pAPI=pDep->GetAPI()) == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Now, get its dependency list */
|
||||
bool dropped = false;
|
||||
List<IfaceInfo>::iterator i_iter = pDep->m_Deps.begin();
|
||||
while (i_iter != pDep->m_Deps.end())
|
||||
{
|
||||
if ((*i_iter).owner == _pExt)
|
||||
{
|
||||
if (!dropped && !pAPI->QueryInterfaceDrop((*i_iter).iface))
|
||||
{
|
||||
dropped = true;
|
||||
}
|
||||
pAPI->NotifyInterfaceDrop((*i_iter).iface);
|
||||
i_iter = pDep->m_Deps.erase(i_iter);
|
||||
} else {
|
||||
i_iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<CExtension *>::iterator iter;
|
||||
for (iter=UnloadQueue.begin(); iter!=UnloadQueue.end(); iter++)
|
||||
{
|
||||
/* NOTE: This is safe because the unload function backs out of anything not present */
|
||||
UnloadExtension((*iter));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -6,12 +6,15 @@
|
||||
#include <sh_list.h>
|
||||
#include <sh_string.h>
|
||||
#include "sm_globals.h"
|
||||
#include "ShareSys.h"
|
||||
#include <ISmmAPI.h>
|
||||
|
||||
using namespace SourceMod;
|
||||
using namespace SourceHook;
|
||||
|
||||
class CExtension : public IExtension
|
||||
{
|
||||
friend class CExtensionManager;
|
||||
public:
|
||||
CExtension(const char *filename, char *error, size_t maxlen);
|
||||
~CExtension();
|
||||
@ -20,14 +23,22 @@ public: //IExtension
|
||||
const char *GetFilename();
|
||||
IdentityToken_t *GetIdentity();
|
||||
bool IsLoaded();
|
||||
ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface);
|
||||
bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface);
|
||||
void FreeDependencyIterator(ITERATOR *iter);
|
||||
public:
|
||||
void SetError(const char *error);
|
||||
void AddDependency(IfaceInfo *pInfo);
|
||||
void AddInterface(SMInterface *pInterface);
|
||||
private:
|
||||
IdentityToken_t *m_pIdentToken;
|
||||
IExtensionInterface *m_pAPI;
|
||||
String m_File;
|
||||
ILibrary *m_pLib;
|
||||
String m_Error;
|
||||
List<IfaceInfo> m_Deps;
|
||||
List<SMInterface *> m_Interfaces;
|
||||
PluginId m_PlId;
|
||||
};
|
||||
|
||||
class CExtensionManager :
|
||||
@ -42,13 +53,13 @@ public: //IExtensionManager
|
||||
ExtensionLifetime lifetime,
|
||||
char *error,
|
||||
size_t err_max);
|
||||
unsigned int NumberOfPluginDependents(IExtension *pExt, unsigned int *optional);
|
||||
bool IsExtensionUnloadable(IExtension *pExtension);
|
||||
bool UnloadExtension(IExtension *pExt);
|
||||
IExtension *FindExtensionByFile(const char *file);
|
||||
IExtension *FindExtensionByName(const char *ext);
|
||||
public:
|
||||
IExtension *LoadAutoExtension(const char *path);
|
||||
void BindDependency(IExtension *pOwner, IfaceInfo *pInfo);
|
||||
void AddInterface(IExtension *pOwner, SMInterface *pInterface);
|
||||
private:
|
||||
List<CExtension *> m_Libs;
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "ShareSys.h"
|
||||
#include "HandleSys.h"
|
||||
#include "ExtensionSys.h"
|
||||
|
||||
ShareSystem g_ShareSys;
|
||||
|
||||
@ -90,7 +91,7 @@ IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type)
|
||||
return pToken;
|
||||
}
|
||||
|
||||
bool ShareSystem::AddInterface(SMInterface *iface, IdentityToken_t *token)
|
||||
bool ShareSystem::AddInterface(IExtension *myself, SMInterface *iface)
|
||||
{
|
||||
if (!iface)
|
||||
{
|
||||
@ -99,16 +100,8 @@ bool ShareSystem::AddInterface(SMInterface *iface, IdentityToken_t *token)
|
||||
|
||||
IfaceInfo info;
|
||||
|
||||
info.owner = myself;
|
||||
info.iface = iface;
|
||||
info.token = token;
|
||||
|
||||
if (token)
|
||||
{
|
||||
/* If we're an external object, we have to do this */
|
||||
info.handle = g_HandleSys.CreateHandle(m_IfaceType, iface, token, GetIdentRoot(), NULL);
|
||||
} else {
|
||||
info.handle = 0;
|
||||
}
|
||||
|
||||
m_Interfaces.push_back(info);
|
||||
|
||||
@ -117,28 +110,13 @@ bool ShareSystem::AddInterface(SMInterface *iface, IdentityToken_t *token)
|
||||
|
||||
bool ShareSystem::RequestInterface(const char *iface_name,
|
||||
unsigned int iface_vers,
|
||||
IdentityToken_t *token,
|
||||
IExtension *mysql,
|
||||
SMInterface **pIface)
|
||||
{
|
||||
/* If Some yahoo.... SOME HOOLIGAN... some NO GOOD DIRTY
|
||||
* HORRIBLE PERSON passed in a token that we don't recognize....
|
||||
* <b>Punish them.</b>
|
||||
*/
|
||||
HandleSecurity sec;
|
||||
|
||||
sec.pIdentity = GetIdentRoot();
|
||||
sec.pOwner = NULL;
|
||||
|
||||
if (!g_HandleSys.ReadHandle(token->ident, m_TypeRoot, &sec, NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* See if the interface exists */
|
||||
List<IfaceInfo>::iterator iter;
|
||||
SMInterface *iface;
|
||||
IdentityToken_t *iface_owner;
|
||||
Handle_t iface_handle;
|
||||
IExtension *iface_owner;
|
||||
bool found = false;
|
||||
for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
|
||||
{
|
||||
@ -149,8 +127,7 @@ bool ShareSystem::RequestInterface(const char *iface_name,
|
||||
if (iface->GetInterfaceVersion() == iface_vers
|
||||
|| iface->IsVersionCompatible(iface_vers))
|
||||
{
|
||||
iface_owner = info.token;
|
||||
iface_handle = info.handle;
|
||||
iface_owner = info.owner;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -162,23 +139,21 @@ bool ShareSystem::RequestInterface(const char *iface_name,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If something external owns this, we need to track it. */
|
||||
/* Add a dependency node */
|
||||
if (iface_owner)
|
||||
{
|
||||
Handle_t newhandle;
|
||||
if (g_HandleSys.CloneHandle(iface_handle, &newhandle, token, &sec)
|
||||
!= HandleError_None)
|
||||
IfaceInfo info;
|
||||
info.iface = iface;
|
||||
info.owner = iface_owner;
|
||||
g_Extensions.BindDependency(iface_owner, &info);
|
||||
}
|
||||
|
||||
if (pIface)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Now we can deny module loads based on dependencies.
|
||||
*/
|
||||
*pIface = iface;
|
||||
}
|
||||
|
||||
/* :TODO: finish */
|
||||
|
||||
return NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShareSystem::AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[])
|
||||
@ -202,3 +177,17 @@ void ShareSystem::DestroyIdentType(IdentityType_t type)
|
||||
g_HandleSys.RemoveType(type, GetIdentRoot());
|
||||
}
|
||||
|
||||
void ShareSystem::RemoveInterfaces(IExtension *pExtension)
|
||||
{
|
||||
List<IfaceInfo>::iterator iter = m_Interfaces.begin();
|
||||
|
||||
while (iter != m_Interfaces.end())
|
||||
{
|
||||
if ((*iter).owner == pExtension)
|
||||
{
|
||||
iter = m_Interfaces.erase(iter);
|
||||
} else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,7 @@ namespace SourceMod
|
||||
struct IfaceInfo
|
||||
{
|
||||
SMInterface *iface;
|
||||
IdentityToken_t *token;
|
||||
Handle_t handle;
|
||||
IExtension *owner;
|
||||
};
|
||||
|
||||
class ShareSystem :
|
||||
@ -32,10 +31,10 @@ class ShareSystem :
|
||||
public:
|
||||
ShareSystem();
|
||||
public: //IShareSys
|
||||
bool AddInterface(SMInterface *iface, IdentityToken_t *token);
|
||||
bool AddInterface(IExtension *myself, SMInterface *pIface);
|
||||
bool RequestInterface(const char *iface_name,
|
||||
unsigned int iface_vers,
|
||||
IdentityToken_t *token,
|
||||
IExtension *mysql,
|
||||
SMInterface **pIface);
|
||||
void AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[]);
|
||||
IdentityType_t CreateIdentType(const char *name);
|
||||
@ -51,6 +50,7 @@ public: //IHandleTypeDispatch
|
||||
void OnHandleDestroy(HandleType_t type, void *object);
|
||||
public:
|
||||
IdentityToken_t *CreateCoreIdentity();
|
||||
void RemoveInterfaces(IExtension *pExtension);
|
||||
public:
|
||||
inline IdentityToken_t *GetIdentRoot()
|
||||
{
|
||||
|
@ -43,7 +43,7 @@
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
@ -60,6 +60,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\sample.ext.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
@ -116,7 +117,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="2"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
@ -133,6 +134,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\sample.ext.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
@ -193,7 +195,7 @@
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SMEXT_CONF_METAMOD"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
@ -211,6 +213,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="tier0.lib"
|
||||
OutputFile="$(OutDir)\sample.ext.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
@ -267,7 +270,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SMEXT_CONF_METAMOD"
|
||||
RuntimeLibrary="2"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
@ -284,6 +287,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\sample.ext.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "smsdk_ext.h"
|
||||
|
||||
IShareSys *g_pShareSys = NULL;
|
||||
IdentityToken_t *myself = NULL;
|
||||
IExtension *myself = NULL;
|
||||
IHandleSys *g_pHandleSys = NULL;
|
||||
|
||||
PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
|
||||
@ -22,7 +22,9 @@ SDKExtension::SDKExtension()
|
||||
bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t err_max, bool late)
|
||||
{
|
||||
g_pShareSys = sys;
|
||||
myself = me->GetIdentity();
|
||||
myself = me;
|
||||
|
||||
m_WeAreUnloaded = true;
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
if (!m_SourceMMLoaded)
|
||||
@ -37,7 +39,13 @@ bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error,
|
||||
|
||||
SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys);
|
||||
|
||||
return SDK_OnLoad(error, err_max, late);
|
||||
if (SDK_OnLoad(error, err_max, late))
|
||||
{
|
||||
m_WeAreUnloaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SDKExtension::IsMetamodExtension()
|
||||
@ -51,7 +59,9 @@ bool SDKExtension::IsMetamodExtension()
|
||||
|
||||
void SDKExtension::OnExtensionPauseChange(bool state)
|
||||
{
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
m_WeGotPauseChange = true;
|
||||
#endif
|
||||
SDK_OnPauseChange(state);
|
||||
}
|
||||
|
||||
@ -62,7 +72,9 @@ void SDKExtension::OnExtensionsAllLoaded()
|
||||
|
||||
void SDKExtension::OnExtensionUnload()
|
||||
{
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
m_WeAreUnloaded = true;
|
||||
#endif
|
||||
SDK_OnUnload();
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ private:
|
||||
extern SDKExtension *g_pExtensionIface;
|
||||
|
||||
extern IShareSys *g_pShareSys;
|
||||
extern IdentityToken_t *myself;
|
||||
extern IExtension *myself;
|
||||
extern IHandleSys *g_pHandleSys;
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
|
Loading…
Reference in New Issue
Block a user