青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴(yán)以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

CEGUI的事件系統(tǒng)分析

作者: 楊粼波
Email: tx7do@yahoo.com.cn


什么是GUI?

       GUI就是圖形用戶界面(Graphics User Interface),是指采用圖形方式顯示的計(jì)算機(jī)操作用戶接口.

 

 什么是GUI的事件?

       所謂事件就是指發(fā)送給GUI系統(tǒng)的消息,該消息通知GUI系統(tǒng)某種事情已發(fā)生,要求作出響應(yīng).簡(jiǎn)言之就是:用戶將自己的一個(gè)或多個(gè)回調(diào)函數(shù)掛鉤到某個(gè)“事件”上,一旦“事件”被觸發(fā),所有掛鉤的函數(shù)都被調(diào)用。

      顯然,事件機(jī)制是一個(gè)非常有用的并且常用的機(jī)制,C#已經(jīng)將之在語(yǔ)言層面進(jìn)行了實(shí)現(xiàn),但是C++并無(wú)實(shí)現(xiàn).不過(guò)很多庫(kù)都有實(shí)現(xiàn)比如:boost::signal. 

 

CEGUI的事件機(jī)制是什么?

       CEGUI的事件機(jī)制采用的是觀察者模式(Observer pattern)的一種實(shí)現(xiàn).很有點(diǎn)像QtSignal/Slot機(jī)制,但是又沒(méi)有那么復(fù)雜.

對(duì)事件的封裝上雖然用到了仿函數(shù),但其實(shí)卻是為了統(tǒng)一接口,其實(shí)質(zhì)可以是回調(diào)函數(shù)也可以是仿函數(shù).


CEGUI事件系統(tǒng)的靜態(tài)類圖



向事件系統(tǒng)注冊(cè)事件的流程

首先客戶調(diào)用EventSet::subscribeEvent方法,傳入的參數(shù)為參數(shù)名和回調(diào)方法.實(shí)際上第二個(gè)參數(shù)的傳入過(guò)程中有一個(gè)創(chuàng)建臨時(shí)變量SubscriberSlot,其實(shí)質(zhì)上是一個(gè)綁定的回調(diào)函數(shù)(函數(shù)指針,成員函數(shù)指針,仿函數(shù)等)的過(guò)程,在圖中并沒(méi)有表現(xiàn)出來(lái).

       接著, EventSet::subscribeEvent方法中會(huì)首先調(diào)用EventSet::getEventObject方法獲取事件,EventSet::getEventObject,如果沒(méi)有查找到事件,則會(huì)創(chuàng)建之.當(dāng)獲取到事件之后, EventSet::subscribeEvent會(huì)調(diào)用Event::subscribe方法.

       Event::subscribe方法中,會(huì)先創(chuàng)建一個(gè)BoundSlot的實(shí)例,而在BoundSlot的構(gòu)造方法當(dāng)中,它會(huì)創(chuàng)建一個(gè)SubscriberSlot的實(shí)例,并將EventSet::subscribeEvent傳入的第二個(gè)參數(shù)保存到SubscriberSlot的實(shí)例里面去.



