OSG 事件处理机制 类图

来源:互联网 发布:nike手机抢购软件 编辑:程序博客网 时间:2024/05/16 14:48


本文为osg源码学习笔记,有理解不当之处,请随时指正. 

PS: 本文参考osg 版本: 3.4.0


1. 事件处理框架

OSG的事件处理可分为两个大的模块. 

1)  事件适配模块(类图右侧) : 为各窗口平台中间抽象层(GA: GUI Abstraction)或适配层, 将各平台的用户输入事件适配为OSG内部定义的事件(EventAdapter).   

2) 事件处理模块(类图左侧):  为用户提供输入事件的处理机制. 用户注册事件handler,对输入事件(EventAdapter)进行处理. 

osg 事件处理类图




2. 源码分析

按照从 用户事件输入->用户事件处理的过程,用源码佐证上述分析. 整个分析过程,以鼠标事件为例.


1) 平台相关事件 适配为  OSG内部定义事件

a. 接收用户输入

源码现场: GraphicsWindowWin32::handleNativeWindowingEvent()

以鼠标事件为例,将windows鼠标事件的相关信息,交由eventqueue处理. 

        case WM_LBUTTONDOWN :        case WM_MBUTTONDOWN :        case WM_RBUTTONDOWN :        /////////////////////            {                ::SetCapture(hwnd);                int button;                if (uMsg==WM_LBUTTONDOWN)      button = 1;                else if (uMsg==WM_MBUTTONDOWN) button = 2;                else button = 3;                _capturedMouseButtons.insert(button);                float mx = GET_X_LPARAM(lParam);                float my = GET_Y_LPARAM(lParam);                transformMouseXY(mx, my);                getEventQueue()->mouseButtonPress(mx, my, button, eventTime);            }            break;


b. 适配事件, 并添加至事件队列

源码现场: osgGA::GUIEventAdapter* EventQueue

GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);    event->setEventType(GUIEventAdapter::PUSH);    event->setTime(time);    switch(button)    {        case(1):            event->setButton(GUIEventAdapter::LEFT_MOUSE_BUTTON);            break;        case(2):            event->setButton(GUIEventAdapter::MIDDLE_MOUSE_BUTTON);            break;        case(3):            event->setButton(GUIEventAdapter::RIGHT_MOUSE_BUTTON);            break;    }    addEvent(event);
事件处理时序图
2) 事件处理

至此,用户 输入外部事件已经适配为osg内部eventAdapter,并添加至事件队列中. 

Viewer负责在事件更新循环中,将事件队列中的事件,分发给各event handler进行处理. 

源码现场: Viewer::eventTraversal()

   for(osgGA::EventQueue::Events::iterator itr = events.begin();        itr != events.end();        ++itr)    {        osgGA::Event* event = itr->get();        for(EventHandlers::iterator hitr = _eventHandlers.begin();            hitr != _eventHandlers.end();            ++hitr)        {          (*hitr)->handle( event, 0, _eventVisitor.get());        }    }



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 7个月宝宝肚子疼怎么办 奶喝一半凉了怎么办 5个月孩子厌奶怎么办 怀孕后特别不爱吃水果怎么办 宝宝吃了无比滴怎么办 婴儿上火怎么办吃什么可以去火 肚子胀怎么办最快的方法 40天婴儿拉水怎么办 8个月宝宝坐不稳怎么办 宝宝段奶不吃奶粉怎么办 3个月宝宝头睡偏了怎么办 2个月婴儿抱着睡怎么办 两个半月的宝宝睡眠少怎么办 七个月宝宝不愿意坐怎么办 一个多月的宝宝老是哭闹怎么办 宝宝头老往后仰怎么办 8个月宝宝不会爬怎么办 孩子个头长得慢怎么办 宝宝个头长得慢怎么办 婴儿个头长得慢怎么办 11个月宝宝认生怎么办 3个月宝宝认人怎么办 3个月的宝宝认生怎么办 两个月的宝宝睡觉一惊一惊怎么办 六个月宝宝不喜欢喝水怎么办 三岁宝宝尿多怎么办 一岁的宝宝尿少怎么办 一岁宝宝尿黄怎么办 三岁宝宝尿黄怎么办 5个月宝宝认生怎么办 3岁宝宝怕生胆小怎么办 2岁宝宝怕生胆小怎么办 1岁半宝宝认生怎么办 宝宝认人一直哭怎么办 七个月宝宝认人怎么办 一个月宝宝认人怎么办 2个多月宝宝认人怎么办 婴儿认人一直哭怎么办 六个月宝宝认人怎么办 十一个月宝宝断奶后辅食怎么办 6个月宝宝不会坐怎么办