OpenWalnut 1.2.5
WGEGroupNode.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WGEGROUPNODE_H
00026 #define WGEGROUPNODE_H
00027 
00028 #include <queue>
00029 #include <utility>
00030 
00031 #include <boost/thread.hpp>
00032 
00033 #include <osg/MatrixTransform>
00034 #include <osg/NodeCallback>
00035 
00036 #include "../common/WCondition.h"
00037 #include "../common/WPredicateHelper.h"
00038 #include "WExportWGE.h"
00039 
00040 /**
00041  * Class to wrap around the osg Group node and providing a thread safe add/removal mechanism. Please be sure to use
00042  * addUpdateCallback() to set your own update callbacks instead of setUpdateCallback, as this class already has set a callback,
00043  * which would be overwritten by a subsequent call to setUpdateCallback(). It is derived from osg::MatrixTransform to allow easy transformations
00044  * of a whole bunch of nodes.
00045  *
00046  * \ingroup GE
00047  */
00048 class WGE_EXPORT WGEGroupNode: public osg::MatrixTransform
00049 {
00050 public:
00051 
00052     /**
00053      * Default constructor.
00054      */
00055     WGEGroupNode();
00056 
00057     /**
00058      * Adds the specified node to the child list of this node in a safe manner. OSG officially requires nodes to be added
00059      * exclusively during update callbacks. Using this method it is ensured to be added during update cycle.
00060      *
00061      * \param node the node to add.
00062      *
00063      * \note the node may not be added instantly. So do not assume that containsNode ( node ) will return true.
00064      */
00065     void insert( osg::ref_ptr< osg::Node > node );
00066 
00067     /**
00068      * Removes the specified node from this group in a thread safe manner. It returns if the node has been removed.
00069      *
00070      * \param node the node to remove
00071      */
00072     void remove( osg::ref_ptr< osg::Node > node );
00073 
00074     /**
00075      * The base type of predicate. Use a specific WPredicateHelper::ArbitraryPredicate instance. For details, see
00076      * \ref WPredicateHelper::ArbitraryPredicateBase.
00077      */
00078     typedef WPredicateHelper::ArbitraryPredicateBase< osg::ref_ptr< osg::Node > const > NodePredicate;
00079 
00080     /**
00081      * Removes a node if the specified predicate evaluates to true.
00082      * \see WPredicateHelper::ArbitraryPredicate for details.
00083      *
00084      * \param predicate the predicate.
00085      */
00086     void remove_if( boost::shared_ptr< WGEGroupNode::NodePredicate > predicate );
00087 
00088     /**
00089      * Removes all children from this node.
00090      */
00091     void clear();
00092 
00093 protected:
00094     /**
00095      * Destructor.
00096      */
00097     virtual ~WGEGroupNode();
00098 
00099     /**
00100      * Update callback which inserts and removes nodes from m_childRemovalQueue and m_childInsertionQueue to the group node.
00101      * This ensures thread safe modification of the osg root node.
00102      */
00103     class SafeUpdaterCallback : public osg::NodeCallback
00104     {
00105     public:
00106 
00107         /**
00108          * Callback method called by the NodeVisitor when visiting a node.
00109          * This inserts and removes enqueued nodes from this group node instance.
00110          *
00111          * \param node the node calling this update
00112          * \param nv The node visitor which performs the traversal. Should be an
00113          * update visitor.
00114          */
00115         virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
00116     };
00117 
00118     /**
00119      * Node callback used to update this root node.
00120      */
00121     osg::ref_ptr< SafeUpdaterCallback > m_nodeUpdater;
00122 
00123     /**
00124      * The type of operation to perform.
00125      */
00126     typedef enum
00127     {
00128         INSERT = 0,         //! insert the specified node
00129         REMOVE,             //! remove the specified node
00130         REMOVE_IF,          //! remove all items where the predicate evaluates to true
00131         CLEAR               //! clear group node completely
00132     }
00133     ChildOperationType;
00134 
00135     /**
00136      * A struct denoting an operation on this group. The operation itself, as well as the item and predicate are stored.
00137      */
00138     struct ChildOperation
00139     {
00140         /**
00141          * Constructs instance and fills members properly.
00142          *
00143          * \param what the operation to make
00144          * \param item the child to delete
00145          */
00146         ChildOperation( ChildOperationType what, osg::ref_ptr< osg::Node > item ):
00147             m_operation( what ),
00148             m_item( item ),
00149             m_predicate()
00150         {
00151         };
00152 
00153         /**
00154          * Constructs instance and fills members properly.
00155          *
00156          * \param what the operation to make
00157          * \param predicate the predicate to use for conditional operations (REMOVE_IF)
00158          */
00159         ChildOperation( ChildOperationType what, boost::shared_ptr< NodePredicate > predicate ):
00160             m_operation( what ),
00161             m_item(),
00162             m_predicate( predicate )
00163         {
00164         };
00165 
00166         ChildOperationType m_operation;                     //!< the operation to take
00167         osg::ref_ptr< osg::Node > m_item;                   //!< the item to delete/add
00168         boost::shared_ptr< NodePredicate > m_predicate;     //!< the predicate used by conditional operations
00169     };
00170 
00171     /**
00172      * 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
00173      * or insertion.
00174      */
00175     std::queue< boost::shared_ptr< ChildOperation > > m_childOperationQueue;
00176 
00177     /**
00178      * Lock used for inserting and removing childs into the child insertion/removal queue.
00179      */
00180     boost::shared_mutex m_childOperationQueueLock;
00181 
00182     /**
00183      * Flag denoting whether the m_childOperationQueue should be considered during the next update of the node.
00184      */
00185     bool m_childOperationQueueDirty;
00186 
00187     /**
00188      * True whenever all child nodes should be removed.
00189      */
00190     bool m_removeAll;
00191 
00192 private:
00193 };
00194 
00195 #endif  // WGEGROUPNODE_H
00196 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends