115 lines
2.9 KiB
C++
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__
|