eng_node_clones.hh

Go to the documentation of this file.
00001 /*
00019  * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
00020  *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
00021  *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
00022  *****************************************************************************/
00023 
00024 #ifndef ENG_NODE_CLONES_HH
00025 #define ENG_NODE_CLONES_HH 1
00026 
00027 namespace eng {
00028 
00033 class NodeClones
00034 {
00035 public:
00036     NodeClones( void ) { }
00037     ~NodeClones() { }
00038 
00039     // tweak: Use Node& instead of Node::Ptr to bypass ref-cnt (be careful).
00040     // Clone() is low-freq and should affect ref-cnt.
00041 
00043     inline bool
00044     IfClone( const Node& node ) const
00045     {
00046         return node.mCloneIdx != Node::INVALID_IDX;
00047     }
00048 
00051     inline bool
00052     IfCloneOfThisGraph( const Node& node ) const
00053     {
00054         // tweak: INVALID_IDX omitted since invariantly is > mClones.size().
00055         return node.mCloneIdx < mClones.size()  // in case parent Graph has clone this Graph doesn't
00056            and mClones[node.mCloneIdx] != NULL_NODE;
00057     }
00058 
00061     void Clone( Node::Ptr node )
00062     {
00063     CHECK_NODE( node );
00064 
00065         // NOP if a clone already exists in this Graph.
00066         if ( not IfCloneOfThisGraph( *node ) )
00067         {
00068             // This Node might've been cloned in a parent Graph.
00069             // If so, reuse the same clone index.
00070             // Else, assign a new clone index.
00071             if ( node->mCloneIdx == Node::INVALID_IDX )
00072             {
00073                 node->mCloneIdx = mClones.size();  // assign new clone index
00074             }
00075 
00076             // Expand mClones[] container.
00077             Expand( mClones, node->mCloneIdx );
00078 
00079             // Make a clone of this Node and store in container.
00080             // Clone() invokes copy ctor which copies the same clone index.
00081             mClones[node->mCloneIdx] = node->Clone();
00082 
00083             ASSERT( node->mCloneIdx == mClones[node->mCloneIdx]->mCloneIdx );  // check copy ctor
00084             ASSERT( node->mCloneIdx < mClones.size() );                        // check Expand()
00085             ASSERT( long(mClones.size()) < long(MAX_NODES_PER_OBJECT) );       // check overrun
00086         }
00087     }
00088 
00092     Node*  // -- raw ptr to speed Graph::Traverse() --
00093     GetCloneOrOriginal( Node& node )  // hi-freq
00094     {
00095     CHECK_NODE( &node );
00096     ASSERT2( Node::INVALID_IDX != 0 );  // here 0 is used as an index
00097     ASSERT( long(mClones.size()) < long(MAX_NODES_PER_OBJECT) );
00098 
00099         // As a Graph is forked, some of its Nodes may be assigned
00100         // clone indexs that are outside mClones[] of earlier Graphs.
00101         // This means the older Graphs are still using the original nodes.
00102 
00103         // Obi One!  Are you OB1?
00104         if ( EX( not IfCloneOfThisGraph(node) ) )
00105         {
00106             return &node;  // return back the original Node
00107         }
00108         else
00109         {
00110         CHECK_NODE( mClones[node.mCloneIdx] );
00111         ASSERT( node.mCloneIdx == mClones[node.mCloneIdx]->mCloneIdx );  // should be equal
00112 
00113             return mClones[node.mCloneIdx].PTR();  // this Graph has a clone
00114         }
00115     }
00116 
00117 private:
00118     // vector is ultimately faster than deque.
00119     typedef vector<Node::Ptr>   Clones;
00120     Clones                      mClones;
00121 };
00122 
00123 } // namespace eng
00124 
00125 #endif // ENG_NODE_CLONES_HH
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:09 2007