first commit
This commit is contained in:
114
include/framework/plugin/plugin_manager.h
Normal file
114
include/framework/plugin/plugin_manager.h
Normal file
@ -0,0 +1,114 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
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__
|
||||
Reference in New Issue
Block a user