Add a versioned IPluginsListener and deprecate the non-versioned class.

This commit is contained in:
David Anderson 2015-11-01 00:23:33 -07:00
parent cb3f6df111
commit d674414cf0
2 changed files with 108 additions and 24 deletions

View File

@ -44,7 +44,8 @@
#include "Translator.h" #include "Translator.h"
#include "Logger.h" #include "Logger.h"
#include "frame_tasks.h" #include "frame_tasks.h"
#include <am-string.h> #include <amtl/am-string.h>
#include <amtl/am-linkedlist.h>
#include <bridge/include/IVEngineServerBridge.h> #include <bridge/include/IVEngineServerBridge.h>
#include <bridge/include/CoreProvider.h> #include <bridge/include/CoreProvider.h>
@ -2240,7 +2241,42 @@ void CPluginManager::ForEachPlugin(ke::Lambda<void(CPlugin *)> callback)
callback(*iter); callback(*iter);
} }
class OldPluginAPI : public IPluginManager class PluginsListenerV1Wrapper final
: public IPluginsListener,
public ke::Refcounted<PluginsListenerV1Wrapper>
{
public:
PluginsListenerV1Wrapper(IPluginsListener_V1 *impl)
: impl_(impl)
{}
// The v2 listener was added with API v7, so we pin these wrappers to v6.
unsigned int GetApiVersion() const override {
return 6;
}
void OnPluginLoaded(IPlugin *plugin) override {
impl_->OnPluginLoaded(plugin);
}
void OnPluginPauseChange(IPlugin *plugin, bool paused) override {
impl_->OnPluginPauseChange(plugin, paused);
}
void OnPluginUnloaded(IPlugin *plugin) override {
impl_->OnPluginUnloaded(plugin);
}
void OnPluginDestroyed(IPlugin *plugin) override {
impl_->OnPluginDestroyed(plugin);
}
bool matches(IPluginsListener_V1 *impl) const {
return impl_ == impl;
}
private:
IPluginsListener_V1 *impl_;
};
class OldPluginAPI final : public IPluginManager
{ {
public: public:
IPlugin *LoadPlugin(const char *path, IPlugin *LoadPlugin(const char *path,
@ -2248,45 +2284,71 @@ public:
PluginType type, PluginType type,
char error[], char error[],
size_t maxlength, size_t maxlength,
bool *wasloaded) bool *wasloaded) override
{ {
return g_PluginSys.LoadPlugin(path, debug, type, error, maxlength, wasloaded); return g_PluginSys.LoadPlugin(path, debug, type, error, maxlength, wasloaded);
} }
bool UnloadPlugin(IPlugin *plugin) bool UnloadPlugin(IPlugin *plugin) override
{ {
return g_PluginSys.UnloadPlugin(plugin); return g_PluginSys.UnloadPlugin(plugin);
} }
IPlugin *FindPluginByContext(const sp_context_t *ctx) IPlugin *FindPluginByContext(const sp_context_t *ctx) override
{ {
return g_PluginSys.FindPluginByContext(ctx); return g_PluginSys.FindPluginByContext(ctx);
} }
unsigned int GetPluginCount() unsigned int GetPluginCount() override
{ {
return g_PluginSys.GetPluginCount(); return g_PluginSys.GetPluginCount();
} }
IPluginIterator *GetPluginIterator() IPluginIterator *GetPluginIterator() override
{ {
return g_PluginSys.GetPluginIterator(); return g_PluginSys.GetPluginIterator();
} }
void AddPluginsListener(IPluginsListener *listener) void AddPluginsListener_V1(IPluginsListener_V1 *listener) override
{
ke::Ref<PluginsListenerV1Wrapper> wrapper = new PluginsListenerV1Wrapper(listener);
v1_wrappers_.append(wrapper);
g_PluginSys.AddPluginsListener(wrapper);
}
void RemovePluginsListener_V1(IPluginsListener_V1 *listener) override
{
ke::Ref<PluginsListenerV1Wrapper> wrapper;
// Find which wrapper has this listener.
for (decltype(v1_wrappers_)::iterator iter(v1_wrappers_); !iter.done(); iter.next()) {
if ((*iter)->matches(listener)) {
wrapper = *iter;
iter.remove();
break;
}
}
g_PluginSys.RemovePluginsListener(wrapper);
}
IPlugin *PluginFromHandle(Handle_t handle, HandleError *err) override
{
return g_PluginSys.PluginFromHandle(handle, err);
}
void AddPluginsListener(IPluginsListener *listener) override
{ {
g_PluginSys.AddPluginsListener(listener); g_PluginSys.AddPluginsListener(listener);
} }
void RemovePluginsListener(IPluginsListener *listener) void RemovePluginsListener(IPluginsListener *listener) override
{ {
g_PluginSys.RemovePluginsListener(listener); g_PluginSys.RemovePluginsListener(listener);
} }
IPlugin *PluginFromHandle(Handle_t handle, HandleError *err) private:
{ ReentrantList<ke::Ref<PluginsListenerV1Wrapper>> v1_wrappers_;
return g_PluginSys.PluginFromHandle(handle, err);
}
}; };
static OldPluginAPI sOldPluginAPI; static OldPluginAPI sOldPluginAPI;

