Browse Source

nodePath refinements

David Rose 24 years ago
parent
commit
5954465fbc

+ 40 - 41
panda/src/pgraph/qpnodePath.I

@@ -20,11 +20,7 @@
 ////////////////////////////////////////////////////////////////////
 //     Function: qpNodePath::Default Constructor
 //       Access: Published
-//  Description: This constructs an empty qpNodePath with no nodes.  It
-//               cannot be extended, since you cannot add nodes without
-//               first specifying the top node.  Use the constructor
-//               that receives a node if you ever want to do anything
-//               with this path.
+//  Description: This constructs an empty qpNodePath with no nodes.
 ////////////////////////////////////////////////////////////////////
 INLINE qpNodePath::
 qpNodePath() :
@@ -35,9 +31,9 @@ qpNodePath() :
 ////////////////////////////////////////////////////////////////////
 //     Function: qpNodePath::Constructor
 //       Access: Published
-//  Description: This constructs an empty qpNodePath with a single
-//               node.  An ordinary PandaNode is created with the
-//               indicated name.
+//  Description: This constructs a new qpNodePath with a single
+//               node.  An ordinary, unattached PandaNode is created
+//               with the indicated name.
 ////////////////////////////////////////////////////////////////////
 INLINE qpNodePath::
 qpNodePath(const string &top_node_name) :
@@ -52,35 +48,53 @@ qpNodePath(const string &top_node_name) :
 //       Access: Published
 //  Description: This constructs a NodePath for the indicated node.
 //               If the node does not have any parents, this creates a
-//               single NodePath; otherwise, it automatically finds
+//               singleton NodePath; otherwise, it automatically finds
 //               the path from the node to the root.  If the node has
 //               multiple paths to the root, one path is chosen
-//               arbitrarily and a warning message is printed.
+//               arbitrarily and a warning message is printed (but see
+//               also NodePath::any_path(), below).
 ////////////////////////////////////////////////////////////////////
 INLINE qpNodePath::
