插件系统是游戏引擎中一个比较大的子系统
这个系统的目的就是动态增加引擎的功能而不必修改引擎接口
之前虽然做过插件这块‘
但是感觉设计的不好
这次总算弄了一个比较完备的插件系统
相关对象和结构
1.插件 Plugin
///////////////////////////////////////////////////////////
/// 定义引擎插件数据结构
///////////////////////////////////////////////////////////
class Plugin
{
public:
Plugin()
{
Reset();
}
///////////////////////////////////////////////////////
/// 插件重启
///////////////////////////////////////////////////////
void Reset();
///////////////////////////////////////////////////////
/// 插件名字
///////////////////////////////////////////////////////
engine_string name;
///////////////////////////////////////////////////////
/// 插件作者
///////////////////////////////////////////////////////
engine_string maker;
///////////////////////////////////////////////////////
///插件描述
///////////////////////////////////////////////////////
engine_string description;
///////////////////////////////////////////////////////
/// 插件版本
///////////////////////////////////////////////////////
ushort vermain;
ushort versub;
ushort verpitch;
///////////////////////////////////////////////////////
/// 插件类型
///////////////////////////////////////////////////////
ushort type;
///////////////////////////////////////////////////////
/// 插件合法性标记
///////////////////////////////////////////////////////
ushort valid;
};
插件数据结构只包含了插件的一些基本信息 比如名字,描述,作者,功能类型等
2.PluginLoader
////////////////////////////////////////////////////////
/// 定义插件载入类
////////////////////////////////////////////////////////
class PluginLoader
{
public:
/////////////////////////////////////////////////////
/// 构造,析构插件载入
/////////////////////////////////////////////////////
PluginLoader();
~PluginLoader();
public:
/////////////////////////////////////////////////////
/// 载入插件和卸载
/////////////////////////////////////////////////////
bool Load(const engine_string &plugin);
void Free();
/////////////////////////////////////////////////////
/// 获取插件指定符号地址
/////////////////////////////////////////////////////
void* GetAddress(const engine_string &name);
/////////////////////////////////////////////////////
/// 检测插件是否合法
/////////////////////////////////////////////////////
bool IsValid()const{return handle != NULL;}
/////////////////////////////////////////////////////
/// 获取插件句柄
/////////////////////////////////////////////////////
void* GetHandle(){return handle;}
void* GetHandle()const{return handle;}
/////////////////////////////////////////////////////
/// 获取插件名
/////////////////////////////////////////////////////
engine_string GetPluginName()const{return pluginame;}
private:
void* handle;
engine_string pluginame;
};
PluginLoader主要是载入插件文件并获取给定符号的函数指针
这个并没没有暴漏出来供用户调用
3.PluginFactory
///////////////////////////////////////////////////////////
/// 定义引擎插件工厂基类
///////////////////////////////////////////////////////////
class GAPI PluginFactory : public Object
{
public:
///////////////////////////////////////////////////////
/// 构造和析构引擎插件工厂基类
///////////////////////////////////////////////////////
PluginFactory();
virtual ~PluginFactory();
public:
///////////////////////////////////////////////////////
/// 注册,反注册插件
///////////////////////////////////////////////////////
virtual bool ENGINE_CALL RegisterFactory(const engine_string& plugin) = 0;
virtual void ENGINE_CALL UnregisterFacory() = 0;
public:
///////////////////////////////////////////////////////
/// 获取对应插件类型标识
///////////////////////////////////////////////////////
virtual ushort GetPluginType()const = 0;
private:
DECLARE_OBJECT(PluginFactory)
};
插件工厂是一切需要从插件中获取功能的对象工厂
她主要提供了插件的注册和反注册以及获取插件工厂所对应的插件类型
4.PluginManager 插件管理器
///////////////////////////////////////////////////////////
/// 定义引擎插件管理器
///////////////////////////////////////////////////////////
class GAPI PluginManager
{
public:
///////////////////////////////////////////////////////
/// 获取,设置插件目录
///////////////////////////////////////////////////////
engine_string GetPluginFolder()const;
void SetPluginFolder(const engine_string& folder);
public:
///////////////////////////////////////////////////////
/// 插件装载和卸载
///////////////////////////////////////////////////////
void InstallPlugin();
void UnstallPlugin();
public:
///////////////////////////////////////////////////////
/// 注册,反注册插件工厂
///////////////////////////////////////////////////////
bool RegisterPluginFactory(PluginFactory* factory);
bool UnregisterPluginFactory(PluginFactory* factory);
public:
///////////////////////////////////////////////////////
/// 获取插件个数
///////////////////////////////////////////////////////
ushort ENGINE_CALL GetPluginNumber()const;
///////////////////////////////////////////////////////
/// 获取给定索引插件信息
///////////////////////////////////////////////////////
Plugin ENGINE_CALL GetPluginByType(ushort index)const;
///////////////////////////////////////////////////////
/// 获取给定索引的插件名
///////////////////////////////////////////////////////
engine_string ENGINE_CALL GetPluginNameByType(ushort index)const;
///////////////////////////////////////////////////////
/// 获取给定插件类型的插件载入类
///////////////////////////////////////////////////////
private:
PluginManagerImpl *impl;
DEFINE_SINGLETON(PluginManager);
};
}
//! 定义插件管理器单件
#define GLOBAL_PLUGINMANAGER_PTR (core::PluginManager::GetInstance())
插件管理器是插件系统的核心,充当了插件管理者的角色
要使用插件线需要设置插件目录
然后装载插件
然后注册特定的插件工厂
然后就可以通过插件工厂获取插件对象指针咯
在这里插件管理器是作为一个单间使用的
具体的宏 DEFINE_SINGLETON(PluginManager);
展开之后为:
#define DEFINE_SINGLETON(SingletonObject)\
private:\
static std::auto_ptr<SingletonObject> instance;\
protected:\
SingletonObject();\
public:\
~SingletonObject();\
static SingletonObject* GetInstance(){\
if(!instance.get())\
{\
instance = std::auto_ptr<SingletonObject>(new SingletonObject());\
}\
return instance.get();\
}
#define IMPLEMENT_SINGLETON(SingletonObject)\
std::auto_ptr<SingletonObject> SingletonObject::instance(NULL);
下面是具体的一个插件对象---摄像头捕获类
如下:通过调用CaptureImage就可以把摄像头所见程序保存为image了
///////////////////////////////////////////////////////////
/// 定义摄像头捕获类(以插件形式提供之)
///////////////////////////////////////////////////////////
class GAPI CapturePicture : public Object
{
public:
///////////////////////////////////////////////////////
/// 构造和析构
///////////////////////////////////////////////////////
CapturePicture();
virtual ~CapturePicture();
public:
///////////////////////////////////////////////////////
/// 获取摄像头图形数据
///////////////////////////////////////////////////////
virtual bool CaptureImage(RefPtr<Image> &image);
private:
DECLARE_OBJECT(CapturePicture)
};
通过调用CaptureImage就可以把摄像头所见程序保存为image了
下面这个是对于的工厂:
///////////////////////////////////////////////////////////
/// 定义摄像头捕获工厂类
///////////////////////////////////////////////////////////
class GAPI CapturePictureFactory : public PluginFactory
{
public:
///////////////////////////////////////////////////////
/// 构造和析构
///////////////////////////////////////////////////////
CapturePictureFactory();
virtual ~CapturePictureFactory();
public:
///////////////////////////////////////////////////////
/// 获取摄像头捕获指针
///////////////////////////////////////////////////////
CapturePicture* Create();
///////////////////////////////////////////////////////
/// 注册插件
///////////////////////////////////////////////////////
bool ENGINE_CALL RegisterFactory(const engine_string& plugin);
void ENGINE_CALL UnregisterFacory();
///////////////////////////////////////////////////////
/// 获取对应插件类型标识
///////////////////////////////////////////////////////
ushort GetPluginType()const;
private:
PluginLoader* loader;
DECLARE_OBJECT(CapturePictureFactory)
};
这个只是多了一个函数Createer而已
然后再说具体的插件部分
插件3函数:
extern "C" void GAPI Plugin_Info(Plugin &plugin);
extern "C" Object* GAPI Plugin_Install();
extern "C" void GAPI Plugin_Unstall(void*);
具体为通过Plugin_Info
通过Plugin_Install获取插件实际对象指针
通过Plugin_Unstall卸载插件
最后一个部分是插件的使用小例子:
#include <cstdlib>
#include <iostream>
#include <GEngine/Header.hpp>
using namespace std;
int main(int argc, char *argv[])
{
GLOBAL_PLUGINMANAGER_PTR->SetPluginFolder("plugin");
GLOBAL_PLUGINMANAGER_PTR->InstallPlugin();
std::cout<<"插件个数:"<<GLOBAL_PLUGINMANAGER_PTR->GetPluginNumber()<<std::endl;
core::CapturePictureFactory factory;
std::cout<<"注册视频捕获插件工厂:"<<GLOBAL_PLUGINMANAGER_PTR->RegisterPluginFactory(&factory)<<std::endl;
core::CapturePicture* capturepicture = factory.Create();
std::cout<<"插件工厂产品标识:"<<factory.GetPluginType()<<std::endl;
core::RefPtr<core::Device> device = core::InitDevice("插件测试");
if(!capturepicture)
{
std::cout<<"生成摄像头捕获指针失败了"<<std::endl;
system("PAUSE");
return -1;
}
core::RefPtr<core::ResourceManager> resmgr = device->GetResourceManager();
core::RefPtr<core::ImageManager> imagemanager = resmgr->GetImageManager();
core::RefPtr<core::Image> image = imagemanager->CreateObject("capturepicture");
capturepicture->CaptureImage(image);
std::cout<<"save image is:"<<image->Save("capture.bmp")<<std::endl;
BEGIN_LOOP(device)
glClearColor(0.1,0.3,0.2,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
END_LOOP(device)
GLOBAL_PLUGINMANAGER_PTR->UnregisterPluginFactory(&factory);
GLOBAL_PLUGINMANAGER_PTR->UnstallPlugin();
//system("PAUSE");
return EXIT_SUCCESS;
}
题后话:
当前引擎支持xp,vista,win7环境
在编译器支持vc7.1,vc8,vc9,devc++,codeblock
也许在不久的将来我会弄一个linux版本的