添加自定义事件以及对osg事件队列的简单理解

添加自定义事件

首先osg在其内部通过osgGA::EventQueue类维护了一个事件队列,队列中的每一个事件都是一个osgGA::GUIEventAdapter对象(这个对象是用来存放所系统捕捉到的事件),在仿真循环阶段被系统捕捉到的所有事件都会被添加到这个事件队列中,之后会有一个事件遍历过程,在这个过程中实际上就是遍历这个事件队列,并且对事件队列中的每一个事件,它都会与我们在事件处理类中方法进行响应(如果事件处理类中没有对这个事件的处理则不会响应)。 

(此代码来自于王锐老师的Beginner‘s Guide中240页)

[cpp]  view plain  copy
  1. struct TimerInfo : public osg::Referenced  
  2. {  
  3.  TimerInfo( unsigned int c ) : _count(c) {}  
  4.  unsigned int _count;  
  5. };  


[cpp]  view plain  copy
  1. bool TimerHandler::handle( const osgGA::GUIEventAdapter& ea,  
  2. osgGA::GUIActionAdapter& aa )  
  3. {  
  4. switch ( ea.getEventType() )  
  5. {  
  6. case osgGA::GUIEventAdapter::FRAME:   
  7. if (_count % 100 == 0 )  
  8. {  
  9. osgViewer::Viewer* viewer =  
  10. dynamic_cast<osgViewer::Viewer*>(&aa);  
  11. if ( viewer )  
  12. {  
  13. //在这里,我们添加了一个用户自定义的时间,我们只需要在下面的时间类型中对USER类型进行判断即可对此事件进行处理,  
[cpp]  view plain  copy
  1. //注意其参数是一个继承自Reference类的对象。  
  2. viewer->getEventQueue()->userEvent(  
  3. new TimerInfo(_count) );  
  4. }  
  5. }  
  6. _count++;  
  7. break;  
  8. case osgGA::GUIEventAdapter::USER:  
  9. if ( _switch.valid() )  
  10. {  
  11. //同过getUserData方法,直接获取用户数据(我们在上面传入的继承自Reference类的对象)  
  12. const TimerInfo* ti =  
  13. dynamic_cast<const TimerInfo*>( ea.getUserData());  
  14. std::cout << "Timer event at: " <<ti->_count<<  
  15. std::endl;  
  16. _switch->setValue( 0, !_switch->getValue(0) );  
  17. _switch->setValue( 1, !_switch->getValue(1) );  
  18. }  
  19. break;  
  20. default:  
  21. break;  
  22. }  
  23. return false;  
  24. }  

在上面这个handle函数中,我们定义了对两个事件的处理,一个为FRAME事件,另一个为USER事件,在FRAME事件的处理中,首先判断_count值是否能呗100整除(在每一个FRAME事件中都会使_count值加一),即每过100帧就会执行一遍if语句下面的内容。在if语句中,它通过调用userEvent方法将事件加入到事件队列中。


上面的图片是userEvent函数的实现源码,我们可以看到在调用userEvent方法时,其函数内部的实现如上,首先设置时间类型为USER(即我们用此方法添加到事件队列中的事件的类型为USER),其次调用setUserData方法设置用户数据,之后设置时间,最后通过addEvent方法将其添加到事件队列中去。这样我们就能在事件处理的handle函数中对此事件进行响应了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值