纵览多数面向对象的库,在事件处理上都希望把事件源和事件处理分开。在说OSG的事件处理之前我想先看一个通用的事件处理模式,Reactor模式。
Reactor的是用于事件驱动的应用程序中的,将一个或多个客户提交的请求分发给相应的事件处理器处理。这里有两个设计需求:
Q1.客户提交的请求时不能阻塞客户代码,我们可以待会处理你的请求,但是不能看到你的请求时理都不理你。
解决: 设计一个Synchronously Event Demultiplexer.使用不阻塞客户代码的API来检测到达的事件源请求,怎么把事件源和事件处理器关联起来呢,我们需要给Reactor提供事件注册能力,告诉Reactor哪些事件你是有兴趣的,什么样的事件源和什么样的事件处理器关联。
Reactor的是用于事件驱动的应用程序中的,将一个或多个客户提交的请求分发给相应的事件处理器处理。这里有两个设计需求:
Q1.客户提交的请求时不能阻塞客户代码,我们可以待会处理你的请求,但是不能看到你的请求时理都不理你。
解决: 设计一个Synchronously Event Demultiplexer.使用不阻塞客户代码的API来检测到达的事件源请求,怎么把事件源和事件处理器关联起来呢,我们需要给Reactor提供事件注册能力,告诉Reactor哪些事件你是有兴趣的,什么样的事件源和什么样的事件处理器关联。
2.程序要求方便扩展,当我要添加一类事件处理能力时不能对现有代码造成大的冲击。
解决:Reactor中为了实现事件派发一定有一张映射表 (Event Source –> Event Handler),我们可以定义一个Event Handler的接口,所有具体的事件处理类都从该接口继承,这样,添加一类新的事件处理时,只需要定义一个新类,并注册给Reactor就可以了。
解决:Reactor中为了实现事件派发一定有一张映射表 (Event Source –> Event Handler),我们可以定义一个Event Handler的接口,所有具体的事件处理类都从该接口继承,这样,添加一类新的事件处理时,只需要定义一个新类,并注册给Reactor就可以了。
那OSG呢,OSG是桌面系统渲染库,我需要相应鼠标操作,键盘操作,以Windows为例是由windows的消息循环处理的,我怎么能用面向对象的发式去包装它使得客户使用的时候也只要简单的定义继承类,注册事件处理类从而只要在事件继承类中填写处理代码就可以了呢。
看看OSG事件处理的客户代码是怎么写的:
先定义具体的事件处理类,这里是picking,必须从OSG预先定义好的事件处理接口继承
class PickHandler : public osgGA::GUIEventHandler
{
public:
看看OSG事件处理的客户代码是怎么写的:
先定义具体的事件处理类,这里是picking,必须从OSG预先定义好的事件处理接口继承
class PickHandler : public osgGA::GUIEventHandler
{
public:
//实现这个接口,在这里填写处理代码 };
bool handler(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa){ …};
bool handler(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa){ …};
};
再看看主程序:
int main(int argc, char** argv)
{
//创建场景的视图
osgViewer::Viewer viewer;
viewer.serSceneData( createScene().get());
//添加pick的事件处理类
viewer.addEventHandler(new PickHandler);
// create the windows and run the threads.
viewer.realize();
再看看主程序:
int main(int argc, char** argv)
{
//创建场景的视图
osgViewer::Viewer viewer;
viewer.serSceneData( createScene().get());
//添加pick的事件处理类
viewer.addEventHandler(new PickHandler);
// create the windows and run the threads.
viewer.realize();
while( !viewer.done() )
{
viewer.sync();// wait for all cull and draw threads to complete.
/*update the scene by traversing it with the the update visitor
{
viewer.sync();// wait for all cull and draw threads to complete.
/*update the scene by traversing it with the the update visitor
which will call all node update c