OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WGEGroupNode.h
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 #ifndef WGEGROUPNODE_H
26 #define WGEGROUPNODE_H
27 
28 #include <queue>
29 #include <utility>
30 
31 #include <boost/thread.hpp>
32 
33 #include <osg/MatrixTransform>
34 #include <osg/NodeCallback>
35 
36 #include "../common/WCondition.h"
37 #include "../common/WPredicateHelper.h"
38 #include "WExportWGE.h"
39 
40 /**
41  * Class to wrap around the osg Group node and providing a thread safe add/removal mechanism. Please be sure to use
42  * addUpdateCallback() to set your own update callbacks instead of setUpdateCallback, as this class already has set a callback,
43  * which would be overwritten by a subsequent call to setUpdateCallback(). It is derived from osg::MatrixTransform to allow easy transformations
44  * of a whole bunch of nodes.
45  *
46  * \ingroup GE
47  */
48 class WGE_EXPORT WGEGroupNode: public osg::MatrixTransform
49 {
50 public:
51 
52  /**
53  * Default constructor.
54  */
55  WGEGroupNode();
56 
57  /**
58  * Adds the specified node to the child list of this node in a safe manner. OSG officially requires nodes to be added
59  * exclusively during update callbacks. Using this method it is ensured to be added during update cycle.
60  *
61  * \param node the node to add.
62  *
63  * \note the node may not be added instantly. So do not assume that containsNode ( node ) will return true.
64  */
65  void insert( osg::ref_ptr< osg::Node > node );
66 
67  /**
68  * Removes the specified node from this group in a thread safe manner. It returns if the node has been removed.
69  *
70  * \param node the node to remove
71  */
72  void remove( osg::ref_ptr< osg::Node > node );
73 
74  /**
75  * The base type of predicate. Use a specific WPredicateHelper::ArbitraryPredicate instance. For details, see
76  * \ref WPredicateHelper::ArbitraryPredicateBase.
77  */
79 
80  /**
81  * Removes a node if the specified predicate evaluates to true.
82  * \see WPredicateHelper::ArbitraryPredicate for details.
83  *
84  * \param predicate the predicate.
85  */
86  void remove_if( boost::shared_ptr< WGEGroupNode::NodePredicate > predicate );
87 
88  /**
89  * Removes all children from this node.
90  */
91  void clear();
92 
93 protected:
94  /**
95  * Destructor.
96  */
97  virtual ~WGEGroupNode();
98 
99  /**
100  * Update callback which inserts and removes nodes from m_childRemovalQueue and m_childInsertionQueue to the group node.
101  * This ensures thread safe modification of the osg root node.
102  */
103  class SafeUpdaterCallback : public osg::NodeCallback
104  {
105  public:
106 
107  /**
108  * Callback method called by the NodeVisitor when visiting a node.
109  * This inserts and removes enqueued nodes from this group node instance.
110  *
111  * \param node the node calling this update
112  * \param nv The node visitor which performs the traversal. Should be an
113  * update visitor.
114  */
115  virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
116  };
117 
118  /**
119  * Node callback used to update this root node.
120  */
121  osg::ref_ptr< SafeUpdaterCallback > m_nodeUpdater;
122 
123  /**
124  * The type of operation to perform.
125  */
126  typedef enum
127  {
128  INSERT = 0, //! insert the specified node
129  REMOVE, //! remove the specified node
130  REMOVE_IF, //! remove all items where the predicate evaluates to true
131  CLEAR //! clear group node completely
132  }
133  ChildOperationType;
134 
135  /**
136  * A struct denoting an operation on this group. The operation itself, as well as the item and predicate are stored.
137  */
139  {
140  /**
141  * Constructs instance and fills members properly.
142  *
143  * \param what the operation to make
144  * \param item the child to delete
145  */
146  ChildOperation( ChildOperationType what, osg::ref_ptr< osg::Node > item ):
147  m_operation( what ),
148  m_item( item ),
149  m_predicate()
150  {
151  };
152 
153  /**
154  * Constructs instance and fills members properly.
155  *
156  * \param what the operation to make
157  * \param predicate the predicate to use for conditional operations (REMOVE_IF)
158  */
159  ChildOperation( ChildOperationType what, boost::shared_ptr< NodePredicate > predicate ):
160  m_operation( what ),
161  m_item(),
162  m_predicate( predicate )
163  {
164  };
165 
166  ChildOperationType m_operation; //!< the operation to take
167  osg::ref_ptr< osg::Node > m_item; //!< the item to delete/add
168  boost::shared_ptr< NodePredicate > m_predicate; //!< the predicate used by conditional operations
169  };
170 
171  /**
172  * Queue of childs that need to be added/removed during the next update cycle. It is a pair per operation, where the bool is denoting removal
173  * or insertion.
174  */
175  std::queue< boost::shared_ptr< ChildOperation > > m_childOperationQueue;
176 
177  /**
178  * Lock used for inserting and removing childs into the child insertion/removal queue.
179  */
180  boost::shared_mutex m_childOperationQueueLock;
181 
182  /**
183  * Flag denoting whether the m_childOperationQueue should be considered during the next update of the node.
184  */
186 
187  /**
188  * True whenever all child nodes should be removed.
189  */
191 
192 private:
193 };
194 
195 #endif // WGEGROUPNODE_H
196