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