Files
Webcam/include/framework/plugin/plugin_manager.h
2026-06-22 11:49:35 +02:00

115 lines
2.9 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __PLUGIN_MANAGER__
#define __PLUGIN_MANAGER__
#include "shared/shared_library.h"
#include "plugin/shared_systems.h"
#include "container/nlist.h"
#include "nstring/nstring.h"
#include "platform.h"
namespace GS {
static const int PluginLoadOk = 0;
static const int PluginLoadError = 1;
static const int PluginMissingClass = 2;
static const int PluginClassError = 3;
static const int PluginMissingVersion = 4;
static const int PluginVersionError = 5;
static const int PluginInterfaceError = 6;
/*!
@short Plugin manager
@author Emmanuel Julien (ejulien@owloh.com)
*/
template <class T> class PluginManager
{
typedef void SetSharedSystems(SharedSystems &);
typedef T *Factory();
typedef const char *GetPluginClass();
typedef uint GetPluginVersion();
public:
struct Plugin
{
String path;
AutoPtr <ISharedLib> shared_lib;
};
private:
AutoList <Plugin *> plugins;
public:
/// Return a new instance to concrete interface the plugin implements.
T *CreatePluginInterface(Plugin *p)
{
Factory *p_factory = p ? (Factory *)p->shared_lib->GetFunctionPointer("createPluginInterface") : 0;
return p_factory ? p_factory() : 0;
}
/*
@short Load a plugin.
The plugin is dynamically loaded from the specified path and its
class and version are checked for compatibility with the host
interface class and version.
A return code can be passed to get more information on failure.
*/
Plugin *LoadPlugin(const char *path, int *code = 0)
{
AutoPtr <Plugin> p(new Plugin);
if (p.IsNull())
return 0;
if (code)
*code = PluginLoadOk;
#define Error(V) { if (code) *code = V; return 0; }
p->shared_lib = Platform::Get().LoadSharedLibrary(path);
if (p->shared_lib.IsNull())
Error(PluginLoadError);
GetPluginClass *get_plugin_class = (GetPluginClass *)p->shared_lib->GetFunctionPointer("getPluginClass");
GetPluginVersion *get_plugin_version = (GetPluginVersion *)p->shared_lib->GetFunctionPointer("getPluginVersion");
SetSharedSystems *set_shared_systems = (SetSharedSystems *)p->shared_lib->GetFunctionPointer("setSharedSystems");
if (!get_plugin_class)
Error(PluginMissingClass);
if (!get_plugin_version)
Error(PluginMissingVersion);
if (!set_shared_systems)
Error(PluginInterfaceError);
if (String(T::GetPluginClass()) != get_plugin_class())
Error(PluginClassError);
if (T::GetPluginVersion() != get_plugin_version())
Error(PluginVersionError);
// Set the shared platform pointer.
SharedSystems shared;
set_shared_systems(shared);
p->path = path;
plugins.Add(p);
return p.Detach();
}
};
} // GS
#endif // __PLUGIN_MANAGER__