osgGA 是osg GUI Abstraction的简写,即:对各类平台中GUI(Graphic User Interface)接口的适配。它的设计目标和继承关系:
1.osgGA::Event/osgGA::EventHandler/osg::GA::EventQueue/osgGA::EventVisitor
osgGA::Event继承自osg::object,osg称其是Event的基类,内容也比较简单,仅包括handle及time两个成员。
osgGA::EventHandler相对于osgGA::Event定义,可理解为Event的处理者,它继承自osg::NodeCallback,osg::DrawableEventCallback。PS:事务处理类Type(class也是个Type)的设计里,一定有一个“执行”或“处理”的函数,也就是它的核心功能函数,osgGA::EventHandler里是:
OsgGA::EventQueue是被设计成 windows的事务(Events)的收集和适配(adept),核心成员是typedef std::list< osg::ref_ptr > Events;成员函数比较多,因为输入设备类型多、没种输入设计的Event类型也比较多(输入设备:鼠标、键盘、触摸屏、手写笔、操作杆,输入设备的Event:按键、滚轮、触摸点,总结下就是手指可做出的动作:拉、压、滚)。
2.osgGA::GUIEventAdapter/osgGA::GUIEventHandler/GUIActionAdapter
2.1 osgGA::GUIEventAdapter -> osgGA::Event 是鼠标、键盘、window Events的适配器,负责保存以上Event相关的数据(比如:按是哪个键)。
2.2 osgGA::GUIEventHandler -> osgGA::EventHandler是事务处理者的必要接口的封装,任何想进入“事务处理者”队列的class都必须从此类继承且实现必须的接口。Osg对它举了栗子:
例如,想象一个可以接收鼠标事务(Event),并通过操纵场景相机进行回应的轨迹球视图。该轨迹球视图就是一个“GUIActionHandler”,它通过“Handle”方法来接收事务。如果用户通过轨迹球来滚动模型(即:通过操作轨迹球来实现视图中模型的滚动效果),则轨迹球视图类可以接收到这个动作,并且要求GUI建立一个时间回调以实现视口的持续刷新。要求GUI这个动作是通过“GUIActionAdapter”完成的。
2.3 GUIActionAdapter 成员不多,但osg对它的注解很长,足以说明它很重要。下面写出osg注解的要点:
1.osgGA::GUIActionAdapter是个虚基类,其接口是GUIEventHandler可能会要求GUI系统做出的回应。GUIEventHandler会发出哪些要求取决于用户系统中的GUI工具包。
2.GUIEventHandler接收到事务(Event)后,它会想做出某些回应,但是它做不到,因为它不清楚平台系统(即:操作系统)可以做到什么。为了解决这一问题,GUIEventHandler通过GUIActionAdapter发布自己的要求,视图则通过平台系统上的GUI工具包回应这个要求。
3.还有其他使用GUIActionAdapter的方法,例如可以从它继承一个视图类,就像已存在的osgGLUT::Viewer。另外,一个从GUIActionAdapter继承的简单类(比如osgQt::QtActionAdapter)可以通往GUIEventHandler::handle()函数;一旦该函数返回,视图马上就能得到handle()的返回结果,并且对GUIActionAdapter的要求做出回应。
4.这里还有其他几种方法来运行你自己的应用和处理窗口的刷新。osgGLUT::Viewer有一个已经注册过的随时等候的回调函数负责刷新。所以,osgGLUT::Viewer可以安全的忽略requestRedraw() 和requestContinousUpdate(),因为它时刻在刷新。
5.其他应用如果想回应requestRedraw() 和requestContinousUpdate(), 依然有很多其他方法。可以override函数requestRedraw() 和requestContinousUpdate(),然后调用自己的窗口刷新。