Chinaunix首页 | 论坛 | 博客
  • 博客访问: 178460
  • 博文数量: 43
  • 博客积分: 827
  • 博客等级: 准尉
  • 技术积分: 487
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-26 19:19
文章分类

全部博文(43)

文章存档

2015年(1)

2014年(1)

2013年(5)

2012年(36)

我的朋友

分类: WINDOWS

2012-05-06 17:08:31

Irrlicht 有自己的一套Gui系统, 而他的事件系统的过程为:

1:Device::run为事件的主循环,在这里将原始的Windows事件Dispatch到WndProc中去

2: WndProc中解析Windows事件,然后生成对应的Irrlicht事件SEvent并传送到Device::postEventFromUser中去。注意:这里只会传到
Device::postEventFromUser,所以Device::postEventFromUser是整个Irrlicht的一个事件入口

3: 在Device::postEventFromUser中主要是三个过程:
        bool absorbed = false;

        if (UserReceiver)
                absorbed = UserReceiver->OnEvent(event);

        if (!absorbed && GUIEnvironment)
                absorbed = GUIEnvironment->postEventFromUser(event);

        scene::ISceneManager* inputReceiver = InputReceivingSceneManager;
        if (!inputReceiver)
                inputReceiver = SceneManager;

        if (!absorbed && inputReceiver)
                absorbed = inputReceiver->postEventFromUser(event);

首先将事件传给UserReceiver中去。在这里的事件通常是还比较原始的Mouse Input或者Key Input的事件,比较底层。而相对于Windows事件高层。
如果没有被处理再发送到GuiEnvirongment中去。 GUIEnvironment->postEventFromUser(event)
在 GUIEnvironment->postEventFromUser(event)中,这是整个Irrlicht Gui系统的事件入口,在这里面将解析Mouse Input还是Key Input,GuiEnvironment将这个事件传播到对应的Gui Element上去(调用对应Gui Element的OnEvent),所以这里事件Mouse或者Key事件转播到对应的Gui 元素上去。在对应的Gui Element上进一步解析Mouse或者Key事件,创建对应的Gui Event。这个时候会将这个Gui Event回传给这个Gui Element的Parent(调用Parent::OnEvent)(在创建Gui Element的时候,如果没有指定Parent,那么Parent就是Gui Environment),这个过程就有些类似于windows的gui 消息机制了。
而在Gui Element回调Parent::OnEvent的时候,通常会回调到GuiEnvironment::OnEvent,在GuiEnvironment::OnEvent,GUI事件能够被传播到GuiEnvironment的UserReceiver

bool CGUIEnvironment::OnEvent(const SEvent& event)
{
        bool ret = false;
        if (UserReceiver
                && (event.EventType != EET_MOUSE_INPUT_EVENT)
                && (event.EventType != EET_KEY_INPUT_EVENT)
                && (event.EventType != EET_GUI_EVENT || event.GUIEvent.Caller != this))
        {
                ret = UserReceiver->OnEvent(event);
        }

        _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
        return ret;
}

所以在这里,Gui事件被传播到外面去处理。

最后如果这个事件还没有被处理,就将这个事件传到SceneManager中去处理,而SceneManager的处理主要是对Camera的事件处理。


说明:
对于在GuiEnvironment中的UserReceiver实际上是Device中的同一个UserReceiver,在Device中创建GuiEnvironment的时候,该UserReceiver会被设定到GuiEnvironment中去,同样在调用Device::SetEventReceiver的时候,同样会被设定到GuiEnvironment中去。
所以在CGUIEnvironment::OnEvent中,会先将EET_MOUSE_INPUT_EVENT,EET_KEY_INPUT_EVENT,event.EventType != EET_GUI_EVENT || event.GUIEvent.Caller != this进行判定,若果是MOUSE和KEY,这显然在Device::Post中首先被处理掉。而后者,是指如果是其他元素发出的GUI事件,那么要传播出去,否则,那代表是自己发出去的(这里有点解释不通)。

整个事件的流程:
阅读(1112) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~