1.1 --- a/core/interfaces/IExtensionSys.h Tue Jan 16 20:45:13 2007 +0000
1.2 +++ b/core/interfaces/IExtensionSys.h Wed Jan 17 03:01:38 2007 +0000
1.3 @@ -7,6 +7,7 @@
1.4 namespace SourceMod
1.5 {
1.6 class IExtensionInterface;
1.7 + typedef void * ITERATOR;
1.8
1.9 /**
1.10 * @brief Encapsulates an IExtension.
1.11 @@ -40,6 +41,32 @@
1.12 * @return An IdentityToken_t pointer.
1.13 */
1.14 virtual IdentityToken_t *GetIdentity() =0;
1.15 +
1.16 + /**
1.17 + * @brief Retrieves the extension dependency list for this extension.
1.18 + *
1.19 + * @param pOwner Optional pointer to store the first interface's owner.
1.20 + * @param pInterface Optional pointer to store the first interface.
1.21 + * @return An ITERATOR pointer for the results, or NULL if no results at all.
1.22 + */
1.23 + virtual ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface) =0;
1.24 +
1.25 + /**
1.26 + * @brief Finds the next dependency in the dependency list.
1.27 + *
1.28 + * @param iter Pointer to iterator from FindFirstDependency.
1.29 + * @param pOwner Optional pointer to store the interface's owner.
1.30 + * @param pInterface Optional pointer to store the interface.
1.31 + * @return True if there are more results after this, false otherwise.
1.32 + */
1.33 + virtual bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface) =0;
1.34 +
1.35 + /**
1.36 + * @brief Frees an ITERATOR handle from FindFirstDependency.
1.37 + *
1.38 + * @param iter Pointer to iterator to free.
1.39 + */
1.40 + virtual void FreeDependencyIterator(ITERATOR *iter) =0;
1.41 };
1.42
1.43 #define SMINTERFACE_EXTENSIONAPI_VERSION 1
1.44 @@ -50,6 +77,11 @@
1.45 class IExtensionInterface
1.46 {
1.47 public:
1.48 + virtual unsigned int GetExtensionVersion()
1.49 + {
1.50 + return SMINTERFACE_EXTENSIONAPI_VERSION;
1.51 + }
1.52 + public:
1.53 /**
1.54 * @brief Called when the extension is loaded.
1.55 *
1.56 @@ -84,16 +116,29 @@
1.57 */
1.58 virtual void OnExtensionPauseChange(bool pause) =0;
1.59
1.60 - virtual unsigned int GetExtensionVersion()
1.61 + /**
1.62 + * @brief Asks the extension whether it's safe to remove an external interface it's using.
1.63 + * If it's not safe, return false, and the extension will be unloaded afterwards.
1.64 + * NOTE: It is important to also hook NotifyInterfaceDrop() in order to clean up resources.
1.65 + *
1.66 + * @param pInterface Pointer to interface being dropped.
1.67 + * @return True to continue, false to unload this extension afterwards.
1.68 + */
1.69 + virtual bool QueryInterfaceDrop(SMInterface *pInterface)
1.70 {
1.71 - return SMINTERFACE_EXTENSIONAPI_VERSION;
1.72 + return true;
1.73 }
1.74
1.75 /**
1.76 - * @brief Returns true if the extension is Metamod-dependent.
1.77 + * @brief Notifies the extension that an external interface it uses is being removed.
1.78 + *
1.79 + * @param pInterface Pointer to interface being dropped.
1.80 */
1.81 + virtual void NotifyInterfaceDrop(SMInterface *pInterface)
1.82 + {
1.83 + }
1.84 + public:
1.85 virtual bool IsMetamodExtension() =0;
1.86 - public:
1.87 virtual const char *GetExtensionName() =0;
1.88 virtual const char *GetExtensionURL() =0;
1.89 virtual const char *GetExtensionTag() =0;
1.90 @@ -139,25 +184,6 @@
1.91 size_t err_max) =0;
1.92
1.93 /**
1.94 - * @brief Returns the number of plugins that will be unloaded when this
1.95 - * module is unloaded.
1.96 - *
1.97 - * @param pExt IExtension pointer.
1.98 - * @param optional Optional pointer to be filled with # of plugins that
1.99 - * are dependent, but will continue safely. NOT YET USED.
1.100 - * @return Total number of dependent plugins.
1.101 - */
1.102 - virtual unsigned int NumberOfPluginDependents(IExtension *pExt, unsigned int *optional) =0;
1.103 -
1.104 - /**
1.105 - * @brief Returns whether or not the extension can be unloaded.
1.106 - *
1.107 - * @param pExt IExtension pointer.
1.108 - * @return True if unloading is possible, false otherwise.
1.109 - */
1.110 - virtual bool IsExtensionUnloadable(IExtension *pExtension) =0;
1.111 -
1.112 - /**
1.113 * @brief Attempts to unload a module.
1.114 *
1.115 * @param pExt IExtension pointer.
2.1 --- a/core/interfaces/IShareSys.h Tue Jan 16 20:45:13 2007 +0000
2.2 +++ b/core/interfaces/IShareSys.h Wed Jan 17 03:01:38 2007 +0000
2.3 @@ -7,6 +7,7 @@
2.4
2.5 namespace SourceMod
2.6 {
2.7 + class IExtension;
2.8 struct IdentityToken_t;
2.9 typedef unsigned int HandleType_t;
2.10 typedef HandleType_t IdentityType_t;
2.11 @@ -53,11 +54,11 @@
2.12 /**
2.13 * @brief Adds an interface to the global interface system.
2.14 *
2.15 + * @param myself Object adding this interface, in order to track dependencies.
2.16 * @param iface Interface pointer (must be unique).
2.17 - * @param token Parent token of the module/interface.
2.18 * @return True on success, false otherwise.
2.19 */
2.20 - virtual bool AddInterface(SMInterface *iface, IdentityToken_t *token) =0;
2.21 + virtual bool AddInterface(IExtension *myself, SMInterface *iface) =0;
2.22
2.23 /**
2.24 * @brief Requests an interface from the global interface system.
2.25 @@ -65,12 +66,12 @@
2.26 *
2.27 * @param iface_name Interface name.
2.28 * @param iface_vers Interface version to attempt to match.
2.29 - * @param token Object requesting this interface, in order to track dependencies.
2.30 + * @param myself Object requesting this interface, in order to track dependencies.
2.31 * @param pIface Pointer to store the return value in.
2.32 */
2.33 virtual bool RequestInterface(const char *iface_name,
2.34 unsigned int iface_vers,
2.35 - IdentityToken_t *token,
2.36 + IExtension *myself,
2.37 SMInterface **pIface) =0;
2.38
2.39 /**
3.1 --- a/core/sourcemm_api.cpp Tue Jan 16 20:45:13 2007 +0000
3.2 +++ b/core/sourcemm_api.cpp Wed Jan 17 03:01:38 2007 +0000
3.3 @@ -7,6 +7,7 @@
3.4 IVEngineServer *engine = NULL;
3.5 IServerGameDLL *gamedll = NULL;
3.6 IServerGameClients *serverClients = NULL;
3.7 +ISmmPluginManager *g_pMMPlugins = NULL;
3.8
3.9 PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core);
3.10
3.11 @@ -18,6 +19,15 @@
3.12 GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
3.13 GET_V_IFACE_CURRENT(serverFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS);
3.14
3.15 + if ((g_pMMPlugins = (ISmmPluginManager *)g_SMAPI->MetaFactory(MMIFACE_PLMANAGER, NULL, NULL)) == NULL)
3.16 + {
3.17 + if (error)
3.18 + {
3.19 + snprintf(error, maxlen, "Unable to find interface %s", MMIFACE_PLMANAGER);
3.20 + }
3.21 + return false;
3.22 + }
3.23 +
3.24 return g_SourceMod.InitializeSourceMod(error, maxlen, late);
3.25 }
3.26
4.1 --- a/core/sourcemm_api.h Tue Jan 16 20:45:13 2007 +0000
4.2 +++ b/core/sourcemm_api.h Wed Jan 17 03:01:38 2007 +0000
4.3 @@ -31,6 +31,7 @@
4.4 extern IVEngineServer *engine;
4.5 extern IServerGameDLL *gamedll;
4.6 extern IServerGameClients *serverClients;
4.7 +extern ISmmPluginManager *g_pMMPlugins;
4.8
4.9 PLUGIN_GLOBALVARS();
4.10
5.1 --- a/core/systems/ExtensionSys.cpp Tue Jan 16 20:45:13 2007 +0000
5.2 +++ b/core/systems/ExtensionSys.cpp Wed Jan 17 03:01:38 2007 +0000
5.3 @@ -2,6 +2,7 @@
5.4 #include "LibrarySys.h"
5.5 #include "ShareSys.h"
5.6 #include "CLogger.h"
5.7 +#include "sourcemm_api.h"
5.8
5.9 CExtensionManager g_Extensions;
5.10 IdentityType_t g_ExtType;
5.11 @@ -11,6 +12,7 @@
5.12 m_File.assign(filename);
5.13 m_pAPI = NULL;
5.14 m_pIdentToken = NULL;
5.15 + m_PlId = 0;
5.16
5.17 char path[PLATFORM_MAX_PATH+1];
5.18 g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s/extensions/%s", g_SourceMod.GetSMBaseDir(), filename);
5.19 @@ -44,7 +46,8 @@
5.20
5.21 if (m_pAPI->IsMetamodExtension())
5.22 {
5.23 - /* :TODO: STUFF */
5.24 + bool already;
5.25 + m_PlId = g_pMMPlugins->Load(path, g_PLID, already, error, err_max);
5.26 }
5.27
5.28 m_pIdentToken = g_ShareSys.CreateIdentity(g_ExtType);
5.29 @@ -53,7 +56,12 @@
5.30 {
5.31 if (m_pAPI->IsMetamodExtension())
5.32 {
5.33 - /* :TODO: stuff */
5.34 + if (m_PlId)
5.35 + {
5.36 + char dummy[255];
5.37 + g_pMMPlugins->Unload(m_PlId, true, dummy, sizeof(dummy));
5.38 + m_PlId = 0;
5.39 + }
5.40 }
5.41 m_pAPI = NULL;
5.42 m_pLib->CloseLibrary();
5.43 @@ -69,6 +77,10 @@
5.44 if (m_pAPI)
5.45 {
5.46 m_pAPI->OnExtensionUnload();
5.47 + if (m_PlId)
5.48 + {
5.49 + g_pMMPlugins->Unload(m_PlId, true, NULL, 0);
5.50 + }
5.51 }
5.52
5.53 if (m_pIdentToken)
5.54 @@ -107,6 +119,81 @@
5.55 return (m_pLib != NULL);
5.56 }
5.57
5.58 +void CExtension::AddDependency(IfaceInfo *pInfo)
5.59 +{
5.60 + m_Deps.push_back(*pInfo);
5.61 +}
5.62 +
5.63 +ITERATOR *CExtension::FindFirstDependency(IExtension **pOwner, SMInterface **pInterface)
5.64 +{
5.65 + List<IfaceInfo>::iterator iter = m_Deps.begin();
5.66 +
5.67 + if (iter == m_Deps.end())
5.68 + {
5.69 + return NULL;
5.70 + }
5.71 +
5.72 + if (pOwner)
5.73 + {
5.74 + *pOwner = (*iter).owner;
5.75 + }
5.76 + if (pInterface)
5.77 + {
5.78 + *pInterface = (*iter).iface;
5.79 + }
5.80 +
5.81 + List<IfaceInfo>::iterator *pIter = new List<IfaceInfo>::iterator(iter);
5.82 +
5.83 + return (ITERATOR *)pIter;
5.84 +}
5.85 +
5.86 +bool CExtension::FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface)
5.87 +{
5.88 + List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
5.89 + List<IfaceInfo>::iterator _iter;
5.90 +
5.91 + if (_iter == m_Deps.end())
5.92 + {
5.93 + return false;
5.94 + }
5.95 +
5.96 + _iter++;
5.97 +
5.98 + if (pOwner)
5.99 + {
5.100 + *pOwner = (*_iter).owner;
5.101 + }
5.102 + if (pInterface)
5.103 + {
5.104 + *pInterface = (*_iter).iface;
5.105 + }
5.106 +
5.107 + *pIter = _iter;
5.108 +
5.109 + if (_iter == m_Deps.end())
5.110 + {
5.111 + return false;
5.112 + }
5.113 +
5.114 + return true;
5.115 +}
5.116 +
5.117 +void CExtension::FreeDependencyIterator(ITERATOR *iter)
5.118 +{
5.119 + List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
5.120 +
5.121 + delete pIter;
5.122 +}
5.123 +
5.124 +void CExtension::AddInterface(SMInterface *pInterface)
5.125 +{
5.126 + m_Interfaces.push_back(pInterface);
5.127 +}
5.128 +
5.129 +/*********************
5.130 + * EXTENSION MANAGER *
5.131 + *********************/
5.132 +
5.133 void CExtensionManager::OnSourceModAllInitialized()
5.134 {
5.135 g_ExtType = g_ShareSys.CreateIdentType("EXTENSION");
5.136 @@ -119,6 +206,12 @@
5.137
5.138 IExtension *CExtensionManager::LoadAutoExtension(const char *path)
5.139 {
5.140 + IExtension *pAlready;
5.141 + if ((pAlready=FindExtensionByFile(path)) != NULL)
5.142 + {
5.143 + return pAlready;
5.144 + }
5.145 +
5.146 char error[256];
5.147 CExtension *p = new CExtension(path, error, sizeof(error));
5.148
5.149 @@ -188,6 +281,12 @@
5.150
5.151 IExtension *CExtensionManager::LoadExtension(const char *file, ExtensionLifetime lifetime, char *error, size_t err_max)
5.152 {
5.153 + IExtension *pAlready;
5.154 + if ((pAlready=FindExtensionByFile(file)) != NULL)
5.155 + {
5.156 + return pAlready;
5.157 + }
5.158 +
5.159 CExtension *pExt = new CExtension(file, error, err_max);
5.160
5.161 /* :NOTE: lifetime is currently ignored */
5.162 @@ -203,20 +302,80 @@
5.163 return pExt;
5.164 }
5.165
5.166 -bool CExtensionManager::UnloadExtension(IExtension *pExt)
5.167 +void CExtensionManager::BindDependency(IExtension *pOwner, IfaceInfo *pInfo)
5.168 {
5.169 - /* :TODO: implement */
5.170 - return true;
5.171 + CExtension *pExt = (CExtension *)pOwner;
5.172 +
5.173 + pExt->AddDependency(pInfo);
5.174 +}
5.175 +
5.176 +void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface)
5.177 +{
5.178 + CExtension *pExt = (CExtension *)pOwner;
5.179 +
5.180 + pExt->AddInterface(pInterface);
5.181 }
5.182
5.183 -unsigned int CExtensionManager::NumberOfPluginDependents(IExtension *pExt, unsigned int *optional)
5.184 +bool CExtensionManager::UnloadExtension(IExtension *_pExt)
5.185 {
5.186 - /* :TODO: implement */
5.187 - return 0;
5.188 -}
5.189 + if (!_pExt)
5.190 + {
5.191 + return false;
5.192 + }
5.193 +
5.194 + CExtension *pExt = (CExtension *)_pExt;
5.195 +
5.196 + if (m_Libs.find(pExt) == m_Libs.end())
5.197 + {
5.198 + return false;
5.199 + }
5.200 +
5.201 + /* First remove us from internal lists */
5.202 + g_ShareSys.RemoveInterfaces(_pExt);
5.203 + m_Libs.remove(pExt);
5.204 +
5.205 + List<CExtension *> UnloadQueue;
5.206
5.207 -bool CExtensionManager::IsExtensionUnloadable(IExtension *pExtension)
5.208 -{
5.209 - /* :TODO: implement */
5.210 + /* Handle dependencies */
5.211 + if (pExt->IsLoaded())
5.212 + {
5.213 + /* Notify and/or unload all dependencies */
5.214 + List<CExtension *>::iterator c_iter;
5.215 + CExtension *pDep;
5.216 + IExtensionInterface *pAPI;
5.217 + for (c_iter = m_Libs.begin(); c_iter != m_Libs.end(); c_iter++)
5.218 + {
5.219 + pDep = (*c_iter);
5.220 + if ((pAPI=pDep->GetAPI()) == NULL)
5.221 + {
5.222 + continue;
5.223 + }
5.224 + /* Now, get its dependency list */
5.225 + bool dropped = false;
5.226 + List<IfaceInfo>::iterator i_iter = pDep->m_Deps.begin();
5.227 + while (i_iter != pDep->m_Deps.end())
5.228 + {
5.229 + if ((*i_iter).owner == _pExt)
5.230 + {
5.231 + if (!dropped && !pAPI->QueryInterfaceDrop((*i_iter).iface))
5.232 + {
5.233 + dropped = true;
5.234 + }
5.235 + pAPI->NotifyInterfaceDrop((*i_iter).iface);
5.236 + i_iter = pDep->m_Deps.erase(i_iter);
5.237 + } else {
5.238 + i_iter++;
5.239 + }
5.240 + }
5.241 + }
5.242 + }
5.243 +
5.244 + List<CExtension *>::iterator iter;
5.245 + for (iter=UnloadQueue.begin(); iter!=UnloadQueue.end(); iter++)
5.246 + {
5.247 + /* NOTE: This is safe because the unload function backs out of anything not present */
5.248 + UnloadExtension((*iter));
5.249 + }
5.250 +
5.251 return true;
5.252 }
6.1 --- a/core/systems/ExtensionSys.h Tue Jan 16 20:45:13 2007 +0000
6.2 +++ b/core/systems/ExtensionSys.h Wed Jan 17 03:01:38 2007 +0000
6.3 @@ -6,12 +6,15 @@
6.4 #include <sh_list.h>
6.5 #include <sh_string.h>
6.6 #include "sm_globals.h"
6.7 +#include "ShareSys.h"
6.8 +#include <ISmmAPI.h>
6.9
6.10 using namespace SourceMod;
6.11 using namespace SourceHook;
6.12
6.13 class CExtension : public IExtension
6.14 {
6.15 + friend class CExtensionManager;
6.16 public:
6.17 CExtension(const char *filename, char *error, size_t maxlen);
6.18 ~CExtension();
6.19 @@ -20,14 +23,22 @@
6.20 const char *GetFilename();
6.21 IdentityToken_t *GetIdentity();
6.22 bool IsLoaded();
6.23 + ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface);
6.24 + bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface);
6.25 + void FreeDependencyIterator(ITERATOR *iter);
6.26 public:
6.27 void SetError(const char *error);
6.28 + void AddDependency(IfaceInfo *pInfo);
6.29 + void AddInterface(SMInterface *pInterface);
6.30 private:
6.31 IdentityToken_t *m_pIdentToken;
6.32 IExtensionInterface *m_pAPI;
6.33 String m_File;
6.34 ILibrary *m_pLib;
6.35 String m_Error;
6.36 + List<IfaceInfo> m_Deps;
6.37 + List<SMInterface *> m_Interfaces;
6.38 + PluginId m_PlId;
6.39 };
6.40
6.41 class CExtensionManager :
6.42 @@ -42,13 +53,13 @@
6.43 ExtensionLifetime lifetime,
6.44 char *error,
6.45 size_t err_max);
6.46 - unsigned int NumberOfPluginDependents(IExtension *pExt, unsigned int *optional);
6.47 - bool IsExtensionUnloadable(IExtension *pExtension);
6.48 bool UnloadExtension(IExtension *pExt);
6.49 IExtension *FindExtensionByFile(const char *file);
6.50 IExtension *FindExtensionByName(const char *ext);
6.51 public:
6.52 IExtension *LoadAutoExtension(const char *path);
6.53 + void BindDependency(IExtension *pOwner, IfaceInfo *pInfo);
6.54 + void AddInterface(IExtension *pOwner, SMInterface *pInterface);
6.55 private:
6.56 List<CExtension *> m_Libs;
6.57 };
7.1 --- a/core/systems/ShareSys.cpp Tue Jan 16 20:45:13 2007 +0000
7.2 +++ b/core/systems/ShareSys.cpp Wed Jan 17 03:01:38 2007 +0000
7.3 @@ -1,5 +1,6 @@
7.4 #include "ShareSys.h"
7.5 #include "HandleSys.h"
7.6 +#include "ExtensionSys.h"
7.7
7.8 ShareSystem g_ShareSys;
7.9
7.10 @@ -90,7 +91,7 @@
7.11 return pToken;
7.12 }
7.13
7.14 -bool ShareSystem::AddInterface(SMInterface *iface, IdentityToken_t *token)
7.15 +bool ShareSystem::AddInterface(IExtension *myself, SMInterface *iface)
7.16 {
7.17 if (!iface)
7.18 {
7.19 @@ -99,17 +100,9 @@
7.20
7.21 IfaceInfo info;
7.22
7.23 + info.owner = myself;
7.24 info.iface = iface;
7.25 - info.token = token;
7.26
7.27 - if (token)
7.28 - {
7.29 - /* If we're an external object, we have to do this */
7.30 - info.handle = g_HandleSys.CreateHandle(m_IfaceType, iface, token, GetIdentRoot(), NULL);
7.31 - } else {
7.32 - info.handle = 0;
7.33 - }
7.34 -
7.35 m_Interfaces.push_back(info);
7.36
7.37 return true;
7.38 @@ -117,28 +110,13 @@
7.39
7.40 bool ShareSystem::RequestInterface(const char *iface_name,
7.41 unsigned int iface_vers,
7.42 - IdentityToken_t *token,
7.43 + IExtension *mysql,
7.44 SMInterface **pIface)
7.45 {
7.46 - /* If Some yahoo.... SOME HOOLIGAN... some NO GOOD DIRTY
7.47 - * HORRIBLE PERSON passed in a token that we don't recognize....
7.48 - * <b>Punish them.</b>
7.49 - */
7.50 - HandleSecurity sec;
7.51 -
7.52 - sec.pIdentity = GetIdentRoot();
7.53 - sec.pOwner = NULL;
7.54 -
7.55 - if (!g_HandleSys.ReadHandle(token->ident, m_TypeRoot, &sec, NULL))
7.56 - {
7.57 - return false;
7.58 - }
7.59 -
7.60 /* See if the interface exists */
7.61 List<IfaceInfo>::iterator iter;
7.62 SMInterface *iface;
7.63 - IdentityToken_t *iface_owner;
7.64 - Handle_t iface_handle;
7.65 + IExtension *iface_owner;
7.66 bool found = false;
7.67 for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
7.68 {
7.69 @@ -149,8 +127,7 @@
7.70 if (iface->GetInterfaceVersion() == iface_vers
7.71 || iface->IsVersionCompatible(iface_vers))
7.72 {
7.73 - iface_owner = info.token;
7.74 - iface_handle = info.handle;
7.75 + iface_owner = info.owner;
7.76 found = true;
7.77 break;
7.78 }
7.79 @@ -162,23 +139,21 @@
7.80 return false;
7.81 }
7.82
7.83 - /* If something external owns this, we need to track it. */
7.84 + /* Add a dependency node */
7.85 if (iface_owner)
7.86 {
7.87 - Handle_t newhandle;
7.88 - if (g_HandleSys.CloneHandle(iface_handle, &newhandle, token, &sec)
7.89 - != HandleError_None)
7.90 - {
7.91 - return false;
7.92 - }
7.93 - /**
7.94 - * Now we can deny module loads based on dependencies.
7.95 - */
7.96 + IfaceInfo info;
7.97 + info.iface = iface;
7.98 + info.owner = iface_owner;
7.99 + g_Extensions.BindDependency(iface_owner, &info);
7.100 }
7.101
7.102 - /* :TODO: finish */
7.103 + if (pIface)
7.104 + {
7.105 + *pIface = iface;
7.106 + }
7.107
7.108 - return NULL;
7.109 + return true;
7.110 }
7.111
7.112 void ShareSystem::AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[])
7.113 @@ -202,3 +177,17 @@
7.114 g_HandleSys.RemoveType(type, GetIdentRoot());
7.115 }
7.116
7.117 +void ShareSystem::RemoveInterfaces(IExtension *pExtension)
7.118 +{
7.119 + List<IfaceInfo>::iterator iter = m_Interfaces.begin();
7.120 +
7.121 + while (iter != m_Interfaces.end())
7.122 + {
7.123 + if ((*iter).owner == pExtension)
7.124 + {
7.125 + iter = m_Interfaces.erase(iter);
7.126 + } else {
7.127 + iter++;
7.128 + }
7.129 + }
7.130 +}
8.1 --- a/core/systems/ShareSys.h Tue Jan 16 20:45:13 2007 +0000
8.2 +++ b/core/systems/ShareSys.h Wed Jan 17 03:01:38 2007 +0000
8.3 @@ -20,8 +20,7 @@
8.4 struct IfaceInfo
8.5 {
8.6 SMInterface *iface;
8.7 - IdentityToken_t *token;
8.8 - Handle_t handle;
8.9 + IExtension *owner;
8.10 };
8.11
8.12 class ShareSystem :
8.13 @@ -32,10 +31,10 @@
8.14 public:
8.15 ShareSystem();
8.16 public: //IShareSys
8.17 - bool AddInterface(SMInterface *iface, IdentityToken_t *token);
8.18 + bool AddInterface(IExtension *myself, SMInterface *pIface);
8.19 bool RequestInterface(const char *iface_name,
8.20 unsigned int iface_vers,
8.21 - IdentityToken_t *token,
8.22 + IExtension *mysql,
8.23 SMInterface **pIface);
8.24 void AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[]);
8.25 IdentityType_t CreateIdentType(const char *name);
8.26 @@ -51,6 +50,7 @@
8.27 void OnHandleDestroy(HandleType_t type, void *object);
8.28 public:
8.29 IdentityToken_t *CreateCoreIdentity();
8.30 + void RemoveInterfaces(IExtension *pExtension);
8.31 public:
8.32 inline IdentityToken_t *GetIdentRoot()
8.33 {
9.1 --- a/extensions/sdk/sdk.vcproj Tue Jan 16 20:45:13 2007 +0000
9.2 +++ b/extensions/sdk/sdk.vcproj Wed Jan 17 03:01:38 2007 +0000
9.3 @@ -43,7 +43,7 @@
9.4 PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
9.5 MinimalRebuild="true"
9.6 BasicRuntimeChecks="3"
9.7 - RuntimeLibrary="3"
9.8 + RuntimeLibrary="1"
9.9 UsePrecompiledHeader="0"
9.10 WarningLevel="3"
9.11 Detect64BitPortabilityProblems="true"
9.12 @@ -60,6 +60,7 @@
9.13 />
9.14 <Tool
9.15 Name="VCLinkerTool"
9.16 + OutputFile="$(OutDir)\sample.ext.dll"
9.17 LinkIncremental="2"
9.18 GenerateDebugInformation="true"
9.19 SubSystem="2"
9.20 @@ -116,7 +117,7 @@
9.21 <Tool
9.22 Name="VCCLCompilerTool"
9.23 PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
9.24 - RuntimeLibrary="2"
9.25 + RuntimeLibrary="0"
9.26 UsePrecompiledHeader="0"
9.27 WarningLevel="3"
9.28 Detect64BitPortabilityProblems="true"
9.29 @@ -133,6 +134,7 @@
9.30 />
9.31 <Tool
9.32 Name="VCLinkerTool"
9.33 + OutputFile="$(OutDir)\sample.ext.dll"
9.34 LinkIncremental="1"
9.35 GenerateDebugInformation="true"
9.36 SubSystem="2"
9.37 @@ -193,7 +195,7 @@
9.38 PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SMEXT_CONF_METAMOD"
9.39 MinimalRebuild="true"
9.40 BasicRuntimeChecks="3"
9.41 - RuntimeLibrary="3"
9.42 + RuntimeLibrary="1"
9.43 UsePrecompiledHeader="0"
9.44 WarningLevel="3"
9.45 Detect64BitPortabilityProblems="true"
9.46 @@ -211,6 +213,7 @@
9.47 <Tool
9.48 Name="VCLinkerTool"
9.49 AdditionalDependencies="tier0.lib"
9.50 + OutputFile="$(OutDir)\sample.ext.dll"
9.51 LinkIncremental="2"
9.52 GenerateDebugInformation="true"
9.53 SubSystem="2"
9.54 @@ -267,7 +270,7 @@
9.55 <Tool
9.56 Name="VCCLCompilerTool"
9.57 PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SDK_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SMEXT_CONF_METAMOD"
9.58 - RuntimeLibrary="2"
9.59 + RuntimeLibrary="0"
9.60 UsePrecompiledHeader="0"
9.61 WarningLevel="3"
9.62 Detect64BitPortabilityProblems="true"
9.63 @@ -284,6 +287,7 @@
9.64 />
9.65 <Tool
9.66 Name="VCLinkerTool"
9.67 + OutputFile="$(OutDir)\sample.ext.dll"
9.68 LinkIncremental="1"
9.69 GenerateDebugInformation="true"
9.70 SubSystem="2"
10.1 --- a/extensions/sdk/smsdk_ext.cpp Tue Jan 16 20:45:13 2007 +0000
10.2 +++ b/extensions/sdk/smsdk_ext.cpp Wed Jan 17 03:01:38 2007 +0000
10.3 @@ -2,7 +2,7 @@
10.4 #include "smsdk_ext.h"
10.5
10.6 IShareSys *g_pShareSys = NULL;
10.7 -IdentityToken_t *myself = NULL;
10.8 +IExtension *myself = NULL;
10.9 IHandleSys *g_pHandleSys = NULL;
10.10
10.11 PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
10.12 @@ -22,7 +22,9 @@
10.13 bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t err_max, bool late)
10.14 {
10.15 g_pShareSys = sys;
10.16 - myself = me->GetIdentity();
10.17 + myself = me;
10.18 +
10.19 + m_WeAreUnloaded = true;
10.20
10.21 #if defined SMEXT_CONF_METAMOD
10.22 if (!m_SourceMMLoaded)
10.23 @@ -37,7 +39,13 @@
10.24
10.25 SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys);
10.26
10.27 - return SDK_OnLoad(error, err_max, late);
10.28 + if (SDK_OnLoad(error, err_max, late))
10.29 + {
10.30 + m_WeAreUnloaded = true;
10.31 + return true;
10.32 + }
10.33 +
10.34 + return false;
10.35 }
10.36
10.37 bool SDKExtension::IsMetamodExtension()
10.38 @@ -51,7 +59,9 @@
10.39
10.40 void SDKExtension::OnExtensionPauseChange(bool state)
10.41 {
10.42 +#if defined SMEXT_CONF_METAMOD
10.43 m_WeGotPauseChange = true;
10.44 +#endif
10.45 SDK_OnPauseChange(state);
10.46 }
10.47
10.48 @@ -62,7 +72,9 @@
10.49
10.50 void SDKExtension::OnExtensionUnload()
10.51 {
10.52 +#if defined SMEXT_CONF_METAMOD
10.53 m_WeAreUnloaded = true;
10.54 +#endif
10.55 SDK_OnUnload();
10.56 }
10.57
11.1 --- a/extensions/sdk/smsdk_ext.h Tue Jan 16 20:45:13 2007 +0000
11.2 +++ b/extensions/sdk/smsdk_ext.h Wed Jan 17 03:01:38 2007 +0000
11.3 @@ -118,7 +118,7 @@
11.4 extern SDKExtension *g_pExtensionIface;
11.5
11.6 extern IShareSys *g_pShareSys;
11.7 -extern IdentityToken_t *myself;
11.8 +extern IExtension *myself;
11.9 extern IHandleSys *g_pHandleSys;
11.10
11.11 #if defined SMEXT_CONF_METAMOD