最近在一个项目中需要动态的添加和删除EventHandler,添加的时候很顺利,使用view->addEventHandler()函数就可以了。
不过在删除的时候,出现点麻烦。
 
直接调用view->removeEventHandler()函数,会导致view在调用frame函数时,崩在这个位置:

void CompositeViewer::eventTraversal()
{
    ...
    
    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
        veitr != viewEventsMap.end();
        ++veitr)
    {
        View* view = veitr->first;
        for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
            itr != veitr->second.end();
            ++itr)
        {
            osgGA::GUIEventAdapter* event = itr->get();
            for(View::EventHandlers::iterator hitr = view->getEventHandlers().begin();
                hitr != view->getEventHandlers().end();
                ++hitr)
            {
                (*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view, 0, 0);
            }
        }
    } 
    ...
}
错误提示说是越界了。
 
跟了一下代码,发现OSG的处理流程是这样的:
定时调用frame函数,在frame函数中主要干这么三件事:

    eventTraversal();
    updateTraversal();
    renderingTraversals();
  其中eventTraversal就是遍历eventHandler,调用它们的handler函数,来处理所有的事件;updateTraversal是处理更新的相关事情;renderingTraversals看名字就是处理渲染的事项了。
 
而在我自己的function类中,在处理完onLButtonDown函数后,我自己就把自己给删除了(removeEventHandler),这样在上面红色部分的代码继续往下走时,自然就会发生越界情况!!
 
当刚出现这个问题时,我上网上搜了一下,发现osgchina的array是这样处理的:
删除的动作最好在更新回调中完成。
 
所以我的改法也是类似,在想删除的时候,做了个记号,标志当前的EventHandler需要删除;然后我重载了updateTraversal函数,在这里检查记号,如果做过记号,就将当前的EventHandler删除。
 
这样就解决上面出现的问题了。

如何在osg中删除EventHandler的更多相关文章

  1. git中手动删除的文件如何在git中删除

    在日常开发中,我们可能或手动删除(delete键删除的)一些文件,然而我们本来应该是用git rm fileName命令删除的,但是现在我们手动删除了,那么要如何在git里面讲那些手动删除的文件删除呢 ...

  2. 如何在Github中删除已有仓库或文件

    一.删除已有仓库如果我们想要删除Github中没有用的仓库,应该如何去做呢? 进入到我们需要删除的仓库里面,找到“settings”即仓库设置: 然后,在仓库设置里拉到最底部,找到“Danger Zo ...

  3. 如何在git中删除指定的文件和目录

    部分场景中,我们会希望删除远程仓库(比如GitHub)的目录或文件. 具体操作 拉取远程的Repo到本地(如果已经在本地,可以略过) $ git clone xxxxxx 在本地仓库删除文件 $ gi ...

  4. 如何在MySQL中删除表中指定列的唯一键?

    语法结构如下: alter table table_name drop  index column_name;

  5. 如何在Linux中轻松删除源安装的软件包?

    第1步:安装Stow 在这个例子中,我们使用的是CentOS,因此我们需要扩展的EPEL库.您可以使用以下命令安装它们:yum install epel-release然后,下面这段命令:yum in ...

  6. 如何在Linux中自动删除或清理/tmp文件夹内容?

    每个Linux系统都有一个名为的目录/tmp,该目录已挂载了单独的文件系统. 它具有称为tmpfs的特殊文件系统.这是一个虚拟文件系统,操作系统将在系统引导时自动挂载/tmp挂载点. 如果要根据应用程 ...

  7. OSG中的示例程序简介

    OSG中的示例程序简介 转自:http://www.cnblogs.com/indif/archive/2011/05/13/2045136.html 1.example_osganimate一)演示 ...

  8. OSG中的示例程序简介(转)

    OSG中的示例程序简介 1.example_osganimate一)演示了路径动画的使用 (AnimationPath.AnimationPathCallback),路径动画回调可以作用在Camera ...

  9. 一步一步学Silverlight 2系列(20):如何在Silverlight中与HTML DOM交互(下)

    述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

随机推荐

  1. 一个通过网络转换Ico到Png图片的小小程序(Ico2Png)

    做软件界面需要用到ico文件, 结果皮肤库不支持ico格式的图标, 所以就想到了把ico转换成png. 网上ico转png的软件貌似并不多, 反倒是png转ico很大一片~~~~~~~~~ 要转换ic ...

  2. [LeetCode] Ugly Number II

    Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime factors ...

  3. hdu 4293 2012成都赛区网络赛 dp ****

    题意:有n个人,可任意分成若干组,然后每个人个各提供一个信息,表示他们组前面有多少人,后面有多少人.问最多有多少个信息是不冲突的. 将n个人看成一组区间,然后每个人的信息可以表示为该人所在组的区间,然 ...

  4. loj 1037(状压dp)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25914 思路:dp[state]表示当前状态下要消耗的最小的sho ...

  5. javascript中时间的手动创建date的方式

    new Date("month dd,yyyy hh:mm:ss"); new Date("month dd,yyyy"); new Date(yyyy,mth ...

  6. 通信原理实践(四)——模拟通信系统性能分析

    一.模拟通信系统性能分析 1.系统框图 2.信噪比定义 (1)输入信噪比: (2)输出信噪比: (3)调制制度增益: 3.模拟通信系统分析等价模型 即自己产生一个高斯白噪声,加入到调制信号,然后在送入 ...

  7. mysql 怎样清空一个数据库中的所有表

    转自:http://blog.csdn.net/zhangzhizhen1988/article/details/8432146 MySQL清空表是很重要的操作,也是最常见的操作之一,下面就为您详细介 ...

  8. mysql性能监控相关

    目录 一,获取mysql用户下的进程总数 二,主机性能状态 三,CPU使用率 四,磁盘IO量 五,swap进出量[内存] 六,数据库性能状态 七.querylog 八.mysqladmin的exten ...

  9. JavaScript 入门 (1)

    一. javascript的调用 JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到<head>中: <html> <hea ...

  10. SpringMVC解析5-DispatcherServlet逻辑细节

    MultipartContent类型的request处理 对于请求的处理,spring首先考虑的是对于Multipart的处理,如果是MultipartContent类型的request,则转换req ...