-qpNodePath(PandaNode *top_node) :
+qpNodePath(PandaNode *node) :
   _error_type(ET_ok)
 {
-  if (top_node != (PandaNode *)NULL) {
-    _head = top_node->get_generic_component(false);
+  if (node != (PandaNode *)NULL) {
+    _head = node->get_generic_component(false);
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: qpNodePath::any_path named constructor
+//       Access: Published, Static
+//  Description: Returns a new NodePath that represents any arbitrary
+//               path from the root to the indicated node.  This is
+//               the same thing that would be returned by
+//               NodePath(node), except that no warning is issued if
+//               the path is ambiguous.
+////////////////////////////////////////////////////////////////////
+INLINE qpNodePath qpNodePath::
+any_path(PandaNode *node) {
+  qpNodePath result;
+  if (node != (PandaNode *)NULL) {
+    result._head = node->get_generic_component(true);
+  }
+  return result;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: qpNodePath::Constructor
 //       Access: Published
 //  Description: Constructs a NodePath with the indicated parent
 //               NodePath and child node; the child node must be a
-
 //               stashed or unstashed child of the parent.
 ////////////////////////////////////////////////////////////////////
 INLINE qpNodePath::
-qpNodePath(const qpNodePath &parent, PandaNode *child) :
+qpNodePath(const qpNodePath &parent, PandaNode *child_node) :
   _error_type(ET_fail)
 {
   nassertv(!parent.is_empty());
-  nassertv(child != (PandaNode *)NULL);
-  _head = PandaNode::get_component(parent._head, child);
+  nassertv(child_node != (PandaNode *)NULL);
+  _head = PandaNode::get_component(parent._head, child_node);
   nassertv(_head != (qpNodePathComponent *)NULL);
 
   if (_head != (qpNodePathComponent *)NULL) {
@@ -155,7 +169,7 @@ fail() {
 ////////////////////////////////////////////////////////////////////
 //     Function: qpNodePath::set_max_search_depth
 //       Access: Published, Static
-//  Description: Certain operations, such as extend_down_to() or
+//  Description: Certain operations, such as find() or
 //               find_all_matches(), require a traversal of the scene
 //               graph to search for the target node or nodes.  This
 //               traversal does not attempt to detect cycles, so an
@@ -252,6 +266,13 @@ node() const {
 //               given key will never be reused for a different
 //               instance (unless the app has been running long enough
 //               that we overflow the integer key value).
+//
+//               There are a few special case circumstances that can
+//               cause the key for a particular instance to be
+//               changed.  These all involve different instances being
+//               collapsed into the same instance by some scene graph
+//               operation (for instance, detaching a node below an
+//               instanced node).
 ////////////////////////////////////////////////////////////////////
 INLINE int qpNodePath::
 get_key() const {
@@ -350,28 +371,6 @@ ls(ostream &out, int indent_level) const {
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: qpNodePath::ls_transitions
-//       Access: Published
-//  Description: Lists the hierarchy at and below the referenced node,
-//               along with the state transitions at each level.
-////////////////////////////////////////////////////////////////////
-INLINE void qpNodePath::
-ls_transitions() const {
-  nassertv(false);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: qpNodePath::ls_transforms
-//       Access: Published
-//  Description: Lists the hierarchy at and below the referenced node,
-//               along with the transforms at each level.
-////////////////////////////////////////////////////////////////////
-INLINE void qpNodePath::
-ls_transforms() const {
-  nassertv(false);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: qpNodePath::get_state
 //       Access: Published
@@ -1078,7 +1077,7 @@ compare_to(const qpNodePath &other) const {
   other.uncollapse_head();
 
   // Nowadays, the NodePathComponents at the head are pointerwise
-  // equivalent if and only iff the NodePaths are equivalent.  So we
+  // equivalent if and only if the NodePaths are equivalent.  So we
   // only have to compare pointers.
   return _head - other._head;
 }

+ 31 - 10
panda/src/pgraph/qpnodePath.cxx

@@ -357,21 +357,42 @@ attach_new_node(PandaNode *node, int sort) const {
 void qpNodePath::
 remove_node() {
   nassertv(_error_type != ET_not_found);
-  if (is_empty() || is_singleton()) {
-    // If we have no parents, remove_node() is just a do-nothing
-    // operation; if we have no nodes, maybe we were already removed.
-    // In either case, quietly do nothing except to ensure the
-    // qpNodePath is clear.
-    (*this) = qpNodePath::removed();
-    return;
-  }
 
-  uncollapse_head();
-  PandaNode::detach(_head);
+  // If we have no parents, remove_node() is just a do-nothing
+  // operation; if we have no nodes, maybe we were already removed.
+  // In either case, quietly do nothing except to ensure the
+  // qpNodePath is clear.
+  if (!is_empty() && !is_singleton()) {
+    uncollapse_head();
+    PandaNode::detach(_head);
+  }
 
   (*this) = qpNodePath::removed();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: qpNodePath::detach_node
+//       Access: Published
+//  Description: Disconnects the referenced node from its parent, but
+//               does not immediately delete it.  The NodePath retains
+//               a pointer to the node.  If there are no other
+//               instances to the node, this becomes a singleton
+//               NodePath; otherwise, this NodePath becomes the same
+//               as another arbitrary instance.
+//
+//               If the NodePath later goes out of scope or is
+//               reassigned to something else, this will have the same
+//               effect as remove_node().
+////////////////////////////////////////////////////////////////////
+void qpNodePath::
+detach_node() {
+  nassertv(_error_type != ET_not_found);
+  if (!is_empty() && !is_singleton()) {
+    uncollapse_head();
+    PandaNode::detach(_head);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: qpNodePath::output
 //       Access: Published

+ 5 - 4
panda/src/pgraph/qpnodePath.h

@@ -149,9 +149,11 @@ PUBLISHED:
 
   INLINE qpNodePath();
   INLINE qpNodePath(const string &top_node_name);
-  INLINE qpNodePath(PandaNode *top_node);
-  INLINE qpNodePath(const qpNodePath &copy);
+  INLINE qpNodePath(PandaNode *node);
+  INLINE static qpNodePath any_path(PandaNode *node);
   INLINE qpNodePath(const qpNodePath &parent, PandaNode *child_node);
+
+  INLINE qpNodePath(const qpNodePath &copy);
   INLINE void operator = (const qpNodePath &copy);
 
   INLINE static qpNodePath not_found();
@@ -202,6 +204,7 @@ PUBLISHED:
   qpNodePath attach_new_node(PandaNode *node, int sort = 0) const;
   INLINE qpNodePath attach_new_node(const string &name, int sort = 0) const;
   void remove_node();
+  void detach_node();
 
   // Handy ways to look at what's there, and other miscellaneous
   // operations.
@@ -210,8 +213,6 @@ PUBLISHED:
 
   INLINE void ls() const;
   INLINE void ls(ostream &out, int indent_level = 0) const;
-  INLINE void ls_transitions() const;
-  INLINE void ls_transforms() const;
 
 
   // Aggregate transform and state information.

+ 0 - 21
panda/src/pgraph/qpnodePathComponent.I

@@ -135,24 +135,3 @@ get_collapsed() const {
   CDReader cdata(_cycler);
   return cdata->_next;
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: qpNodePathComponent::collapse_with
-//       Access: Private
-//  Description: Indicates that this component pointer is no longer
-//               valid, and that the indicated component should be
-//               used instead.  This is done whenever two
-//               qpNodePathComponents have been collapsed together due
-//               to an instance being removed higher up in the graph.
-////////////////////////////////////////////////////////////////////
-INLINE void qpNodePathComponent::
-collapse_with(qpNodePathComponent *next) {
-  nassertv(!is_collapsed());
-  nassertv(next != (qpNodePathComponent *)NULL);
-  CDWriter cdata(_cycler);
-  cdata->_next = next;
-  cdata->_length = 0;
-
-  // We indicate a component has been collapsed by setting its length
-  // to zero.
-}

+ 27 - 0
panda/src/pgraph/qpnodePathComponent.cxx

@@ -193,3 +193,30 @@ set_top_node() {
     cdata->_next = (qpNodePathComponent *)NULL;
   }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpNodePathComponent::collapse_with
+//       Access: Private
+//  Description: Indicates that this component pointer is no longer
+//               valid, and that the indicated component should be
+//               used instead.  This is done whenever two
+//               qpNodePathComponents have been collapsed together due
+//               to an instance being removed higher up in the graph.
+////////////////////////////////////////////////////////////////////
+void qpNodePathComponent::
+collapse_with(qpNodePathComponent *next) {
+  nassertv(!is_collapsed());
+  nassertv(next != (qpNodePathComponent *)NULL);
+  CDWriter cdata(_cycler);
+
+  // We indicate a component has been collapsed by setting its length
+  // to zero.
+  cdata->_next = next;
+  cdata->_length = 0;
+
+  if (_key != 0 && next->_key == 0) {
+    // If we had a key set and the other one didn't, it inherits our
+    // key.  Otherwise, we inherit the other's key.
+    next->_key = _key;
+  }
+}

+ 1 - 1
panda/src/pgraph/qpnodePathComponent.h

@@ -68,7 +68,7 @@ public:
 private:
   void set_next(qpNodePathComponent *next);
   void set_top_node();
-  INLINE void collapse_with(qpNodePathComponent *next);
+  void collapse_with(qpNodePathComponent *next);
 
   // We don't have to cycle the _node and _key elements, since these
   // are permanent properties of this object.  (Well, the _key is