OpenWalnut  1.4.0
WGEGroupNode.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <iostream>
26 
27 #include <osg/ShapeDrawable>
28 #include <osg/MatrixTransform>
29 #include <osg/Geode>
30 
31 #include "WGEGroupNode.h"
32 
34  osg::MatrixTransform(),
35  m_childOperationQueueDirty( false ),
36  m_removeAll( false )
37 {
38  setDataVariance( osg::Object::DYNAMIC );
39 
40  // setup an update callback
41  m_nodeUpdater = osg::ref_ptr< SafeUpdaterCallback >( new SafeUpdaterCallback() );
42  addUpdateCallback( m_nodeUpdater );
43 
44  osg::Matrix m;
45  m.makeIdentity();
46  setMatrix( m );
47 }
48 
50 {
51  // cleanup
52 }
53 
54 void WGEGroupNode::insert( osg::ref_ptr< osg::Node > node )
55 {
56  boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_childOperationQueueLock );
57  m_childOperationQueue.push( boost::shared_ptr< ChildOperation >( new ChildOperation( INSERT, node ) ) );
59  lock.unlock();
60 }
61 
62 void WGEGroupNode::remove( osg::ref_ptr< osg::Node > node )
63 {
64  boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_childOperationQueueLock );
65  m_childOperationQueue.push( boost::shared_ptr< ChildOperation >( new ChildOperation( REMOVE, node ) ) );
67  lock.unlock();
68 }
69 
70 void WGEGroupNode::remove_if( boost::shared_ptr< WGEGroupNode::NodePredicate > predicate )
71 {
72  boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_childOperationQueueLock );
73  m_childOperationQueue.push( boost::shared_ptr< ChildOperation >( new ChildOperation( REMOVE_IF, predicate ) ) );
75  lock.unlock();
76 }
77 
79 {
80  boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_childOperationQueueLock );
81  m_childOperationQueue.push( boost::shared_ptr< ChildOperation >( new ChildOperation( CLEAR, osg::ref_ptr< osg::Node >() ) ) );
82  // this encodes the remove all feature
84  lock.unlock();
85 }
86 
87 void WGEGroupNode::SafeUpdaterCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
88 {
89  // the node also is a WGEGroupNode
90  WGEGroupNode* rootNode = static_cast< WGEGroupNode* >( node );
91 
92  // write lock the insertion list
93  boost::unique_lock<boost::shared_mutex> lock;
94 
95  // write lock the removal list
96  if( rootNode->m_childOperationQueueDirty )
97  {
98  lock = boost::unique_lock<boost::shared_mutex>( rootNode->m_childOperationQueueLock );
99  // insert/remove children which requested it
100  while( !rootNode->m_childOperationQueue.empty() )
101  {
102  // remove or insert or remove all?
103  if( rootNode->m_childOperationQueue.front()->m_operation == INSERT )
104  {
105  // add specified child
106  rootNode->addChild( rootNode->m_childOperationQueue.front()->m_item );
107  }
108 
109  if( rootNode->m_childOperationQueue.front()->m_operation == REMOVE )
110  {
111  // remove specified child
112  rootNode->removeChild( rootNode->m_childOperationQueue.front()->m_item );
113  }
114 
115  if( rootNode->m_childOperationQueue.front()->m_operation == REMOVE_IF )
116  {
117  // remove children where m_predicate is true
118  for( size_t i = 0; i < rootNode->getNumChildren(); )
119  {
120  if( ( *rootNode->m_childOperationQueue.front()->m_predicate )( rootNode->getChild( i ) ) )
121  {
122  // remove item but do not increment index
123  rootNode->removeChild( i );
124  }
125 
126  // this was not removed. Go to next one.
127  ++i;
128  }
129  }
130 
131  if( rootNode->m_childOperationQueue.front()->m_operation == CLEAR )
132  {
133  // remove all
134  rootNode->removeChild( 0, rootNode->getNumChildren() );
135  }
136 
137  // pop item
138  rootNode->m_childOperationQueue.pop();
139  }
140 
141  rootNode->dirtyBound();
142 
143  // all children added/removed -> clear
144  rootNode->m_childOperationQueueDirty = false;
145  rootNode->m_removeAll = false;
146 
147  lock.unlock();
148  }
149 
150  // forward the call
151  traverse( node, nv );
152 }
153 
Update callback which inserts and removes nodes from m_childRemovalQueue and m_childInsertionQueue to...
Definition: WGEGroupNode.h:102
remove all items where the predicate evaluates to true
Definition: WGEGroupNode.h:129
virtual ~WGEGroupNode()
Destructor.
remove the specified node
Definition: WGEGroupNode.h:128
A struct denoting an operation on this group.
Definition: WGEGroupNode.h:136
virtual void operator()(osg::Node *node, osg::NodeVisitor *nv)
Callback method called by the NodeVisitor when visiting a node.
std::queue< boost::shared_ptr< ChildOperation > > m_childOperationQueue
Queue of childs that need to be added/removed during the next update cycle.
Definition: WGEGroupNode.h:173
boost::shared_mutex m_childOperationQueueLock
Lock used for inserting and removing childs into the child insertion/removal queue.
Definition: WGEGroupNode.h:178
void insert(osg::ref_ptr< osg::Node > node)
Adds the specified node to the child list of this node in a safe manner.
osg::ref_ptr< SafeUpdaterCallback > m_nodeUpdater
Node callback used to update this root node.
Definition: WGEGroupNode.h:119
Class to wrap around the osg Group node and providing a thread safe add/removal mechanism.
Definition: WGEGroupNode.h:48
void clear()
Removes all children from this node.
WGEGroupNode()
Default constructor.
bool m_removeAll
True whenever all child nodes should be removed.
Definition: WGEGroupNode.h:188
insert the specified node
Definition: WGEGroupNode.h:127
bool m_childOperationQueueDirty
Flag denoting whether the m_childOperationQueue should be considered during the next update of the no...
Definition: WGEGroupNode.h:183
void remove_if(boost::shared_ptr< WGEGroupNode::NodePredicate > predicate)
Removes a node if the specified predicate evaluates to true.
void remove(osg::ref_ptr< osg::Node > node)
Removes the specified node from this group in a thread safe manner.