事件系統(tǒng)響應(yīng)事件的流程

       首先要說(shuō)明的是,客戶首先必須要從EventSet繼承下來(lái)才行,CEGUI里面有System,Renderer,Window,MouseCursor以及GlobalEventSet.其中GlobalEventSet是單件,系統(tǒng)創(chuàng)建以后就要?jiǎng)?chuàng)建它,EventSet對(duì)它是有依賴的,由上圖就可以得知.

       EventSet是什么呢?EventSet它是一個(gè)事件的容器,它是一個(gè)事件處理中心.可以說(shuō)是事件系統(tǒng)的接口.

       當(dāng)客戶向事件系統(tǒng)發(fā)送了一個(gè)事件之后,即是執(zhí)行EventSet::fireEvent. EventSet::fireEvent首先執(zhí)行了GlobalEventSet:: fireEvent,而后才執(zhí)行其自身的一個(gè)方法EventSet::fireEvent_impl,該方法才是真正進(jìn)行事件處理的方法,由該方法的后綴impl即可得知了. EventSet::fireEvent_impl先是執(zhí)行了getEventObject方法查找到事件,然后調(diào)用該事件Event的仿函數(shù),該仿函數(shù)調(diào)用BoundSlot:: m_pSubscriber的仿函數(shù),它最終將會(huì)調(diào)用到SlotFunctorBase接口的實(shí)現(xiàn)的仿函數(shù),而這個(gè)仿函數(shù)內(nèi)部調(diào)用到的是真正的回調(diào)方法.

       SlotFunctorBase這一塊實(shí)際上是Gof模式之一的適配器模式(adapter pattern)的應(yīng)用.

 

測(cè)試代碼:

using namespace CEGUI;

/// 事件參數(shù)
class TestEventArgs : public EventArgs
{
public:
    TestEventArgs(
const int& _n) : n(_n) {}

    
int n;    
}
;

/// 事件
class testEvent : public EventSet
{
public:
    testEvent()
{}

    
static const String EventNamespace;
    
static const String EventTest;

    
void injectTest(int n)
    
{
        TestEventArgs e(n);
        fireEvent(EventTest, e, EventNamespace);
    }

}
;
const String testEvent::EventTest("test");
const String testEvent::EventNamespace("testEvent");

/// 客戶
class testClient
{
public:
    testClient()
    
{
        Init();
    }


    
void Init()
    
{
        
new GlobalEventSet();
        mEvent.subscribeEvent(testEvent::EventTest, Event::Subscriber(
&testClient::handleTest, this) );
    }


    
bool handleTest(const CEGUI::EventArgs& e)
    
{
        
int val = static_cast<const TestEventArgs&>(e).n;
        std::cout 
<< val << std::endl;
        
return true;
    }


    
void exe()
    
{
        mEvent.injectTest(
99);
        mEvent.injectTest(
5555);
    }


private:
    testEvent mEvent;
}
;

int main()
{
    testClient client;
    client.exe();

    system(
"pause");
    
return 0;
}

下面對(duì)代碼進(jìn)行講解.
   首先,我們需要聲明一個(gè)事件參數(shù),在CEGUI主模塊里面都是一些鍵盤鼠標(biāo)的輸入事件參數(shù).
   然后,我們需要聲明一個(gè)事件集,它由EventSet繼承而來(lái).
   在測(cè)試代碼里面,我們聲明了一個(gè)testClient的類,代表著客戶在里面我們聲明一個(gè)回調(diào)方法:testClient::handleTest.testClient::Init方法作為客戶的初始代碼,在這里面,我們注冊(cè)事件.在testClient::exe里面執(zhí)行觸發(fā)事件的代碼.而后,事件將會(huì)被觸發(fā),繼而testClient::handleTest方法將會(huì)被回調(diào)執(zhí)行.


代碼下載:
testEventSystem.rar
需要注意的是,這份代碼里面的事件系統(tǒng)不是原汁原味的CEGUI的事件系統(tǒng),是經(jīng)過(guò)我略加修改之后的東西.


文檔和圖片下載:
CEGUI事件系統(tǒng)分析.rar
靜態(tài)類圖貌似過(guò)大了,上傳到博客上面它自動(dòng)給我縮小了--!那根本就看不清楚,Word和PDF文檔里面也勉強(qiáng)能看清楚,沒(méi)辦法只好都打包進(jìn)去了.


參考資料

1.       圖形用戶界面 http://zh.wikipedia.org/zh-cn/GUI

2.       GUI系統(tǒng)的事件機(jī)制 http://wenku.baidu.com/view/a07ea19951e79b896802260d.html

posted on 2010-06-02 00:58 楊粼波 閱讀(4331) 評(píng)論(3)  編輯 收藏 引用

