diff --git a/core/Database.cpp b/core/Database.cpp index 4b9e4294..294f8c51 100644 --- a/core/Database.cpp +++ b/core/Database.cpp @@ -717,3 +717,9 @@ const char *DBManager::GetDefaultDriverName() { return m_DefDriver.c_str(); } + +void DBManager::AddDependency(IExtension *myself, IDBDriver *driver) +{ + g_Extensions.AddRawDependency(myself, driver->GetIdentity(), driver); +} + diff --git a/core/Database.h b/core/Database.h index 505842a3..67382967 100644 --- a/core/Database.h +++ b/core/Database.h @@ -92,6 +92,7 @@ public: //IDBManager Handle_t CreateHandle(DBHandleType type, void *ptr, IdentityToken_t *pToken); HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr); HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token); + void AddDependency(IExtension *myself, IDBDriver *driver); public: //ITextListener_SMC void ReadSMC_ParseStart(); SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); diff --git a/core/systems/ExtensionSys.cpp b/core/systems/ExtensionSys.cpp index 14229452..af9c47d2 100644 --- a/core/systems/ExtensionSys.cpp +++ b/core/systems/ExtensionSys.cpp @@ -305,7 +305,7 @@ bool CLocalExtension::IsLoaded() return (m_pLib != NULL); } -void CExtension::AddDependency(IfaceInfo *pInfo) +void CExtension::AddDependency(const IfaceInfo *pInfo) { if (m_Deps.find(*pInfo) == m_Deps.end()) { @@ -633,6 +633,20 @@ void CExtensionManager::BindDependency(IExtension *pRequester, IfaceInfo *pInfo) } } +void CExtensionManager::AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface) +{ + CExtension *pExt = (CExtension *)ext; + CExtension *pOwner = GetExtensionFromIdent(other); + + IfaceInfo info; + + info.iface = (SMInterface *)iface; + info.owner = pOwner; + + pExt->AddDependency(&info); + pOwner->AddChildDependent(pExt, (SMInterface *)iface); +} + void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface) { CExtension *pExt = (CExtension *)pOwner; diff --git a/core/systems/ExtensionSys.h b/core/systems/ExtensionSys.h index 2f6894a3..901fd2de 100644 --- a/core/systems/ExtensionSys.h +++ b/core/systems/ExtensionSys.h @@ -73,7 +73,7 @@ public: //IExtension bool IsRunning(char *error, size_t maxlength); public: void SetError(const char *error); - void AddDependency(IfaceInfo *pInfo); + void AddDependency(const IfaceInfo *pInfo); void AddChildDependent(CExtension *pOther, SMInterface *iface); void AddInterface(SMInterface *pInterface); void AddPlugin(CPlugin *pPlugin); @@ -166,6 +166,7 @@ public: void AddLibrary(IExtension *pSource, const char *library); bool LibraryExists(const char *library); void CallOnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax); + void AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface); public: CExtension *GetExtensionFromIdent(IdentityToken_t *ptr); void Shutdown(); diff --git a/public/IDBDriver.h b/public/IDBDriver.h index 47ae9467..bf02b7f7 100644 --- a/public/IDBDriver.h +++ b/public/IDBDriver.h @@ -42,7 +42,7 @@ */ #define SMINTERFACE_DBI_NAME "IDBI" -#define SMINTERFACE_DBI_VERSION 6 +#define SMINTERFACE_DBI_VERSION 7 namespace SourceMod { @@ -867,7 +867,16 @@ namespace SourceMod * @return True on success, false on failure. */ virtual bool AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio) =0; + + /** + * @brief Adds a dependency from one extension to the owner of a driver. + * + * @param myself Extension that is using the IDBDriver. + * @param driver Driver that is being used. + */ + virtual void AddDependency(IExtension *myself, IDBDriver *driver) =0; }; } #endif //_INCLUDE_SOURCEMOD_INTERFACE_DBDRIVER_H_ + diff --git a/public/IExtensionSys.h b/public/IExtensionSys.h index 64ae3719..f707dbeb 100644 --- a/public/IExtensionSys.h +++ b/public/IExtensionSys.h @@ -186,10 +186,16 @@ namespace SourceMod * 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. + * 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. + * @param pInterface Pointer to interface being dropped. This + * pointer may be opaque, and it should not + * be queried using SMInterface functions unless + * it can be verified to match an existing + * pointer of known type. + * @return True to continue, false to unload this + * extension afterwards. */ virtual bool QueryInterfaceDrop(SMInterface *pInterface) { @@ -199,7 +205,10 @@ namespace SourceMod /** * @brief Notifies the extension that an external interface it uses is being removed. * - * @param pInterface Pointer to interface being dropped. + * @param pInterface Pointer to interface being dropped. This + * pointer may be opaque, and it should not + * be queried using SMInterface functions unless + * it can be verified to match an existing */ virtual void NotifyInterfaceDrop(SMInterface *pInterface) {