插件系統(tǒng)是游戲引擎中一個(gè)比較大的子系統(tǒng)
這個(gè)系統(tǒng)的目的就是動(dòng)態(tài)增加引擎的功能而不必修改引擎接口
之前雖然做過插件這塊‘
但是感覺設(shè)計(jì)的不好
這次總算弄了一個(gè)比較完備的插件系統(tǒng)
相關(guān)對(duì)象和結(jié)構(gòu)
1.插件 Plugin
///////////////////////////////////////////////////////////
/// 定義引擎插件數(shù)據(jù)結(jié)構(gòu)
///////////////////////////////////////////////////////////
class Plugin
{
public:
Plugin()
{
Reset();
}
///////////////////////////////////////////////////////
/// 插件重啟
///////////////////////////////////////////////////////
void Reset();
///////////////////////////////////////////////////////
/// 插件名字
///////////////////////////////////////////////////////
engine_string name;
///////////////////////////////////////////////////////
/// 插件作者
///////////////////////////////////////////////////////
engine_string maker;
///////////////////////////////////////////////////////
///插件描述
///////////////////////////////////////////////////////
engine_string description;
///////////////////////////////////////////////////////
/// 插件版本
///////////////////////////////////////////////////////
ushort vermain;
ushort versub;
ushort verpitch;
///////////////////////////////////////////////////////
/// 插件類型
///////////////////////////////////////////////////////
ushort type;
///////////////////////////////////////////////////////
/// 插件合法性標(biāo)記
///////////////////////////////////////////////////////
ushort valid;
};
插件數(shù)據(jù)結(jié)構(gòu)只包含了插件的一些基本信息 比如名字,描述,作者,功能類型等
2.PluginLoader
////////////////////////////////////////////////////////
/// 定義插件載入類
////////////////////////////////////////////////////////
class PluginLoader
{
public:
/////////////////////////////////////////////////////
/// 構(gòu)造,析構(gòu)插件載入
/////////////////////////////////////////////////////
PluginLoader();
~PluginLoader();
public:
/////////////////////////////////////////////////////
/// 載入插件和卸載
/////////////////////////////////////////////////////
bool Load(const engine_string &plugin);
void Free();
/////////////////////////////////////////////////////
/// 獲取插件指定符號(hào)地址
/////////////////////////////////////////////////////
void* GetAddress(const engine_string &name);
/////////////////////////////////////////////////////
/// 檢測(cè)插件是否合法
/////////////////////////////////////////////////////
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主要是載入插件文件并獲取給定符號(hào)的函數(shù)指針
這個(gè)并沒沒有暴漏出來供用戶調(diào)用
3.PluginFactory
///////////////////////////////////////////////////////////
/// 定義引擎插件工廠基類
///////////////////////////////////////////////////////////
class GAPI PluginFactory : public Object
{
public:
///////////////////////////////////////////////////////
/// 構(gòu)造和析構(gòu)引擎插件工廠基類
///////////////////////////////////////////////////////
PluginFactory();
virtual ~PluginFactory();
public:
///////////////////////////////////////////////////////
/// 注冊(cè),反注冊(cè)插件
///////////////////////////////////////////////////////
virtual bool ENGINE_CALL RegisterFactory(const engine_string& plugin) = 0;
virtual void ENGINE_CALL UnregisterFacory() = 0;
public:
///////////////////////////////////////////////////////
/// 獲取對(duì)應(yīng)插件類型標(biāo)識(shí)
///////////////////////////////////////////////////////
virtual ushort GetPluginType()const = 0;
private:
DECLARE_OBJECT(PluginFactory)
};
插件工廠是一切需要從插件中獲取功能的對(duì)象工廠
她主要提供了插件的注冊(cè)和反注冊(cè)以及獲取插件工廠所對(duì)應(yīng)的插件類型
4.PluginManager 插件管理器
///////////////////////////////////////////////////////////
/// 定義引擎插件管理器
///////////////////////////////////////////////////////////
class GAPI PluginManager
{
public:
///////////////////////////////////////////////////////
/// 獲取,設(shè)置插件目錄
///////////////////////////////////////////////////////
engine_string GetPluginFolder()const;
void SetPluginFolder(const engine_string& folder);
public:
///////////////////////////////////////////////////////
/// 插件裝載和卸載
///////////////////////////////////////////////////////
void InstallPlugin();
void UnstallPlugin();
public:
///////////////////////////////////////////////////////
/// 注冊(cè),反注冊(cè)插件工廠
///////////////////////////////////////////////////////
bool RegisterPluginFactory(PluginFactory* factory);
bool UnregisterPluginFactory(PluginFactory* factory);
public:
///////////////////////////////////////////////////////
/// 獲取插件個(gè)數(shù)
///////////////////////////////////////////////////////
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())
插件管理器是插件系統(tǒng)的核心,充當(dāng)了插件管理者的角色
要使用插件線需要設(shè)置插件目錄
然后裝載插件
然后注冊(cè)特定的插件工廠
然后就可以通過插件工廠獲取插件對(duì)象指針咯
在這里插件管理器是作為一個(gè)單間使用的
具體的宏 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);
下面是具體的一個(gè)插件對(duì)象---攝像頭捕獲類
如下:通過調(diào)用CaptureImage就可以把攝像頭所見程序保存為image了
///////////////////////////////////////////////////////////
/// 定義攝像頭捕獲類(以插件形式提供之)
///////////////////////////////////////////////////////////
class GAPI CapturePicture : public Object
{
public:
///////////////////////////////////////////////////////
/// 構(gòu)造和析構(gòu)
///////////////////////////////////////////////////////
CapturePicture();
virtual ~CapturePicture();
public:
///////////////////////////////////////////////////////
/// 獲取攝像頭圖形數(shù)據(jù)
///////////////////////////////////////////////////////
virtual bool CaptureImage(RefPtr<Image> &image);
private:
DECLARE_OBJECT(CapturePicture)
};
通過調(diào)用CaptureImage就可以把攝像頭所見程序保存為image了
下面這個(gè)是對(duì)于的工廠:
///////////////////////////////////////////////////////////
/// 定義攝像頭捕獲工廠類
///////////////////////////////////////////////////////////
class GAPI CapturePictureFactory : public PluginFactory
{
public:
///////////////////////////////////////////////////////
/// 構(gòu)造和析構(gòu)
///////////////////////////////////////////////////////
CapturePictureFactory();
virtual ~CapturePictureFactory();
public:
///////////////////////////////////////////////////////
/// 獲取攝像頭捕獲指針
///////////////////////////////////////////////////////
CapturePicture* Create();
///////////////////////////////////////////////////////
/// 注冊(cè)插件
///////////////////////////////////////////////////////
bool ENGINE_CALL RegisterFactory(const engine_string& plugin);
void ENGINE_CALL UnregisterFacory();
///////////////////////////////////////////////////////
/// 獲取對(duì)應(yīng)插件類型標(biāo)識(shí)
///////////////////////////////////////////////////////
ushort GetPluginType()const;
private:
PluginLoader* loader;
DECLARE_OBJECT(CapturePictureFactory)
};
這個(gè)只是多了一個(gè)函數(shù)Createer而已
然后再說具體的插件部分
插件3函數(shù):
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獲取插件實(shí)際對(duì)象指針
通過Plugin_Unstall卸載插件
最后一個(gè)部分是插件的使用小例子:
#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<<"插件個(gè)數(shù):"<<GLOBAL_PLUGINMANAGER_PTR->GetPluginNumber()<<std::endl;
core::CapturePictureFactory factory;
std::cout<<"注冊(cè)視頻捕獲插件工廠:"<<GLOBAL_PLUGINMANAGER_PTR->RegisterPluginFactory(&factory)<<std::endl;
core::CapturePicture* capturepicture = factory.Create();
std::cout<<"插件工廠產(chǎn)品標(biāo)識(shí):"<<factory.GetPluginType()<<std::endl;
core::RefPtr<core::Device> device = core::InitDevice("插件測(cè)試");
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;
}
題后話:
當(dāng)前引擎支持xp,vista,win7環(huán)境
在編譯器支持vc7.1,vc8,vc9,devc++,codeblock
也許在不久的將來我會(huì)弄一個(gè)linux版本的