现在的位置: 首页 > 综合 > 正文

OGRE 分析之消息机制

2018年01月16日 ⁄ 综合 ⁄ 共 4331字 ⁄ 字号 评论关闭

一、 消息的产生
        InputReader:从各种输入设备读取数据,可以看作是消息产生地。具体的InputReader由PlatformManager 创建,它是与平台相关的。
                                       OGRE::InputReader
                        ________________|_______________
                        |                           |                         |
                Ogre::GLXInput   Ogre::SDLInput   Ogre::Win32Input8

        InputEvent:消息的载体。界面元素层输入消息的基类。
        输入消息在它的产生地正常处理之前先被发送给Listeners。这样就可以用Listeners 和GuiElement subclasses 拦截消息,改变消息处理的默认行为。
        InputEvent 包含判断组合键的按下情况。
                        Ogre::InputEvent
                     ________|_______
                    |                            |
            Ogre::KeyEvent   Ogre::MouseEvent
二、 消息的处理
        EventListener:真正处理消息的地方。
                               Ogre::EventListener
           _________________|___________________
           |                              |                              |
Ogre::KeyListener   Ogre::MouseListener   Ogre::MouseMotionListener
 
       EventTarget:处理消息的中介。所有InputEvent消息处理者的基类。EventTarget处理
消息是由各种Listener 完成的。KeyTarget 调用KeyListener , MouseTarget 调用
MouseListener,MouseMotionTarget调用MouseMotionListener。
                                        Ogre::EventTarget
                        _______________|____________________
                        |                                                            |
            Ogre::KeyTarget                                      Ogre::PositionTarget
                        |                                         __________|________________
           Ogre::EventProcessor                       |                                              |
                                      Ogre::MouseMotionTarget               Ogre::MouseTarget
                          ___________|________                     __________|________
                          |                                 |                    |                                |
               Ogre::Cursor     Ogre::EventProcessor   Ogre::Cursor   Ogre::EventProcessor
 三、 消息的传递
        EventDispatcher:代理分发消息。负责把InputEvent消息分派给EventTarget。在分发消息时,EventDispatcher根据InputEvent的类型(MouseEvent或者KeyEvent)分别发送给需要的PositionTarget。
        EventTarget 由TargetManager 管理, 每一个TargetManager 都对应一个EventDispatcher。对应OverlayManager的EventDispatcher管理2D GUI组件,对应
SceneManager的EventDispatcher管理3D物体。

        EventProcessor:获取消息、维护消息队列、分发消息。
                    Ogre::EventTarget     Ogre::EventTarget
                                   |                          | 
                   Ogre::PositionTarget  Ogre::PositionTarget                         Ogre::EventTarget
                                    |                         |                                                             |
Ogre::FrameListener      |                         |                                                             |
            |      Ogre::MouseTarget    Ogre::MouseMotionTarget                   Ogre::KeyTarget
            |                       |                       |        Ogre::Singleton<EventProcessor>  |
            |_____________|_____________|________________|__________________|
                                                             |
                                           Ogre::EventProcessor
        EventProcessor 在初始化的时候,创建一个EventQueue 和一个InputReader,
InputReader 初始化为侦听鼠标和键盘消息,接收到的消息存放于上述的EventQueue
中。
        EventProcessor 是一个FrameListener,调用EventProcessor::startProcessingEvents(true)把EventProcessor 添加到Root 的FrameListener 链表中(实际为std::set),并激活EventQueue。
        EventProcessor又是EvenetTarget,所以维护有Listener列表,从基类继承而来的。除此之外,EventProcessor还维护了一个EvenetTarget列表和EventDispatcher列表。而所有的这些都是用来处理或传递消息的。

四、 消息处理整个过程
        程序进入Root::startRendering()后,进入消息循环。在渲染帧开始之前,Root 调用所有注册的FrameListener 的FrameListener::framStarted(…)函数,使之做好渲染前的准备。前面分析了EventProcessor 属于FrameListener 并注册到了Root,所以Root会调用EventProcessor:: framStarted(…) 函数。此时, EventProcessor 调用InputReader 捕获鼠标、键盘消息,然后进入消息分发阶段。
        EventProcessor将把队列中所有的消息通过EventDispatchers分发给EventTarget处理,EventTarget本身不能处理消息,需要借助EventListeners来处理。所以消息由依附在EventTarget上的EventListeners处理。
        EventDispatchers返回后,若存在没有处理的消息则先由EventProcessor维护的EventTargets处理,仍未处理的则由EventProcessor本身处理。由于EventProcessor也是EventTargets,所以它需要发给添加到EventProcessor中的EventListeners来处理。
        处理完鼠标键盘消息之后,Root 开始调用RenderSystem 来渲染RenderTarget。然后调用所有FrameListener 的FrameListener::frameEnded(…)。

总体过程可以看成如下顺序如下:
InputReader
--> EventProcessor --> EventDispatcher --> EventTarget
--> EventListener

抱歉!评论已关闭.