查看: 1933|回复: 8

删除节点后程序崩溃

[复制链接]

该用户从未签到

发表于 2011-2-24 09:33:32 | 显示全部楼层 |阅读模式
本帖最后由 qingfeng5211 于 2011-2-24 09:34 编辑

用MFC框架做了个程序, 通过点击工具栏添加节点, 通过在view中点击选择然后按delete键来删除节点, 第一次删除没有问题,反复添加删除几次,再次点击添加时就崩溃了。


我在论坛了看了以往的帖子,添加和删除都是放在NodeCallback里进行的。不知道是什么问题,请大牛们指点。

我用2.9.9版本发现有问题,就又编译2.8.3版本试了一下,还是有问题。

更新回调实现
  1. CAddRemoveCallback::CAddRemoveCallback()
  2. {
  3.         _paused = TRUE;
  4. }
  5. void CAddRemoveCallback::operator()(osg::Node * node, osg::NodeVisitor * nv)
  6. {
  7.         if(!_paused)
  8.         {
  9.                 osg::Group* root = dynamic_cast<osg::Group*>(node);
  10.                 if ( root != NULL )
  11.                 {
  12.                         for ( size_t i = 0; i < _vtRemoving.size(); ++i )
  13.                         {
  14.                                 osg::Node::ParentList parents = _vtRemoving[i]->getParents();
  15.                                 for(osg::Node::ParentList::iterator it = parents.begin();
  16.                                         it!=parents.end();
  17.                                         ++it)
  18.                                 {
  19.                                         (*it)->removeChild(_vtRemoving[i]);
  20.                                 }
  21.                         }

  22.                         if (_vtRemoving.size()>0)
  23.                         {
  24.                                 _vtRemoving.clear();
  25.                         }
  26.                         for ( size_t i = 0; i < _vtAdding.size(); ++i )
  27.                         {
  28.                                 root->addChild( _vtAdding[i] );
  29.                         }
  30.                         
  31.                         if (_vtAdding.size())
  32.                         {
  33.                                 _vtAdding.clear();
  34.                         }
  35.                 }
  36.                 _paused = TRUE;
  37.         }
  38. }

  39. void CAddRemoveCallback::AddNode(osg::Node * node)
  40. {
  41.         _paused = FALSE;
  42.         _vtAdding.push_back(node);
  43. }
  44. void CAddRemoveCallback::RemoveNode(osg::Node * node)
  45. {
  46.         _paused = FALSE;
  47.         _vtRemoving.push_back(node);
  48. }
  49. void CAddRemoveCallback::SetFlag(BOOL bpaused)
  50. {
  51.         _paused = bpaused;
  52. }
复制代码


添加时的调用:

  1.         mRoot = new osg::Group;
  2. mRoot->setDataVariance(osg::Object::DYNAMIC);
  3. mAddRemoveCallback = new CAddRemoveCallback;
  4. mRoot->setUpdateCallback(mAddRemoveCallback);

  5. mAddRemoveCallback->AddNode(group);
复制代码


删除时的调用

  1. mAddRemoveCallBack->RemoveNode(group2);
复制代码

该用户从未签到

发表于 2011-2-24 10:10:44 | 显示全部楼层
这种方法还是有问题的。
因为添加、删除都不是实时起作用的,这种操作延迟会造成外部客户端代码的其它不安全问题。这是导致崩溃的原因。
实际上在每一帧渲染结束后执行添加删除工作也可以,但是同样应该注意多线程与操作延迟带来的不安全问题。

该用户从未签到

 楼主| 发表于 2011-2-24 10:35:35 | 显示全部楼层
本帖最后由 qingfeng5211 于 2011-2-24 10:42 编辑

回复 2# qele


添加删除的类也是参考你的代码实现的,谢谢。


你说的“每帧后”,怎么实现呢?是放在frame()函数调用之后吗?

不知道各位大牛添加和删除节点一般都采用什么方法?

该用户从未签到

发表于 2011-2-24 11:27:33 | 显示全部楼层
在回调中进行当然是最好的,可以通过修改状态来出来处理某个节点的。

该用户从未签到

 楼主| 发表于 2011-2-24 11:33:18 | 显示全部楼层
回复 4# aaa696


回调中处理的话,我给出的代码有什么问题吗?为什么总崩溃?

放到帧渲染之后,好像没有问题了,不知道会不会影响效率

该用户从未签到

发表于 2011-2-24 14:36:25 | 显示全部楼层
在回调中进行是最好的选择,所谓的“帧渲染之后”,其实是很不安全的

该用户从未签到

 楼主| 发表于 2011-2-24 15:17:33 | 显示全部楼层
本帖最后由 qingfeng5211 于 2011-2-24 15:20 编辑

回复 6# array

array 能帮我看看我贴出的代码那里有问题吗?我贴出的代码就是参考你说的在nodecallback里添加和删除节点。


删除操作后不会马上崩溃,但是再次添加就崩溃了

放在帧渲染之后处理,崩溃的几率下降了,但是反复操作几次还是会崩掉的

该用户从未签到

发表于 2011-2-24 16:55:42 | 显示全部楼层
不知您的AddNode和RemoveNode函数是什么时候调用的,如果是在界面线程里,那么我没有看到任何有关线程数据保护的操作,这样无疑是很危险的

该用户从未签到

 楼主| 发表于 2011-2-24 17:10:57 | 显示全部楼层
回复 8# array


添加时响应单击界面按钮实现的,删除是在GUIEventHandler的消息响应里面处理的。

那应该是线程没有保护的问题了,谢谢array
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表