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) |