如何在osg中删除EventHandler

最近在一个项目中需要动态的添加和删除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删除。
 
这样就解决上面出现的问题了。




原文地址:https://www.cnblogs.com/chaoswong/p/3151942.html