插件系統是游戲引擎中一個比較大的子系統
這個系統的目的就是動態增加引擎的功能而不必修改引擎接口
之前雖然做過插件這塊‘
但是感覺設計的不好
這次總算弄了一個比較完備的插件系統
相關對象和結構
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版本的