View File

@ -38,7 +38,7 @@
#include <sp_vm_api.h> #include <sp_vm_api.h>
#define SMINTERFACE_PLUGINSYSTEM_NAME "IPluginManager" #define SMINTERFACE_PLUGINSYSTEM_NAME "IPluginManager"
#define SMINTERFACE_PLUGINSYSTEM_VERSION 6 #define SMINTERFACE_PLUGINSYSTEM_VERSION 7
/** Context user slot 3 is used Core for holding an IPluginContext pointer. */ /** Context user slot 3 is used Core for holding an IPluginContext pointer. */
#define SM_CONTEXTVAR_USER 3 #define SM_CONTEXTVAR_USER 3
@ -278,7 +278,7 @@ namespace SourceMod
/** /**
* @brief Listens for plugin-oriented events. * @brief Listens for plugin-oriented events.
*/ */
class IPluginsListener class IPluginsListener_V1
{ {
public: public:
// @brief This callback should not be used since plugins may be in // @brief This callback should not be used since plugins may be in
@ -315,6 +315,14 @@ namespace SourceMod
} }
}; };
// @brief Listens for plugin-oriented events. Extends the V1 listener class.
class IPluginsListener : public IPluginsListener_V1
{
public:
virtual unsigned int GetApiVersion() const {
return SMINTERFACE_PLUGINSYSTEM_VERSION;
}
};
/** /**
* @brief Manages the runtime loading and unloading of plugins. * @brief Manages the runtime loading and unloading of plugins.
@ -380,6 +388,29 @@ namespace SourceMod
*/ */
virtual IPluginIterator *GetPluginIterator() =0; virtual IPluginIterator *GetPluginIterator() =0;
/**
* @brief Adds a V1 plugin manager listener.
*
* @param listener Pointer to a listener.
*/
virtual void AddPluginsListener_V1(IPluginsListener_V1 *listener) =0;
/**
* @brief Removes a V1 plugin listener.
*
* @param listener Pointer to a listener.
*/
virtual void RemovePluginsListener_V1(IPluginsListener_V1 *listener) =0;
/**
* @brief Converts a Handle to an IPlugin if possible.
*
* @param handle Handle.
* @param err Error, set on failure (otherwise undefined).
* @return IPlugin pointer, or NULL on failure.
*/
virtual IPlugin *PluginFromHandle(Handle_t handle, HandleError *err) =0;
/** /**
* @brief Adds a plugin manager listener. * @brief Adds a plugin manager listener.
* *
@ -393,15 +424,6 @@ namespace SourceMod
* @param listener Pointer to a listener. * @param listener Pointer to a listener.
*/ */
virtual void RemovePluginsListener(IPluginsListener *listener) =0; virtual void RemovePluginsListener(IPluginsListener *listener) =0;
/**
* @brief Converts a Handle to an IPlugin if possible.
*
* @param handle Handle.
* @param err Error, set on failure (otherwise undefined).
* @return IPlugin pointer, or NULL on failure.
*/
virtual IPlugin *PluginFromHandle(Handle_t handle, HandleError *err) =0;
}; };
} }