消息机制的设计一般总要设计到三个部分:消息的产生、消息的传递和消息的处理。
OGRE中的消息处理者的抽象类主要是listener类,而listener必须是对应特定的target的,所以可以认为是由listener和target两个抽象类组成。而消息传递由Dispatcher和Processor组成。
一般来讲立即模式适合于3D场景漫游过程,当在每帧渲染之前,系统捕获输入设备状态,并根据这些状态对场景中的物体和摄象机进行控制。
而缓冲模式适合于GUI界面的情况(如设置菜单),输入设备状态可以被发送到各GUI元素进行处理(如按钮被按下)。
在实际运用中,可以从ExampleFrameListener中派生自己的myFrameListener类,重新实现frameStarted函数,以实现更复杂的功能,如让3D物体运动等等。当然最后不要忘了调用基类ExampleFrameListener中的frameStarted函数。否则,基本的键盘鼠标控制就没了。
非缓冲模式下的按键处理,相当于查询操作,每次都查看一下有无相应的键按下,并没有利用到OGRE中的消息处理机制。
分析一下缓冲模式下的消息处理机制。
缓冲模式下,OGRE把缓冲模式下的消息处理交给了EventProcessor类。
KeyTarget又继承自EventTarget。
OGRE中有关键盘消息处理的有以下三个主要的类,EventTarget, EventListener, InputEvent. 如图:
可以看到EventListener类能过调用EventTarget的add/remove KeyListener可以注册到EventTarget上,当有消息到达时,EventTarget负责调用相应EventListener的处理函数。同时,消息本身被封装成InputEvent类。
现在回到ExampleFrameListener在缓冲模式中的初始化情况。
在initialise中做了以下几个事情:
cleanup()。清除mEventQueue, mdispatchList, mInputDevice等。
创建新的mEventQueue
创建新的mInputDevice. mEventQuue = InputDevice中的mEventQueue。
在startProcessingEvents中做了以下的事情:
addFrameListener(this)。这个this指的是EventProcessor。这就是在OGRE中将EventProcessor注册为一个FrameListener。
在addKeyListener(this)这个this指的是ExampleFrameListener。因为mEventProcessor继承了KeyTarget。所以可以调用addKeyListener。这时候ExampleFrameListener就被当成是一个KeyListener了。因此,ExampleFrameListener必须声明或实现KeyListener中的一些函数,如keyClicked, keyPressed, keyReleased。
这时候EventProcess就初始化结束了,OGRE会在每帧的开始的时候调用EventProcess的frameStarted(evt)函数。