評(píng)論

# re: CEGUI的事件系統(tǒng)分析 2010-06-02 10:48 Any

可否告訴我文中的圖用什么畫的?  回復(fù)  更多評(píng)論   

# re: CEGUI的事件系統(tǒng)分析 2010-06-02 10:53 楊粼波

用EA(Enterprise Architect 7.5)畫的.  回復(fù)  更多評(píng)論   

# re: CEGUI的事件系統(tǒng)分析 2011-04-15 12:36 liigo

我(liigo)認(rèn)為CEGUI使用的這套事件處理機(jī)制挺漂亮的,簡(jiǎn)單實(shí)用。基本上由EventSet管理:它維護(hù)著一個(gè)string為key,鏈表為value的哈希表;每個(gè)string就對(duì)應(yīng)一個(gè)事件名稱,鏈表里則存儲(chǔ)著用于接收這個(gè)事件的用戶處理代碼的抽象(仿函數(shù),由subscribeEvent提供)。注冊(cè)一個(gè)事件處理函數(shù)(也可以是任意對(duì)象方法或仿函數(shù)),就是往哈希表中事件名稱對(duì)應(yīng)的鏈表中添加一個(gè)項(xiàng);觸發(fā)事件處理函數(shù)呢,就是循環(huán)調(diào)用指定事件名稱對(duì)應(yīng)的鏈表中的每一個(gè)仿函數(shù)。  回復(fù)  更多評(píng)論   


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩欧美一区二区| 国产欧美一区二区三区另类精品| 久久这里有精品15一区二区三区| 国产精品三区www17con| 一本久道久久久| 亚洲黄色在线看| 久久亚洲综合网| 影音先锋一区| 久久久久久9999| 欧美影院成人| 国产一区二区在线观看免费| 久久精品亚洲精品| 欧美在线看片a免费观看| 国产午夜精品久久久| 欧美一区2区三区4区公司二百| 在线视频精品一区| 亚洲国产成人精品久久| 免费成人高清| 91久久香蕉国产日韩欧美9色| 免费h精品视频在线播放| 久久琪琪电影院| 亚洲国产另类久久精品| 欧美国产亚洲视频| 欧美精品日韩www.p站| 99精品久久久| 亚洲午夜视频在线| 国产一区二区日韩| 免费观看一区| 欧美激情精品久久久久久变态| 日韩一二在线观看| 在线性视频日韩欧美| 国产区欧美区日韩区| 久久中文字幕一区| 欧美激情国产日韩| 欧美一区二区三区视频在线观看| 欧美在线一二三| 91久久午夜| 亚洲一区二区毛片| 一区二区在线观看av| 亚洲日本在线视频观看| 国产精品一区二区a| 免费不卡欧美自拍视频| 欧美日韩视频第一区| 久久九九精品| 欧美另类高清视频在线| 久久精品国产精品亚洲综合| 欧美成人免费在线| 午夜精品免费在线| 免费成人av| 欧美一区二区三区视频在线观看| 久久综合给合| 亚洲欧美日韩精品在线| 久久久国产精品亚洲一区| 亚洲香蕉在线观看| 免费观看成人网| 久久不射中文字幕| 欧美日韩国产欧| 免费成人网www| 国产精品久久久久久福利一牛影视| 久久久久国产一区二区三区| 欧美日产一区二区三区在线观看| 久久久久久电影| 欧美视频在线不卡| 欧美黑人一区二区三区| 国产日韩欧美视频在线| 亚洲伦理一区| 亚洲电影视频在线| 欧美一区二区精美| 一区二区国产日产| 欧美v日韩v国产v| 久久一区激情| 国产午夜精品一区理论片飘花| 99re在线精品| 亚洲日本va在线观看| 欧美自拍丝袜亚洲| 欧美在线播放一区| 国产精品久久久久一区二区三区共| 亚洲第一精品影视| 激情久久久久久久| 欧美主播一区二区三区| 欧美在线视频免费播放| 亚洲一区视频| 亚洲影视在线| 欧美午夜一区二区福利视频| 亚洲精品中文字幕有码专区| 亚洲国产导航| 久久亚洲精品伦理| 久久综合999| 黄色成人av| 久久久久久亚洲综合影院红桃| 久久久精品国产免费观看同学| 国产欧美日韩免费| 欧美专区在线播放| 欧美69wwwcom| 日韩天堂在线视频| 国产精品videossex久久发布| 9色国产精品| 小处雏高清一区二区三区| 国产精品亚洲产品| 久久精品国产一区二区电影 | 亚洲乱码精品一二三四区日韩在线| 久久aⅴ国产欧美74aaa| 久久久噜噜噜| 亚洲国产一区二区精品专区| 美女久久网站| 亚洲欧洲精品一区二区三区不卡 | 日韩亚洲视频在线| 欧美日韩福利在线观看| 99视频一区二区三区| 午夜宅男久久久| 国产一区深夜福利| 噜噜噜91成人网| 亚洲日本va午夜在线影院| 亚洲制服av| 精品动漫一区| 欧美精品一区二区三区四区| 日韩亚洲欧美一区| 欧美一级网站| 亚洲承认在线| 欧美婷婷久久| 久久精品成人| 亚洲日本免费| 欧美制服丝袜| 亚洲日本久久| 国产色产综合产在线视频| 另类综合日韩欧美亚洲| 夜夜精品视频| 免费在线亚洲欧美| 亚洲图片欧洲图片日韩av| 国产视频综合在线| 欧美激情aaaa| 久久成人精品电影| 亚洲精品之草原avav久久| 欧美专区18| 9久re热视频在线精品| 国产视频一区在线观看一区免费| 蜜臀久久久99精品久久久久久| 一区二区三区免费在线观看| 久久综合精品国产一区二区三区| av成人免费| 亚洲第一久久影院| 国产农村妇女精品| 欧美精品大片| 久久婷婷综合激情| 午夜电影亚洲| 99视频精品全部免费在线| 免费亚洲视频| 在线观看一区二区视频| 欧美午夜电影一区| 狼狼综合久久久久综合网 | 亚洲欧美日韩精品久久久久| 欧美激情视频给我| 久久夜色精品国产| 香蕉成人啪国产精品视频综合网| 亚洲黄网站黄| 伊伊综合在线| 国产一区二区日韩精品| 国产精品亚洲综合色区韩国| 欧美喷潮久久久xxxxx| 久久网站热最新地址| 欧美一区二区视频观看视频| 一二三区精品福利视频| 亚洲青涩在线| 亚洲国产日韩一区二区| 蜜臀99久久精品久久久久久软件 | 久久久久久夜精品精品免费| 亚洲一区二区日本| 99这里只有精品| 亚洲伦理在线免费看| 亚洲国产清纯| 亚洲国产裸拍裸体视频在线观看乱了中文 | 欧美精品久久久久久久免费观看| 久久精品国产一区二区三区免费看 | 亚洲精品123区| 狠狠操狠狠色综合网| 亚洲第一区在线| 女生裸体视频一区二区三区| 久久精品视频一| 久久九九免费视频| 久久久欧美一区二区| 老司机午夜精品视频在线观看| 欧美中文在线免费| 久久久久在线观看| 裸体女人亚洲精品一区| 免费高清在线一区| 欧美高清在线视频| 亚洲欧洲在线看| 夜夜狂射影院欧美极品| 中文精品99久久国产香蕉| 亚洲一卡久久| 欧美中文在线视频| 久久婷婷久久| 欧美另类综合| 国产精品欧美精品| 国产一区二区在线观看免费| 亚洲国产精品毛片| 在线亚洲伦理| 久久精品国产久精国产一老狼| 老司机免费视频久久| 91久久在线|