diff --git a/panda/src/builder/builder.cxx b/panda/src/builder/builder.cxx index f068def05c..8ab13825b9 100644 --- a/panda/src/builder/builder.cxx +++ b/panda/src/builder/builder.cxx @@ -179,7 +179,9 @@ build(const string &default_name) { } // Only reparent the geom_node if it has no parent already. - if (geom_node->_parents.empty()) { + int num_parents = + geom_node->get_num_parents(RenderRelation::get_class_type()); + if (num_parents == 0) { if (geom_node->get_num_geoms() == 0) { // If there was nothing added, never mind. delete geom_node; diff --git a/panda/src/graph/Sources.pp b/panda/src/graph/Sources.pp index 91bc8f2ada..f2b859834e 100644 --- a/panda/src/graph/Sources.pp +++ b/panda/src/graph/Sources.pp @@ -7,116 +7,81 @@ putil mathutil #define SOURCES \ - allAttributesWrapper.I nodeAttributes.cxx \ - allAttributesWrapper.T nodeAttributes.h \ - allAttributesWrapper.cxx nodeRelation.I \ - allAttributesWrapper.h nodeRelation.N \ - allTransitionsWrapper.I nodeRelation.T \ - allTransitionsWrapper.T nodeRelation.cxx \ - allTransitionsWrapper.cxx nodeRelation.h \ - allTransitionsWrapper.h nodeTransition.I \ - arcChain.I nodeTransition.N \ - arcChain.cxx nodeTransition.cxx \ - arcChain.h nodeTransition.h \ - bitMask32Transition.cxx nodeTransitionCache.I \ - bitMask32Transition.h nodeTransitionCache.cxx \ - bitMaskAttribute.T nodeTransitionCache.h \ - bitMaskAttribute.h nodeTransitionCacheEntry.I \ - bitMaskTransition.T nodeTransitionCacheEntry.cxx \ - bitMaskTransition.h nodeTransitionCacheEntry.h \ - boundedObject.I nodeTransitionWrapper.I \ - boundedObject.N nodeTransitionWrapper.T \ - boundedObject.cxx nodeTransitionWrapper.cxx \ - boundedObject.h nodeTransitionWrapper.h \ - config_graph.cxx nodeTransitions.I \ - config_graph.h nodeTransitions.T \ - dftraverser.T nodeTransitions.cxx \ - dftraverser.h nodeTransitions.h \ - graphReducer.cxx nullAttributeWrapper.I \ - graphReducer.h nullAttributeWrapper.cxx \ - immediateAttribute.cxx nullAttributeWrapper.h \ - immediateAttribute.h nullLevelState.cxx \ - immediateTransition.I nullLevelState.h \ - immediateTransition.cxx nullTransitionWrapper.I \ - immediateTransition.h nullTransitionWrapper.cxx \ - lmatrix4fTransition.cxx nullTransitionWrapper.h \ - lmatrix4fTransition.h onAttribute.cxx \ - matrixAttribute.T onAttribute.h \ - matrixAttribute.h onOffAttribute.I \ - matrixTransition.T onOffAttribute.cxx \ - matrixTransition.h onOffAttribute.h \ - multiAttribute.T onOffTransition.I \ - multiAttribute.h onOffTransition.cxx \ - multiNodeAttribute.cxx onOffTransition.h \ - multiNodeAttribute.h onTransition.I \ - multiNodeTransition.cxx onTransition.cxx \ - multiNodeTransition.h onTransition.h \ - multiTransition.T pointerNameClass.h \ - multiTransition.h pt_NamedNode.N \ - multiTransitionHelpers.I pt_NamedNode.cxx \ - multiTransitionHelpers.h pt_NamedNode.h \ - namedNode.I pt_Node.N \ - namedNode.cxx pt_Node.cxx \ - namedNode.h pt_Node.h \ - node.I setTransitionHelpers.T \ - node.cxx setTransitionHelpers.h \ - node.h \ - nodeAttribute.I \ - nodeAttribute.N \ - nodeAttribute.cxx transitionDirection.h \ - nodeAttribute.h traverserVisitor.T \ - nodeAttributeWrapper.I traverserVisitor.h \ - nodeAttributeWrapper.T vector_PT_Node.cxx \ - nodeAttributeWrapper.cxx vector_PT_Node.h \ - nodeAttributeWrapper.h wrt.I \ - nodeAttributes.I wrt.cxx \ - nodeAttributes.N wrt.h \ - nodeAttributes.T + allAttributesWrapper.I allAttributesWrapper.T \ + allAttributesWrapper.cxx allAttributesWrapper.h \ + allTransitionsWrapper.I allTransitionsWrapper.T \ + allTransitionsWrapper.cxx allTransitionsWrapper.h arcChain.I \ + arcChain.cxx arcChain.h bitMask32Transition.cxx \ + bitMask32Transition.h bitMaskAttribute.T bitMaskAttribute.h \ + bitMaskTransition.T bitMaskTransition.h boundedObject.I \ + boundedObject.N boundedObject.cxx boundedObject.h config_graph.cxx \ + config_graph.h dftraverser.T dftraverser.h graphReducer.cxx \ + graphReducer.h immediateAttribute.cxx immediateAttribute.h \ + immediateTransition.I immediateTransition.cxx \ + immediateTransition.h lmatrix4fTransition.cxx \ + lmatrix4fTransition.h matrixAttribute.T matrixAttribute.h \ + matrixTransition.T matrixTransition.h multiAttribute.T \ + multiAttribute.h multiNodeAttribute.cxx multiNodeAttribute.h \ + multiNodeTransition.cxx multiNodeTransition.h multiTransition.T \ + multiTransition.h multiTransitionHelpers.I \ + multiTransitionHelpers.h namedNode.I namedNode.cxx namedNode.h \ + node.I node.cxx node.h nodeAttribute.I nodeAttribute.N \ + nodeAttribute.cxx nodeAttribute.h nodeAttributeWrapper.I \ + nodeAttributeWrapper.T nodeAttributeWrapper.cxx \ + nodeAttributeWrapper.h nodeAttributes.I nodeAttributes.N \ + nodeAttributes.T nodeAttributes.cxx nodeAttributes.h \ + nodeConnection.I nodeConnection.cxx nodeConnection.h \ + nodeRelation.I nodeRelation.N nodeRelation.T nodeRelation.cxx \ + nodeRelation.h nodeTransition.I nodeTransition.N \ + nodeTransition.cxx nodeTransition.h nodeTransitionCache.I \ + nodeTransitionCache.cxx nodeTransitionCache.h \ + nodeTransitionCacheEntry.I nodeTransitionCacheEntry.cxx \ + nodeTransitionCacheEntry.h nodeTransitionWrapper.I \ + nodeTransitionWrapper.T nodeTransitionWrapper.cxx \ + nodeTransitionWrapper.h nodeTransitions.I nodeTransitions.T \ + nodeTransitions.cxx nodeTransitions.h nullAttributeWrapper.I \ + nullAttributeWrapper.cxx nullAttributeWrapper.h nullLevelState.cxx \ + nullLevelState.h nullTransitionWrapper.I nullTransitionWrapper.cxx \ + nullTransitionWrapper.h onAttribute.cxx onAttribute.h \ + onOffAttribute.I onOffAttribute.cxx onOffAttribute.h \ + onOffTransition.I onOffTransition.cxx onOffTransition.h \ + onTransition.I onTransition.cxx onTransition.h pointerNameClass.h \ + pt_NamedNode.N pt_NamedNode.cxx pt_NamedNode.h pt_Node.N \ + pt_Node.cxx pt_Node.h setTransitionHelpers.T \ + setTransitionHelpers.h transitionDirection.h traverserVisitor.T \ + traverserVisitor.h vector_PT_Node.cxx vector_PT_Node.h wrt.I \ + wrt.cxx wrt.h #define INSTALL_HEADERS \ - allAttributesWrapper.I nodeAttributeWrapper.h \ - allAttributesWrapper.T nodeAttributes.I \ - allAttributesWrapper.h nodeAttributes.T \ - allTransitionsWrapper.I nodeAttributes.h \ - allTransitionsWrapper.T nodeRelation.I \ - allTransitionsWrapper.h nodeRelation.T \ - arcChain.I nodeRelation.h \ - arcChain.h nodeTransition.I \ - bitMask32Transition.h nodeTransition.h \ - bitMaskAttribute.T nodeTransitionCache.I \ - bitMaskAttribute.h nodeTransitionCache.h \ - bitMaskTransition.T nodeTransitionCacheEntry.I \ - bitMaskTransition.h nodeTransitionCacheEntry.h \ - boundedObject.I nodeTransitionWrapper.I \ - boundedObject.h nodeTransitionWrapper.T \ - config_graph.h nodeTransitionWrapper.h \ - dftraverser.T nodeTransitions.I \ - dftraverser.h nodeTransitions.T \ - graphReducer.h nodeTransitions.h \ - immediateAttribute.h nullAttributeWrapper.I \ - immediateTransition.I nullAttributeWrapper.h \ - immediateTransition.h nullLevelState.h \ - lmatrix4fTransition.h nullTransitionWrapper.I \ - matrixAttribute.T nullTransitionWrapper.h \ - matrixAttribute.h onAttribute.h \ - matrixTransition.T onOffAttribute.I \ - matrixTransition.h onOffAttribute.h \ - multiAttribute.T onOffTransition.I \ - multiAttribute.h onOffTransition.h \ - multiNodeAttribute.h onTransition.I \ - multiNodeTransition.h onTransition.h \ - multiTransition.T pointerNameClass.h \ - multiTransition.h pt_NamedNode.h \ - multiTransitionHelpers.I pt_Node.h \ - multiTransitionHelpers.h setTransitionHelpers.T \ - namedNode.I setTransitionHelpers.h \ - namedNode.h transitionDirection.h \ - node.I traverserVisitor.T \ - node.h traverserVisitor.h \ - nodeAttribute.I vector_PT_Node.h \ - nodeAttribute.h wrt.I \ - nodeAttributeWrapper.I wrt.h \ - nodeAttributeWrapper.T + allAttributesWrapper.I allAttributesWrapper.T \ + allAttributesWrapper.h allTransitionsWrapper.I \ + allTransitionsWrapper.T allTransitionsWrapper.h arcChain.I \ + arcChain.h bitMask32Transition.h bitMaskAttribute.T \ + bitMaskAttribute.h bitMaskTransition.T bitMaskTransition.h \ + boundedObject.I boundedObject.h config_graph.h dftraverser.T \ + dftraverser.h graphReducer.h immediateAttribute.h \ + immediateTransition.I immediateTransition.h lmatrix4fTransition.h \ + matrixAttribute.T matrixAttribute.h matrixTransition.T \ + matrixTransition.h multiAttribute.T multiAttribute.h \ + multiNodeAttribute.h multiNodeTransition.h multiTransition.T \ + multiTransition.h multiTransitionHelpers.I \ + multiTransitionHelpers.h namedNode.I namedNode.h node.I node.h \ + nodeAttribute.I nodeAttribute.h nodeAttributeWrapper.I \ + nodeAttributeWrapper.T nodeAttributeWrapper.h nodeAttributes.I \ + nodeAttributes.T nodeAttributes.h nodeConnection.I \ + nodeConnection.h nodeRelation.I nodeRelation.T nodeRelation.h \ + nodeTransition.I nodeTransition.h nodeTransitionCache.I \ + nodeTransitionCache.h nodeTransitionCacheEntry.I \ + nodeTransitionCacheEntry.h nodeTransitionWrapper.I \ + nodeTransitionWrapper.T nodeTransitionWrapper.h nodeTransitions.I \ + nodeTransitions.T nodeTransitions.h nullAttributeWrapper.I \ + nullAttributeWrapper.h nullLevelState.h nullTransitionWrapper.I \ + nullTransitionWrapper.h onAttribute.h onOffAttribute.I \ + onOffAttribute.h onOffTransition.I onOffTransition.h \ + onTransition.I onTransition.h pointerNameClass.h pt_NamedNode.h \ + pt_Node.h setTransitionHelpers.T setTransitionHelpers.h \ + transitionDirection.h traverserVisitor.T traverserVisitor.h \ + vector_PT_Node.h wrt.I wrt.h #define IGATESCAN all @@ -133,25 +98,3 @@ #end test_bin_target -#begin test_bin_target - #define TARGET test_graphRead - #define LOCAL_LIBS \ - putil graph - #define OTHER_LIBS $[OTHER_LIBS] pystub - - #define SOURCES \ - test_graphRead.cxx - -#end test_bin_target - -#begin test_bin_target - #define TARGET test_graphWrite - #define LOCAL_LIBS \ - graph putil - #define OTHER_LIBS $[OTHER_LIBS] pystub - - #define SOURCES \ - test_graphWrite.cxx - -#end test_bin_target - diff --git a/panda/src/graph/dftraverser.T b/panda/src/graph/dftraverser.T index aa17eba5c9..32f662c2ac 100644 --- a/panda/src/graph/dftraverser.T +++ b/panda/src/graph/dftraverser.T @@ -84,17 +84,13 @@ traverse(Node *node, AttributeWrapper &state, LevelState &level_state) { if (_visitor.reached_node(node, state, level_state)) { // Look for further children of the given NodeRelation. - DownRelations::const_iterator dri; - dri = node->_children.find(_graph_type); - if (dri != node->_children.end()) { - // Here are some! - const DownRelationPointers &drp = (*dri).second; + const DownRelationPointers &drp = + node->find_connection(_graph_type).get_down(); - // Now visit each of the children in turn. - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - traverse(*drpi, state, level_state); - } + // Now visit each of the children in turn. + DownRelationPointers::const_iterator drpi; + for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { + traverse(*drpi, state, level_state); } } } diff --git a/panda/src/graph/graphReducer.cxx b/panda/src/graph/graphReducer.cxx index 4a10a2ac45..da64320dc8 100644 --- a/panda/src/graph/graphReducer.cxx +++ b/panda/src/graph/graphReducer.cxx @@ -61,21 +61,18 @@ flatten(Node *root, bool combine_siblings) { do { num_pass_nodes = 0; - DownRelations::const_iterator dri; - dri = root->_children.find(_graph_type); - if (dri != root->_children.end()) { - const DownRelationPointers &drp = (*dri).second; + const DownRelationPointers &drp = + root->find_connection(_graph_type).get_down(); - // Get a copy of the children list, so we don't have to worry - // about self-modifications. - DownRelationPointers drp_copy = drp; + // Get a copy of the children list, so we don't have to worry + // about self-modifications. + DownRelationPointers drp_copy = drp; - // Now visit each of the children in turn. - DownRelationPointers::const_iterator drpi; - for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) { - NodeRelation *arc = (*drpi); - num_pass_nodes += r_flatten(arc->get_child(), combine_siblings); - } + // Now visit each of the children in turn. + DownRelationPointers::const_iterator drpi; + for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) { + NodeRelation *arc = (*drpi); + num_pass_nodes += r_flatten(arc->get_child(), combine_siblings); } num_total_nodes += num_pass_nodes; @@ -100,33 +97,30 @@ int GraphReducer:: r_flatten(Node *root, bool combine_siblings) { int num_nodes = 0; - DownRelations::const_iterator dri; - dri = root->_children.find(_graph_type); - if (dri != root->_children.end()) { - const DownRelationPointers &drp = (*dri).second; + const DownRelationPointers &drp = + root->find_connection(_graph_type).get_down(); - // Get a copy of the children list, so we don't have to worry - // about self-modifications. - DownRelationPointers drp_copy = drp; + // Get a copy of the children list, so we don't have to worry + // about self-modifications. + DownRelationPointers drp_copy = drp; - // Now visit each of the children in turn. - DownRelationPointers::const_iterator drpi; - for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) { - NodeRelation *arc = (*drpi); - num_nodes += r_flatten(arc->get_child(), combine_siblings); - } - - if (combine_siblings && drp.size() >= 2) { - num_nodes += flatten_siblings(root); - } - - if (drp.size() == 1) { - // If we have exactly one child, consider flattening it. - NodeRelation *arc = *drp.begin(); - if (consider_arc(arc)) { - if (flatten_arc(arc)) { - num_nodes++; - } + // Now visit each of the children in turn. + DownRelationPointers::const_iterator drpi; + for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) { + NodeRelation *arc = (*drpi); + num_nodes += r_flatten(arc->get_child(), combine_siblings); + } + + if (combine_siblings && drp.size() >= 2) { + num_nodes += flatten_siblings(root); + } + + if (drp.size() == 1) { + // If we have exactly one child, consider flattening it. + NodeRelation *arc = *drp.begin(); + if (consider_arc(arc)) { + if (flatten_arc(arc)) { + num_nodes++; } } } @@ -161,17 +155,12 @@ flatten_siblings(Node *root) { typedef map, SortByTransitions> Children; Children children; - DownRelations::const_iterator dri; - dri = root->_children.find(_graph_type); - if (dri != root->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - NodeRelation *arc = (*drpi); - - children[arc].push_back(arc); - } + const DownRelationPointers &drp = + root->find_connection(_graph_type).get_down(); + DownRelationPointers::const_iterator drpi; + for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { + NodeRelation *arc = (*drpi); + children[arc].push_back(arc); } // Now visit each of those groups and try to collapse them together. diff --git a/panda/src/graph/node.I b/panda/src/graph/node.I index 243a5ffcbe..59e376a726 100644 --- a/panda/src/graph/node.I +++ b/panda/src/graph/node.I @@ -6,6 +6,47 @@ #include +//////////////////////////////////////////////////////////////////// +// Function: Node::find_connection +// Access: Public +// Description: Returns a const reference to the NodeConnection of +// the indicated graph type, if one exists, or a const +// reference to an empty NodeConnection if a connection +// of the indicated type does not exist. +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH const NodeConnection &Node:: +find_connection(TypeHandle graph_type) const { + if (_connections[0].get_graph_type() == graph_type) { + return _connections[0]; + } + if (max_node_graphs > 1) { + return p_find_connection(graph_type); + } else { + return _empty_connection; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: Node::update_connection +// Access: Public +// Description: Returns a non-const pointer to the NodeConnection of +// the indicated graph type, if one exists. If a +// NodeConnection of the indicated type does not already +// exist, creates one if possible and returns its +// pointer. Otherwise, returns NULL. +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH NodeConnection *Node:: +update_connection(TypeHandle graph_type) { + if (_connections[0].get_graph_type() == graph_type) { + return &_connections[0]; + } + if (max_node_graphs > 1) { + return p_update_connection(graph_type); + } else { + return (NodeConnection *)NULL; + } +} + //////////////////////////////////////////////////////////////////// // Function: remove_child // Description: Finds the arc that connects the indicated nodes and diff --git a/panda/src/graph/node.cxx b/panda/src/graph/node.cxx index 2b1f09a743..e08adc67ce 100644 --- a/panda/src/graph/node.cxx +++ b/panda/src/graph/node.cxx @@ -11,9 +11,11 @@ #include #include +NodeConnection Node::_empty_connection; TypeHandle Node::_type_handle; Node* const Node::Null = (Node*)0L; + //////////////////////////////////////////////////////////////////// // Function: Node::Constructor // Access: Public @@ -26,7 +28,11 @@ Node() { //////////////////////////////////////////////////////////////////// // Function: Node::Copy Constructor // Access: Public -// Description: +// Description: The Node copy constructor does not copy children. +// Use copy_subgraph() if you want a deep copy of the +// node and all of its children. Also, you should use +// make_copy() if you just want a typed copy of the Node +// (without children). //////////////////////////////////////////////////////////////////// Node:: Node(const Node ©) : @@ -59,22 +65,23 @@ Node:: // We'd better not have any arcs pointing into this node, since // we're destructing it now. If we do, the destructor was called in // error. - UpRelations::iterator uri; - for (uri = _parents.begin(); uri != _parents.end(); ++uri) { - nassertv((*uri).second.empty()); + int i; + for (i = 0; i < max_node_graphs; i++) { + UpRelationPointers &urp = _connections[i].get_up(); + nassertv(urp.empty()); } - DownRelations::iterator dri; - for (dri = _children.begin(); dri != _children.end(); ++dri) { - DownRelationPointers &drp = (*dri).second; + // Now disconnect all the child arcs. + for (i = 0; i < max_node_graphs; i++) { + DownRelationPointers &drp = _connections[i].get_down(); DownRelationPointers::iterator drpi; for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - PT(NodeRelation) relation = (*drpi); + NodeRelation *arc = (*drpi); // This deletes the arc and anything below it through the magic // of reference-counting. - relation->detach_below(); + arc->detach_below(); } } } @@ -168,12 +175,8 @@ transform_changed(NodeRelation *) { //////////////////////////////////////////////////////////////////// int Node:: get_num_parents(TypeHandle type) const { - UpRelations::const_iterator uri; - uri = _parents.find(type); - if (uri == _parents.end()) { - return 0; - } - return (*uri).second.size(); + const UpRelationPointers &urp = find_connection(type).get_up(); + return urp.size(); } //////////////////////////////////////////////////////////////////// @@ -185,12 +188,10 @@ get_num_parents(TypeHandle type) const { //////////////////////////////////////////////////////////////////// NodeRelation *Node:: get_parent(TypeHandle type, int index) const { - UpRelations::const_iterator uri; - uri = _parents.find(type); - nassertr(uri != _parents.end(), (NodeRelation *)NULL); - nassertr(index >= 0 && index < (int)(*uri).second.size(), + const UpRelationPointers &urp = find_connection(type).get_up(); + nassertr(index >= 0 && index < (int)urp.size(), (NodeRelation *)NULL); - return (*uri).second[index]; + return urp[index]; } //////////////////////////////////////////////////////////////////// @@ -202,12 +203,8 @@ get_parent(TypeHandle type, int index) const { //////////////////////////////////////////////////////////////////// int Node:: get_num_children(TypeHandle type) const { - DownRelations::const_iterator dri; - dri = _children.find(type); - if (dri == _children.end()) { - return 0; - } - return (*dri).second.size(); + const DownRelationPointers &drp = find_connection(type).get_down(); + return drp.size(); } //////////////////////////////////////////////////////////////////// @@ -219,12 +216,10 @@ get_num_children(TypeHandle type) const { //////////////////////////////////////////////////////////////////// NodeRelation *Node:: get_child(TypeHandle type, int index) const { - DownRelations::const_iterator dri; - dri = _children.find(type); - nassertr(dri != _children.end(), (NodeRelation *)NULL); - nassertr(index >= 0 && index < (int)(*dri).second.size(), + const DownRelationPointers &drp = find_connection(type).get_down(); + nassertr(index >= 0 && index < (int)drp.size(), (NodeRelation *)NULL); - return (*dri).second[index]; + return drp[index]; } //////////////////////////////////////////////////////////////////// @@ -274,6 +269,49 @@ write(ostream &out, int indent_level) const { } +//////////////////////////////////////////////////////////////////// +// Function: Node::p_find_connection +// Access: Private +// Description: The non-inline implementation of find_connection(). +//////////////////////////////////////////////////////////////////// +const NodeConnection &Node:: +p_find_connection(TypeHandle graph_type) const { + // _connections[0] is already tested by the inline implementation. + for (int i = 1; i < max_node_graphs; i++) { + if (_connections[i].get_graph_type() == graph_type) { + return _connections[i]; + } + } + return _empty_connection; +} + +//////////////////////////////////////////////////////////////////// +// Function: Node::p_update_connection +// Access: Private +// Description: The non-inline implementation of update_connection(). +//////////////////////////////////////////////////////////////////// +NodeConnection *Node:: +p_update_connection(TypeHandle graph_type) { + // _connections[0] is already tested by the inline implementation. + int i; + for (i = 1; i < max_node_graphs; i++) { + if (_connections[i].get_graph_type() == graph_type) { + return &_connections[i]; + } + } + + // No such connection; can we create a new one? + for (i = 0; i < max_node_graphs; i++) { + if (_connections[i].is_empty()) { + _connections[i].set_graph_type(graph_type); + return &_connections[i]; + } + } + + // Too bad. + return (NodeConnection *)NULL; +} + //////////////////////////////////////////////////////////////////// // Function: Node::propagate_stale_bound // Access: Protected, Virtual @@ -284,10 +322,8 @@ write(ostream &out, int indent_level) const { void Node:: propagate_stale_bound() { // Mark all of our parent arcs, in all graphs, stale as well. - UpRelations::const_iterator uri; - for (uri = _parents.begin(); uri != _parents.end(); ++uri) { - const UpRelationPointers &urp = (*uri).second; - + for (int i = 0; i < max_node_graphs; i++) { + const UpRelationPointers &urp = _connections[i].get_up(); UpRelationPointers::const_iterator urpi; for (urpi = urp.begin(); urpi != urp.end(); ++urpi) { (*urpi)->mark_bound_stale(); @@ -324,10 +360,10 @@ r_copy_subgraph(TypeHandle graph_type, Node::InstanceMap &inst_map) const { //////////////////////////////////////////////////////////////////// // Function: Node::r_copy_children // Access: Protected, Virtual -// Description: This is called by r_deep_copy(); the copy has already -// been made of this particular node (and this is the -// copy); this function's job is to copy all of the -// children from the original. +// Description: This is called by r_copy_subgraph(); the copy has +// already been made of this particular node (and this +// is the copy); this function's job is to copy all of +// the children from the original. // // Note that it includes the parameter inst_map, which // is a map type, and is not (and cannot be) exported @@ -339,39 +375,35 @@ r_copy_subgraph(TypeHandle graph_type, Node::InstanceMap &inst_map) const { void Node:: r_copy_children(const Node *from, TypeHandle graph_type, Node::InstanceMap &inst_map) { - DownRelations::const_iterator dri; - dri = from->_children.find(graph_type); - if (dri != from->_children.end()) { - const DownRelationPointers &drp = (*dri).second; + const DownRelationPointers &drp = + from->find_connection(graph_type).get_down(); + DownRelationPointers::const_iterator drpi; + for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { + NodeRelation *source_arc = (*drpi); + Node *source_child = source_arc->get_child(); + nassertv(source_child != (Node *)NULL); - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - NodeRelation *source_arc = (*drpi); - Node *source_child = source_arc->get_child(); - nassertv(source_child != (Node *)NULL); + Node *dest_child; - Node *dest_child; - - // Check to see if we have already copied this child. If we - // have, use the copy. In this way, a subgraph that contains - // instances will be correctly duplicated into another subgraph - // that also contains its own instances. - InstanceMap::const_iterator ci; - ci = inst_map.find(source_child); - if (ci != inst_map.end()) { - dest_child = (*ci).second; - } else { - dest_child = source_child->r_copy_subgraph(graph_type, inst_map); - inst_map[source_child] = dest_child; - } - - NodeRelation *dest_arc = - NodeRelation::create_typed_arc(graph_type, this, dest_child); - nassertv(dest_arc != (NodeRelation *)NULL); - nassertv(dest_arc->is_exact_type(graph_type)); - - dest_arc->copy_transitions_from(source_arc); + // Check to see if we have already copied this child. If we + // have, use the copy. In this way, a subgraph that contains + // instances will be correctly duplicated into another subgraph + // that also contains its own instances. + InstanceMap::const_iterator ci; + ci = inst_map.find(source_child); + if (ci != inst_map.end()) { + dest_child = (*ci).second; + } else { + dest_child = source_child->r_copy_subgraph(graph_type, inst_map); + inst_map[source_child] = dest_child; } + + NodeRelation *dest_arc = + NodeRelation::create_typed_arc(graph_type, this, dest_child); + nassertv(dest_arc != (NodeRelation *)NULL); + nassertv(dest_arc->is_exact_type(graph_type)); + + dest_arc->copy_transitions_from(source_arc); } } @@ -389,18 +421,29 @@ write_datagram(BamWriter *manager, Datagram &me) { // write out all of the UpRelations then writing any node in a graph // would cause the entire graph to be written out. - me.add_uint16(_children.size()); + // First, count up the number of NodeConnections that are nonempty. + int num_connections = 0; + int i; + for (i = 0; i < max_node_graphs; i++) { + if (!_connections[i].is_empty()) { + num_connections++; + } + } - DownRelations::iterator dri; - for (dri = _children.begin(); dri != _children.end(); ++dri) { - manager->write_handle(me, (*dri).first); + me.add_uint16(num_connections); - DownRelationPointers &drp = (*dri).second; - me.add_uint16(drp.size()); - DownRelationPointers::iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - NodeRelation *relation = (*drpi); - manager->write_pointer(me, relation); + // Now write them out. + for (i = 0; i < max_node_graphs; i++) { + if (!_connections[i].is_empty()) { + manager->write_handle(me, _connections[i].get_graph_type()); + + const DownRelationPointers &drp = _connections[i].get_down(); + me.add_uint16(drp.size()); + DownRelationPointers::const_iterator drpi; + for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { + NodeRelation *relation = (*drpi); + manager->write_pointer(me, relation); + } } } } @@ -420,28 +463,37 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) { // the arcs are completely responsible for adding themselves to // our list); we only need to return the number of pointers we // expected to receive. - return _num_pointers; + + // As of 5/7/01, we no longer store this number, as a memory + // optimization. This means bams before 3.3 cannot be reliably + // loaded. + + graph_cat.warning() + << "Unable to reliably load bam version " + << manager->get_file_major_ver() << "." + << manager->get_file_minor_ver() << "\n"; + + return 0; } // Beginning at bam version 3.3, we are responsible for adding our // child arcs directly. - int i = 0; + int count = 0; - DownRelations::iterator dri; - for (dri = _children.begin(); dri != _children.end(); ++dri) { - DownRelationPointers &drp = (*dri).second; + for (int i = 0; i < max_node_graphs; i++) { + if (!_connections[i].is_empty()) { + DownRelationPointers &drp = _connections[i].get_down(); - DownRelationPointers::iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - nassertr(i < _num_pointers, _num_pointers); - (*drpi) = DCAST(NodeRelation, plist[i]); - i++; + DownRelationPointers::iterator drpi; + for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { + (*drpi) = DCAST(NodeRelation, plist[count]); + count++; + } } } - nassertr(i == _num_pointers, _num_pointers); - return _num_pointers; + return count; } //////////////////////////////////////////////////////////////////// @@ -450,8 +502,7 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) { // Description: Factory method to generate a node object //////////////////////////////////////////////////////////////////// TypedWriteable* Node:: -make_Node(const FactoryParams ¶ms) -{ +make_Node(const FactoryParams ¶ms) { Node *me = new Node; BamReader *manager; Datagram packet; @@ -477,14 +528,12 @@ fillin(DatagramIterator &scan, BamReader *manager) { // In bam versions before 3.3, we only need to count up the total // number of arcs across all types, because we don't add the arc // pointers explicitly here. - _num_pointers = 0; int num_types = scan.get_uint16(); while (num_types > 0) { int num_arcs = scan.get_uint16(); while (num_arcs > 0) { manager->read_pointer(scan, this); - _num_pointers++; num_arcs--; } num_types--; @@ -494,24 +543,38 @@ fillin(DatagramIterator &scan, BamReader *manager) { // Beginning at bam version 3.3, we do all the reading of our // children arcs of all types, which means we need to record the // numbers of each type of children. We do this by recording a - // series of NULL pointers, rather than depending on - // _num_pointers. + // series of NULL pointers in our NodeConnections. - _num_pointers = 0; - int num_types = scan.get_uint16(); - - while (num_types > 0) { + int num_connections = scan.get_uint16(); + if (num_connections > max_node_graphs) { + // Oops, too many graph types in this bam file. We'll have to + // discard some. + graph_cat.error() + << "Bam file specifies " << num_connections << " graph types for " + << *this << "; this version of Panda can only support " + << max_node_graphs << " simultaneous graph types.\n"; + } + for (int i = 0; i < num_connections; i++) { TypeHandle type = manager->read_handle(scan); + + if (i < max_node_graphs) { + _connections[i].set_graph_type(type); - DownRelationPointers &drp = _children[type]; - int num_arcs = scan.get_uint16(); - while (num_arcs > 0) { - manager->read_pointer(scan, this); - drp.push_back((NodeRelation *)NULL); - _num_pointers++; - num_arcs--; + DownRelationPointers &drp = _connections[i].get_down(); + int num_arcs = scan.get_uint16(); + while (num_arcs > 0) { + manager->read_pointer(scan, this); + drp.push_back((NodeRelation *)NULL); + num_arcs--; + } + } else { + // Read and discard. + int num_arcs = scan.get_uint16(); + while (num_arcs > 0) { + manager->skip_pointer(scan); + num_arcs--; + } } - num_types--; } } } @@ -522,8 +585,7 @@ fillin(DatagramIterator &scan, BamReader *manager) { // Description: Factory method to generate a node object //////////////////////////////////////////////////////////////////// void Node:: -register_with_read_factory(void) -{ +register_with_read_factory(void) { BamReader::get_factory()->register_factory(get_class_type(), make_Node); } @@ -540,16 +602,12 @@ find_arc(Node *parent, Node *child, TypeHandle graph_type) { // the parent arc, on the assumption there are likely to be fewer // parents than children. - UpRelations::const_iterator uri = child->_parents.find(graph_type); - - if (uri != child->_parents.end()) { - const UpRelationPointers &urp = (*uri).second; - UpRelationPointers::const_iterator urpi; - for (urpi = urp.begin(); urpi != urp.end(); ++urpi) { - if ((*urpi)->get_parent() == parent && - (*urpi)->get_child() == child) { - return (*urpi); - } + const UpRelationPointers &urp = child->find_connection(graph_type).get_up(); + UpRelationPointers::const_iterator urpi; + for (urpi = urp.begin(); urpi != urp.end(); ++urpi) { + NodeRelation *arc = (*urpi); + if (arc->get_parent() == parent && arc->get_child() == child) { + return arc; } } diff --git a/panda/src/graph/node.h b/panda/src/graph/node.h index adc7d10adc..c0e6f0e9d3 100644 --- a/panda/src/graph/node.h +++ b/panda/src/graph/node.h @@ -9,6 +9,7 @@ #include "nodeRelation.h" #include "boundedObject.h" +#include "nodeConnection.h" #include #include @@ -23,6 +24,10 @@ class BamReader; class Datagram; class DatagramIterator; +// This is the maximum number of graph types a node may simultaneously +// exist in. +static const int max_node_graphs = 2; + //////////////////////////////////////////////////////////////////// // Class : Node // Description : The base class for all scene graph nodes. A Node may @@ -77,6 +82,7 @@ PUBLISHED: virtual void output(ostream &out) const; virtual void write(ostream &out, int indent_level = 0) const; +public: // We reference-count the child pointer, but not the parent pointer, // to avoid circular reference counting. @@ -84,9 +90,15 @@ PUBLISHED: // through the scene graph when necessary, but beware! It is not // safe to access these members directly outside of PANDA.DLL. // Instead, use the get_parent()/get_child() interface, above. + INLINE_GRAPH const NodeConnection &find_connection(TypeHandle graph_type) const; + INLINE_GRAPH NodeConnection *update_connection(TypeHandle graph_type); - UpRelations _parents; - DownRelations _children; + NodeConnection _connections[max_node_graphs]; + +private: + const NodeConnection &p_find_connection(TypeHandle graph_type) const; + NodeConnection *p_update_connection(TypeHandle graph_type); + static NodeConnection _empty_connection; protected: virtual void propagate_stale_bound(); @@ -108,17 +120,6 @@ public: protected: void fillin(DatagramIterator& scan, BamReader* manager); -private: - //This variable is set inside fillin to the number of pointers - //that are "read" by Node. This needs to be set, even though - //node does nothing in complete_pointers, because it needs to - //return the number of pointer requests that it made. This - //is necessary because the vector of pointers to TypedWriteables - //that is given to it by BamReader, will be filled with those requests - //and any children of Node, need to be able to ignore those as well. - //So complete_pointers must return the correct number read - int _num_pointers; - public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/graph/nodeConnection.I b/panda/src/graph/nodeConnection.I new file mode 100644 index 0000000000..6f7d111e3f --- /dev/null +++ b/panda/src/graph/nodeConnection.I @@ -0,0 +1,127 @@ +// Filename: nodeConnection.I +// Created by: drose (07May01) +// +//////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH NodeConnection:: +NodeConnection(TypeHandle graph_type) : _graph_type(graph_type) { +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH NodeConnection:: +~NodeConnection() { +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::Copy Constructor +// Access: Private +// Description: The copy constructor is private. Copying +// NodeConnections is not a good idea. +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH NodeConnection:: +NodeConnection(const NodeConnection ©) { +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::Copy Assignment Operator +// Access: Private +// Description: The assignment constructor is private. Copying +// NodeConnections is not a good idea. +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH void NodeConnection:: +operator = (const NodeConnection ©) { +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::is_empty +// Access: Public +// Description: Returns true if the NodeConnection has no arcs, false +// otherwise. +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH bool NodeConnection:: +is_empty() const { + return _up.empty() && _down.empty(); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::get_graph_type +// Access: Public +// Description: Returns the type of graph represented by this +// NodeConnection. A node can coexist simultaneously in +// several different graphs of different types; each +// type requires a NodeConnection object to be stored +// with the node. +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH TypeHandle NodeConnection:: +get_graph_type() const { + return _graph_type; +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::set_graph_type +// Access: Public +// Description: Changes the type of graph represented by this +// NodeConnection. It is legal to do this only when the +// NodeConnection is empty, i.e. is_empty() returns +// true. +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH void NodeConnection:: +set_graph_type(TypeHandle graph_type) { + nassertv(is_empty()); + _graph_type = graph_type; +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::get_up +// Access: Public +// Description: Returns the list of arcs pointing to the node's +// parent(s). +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH UpRelationPointers &NodeConnection:: +get_up() { + return _up; +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::get_up +// Access: Public +// Description: Returns the list of arcs pointing to the node's +// parent(s). +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH const UpRelationPointers &NodeConnection:: +get_up() const { + return _up; +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::get_down +// Access: Public +// Description: Returns the list of arcs pointing to the node's +// child(ren). +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH DownRelationPointers &NodeConnection:: +get_down() { + return _down; +} + +//////////////////////////////////////////////////////////////////// +// Function: NodeConnection::get_down +// Access: Public +// Description: Returns the list of arcs pointing to the node's +// child(ren). +//////////////////////////////////////////////////////////////////// +INLINE_GRAPH const DownRelationPointers &NodeConnection:: +get_down() const { + return _down; +} diff --git a/panda/src/graph/nodeConnection.cxx b/panda/src/graph/nodeConnection.cxx new file mode 100644 index 0000000000..ecda399dad --- /dev/null +++ b/panda/src/graph/nodeConnection.cxx @@ -0,0 +1,7 @@ +// Filename: nodeConnection.cxx +// Created by: drose (07May01) +// +//////////////////////////////////////////////////////////////////// + +#include "node.h" +#include "nodeConnection.h" diff --git a/panda/src/graph/nodeConnection.h b/panda/src/graph/nodeConnection.h new file mode 100644 index 0000000000..bfd7ad07ec --- /dev/null +++ b/panda/src/graph/nodeConnection.h @@ -0,0 +1,57 @@ +// Filename: nodeConnection.h +// Created by: drose (07May01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef NODECONNECTION_H +#define NODECONNECTION_H + +#include + +#include "nodeRelation.h" +#include "config_graph.h" + + +/////////////////////////////////////////////////////////////////// +// Class : NodeConnection +// Description : This class represents the table, stored within each +// Node, of all the connected NodeRelations (arcs) of a +// particular graph type. +// +// Node that this class is not exported from PANDA.DLL. +// You should use the get_parent()/get_child() interface +// to Node for code outside of PANDA.DLL. +//////////////////////////////////////////////////////////////////// +class NodeConnection { +public: + INLINE_GRAPH NodeConnection(TypeHandle graph_type = TypeHandle::none()); + INLINE_GRAPH ~NodeConnection(); + +private: + INLINE_GRAPH NodeConnection(const NodeConnection ©); + INLINE_GRAPH void operator = (const NodeConnection ©); + +public: + INLINE_GRAPH bool is_empty() const; + + INLINE_GRAPH TypeHandle get_graph_type() const; + INLINE_GRAPH void set_graph_type(TypeHandle graph_type); + + INLINE_GRAPH UpRelationPointers &get_up(); + INLINE_GRAPH const UpRelationPointers &get_up() const; + + INLINE_GRAPH DownRelationPointers &get_down(); + INLINE_GRAPH const DownRelationPointers &get_down() const; + +private: + TypeHandle _graph_type; + UpRelationPointers _up; + DownRelationPointers _down; +}; + +#ifndef DONT_INLINE_GRAPH +#include "nodeConnection.I" +#endif + +#endif + diff --git a/panda/src/graph/nodeRelation.cxx b/panda/src/graph/nodeRelation.cxx index e6554c3039..a718f10e6b 100644 --- a/panda/src/graph/nodeRelation.cxx +++ b/panda/src/graph/nodeRelation.cxx @@ -49,16 +49,16 @@ init_last_graph_update() { // Following are a handful of local template functions that provide // support for manipulating the list of arcs on nodes. They are -// template functions because they work as well on UpRelationArcs as -// as they do on DownRelationArcs, which are slightly different things -// (DownRelationArcs are reference-counting). +// template functions because they work as well on UpRelationPointers +// as as they do on DownRelationPointers, which are slightly different +// things (DownRelationPointers are reference-counting). //////////////////////////////////////////////////////////////////// // Function: verify_arc_list // Description: A local template function that verifies that the list -// of arcs (either UpRelationArcs or DownRelationArcs) -// is correctly sorted, if paranoid_graph is set. -// Otherwise, it does nothing. +// of arcs (either UpRelationPointers or +// DownRelationPointers) is correctly sorted, if +// paranoid_graph is set. Otherwise, it does nothing. //////////////////////////////////////////////////////////////////// #ifdef NDEBUG template @@ -87,9 +87,9 @@ verify_arc_list(Iterator begin, Iterator end) { //////////////////////////////////////////////////////////////////// // Function: find_insert_position // Description: A local template function that performs a binary -// search on the arcs list (either UpRelationArcs or -// DownRelationArcs) and finds the place to insert the -// indicated arc. +// search on the arcs list (either UpRelationPointers or +// DownRelationPointers) and finds the place to insert +// the indicated arc. // // This place will be at the end of the similarly-sorted // arcs. @@ -141,10 +141,10 @@ find_insert_position(Iterator begin, Iterator end, NodeRelation *arc) { //////////////////////////////////////////////////////////////////// // Function: find_arc // Description: A local template function that performs a binary -// search on the arcs list (either UpRelationArcs or -// DownRelationArcs) and finds the arc's position within -// the list. It returns end if the arc is not within -// the list. +// search on the arcs list (either UpRelationPointers or +// DownRelationPointers) and finds the arc's position +// within the list. It returns end if the arc is not +// within the list. //////////////////////////////////////////////////////////////////// template static Iterator @@ -609,13 +609,25 @@ attach() { nassertv(_child != (Node*)NULL); nassertv(!_attached); - _attached = true; - if (_parent_ref != 0) { - _parent->ref(); + NodeConnection *parent_connection = _parent->update_connection(_graph_type); + NodeConnection *child_connection = _child->update_connection(_graph_type); + + if (parent_connection == (NodeConnection *)NULL) { + graph_cat.error() + << "Attempt to attach " << _parent << " simultaneously to more than " + << max_node_graphs << " different graph types.\n"; + nassertv(false); } - DownRelationPointers &parent_list = _parent->_children[_graph_type]; - UpRelationPointers &child_list = _child->_parents[_graph_type]; + if (child_connection == (NodeConnection *)NULL) { + graph_cat.error() + << "Attempt to attach " << _child << " simultaneously to more than " + << max_node_graphs << " different graph types.\n"; + nassertv(false); + } + + DownRelationPointers &parent_list = parent_connection->get_down(); + UpRelationPointers &child_list = child_connection->get_up(); bool inserted_one = internal_insert_arc(parent_list, this); bool inserted_two = internal_insert_arc(child_list, this); @@ -634,6 +646,11 @@ attach() { child_list[1]->_last_update = _last_update; } + _attached = true; + if (_parent_ref != 0) { + _parent->ref(); + } + _parent->force_bound_stale(); mark_bound_stale(); } @@ -664,8 +681,16 @@ detach() { force_bound_stale(); - DownRelationPointers &parent_list = _parent->_children[_graph_type]; - UpRelationPointers &child_list = _child->_parents[_graph_type]; + NodeConnection *parent_connection = _parent->update_connection(_graph_type); + NodeConnection *child_connection = _child->update_connection(_graph_type); + + // These should never be NULL, because we're already attached, after + // all. + nassertr(parent_connection != (NodeConnection *)NULL && + child_connection != (NodeConnection *)NULL, result); + + DownRelationPointers &parent_list = parent_connection->get_down(); + UpRelationPointers &child_list = child_connection->get_up(); bool removed_one = internal_remove_arc(parent_list, this); bool removed_two = internal_remove_arc(child_list, this); @@ -690,16 +715,6 @@ detach() { child_list[0]->_last_update = _last_update; } - // If we have completely emptied the parent or child lists, remove - // the entry for this graph type from the node, as a small render - // optimization. - if (parent_list.empty()) { - _parent->_children.erase(_graph_type); - } - if (child_list.empty()) { - _child->_parents.erase(_graph_type); - } - return result; } @@ -721,7 +736,11 @@ detach_below() { force_bound_stale(); - bool removed = internal_remove_arc(_child->_parents[_graph_type], this); + NodeConnection *child_connection = _child->update_connection(_graph_type); + nassertr(child_connection != (NodeConnection *)NULL, result); + + UpRelationPointers &child_list = child_connection->get_up(); + bool removed = internal_remove_arc(child_list, this); nassertr(removed, result); @@ -767,15 +786,10 @@ propagate_stale_bound() { Node *node = _parent; nassertv(node != (Node*)NULL); - UpRelations::const_iterator uri; - uri = node->_parents.find(_graph_type); - if (uri != node->_parents.end()) { - const UpRelationPointers &urp = (*uri).second; - - UpRelationPointers::const_iterator urpi; - for (urpi = urp.begin(); urpi != urp.end(); ++urpi) { - (*urpi)->mark_bound_stale(); - } + const UpRelationPointers &urp = node->find_connection(_graph_type).get_up(); + UpRelationPointers::const_iterator urpi; + for (urpi = urp.begin(); urpi != urp.end(); ++urpi) { + (*urpi)->mark_bound_stale(); } } @@ -800,15 +814,11 @@ recompute_bound() { child_volumes.push_back(&node->get_bound()); - DownRelations::const_iterator dri; - dri = node->_children.find(_graph_type); - if (dri != node->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - child_volumes.push_back(&(*drpi)->get_bound()); - } + const DownRelationPointers &drp = + node->find_connection(_graph_type).get_down(); + DownRelationPointers::const_iterator drpi; + for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { + child_volumes.push_back(&(*drpi)->get_bound()); } bool success = @@ -855,8 +865,7 @@ write_datagram(BamWriter *manager, Datagram &me) //Now write out all the Transitions on this arc me.add_uint16(_transitions.size()); NodeTransitions::iterator ci; - for(ci = _transitions.begin(); ci != _transitions.end(); ci++) - { + for(ci = _transitions.begin(); ci != _transitions.end(); ci++) { manager->write_pointer(me, (*ci).second); } } @@ -865,13 +874,12 @@ write_datagram(BamWriter *manager, Datagram &me) //////////////////////////////////////////////////////////////////// // Function: NodeRelation::complete_pointers // Access: Public -// Description: Takes in a vector of pointes to TypedWriteable +// Description: Takes in a vector of pointers to TypedWriteable // objects that correspond to all the requests for // pointers that this object made to BamReader. //////////////////////////////////////////////////////////////////// int NodeRelation:: -complete_pointers(vector_typedWriteable &plist, BamReader *manager) -{ +complete_pointers(vector_typedWriteable &plist, BamReader *manager) { nassertr(plist[0] != TypedWriteable::Null && plist[1] != TypedWriteable::Null, 0); _parent = DCAST(Node, plist[0]); @@ -889,10 +897,13 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) // We must explicitly add the arc to its child node, but not to // its parent node. - UpRelationPointers &child_list = _child->_parents[_graph_type]; - bool inserted = internal_insert_arc(child_list, this); - nassertr(inserted, _num_transitions + 2); - _attached = true; + NodeConnection *child_connection = _child->update_connection(_graph_type); + if (child_connection != (NodeConnection *)NULL) { + UpRelationPointers &child_list = child_connection->get_up(); + bool inserted = internal_insert_arc(child_list, this); + nassertr(inserted, _num_transitions + 2); + _attached = true; + } } //The rest of this is the list of Transitions @@ -1072,4 +1083,3 @@ clear_transition(TypeHandle handle) { changed_transition(handle); return old_trans; } - diff --git a/panda/src/graph/nodeRelation.h b/panda/src/graph/nodeRelation.h index 875b5a018f..ef20a690cc 100644 --- a/panda/src/graph/nodeRelation.h +++ b/panda/src/graph/nodeRelation.h @@ -223,10 +223,7 @@ EXPCL_PANDA INLINE_GRAPH ostream & operator << (ostream &out, const NodeRelation &arc); typedef vector< PT(NodeRelation) > DownRelationPointers; -typedef map DownRelations; - typedef vector UpRelationPointers; -typedef map UpRelations; #include "nodeRelation.T" diff --git a/panda/src/graph/nodeTransitionCache.cxx b/panda/src/graph/nodeTransitionCache.cxx index ccbd96b945..8432835f22 100644 --- a/panda/src/graph/nodeTransitionCache.cxx +++ b/panda/src/graph/nodeTransitionCache.cxx @@ -73,8 +73,9 @@ is_identity() const { //////////////////////////////////////////////////////////////////// int NodeTransitionCache:: compare_to(const NodeTransitionCache &other) const { - return tmap_compare_cache(_cache.begin(), _cache.end(), - other._cache.begin(), other._cache.end()); + int result = tmap_compare_cache(_cache.begin(), _cache.end(), + other._cache.begin(), other._cache.end()); + return result; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/graph/test_graphRead.cxx b/panda/src/graph/test_graphRead.cxx deleted file mode 100644 index e61c3b3170..0000000000 --- a/panda/src/graph/test_graphRead.cxx +++ /dev/null @@ -1,49 +0,0 @@ -// Filename: test_graphRead.cxx -// Created by: jason (15Jun00) - -#include "nodeRelation.h" -#include "namedNode.h" -#include "pt_NamedNode.h" -#include -#include - -#include - -int main() { - string test_file = "graphTest.out"; - datagram_file stream(test_file); - BamReader manager(&stream); - stream.open(file::FILE_READ); - - manager.init(); - - PT_NamedNode r = DCAST(NamedNode, manager.read_object()); - PT_NamedNode a = DCAST(NamedNode, manager.read_object()); - PT_NamedNode b = DCAST(NamedNode, manager.read_object()); - PT_NamedNode aa = DCAST(NamedNode, manager.read_object()); - PT_NamedNode ab = DCAST(NamedNode, manager.read_object()); - PT_NamedNode ba = DCAST(NamedNode, manager.read_object()); - - NodeRelation *r_a = DCAST(NodeRelation, manager.read_object()); - NodeRelation *r_b = DCAST(NodeRelation, manager.read_object()); - NodeRelation *a_aa = DCAST(NodeRelation, manager.read_object()); - NodeRelation *a_ab = DCAST(NodeRelation, manager.read_object()); - NodeRelation *b_ba = DCAST(NodeRelation, manager.read_object()); - - manager.resolve(); - - r_a->output(nout); - nout << endl; - r_b->output(nout); - nout << endl; - a_aa->output(nout); - nout << endl; - a_ab->output(nout); - nout << endl; - b_ba->output(nout); - nout << endl; - - stream.close(); - - return 0; -} diff --git a/panda/src/graph/test_graphWrite.cxx b/panda/src/graph/test_graphWrite.cxx deleted file mode 100644 index bf6c1f878f..0000000000 --- a/panda/src/graph/test_graphWrite.cxx +++ /dev/null @@ -1,68 +0,0 @@ -// Filename: test_graphWrite.cxx -// Created by: jason (15Jun00) - -#include "nodeRelation.h" -#include "namedNode.h" -#include "pt_NamedNode.h" -#include -#include - -#include - -int main() { - string test_file = "graphTest.out"; - datagram_file stream(test_file); - BamWriter manager(&stream); - stream.open(file::FILE_WRITE); - - PT_NamedNode r = new NamedNode("r"); - - PT_NamedNode a = new NamedNode("a"); - PT_NamedNode b = new NamedNode("b"); - - PT_NamedNode aa = new NamedNode("aa"); - PT_NamedNode ab = new NamedNode("ab"); - PT_NamedNode ba = new NamedNode("ba"); - - NodeRelation *r_a = - new NodeRelation(r, a, 0, NodeRelation::get_class_type()); - NodeRelation *r_b = - new NodeRelation(r, b, 0, NodeRelation::get_class_type()); - - NodeRelation *a_aa = - new NodeRelation(a, aa, 0, NodeRelation::get_class_type()); - NodeRelation *a_ab = - new NodeRelation(a, ab, 0, NodeRelation::get_class_type()); - NodeRelation *b_ba = - new NodeRelation(b, ba, 0, NodeRelation::get_class_type()); - - r_a->output(nout); - nout << endl; - r_b->output(nout); - nout << endl; - a_aa->output(nout); - nout << endl; - a_ab->output(nout); - nout << endl; - b_ba->output(nout); - nout << endl; - - if (manager.init()) - { - manager.write_object(r); - manager.write_object(a); - manager.write_object(b); - manager.write_object(aa); - manager.write_object(ab); - manager.write_object(ba); - - manager.write_object(r_a); - manager.write_object(r_b); - manager.write_object(a_aa); - manager.write_object(a_ab); - manager.write_object(b_ba); - } - - stream.close(); - return 0; -} diff --git a/panda/src/graph/wrt.I b/panda/src/graph/wrt.I index 427f7e353b..872b99d1a5 100644 --- a/panda/src/graph/wrt.I +++ b/panda/src/graph/wrt.I @@ -15,18 +15,20 @@ void describe_ambiguous_wrt(const Node *node, InputIterator arc_list_begin, InputIterator arc_list_end, - const UpRelationPointers &urp) { + TypeHandle graph_type) { if (wrt_cat.is_warning()) { + int num_parents = node->get_num_parents(graph_type); wrt_cat.warning() - << *node << " has " << urp.size() << " parents; wrt() ambiguous.\n" + << *node << " has " << num_parents << " parents; wrt() ambiguous.\n" << " parents are: "; - UpRelationPointers::const_iterator urpi; - urpi = urp.begin(); - wrt_cat.warning(false) << *(*urpi)->get_parent(); - urpi++; - while (urpi != urp.end()) { - wrt_cat.warning(false) << ", " << *(*urpi)->get_parent(); - urpi++; + nassertv(num_parents > 1); + + NodeRelation *parent_arc = node->get_parent(graph_type, 0); + wrt_cat.warning(false) << *parent_arc->get_parent(); + for (int i = 1; i < num_parents; i++) { + parent_arc = node->get_parent(graph_type, 0); + wrt_cat.warning(false) + << ", " << *node->get_parent(graph_type, i)->get_parent(); } wrt_cat.warning(false) << "\n"; @@ -129,16 +131,15 @@ get_cached_net_transition(NodeRelation *arc, Node *&root, // Get the node above the arc. Node *node = arc->get_parent(); - UpRelations::const_iterator uri; - uri = node->_parents.find(graph_type); + int num_parents = node->get_num_parents(graph_type); - if (uri == node->_parents.end() || (*uri).second.size() != 1) { + if (num_parents != 1) { // The node has zero or multiple parents. It's thus either the // top of the scene graph, or it's the first ancestor with // multiple parents; in either case, it's as far as we can take // the caching. Stop here. - if (uri == node->_parents.end() || (*uri).second.empty()) { + if (num_parents == 0) { // The node is the very top of the scene graph. We'll treat // this as a special case by setting the node to NULL. This // will tell our calling function that there's no need to look @@ -154,8 +155,8 @@ get_cached_net_transition(NodeRelation *arc, Node *&root, } else { // The node has exactly one parent. Carry on. - NodeRelation *parent = *(*uri).second.begin(); - get_cached_net_transition(parent, root, as_of, now, net, graph_type); + NodeRelation *parent_arc = node->get_parent(graph_type, 0); + get_cached_net_transition(parent_arc, root, as_of, now, net, graph_type); // Now recompute our own cache. TransitionWrapper cur_value = TransitionWrapper::init_from(net); @@ -222,42 +223,26 @@ get_cached_net_transition(const Node *node, return; } - UpRelations::const_iterator uri; - uri = node->_parents.find(graph_type); - - if (uri == node->_parents.end()) { - // This node has no parents. Stop here. - result.make_identity(); - -#ifndef NDEBUG - if (wrt_cat.is_debug()) { - wrt_cat.debug() - << "get_cached_net_transition(" << *node << ") has no parents.\n"; - } -#endif - return; - } - - const UpRelationPointers &urp = (*uri).second; - if (urp.empty()) { - // Again, this node has no parents. - result.make_identity(); - -#ifndef NDEBUG - if (wrt_cat.is_debug()) { - wrt_cat.debug() - << "get_cached_net_transition(" << *node << ") has no parents.\n"; - } -#endif - return; - } + int num_parents = node->get_num_parents(graph_type); const NodeRelation *parent_arc = (const NodeRelation *)NULL; - if (urp.size() == 1) { + if (num_parents == 1) { // There is only one parent, so there's no doubt as to which arc // to choose. - parent_arc = *(urp.begin()); + parent_arc = node->get_parent(graph_type, 0); + + } else if (num_parents == 0) { + // This node has no parents. Stop here. + result.make_identity(); + +#ifndef NDEBUG + if (wrt_cat.is_debug()) { + wrt_cat.debug() + << "get_cached_net_transition(" << *node << ") has no parents.\n"; + } +#endif + return; } else { // The node has multiple parents, and we have a list of arcs in @@ -275,9 +260,9 @@ get_cached_net_transition(const Node *node, #ifndef NDEBUG // No, it wasn't mentioned. Issue a warning and use the first // one. - describe_ambiguous_wrt(node, arc_list_begin, arc_list_end, urp); + describe_ambiguous_wrt(node, arc_list_begin, arc_list_end, graph_type); #endif - parent_arc = *(urp.begin()); + parent_arc = node->get_parent(graph_type, 0); } } @@ -332,10 +317,16 @@ get_uncached_net_transition(const Node *node, return; } - UpRelations::const_iterator uri; - uri = node->_parents.find(graph_type); + int num_parents = node->get_num_parents(graph_type); - if (uri == node->_parents.end()) { + const NodeRelation *parent_arc = (const NodeRelation *)NULL; + + if (num_parents == 1) { + // There is only one parent, so there's no doubt as to which arc + // to choose. + parent_arc = node->get_parent(graph_type, 0); + + } else if (num_parents == 0) { // This node has no parents. Stop here. if (wrt_cat.is_spam()) { wrt_cat.spam() @@ -343,25 +334,6 @@ get_uncached_net_transition(const Node *node, } result.make_identity(); return; - } - - const UpRelationPointers &urp = (*uri).second; - if (urp.empty()) { - // Again, this node has no parents. - if (wrt_cat.is_spam()) { - wrt_cat.spam() - << "get_uncached_net_transition(" << *node << ") has no parents.\n"; - } - result.make_identity(); - return; - } - - const NodeRelation *parent_arc = (const NodeRelation *)NULL; - - if (urp.size() == 1) { - // There is only one parent, so there's no doubt as to which arc - // to choose. - parent_arc = *(urp.begin()); } else { // The node has multiple parents, and we have a list of arcs in @@ -379,9 +351,9 @@ get_uncached_net_transition(const Node *node, #ifndef NDEBUG // No, it wasn't mentioned. Issue a warning and use the first // one. - describe_ambiguous_wrt(node, arc_list_begin, arc_list_end, urp); + describe_ambiguous_wrt(node, arc_list_begin, arc_list_end, graph_type); #endif - parent_arc = *(urp.begin()); + parent_arc = node->get_parent(graph_type, 0); } } @@ -404,7 +376,7 @@ get_uncached_net_transition(const Node *node, } wrt_cat.spam(false) - << "), " << urp.size() << " parents, is:\n"; + << "), " << num_parents << " parents, is:\n"; result.write(wrt_cat.spam(false), 2); } } @@ -647,10 +619,10 @@ Node * get_uncached_wrt_subtree(Node *node, Node *to, TransitionWrapper &result, TypeHandle graph_type) { nassertr(node != (Node *)NULL, to); - UpRelations::const_iterator uri; - uri = node->_parents.find(graph_type); - if (uri == node->_parents.end()) { + int num_parents = node->get_num_parents(graph_type); + + if (num_parents == 0) { // This node has no parents. Stop here. if (wrt_cat.is_spam()) { wrt_cat.spam() @@ -660,22 +632,11 @@ get_uncached_wrt_subtree(Node *node, Node *to, TransitionWrapper &result, return (Node *)NULL; } - const UpRelationPointers &urp = (*uri).second; - if (urp.empty()) { - // Again, no parents. Stop here. - if (wrt_cat.is_spam()) { - wrt_cat.spam() - << "get_uncached_wrt_subtree(" << *node << ") has no parents.\n"; - } - result.make_identity(); - return (Node *)NULL; - } - - if (urp.size() != 1) { + if (num_parents != 1) { // There are multiple parents, so stop here. if (wrt_cat.is_spam()) { wrt_cat.spam() - << "get_uncached_wrt_subtree(" << *node << ") has " << urp.size() + << "get_uncached_wrt_subtree(" << *node << ") has " << num_parents << " parents.\n"; } result.make_identity(); @@ -706,7 +667,7 @@ get_uncached_wrt_subtree(Node *node, Node *to, TransitionWrapper &result, } } - const NodeRelation *parent_arc = *(urp.begin()); + const NodeRelation *parent_arc = node->get_parent(graph_type, 0); Node *stop = get_uncached_wrt_subtree(parent_arc->get_parent(), to, diff --git a/panda/src/putil/bamReader.cxx b/panda/src/putil/bamReader.cxx index 8d8cf5cdaf..3205291464 100644 --- a/panda/src/putil/bamReader.cxx +++ b/panda/src/putil/bamReader.cxx @@ -283,15 +283,16 @@ read_pointer(DatagramIterator& scan, TypedWriteable* forWhom) { PN_uint16 objId = scan.get_uint16(); _deferred_pointers[forWhom].push_back(objId); - //This is safe since we have already read the full datagram - //for the object requesting this object. So there can be - //no collision on that front. - //IMPORTANT NOTE: This does make the assumption that - //that objects are requested by other objects in the same - //order that they wrote them originally. + // This is safe since we have already read the full datagram for the + // object requesting this object. So there can be no collision on + // that front. - //Don't queue a read of a null pointer - //or if the object has already been read + // IMPORTANT NOTE: This does make the assumption that objects are + // requested by other objects in the same order that they wrote them + // originally. + + // Don't queue a read of a null pointer or if the object has already + // been read if ((objId != 0) && (_created_objs.find(objId) == _created_objs.end())) queue(objId); } @@ -310,6 +311,19 @@ read_pointers(DatagramIterator &scan, TypedWriteable *forWhom, int count) { } } +//////////////////////////////////////////////////////////////////// +// Function: BamReader::skip_pointer +// Access: Public +// Description: Reads and discards a pointer value from the Bam file. +// This pointer will not be counted among the pointers +// read for a given object, and will not be in the list +// of pointers passed to complete_pointers(). +//////////////////////////////////////////////////////////////////// +void BamReader:: +skip_pointer(DatagramIterator &scan) { + scan.get_uint16(); +} + //////////////////////////////////////////////////////////////////// // Function: BamReader::register_finalize // Access: Public diff --git a/panda/src/putil/bamReader.h b/panda/src/putil/bamReader.h index 114587ce46..b844318fad 100644 --- a/panda/src/putil/bamReader.h +++ b/panda/src/putil/bamReader.h @@ -66,6 +66,7 @@ public: //can register in itself for later "fixing" void read_pointer(DatagramIterator &scan, TypedWriteable* forWhom); void read_pointers(DatagramIterator &scan, TypedWriteable* forWhom, int count); + void skip_pointer(DatagramIterator &scan); //At any time you can call this function to try and resolve all //outstanding pointer requests. Will resolve all requests that diff --git a/panda/src/sgmanip/findApproxLevel.cxx b/panda/src/sgmanip/findApproxLevel.cxx index 73e1737193..cf414bcb27 100644 --- a/panda/src/sgmanip/findApproxLevel.cxx +++ b/panda/src/sgmanip/findApproxLevel.cxx @@ -68,19 +68,14 @@ consider_node(NodePathCollection &result, FindApproxLevel &next_level, if (next_is_stashed()) { next_graph_type = NodeRelation::get_stashed_type(); } - - DownRelations::const_iterator dri; - dri = bottom_node->_children.find(next_graph_type); - if (dri != bottom_node->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - NodeRelation *arc = (*drpi); - consider_next_step(result, arc, next_level, max_matches, graph_type); - if (max_matches > 0 && result.get_num_paths() >= max_matches) { - return; - } + + int num_children = bottom_node->get_num_children(next_graph_type); + for (int i = 0; i < num_children; i++) { + NodeRelation *child_arc = bottom_node->get_child(next_graph_type, i); + + consider_next_step(result, child_arc, next_level, max_matches, graph_type); + if (max_matches > 0 && result.get_num_paths() >= max_matches) { + return; } } } diff --git a/panda/src/sgmanip/nodePath.cxx b/panda/src/sgmanip/nodePath.cxx index 6ea2b29387..bc4ded2fb4 100644 --- a/panda/src/sgmanip/nodePath.cxx +++ b/panda/src/sgmanip/nodePath.cxx @@ -263,18 +263,13 @@ get_children() const { nassertr(!is_empty(), result); Node *bottom_node = node(); - DownRelations::const_iterator dri; - dri = bottom_node->_children.find(_graph_type); - if (dri != bottom_node->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - NodeRelation *arc = (*drpi); - NodePath child(*this); - child.extend_by(arc); - result.add_path(child); - } + + int num_children = bottom_node->get_num_children(_graph_type); + for (int i = 0; i < num_children; i++) { + NodeRelation *child_arc = bottom_node->get_child(_graph_type, i); + NodePath child(*this); + child.extend_by(child_arc); + result.add_path(child); } return result; @@ -297,19 +292,15 @@ get_siblings() const { parent.shorten(1); Node *parent_node = parent.node(); - DownRelations::const_iterator dri; - dri = parent_node->_children.find(_graph_type); - if (dri != parent_node->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - NodeRelation *arc = (*drpi); - if (arc != my_arc) { - NodePath sib(parent); - sib.extend_by(arc); - result.add_path(sib); - } + + int num_children = parent_node->get_num_children(_graph_type); + for (int i = 0; i < num_children; i++) { + NodeRelation *child_arc = parent_node->get_child(_graph_type, i); + + if (child_arc != my_arc) { + NodePath sib(parent); + sib.extend_by(child_arc); + result.add_path(sib); } } @@ -2710,27 +2701,21 @@ r_list_descendants(ostream &out, int indent_level) const { Node *bottom_node = node(); nassertv(bottom_node != (Node *)NULL); indent(out, indent_level) << *bottom_node << "\n"; - - DownRelations::const_iterator dri; - dri = bottom_node->_children.find(_graph_type); - if (dri != bottom_node->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - NodeRelation *arc = (*drpi); - NodePath next(*this); - next.extend_by(arc); - next.r_list_descendants(out, indent_level + 2); - } + + int num_children = bottom_node->get_num_children(_graph_type); + for (int i = 0; i < num_children; i++) { + NodeRelation *child_arc = bottom_node->get_child(_graph_type, i); + + NodePath next(*this); + next.extend_by(child_arc); + next.r_list_descendants(out, indent_level + 2); } if (_graph_type != NodeRelation::get_stashed_type()) { // Also report the number of stashed nodes at this level. - dri = bottom_node->_children.find(NodeRelation::get_stashed_type()); - if (dri != bottom_node->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - indent(out, indent_level) << "(" << drp.size() << " stashed)\n"; + int num_stashed = bottom_node->get_num_children(NodeRelation::get_stashed_type()); + if (num_stashed != 0) { + indent(out, indent_level) << "(" << num_stashed << " stashed)\n"; } } } @@ -2747,22 +2732,16 @@ r_list_transitions(ostream &out, int indent_level) const { out << "\n+"; indent(out, indent_level + 1) << *bottom_node << "\n\n"; - - DownRelations::const_iterator dri; - dri = bottom_node->_children.find(_graph_type); - if (dri != bottom_node->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - NodeRelation *arc = (*drpi); - NodePath next(*this); - next.extend_by(arc); - indent(out, indent_level + 2) << *arc << ":\n"; - arc->write_transitions(out, indent_level + 2); - next.r_list_transitions(out, indent_level + 2); - } + int num_children = bottom_node->get_num_children(_graph_type); + for (int i = 0; i < num_children; i++) { + NodeRelation *child_arc = bottom_node->get_child(_graph_type, i); + NodePath next(*this); + next.extend_by(child_arc); + + indent(out, indent_level + 2) << *child_arc << ":\n"; + child_arc->write_transitions(out, indent_level + 2); + next.r_list_transitions(out, indent_level + 2); } } @@ -2778,14 +2757,10 @@ r_adjust_all_priorities(NodeRelation *arc, int adjustment) { arc->adjust_all_priorities(adjustment); Node *dnode = arc->get_child(); - DownRelations::const_iterator dri; - dri = dnode->_children.find(_graph_type); - if (dri != dnode->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - r_adjust_all_priorities(*drpi, adjustment); - } + + int num_children = dnode->get_num_children(_graph_type); + for (int i = 0; i < num_children; i++) { + NodeRelation *child_arc = dnode->get_child(_graph_type, i); + r_adjust_all_priorities(child_arc, adjustment); } } diff --git a/panda/src/sgraphutil/frustumCullTraverser.I b/panda/src/sgraphutil/frustumCullTraverser.I index 4f5bc64664..950091656d 100644 --- a/panda/src/sgraphutil/frustumCullTraverser.I +++ b/panda/src/sgraphutil/frustumCullTraverser.I @@ -233,17 +233,13 @@ traverse(Node *node, AttributeWrapper &render_state, LevelState &level_state, if (_visitor.reached_node(node, render_state, level_state)) { // Look for further children of the given NodeRelation. - DownRelations::const_iterator dri; - dri = node->_children.find(_graph_type); - if (dri != node->_children.end()) { - // Here are some! - const DownRelationPointers &drp = (*dri).second; + const DownRelationPointers &drp = + node->find_connection(_graph_type).get_down(); - // Now visit each of the children in turn. - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - traverse(*drpi, render_state, level_state, local_frustum, all_in); - } + // Now visit each of the children in turn. + DownRelationPointers::const_iterator drpi; + for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { + traverse(*drpi, render_state, level_state, local_frustum, all_in); } } } diff --git a/panda/src/sgraphutil/sceneGraphReducer.cxx b/panda/src/sgraphutil/sceneGraphReducer.cxx index 4d77247a27..dea0a40c33 100644 --- a/panda/src/sgraphutil/sceneGraphReducer.cxx +++ b/panda/src/sgraphutil/sceneGraphReducer.cxx @@ -261,18 +261,14 @@ r_apply_transitions(NodeRelation *arc, int transition_types, } } - DownRelations::const_iterator dri; - dri = node->_children.find(_graph_type); - if (dri != node->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - DownRelationPointers drp_copy = drp; + const DownRelationPointers &drp = + node->find_connection(_graph_type).get_down(); + DownRelationPointers drp_copy = drp; - DownRelationPointers::const_iterator drpi; - for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) { - NodeRelation *child_arc = (*drpi); - - r_apply_transitions(child_arc, transition_types, trans, duplicate); - } + DownRelationPointers::const_iterator drpi; + for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) { + NodeRelation *child_arc = (*drpi); + r_apply_transitions(child_arc, transition_types, trans, duplicate); } } diff --git a/panda/src/text/textFont.cxx b/panda/src/text/textFont.cxx index 464f26ab98..27fe3ae627 100644 --- a/panda/src/text/textFont.cxx +++ b/panda/src/text/textFont.cxx @@ -242,15 +242,12 @@ find_character_gsets(Node *root, Geom *&ch, GeomPoint *&dot, return found; } else { - DownRelations::const_iterator dri; - dri = root->_children.find(RenderRelation::get_class_type()); - if (dri != root->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - if (find_character_gsets((*drpi)->get_child(), ch, dot, trans)) { - trans.extract_from(*drpi); - } + TypeHandle graph_type = RenderRelation::get_class_type(); + int num_children = root->get_num_children(graph_type); + for (int i = 0; i < num_children; i++) { + NodeRelation *child_arc = root->get_child(graph_type, i); + if (find_character_gsets(child_arc->get_child(), ch, dot, trans)) { + trans.extract_from(child_arc); } } return false; @@ -328,15 +325,11 @@ find_characters(Node *root) { } } else { - DownRelations::const_iterator dri; - dri = root->_children.find(RenderRelation::get_class_type()); - if (dri != root->_children.end()) { - const DownRelationPointers &drp = (*dri).second; - DownRelationPointers::const_iterator drpi; - for (drpi = drp.begin(); drpi != drp.end(); ++drpi) { - Node *node = (*drpi)->get_child(); - find_characters(node); - } + TypeHandle graph_type = RenderRelation::get_class_type(); + int num_children = root->get_num_children(graph_type); + for (int i = 0; i < num_children; i++) { + NodeRelation *child_arc = root->get_child(graph_type, i); + find_characters(child_arc->get_child()); } } } diff --git a/panda/src/text/textNode.cxx b/panda/src/text/textNode.cxx index a79179af3a..ac63c140d3 100644 --- a/panda/src/text/textNode.cxx +++ b/panda/src/text/textNode.cxx @@ -212,12 +212,13 @@ generate() { _lr3d.set(0.0, 0.0, 0.0); _num_rows = 0; - if (_text.empty() || _font.is_null()) { - return (Node *)NULL; - } - // Now build a new sub-tree for all the text components. PT_Node root = new NamedNode(_text); + + if (_text.empty() || _font.is_null()) { + return root; + } + PT_Node sub_root = new NamedNode(); RenderRelation *root_arc = new RenderRelation(root, sub_root);