Forráskód Böngészése

distinction between empty and error nodepaths

David Rose 24 éve
szülő
commit
a51271948f

+ 3 - 3
panda/src/sgmanip/Sources.pp

@@ -11,15 +11,15 @@
   #define SOURCES \
      config_sgmanip.h findApproxLevel.I findApproxLevel.h  \
      findApproxPath.I findApproxPath.h nodePath.I nodePath.h  \
-     nodePathBase.I nodePathBase.h nodePathCollection.I  \
+     nodePathCollection.I  \
      nodePathCollection.h nodePathLerps.h nodePath.cxx
     
   #define INCLUDED_SOURCES \
      config_sgmanip.cxx findApproxLevel.cxx findApproxPath.cxx  \
-     nodePathBase.cxx nodePathCollection.cxx nodePathLerps.cxx 
+     nodePathCollection.cxx nodePathLerps.cxx 
 
   #define INSTALL_HEADERS \
-    nodePath.I nodePath.h nodePathBase.I nodePathBase.h \
+    nodePath.I nodePath.h \
     nodePathCollection.I nodePathCollection.h
 
   #define IGATESCAN all

+ 0 - 2
panda/src/sgmanip/config_sgmanip.cxx

@@ -20,7 +20,6 @@
 
 #include <dconfig.h>
 
-#include "nodePathBase.h"
 #include "nodePath.h"
 #include "nodePathLerps.h"
 
@@ -28,7 +27,6 @@ Configure(config_sgmanip);
 NotifyCategoryDef(sgmanip, "");
 
 ConfigureFn(config_sgmanip) {
-  NodePathBase::init_type();
   NodePath::init_type();
   PosLerpFunctor::init_type();
   HprLerpFunctor::init_type();

+ 86 - 16
panda/src/sgmanip/nodePath.I

@@ -26,7 +26,10 @@
 //               this object.
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath::
-NodePath(TypeHandle graph_type) : NodePathBase(graph_type) {
+NodePath(TypeHandle graph_type) :
+  _graph_type(graph_type),
+  _error_type(ET_ok)
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -41,8 +44,11 @@ NodePath(TypeHandle graph_type) : NodePathBase(graph_type) {
 //               empty NodePath.
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath::
-NodePath(Node *top_node, TypeHandle graph_type) : NodePathBase(top_node, graph_type) {
-  nassertv(verify_connectivity());
+NodePath(Node *top_node, TypeHandle graph_type) :
+  ArcChain(top_node),
+  _graph_type(graph_type),
+  _error_type(ET_ok)
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -56,9 +62,10 @@ NodePath(Node *top_node, TypeHandle graph_type) : NodePathBase(top_node, graph_t
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath::
 NodePath(const ArcChain &chain, TypeHandle graph_type) :
-  NodePathBase(chain, graph_type)
+  ArcChain(chain),
+  _graph_type(graph_type),
+  _error_type(ET_ok)
 {
-  nassertv(verify_connectivity());
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -67,7 +74,11 @@ NodePath(const ArcChain &chain, TypeHandle graph_type) :
 //  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath::
-NodePath(const NodePathBase &copy) : NodePathBase(copy) {
+NodePath(const NodePath &copy) :
+  ArcChain(copy),
+  _graph_type(copy._graph_type),
+  _error_type(copy._error_type)
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -77,7 +88,9 @@ NodePath(const NodePathBase &copy) : NodePathBase(copy) {
 ////////////////////////////////////////////////////////////////////
 INLINE void NodePath::
 operator = (const NodePath &copy) {
-  NodePathBase::operator = (copy);
+  ArcChain::operator = (copy);
+  _graph_type = copy._graph_type;
+  _error_type = copy._error_type;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -89,6 +102,45 @@ INLINE NodePath::
 ~NodePath() {
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodePath::not_found named constructor
+//       Access: Public, Static
+//  Description: Creates a NodePath with the ET_not_found error type
+//               set.
+////////////////////////////////////////////////////////////////////
+INLINE NodePath NodePath::
+not_found() {
+  NodePath result;
+  result._error_type = ET_not_found;
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: NodePath::removed named constructor
+//       Access: Public, Static
+//  Description: Creates a NodePath with the ET_removed error type
+//               set.
+////////////////////////////////////////////////////////////////////
+INLINE NodePath NodePath::
+removed() {
+  NodePath result;
+  result._error_type = ET_removed;
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: NodePath::fail named constructor
+//       Access: Public, Static
+//  Description: Creates a NodePath with the ET_fail error type
+//               set.
+////////////////////////////////////////////////////////////////////
+INLINE NodePath NodePath::
+fail() {
+  NodePath result;
+  result._error_type = ET_fail;
+  return result;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePath::Equality Operator
 //       Access: Public
@@ -120,7 +172,10 @@ operator != (const NodePath &other) const {
 ////////////////////////////////////////////////////////////////////
 INLINE int NodePath::
 compare_to(const NodePath &other) const {
-  return NodePathBase::compare_to(other);
+  if (is_empty() && other.is_empty()) {
+    return (int)get_error_type() - (int)other.get_error_type();
+  }
+  return ArcChain::compare_to(other);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -198,6 +253,17 @@ is_empty() const {
   return !ArcChain::has_node();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodePath::get_error_type
+//       Access: Public
+//  Description: If is_empty() is true, this returns a code that
+//               represents the reason why the NodePath is empty.
+////////////////////////////////////////////////////////////////////
+INLINE NodePath::ErrorType NodePath::
+get_error_type() const {
+  return _error_type;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePath::is_singleton
 //       Access: Public
@@ -243,6 +309,7 @@ get_num_arcs() const {
 ////////////////////////////////////////////////////////////////////
 INLINE Node *NodePath::
 node() const {
+  nassertr(_error_type == ET_ok, (Node *)NULL);
   if (is_empty()) {
     return (Node *)NULL;
   }
@@ -257,6 +324,7 @@ node() const {
 ////////////////////////////////////////////////////////////////////
 INLINE NodeRelation *NodePath::
 arc() const {
+  nassertr(_error_type == ET_ok, (NodeRelation *)NULL);
   if (!has_arcs()) {
     // A singleton or empty list.
     return (NodeRelation *)NULL;
@@ -288,9 +356,9 @@ get_num_children() const {
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath NodePath::
 get_child(int n) const {
-  nassertr(verify_connectivity(), NodePath());
-  nassertr(!is_empty(), NodePath());
-  nassertr(n >= 0 && n < get_num_children(), NodePath());
+  nassertr(verify_connectivity(), NodePath::fail());
+  nassertr(!is_empty(), NodePath::fail());
+  nassertr(n >= 0 && n < get_num_children(), NodePath::fail());
 
   NodePath result(*this);
   result.extend_by(node()->get_child(_graph_type, n));
@@ -317,7 +385,7 @@ has_parent() const {
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath NodePath::
 get_parent() const {
-  nassertr(has_parent(), NodePath());
+  nassertr(has_parent(), NodePath::fail());
   NodePath parent(*this);
   parent.shorten();
   return parent;
@@ -333,11 +401,12 @@ get_parent() const {
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath NodePath::
 find_path_down_to(Node *dnode) const {
+  nassertr(_error_type == ET_ok, *this);
   NodePath result(*this);
   if (result.extend_down_to(dnode)) {
     return result;
   }
-  return NodePath();
+  return NodePath::not_found();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -350,11 +419,12 @@ find_path_down_to(Node *dnode) const {
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath NodePath::
 find(const string &path) const {
+  nassertr(_error_type == ET_ok, *this);
   NodePath result(*this);
   if (result.extend_by(path)) {
     return result;
   }
-  return NodePath();
+  return NodePath::not_found();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -366,8 +436,8 @@ find(const string &path) const {
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath NodePath::
 attach_new_node(const string &name, int sort) const {
-  nassertr(verify_connectivity(), NodePath());
-  nassertr(!is_empty(), NodePath(_graph_type));
+  nassertr(verify_connectivity(), NodePath::fail());
+  nassertr(!is_empty(), *this);
 
   return attach_new_node(new NamedNode(name), sort);
 }

+ 45 - 17
panda/src/sgmanip/nodePath.cxx

@@ -44,6 +44,7 @@
 
 #include "plist.h"
 
+int NodePath::_max_search_depth = 10000;
 TypeHandle NodePath::_type_handle;
 
 
@@ -93,6 +94,7 @@ public:
 ////////////////////////////////////////////////////////////////////
 bool NodePath::
 extend_by(Node *dnode) {
+  nassertr(_error_type == ET_ok, false);
   nassertr(verify_connectivity(), false);
   nassertr(dnode != (Node *)NULL, false);
 
@@ -129,6 +131,7 @@ extend_by(Node *dnode) {
 ////////////////////////////////////////////////////////////////////
 bool NodePath::
 extend_by(NodeRelation *darc) {
+  nassertr(_error_type == ET_ok, false);
   nassertr(verify_connectivity(), false);
   nassertr(darc != (NodeRelation *)NULL, false);
 
@@ -173,6 +176,8 @@ extend_by(NodeRelation *darc) {
 ////////////////////////////////////////////////////////////////////
 bool NodePath::
 extend_by(const NodePath &other) {
+  nassertr(_error_type == ET_ok, false);
+  nassertr(other._error_type == ET_ok, false);
   nassertr(verify_connectivity(), false);
   if (is_empty()) {
     // A special case: extending an empty path by another path is just
@@ -195,6 +200,7 @@ extend_by(const NodePath &other) {
 ////////////////////////////////////////////////////////////////////
 bool NodePath::
 extend_by(const string &path) {
+  nassertr(_error_type == ET_ok, false);
   nassertr(verify_connectivity(), false);
   NodePathCollection col;
   find_matches(col, path, 1);
@@ -223,6 +229,7 @@ extend_by(const string &path) {
 ////////////////////////////////////////////////////////////////////
 bool NodePath::
 extend_down_to(Node *dnode) {
+  nassertr(_error_type == ET_ok, false);
   if (!is_empty() && node() == dnode) {
     // We're already there!
     return true;
@@ -258,6 +265,7 @@ extend_down_to(Node *dnode) {
 ////////////////////////////////////////////////////////////////////
 void NodePath::
 shorten(int num_nodes) {
+  nassertv(_error_type == ET_ok);
   nassertv(num_nodes >= 0 && num_nodes <= get_num_nodes());
 
   int count = num_nodes;
@@ -276,6 +284,7 @@ shorten(int num_nodes) {
 void NodePath::
 clear() {
   _head.clear();
+  _error_type = ET_ok;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -345,6 +354,7 @@ get_siblings() const {
 NodePathCollection NodePath::
 find_all_paths_down_to(Node *dnode) const {
   NodePathCollection col;
+  nassertr(!is_empty(), col);
   nassertr(verify_connectivity(), col);
   nassertr(dnode != (Node *)NULL, col);
   FindApproxPath approx_path;
@@ -365,6 +375,7 @@ find_all_paths_down_to(Node *dnode) const {
 NodePathCollection NodePath::
 find_all_matches(const string &path) const {
   NodePathCollection col;
+  nassertr(!is_empty(), col);
   nassertr(verify_connectivity(), col);
   find_matches(col, path, -1);
   return col;
@@ -386,6 +397,8 @@ find_all_matches(const string &path) const {
 ////////////////////////////////////////////////////////////////////
 NodePath NodePath::
 find_singular_transform() const {
+  nassertr(!is_empty(), NodePath::fail());
+
   if (has_mat()) {
     LMatrix4f mat;
     if (!mat.invert_from(get_mat())) {
@@ -402,7 +415,7 @@ find_singular_transform() const {
     }
   }
 
-  return NodePath();
+  return NodePath::not_found();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -800,16 +813,16 @@ wrt_reparent_to(const NodePath &other, int sort) {
 ////////////////////////////////////////////////////////////////////
 NodePath NodePath::
 instance_to(const NodePath &other, int sort) const {
-  nassertr(verify_connectivity(), NodePath());
-  nassertr(!is_empty(), NodePath());
-  nassertr(!other.is_empty(), NodePath());
+  nassertr(verify_connectivity(), NodePath::fail());
+  nassertr(!is_empty(), NodePath::fail());
+  nassertr(!other.is_empty(), NodePath::fail());
 
   Node *bottom_node = node();
   NodeRelation *darc =
     NodeRelation::create_typed_arc(_graph_type, other.node(),
                                    bottom_node, sort);
-  nassertr(darc != (NodeRelation *)NULL, NodePath());
-  nassertr(darc->is_exact_type(_graph_type), NodePath());
+  nassertr(darc != (NodeRelation *)NULL, NodePath::fail());
+  nassertr(darc->is_exact_type(_graph_type), NodePath::fail());
 
   if (has_arcs()) {
     // Copy the transitions from this one's bottom arc, so the
@@ -839,19 +852,19 @@ instance_to(const NodePath &other, int sort) const {
 ////////////////////////////////////////////////////////////////////
 NodePath NodePath::
 copy_to(const NodePath &other, int sort) const {
-  nassertr(verify_connectivity(), NodePath());
-  nassertr(!is_empty(), NodePath());
-  nassertr(!other.is_empty(), NodePath());
+  nassertr(verify_connectivity(), NodePath::fail());
+  nassertr(!is_empty(), NodePath::fail());
+  nassertr(!other.is_empty(), NodePath::fail());
 
   Node *source_node = node();
   PT_Node copy_node = source_node->copy_subgraph(_graph_type);
-  nassertr(copy_node != (Node *)NULL, NodePath());
+  nassertr(copy_node != (Node *)NULL, NodePath::fail());
 
   NodeRelation *darc =
     NodeRelation::create_typed_arc(_graph_type, other.node(),
                                    copy_node, sort);
-  nassertr(darc != (NodeRelation *)NULL, NodePath());
-  nassertr(darc->is_exact_type(_graph_type), NodePath());
+  nassertr(darc != (NodeRelation *)NULL, NodePath::fail());
+  nassertr(darc->is_exact_type(_graph_type), NodePath::fail());
 
   if (has_arcs()) {
     // Copy the transitions from this one's bottom arc, so the
@@ -879,7 +892,7 @@ copy_to(const NodePath &other, int sort) const {
 ////////////////////////////////////////////////////////////////////
 NodePath NodePath::
 attach_new_node(Node *dnode, int sort) const {
-  nassertr(verify_connectivity(), NodePath());
+  nassertr(verify_connectivity(), NodePath::fail());
   nassertr(!is_empty(), NodePath(_graph_type));
   nassertr(dnode != (Node *)NULL, NodePath(_graph_type));
 
@@ -906,11 +919,12 @@ attach_new_node(Node *dnode, int sort) const {
 ////////////////////////////////////////////////////////////////////
 void NodePath::
 remove_node() {
+  nassertv(_error_type != ET_not_found);
   if (!has_arcs() || !arc()->is_attached()) {
     // If we have no arcs (maybe we were already removed), or if the
     // bottom arc has been disconnected (maybe a parent was removed),
     // quietly do nothing except to ensure the NodePath is clear.
-    clear();
+    (*this) = NodePath::removed();
     return;
   }
 
@@ -935,7 +949,7 @@ remove_node() {
   // from being actually destructed (although it has been removed from
   // the scene graph), and they will now believe they are rooted at
   // that destructed node, cut off from the rest of the world.
-  clear();
+  (*this) = NodePath::removed();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -963,6 +977,17 @@ string NodePath::
 as_string(int start_at_node) const {
   nassertr(start_at_node >= 0, string());
 
+  switch (_error_type) {
+  case ET_not_found:
+    return "**not found**";
+  case ET_removed:
+    return "**removed**";
+  case ET_fail:
+    return "**error**";
+  default:
+    break;
+  }
+
   if (is_empty()) {
     // An empty path always returns an empty string.
     return string();
@@ -1854,6 +1879,8 @@ set_pos_hpr_scale(const NodePath &other,
 ////////////////////////////////////////////////////////////////////
 LMatrix4f NodePath::
 get_mat(const NodePath &other) const {
+  nassertr(_error_type == ET_ok && other._error_type == ET_ok,
+           LMatrix4f::ident_mat());
   NodeTransitionWrapper ntw(TransformTransition::get_class_type());
 
   if (is_empty() && other.is_empty()) {
@@ -1890,6 +1917,7 @@ get_mat(const NodePath &other) const {
 ////////////////////////////////////////////////////////////////////
 void NodePath::
 set_mat(const NodePath &other, const LMatrix4f &mat) {
+  nassertv(_error_type == ET_ok && other._error_type == ET_ok);
   nassertv_always(has_arcs());
 
 #ifndef NDEBUG
@@ -2735,7 +2763,7 @@ get_transparency() const {
 NodePath NodePath::
 get_hidden_ancestor() const {
   if (!has_arcs()) {
-    return NodePath();
+    return NodePath::not_found();
   }
 
   if (arc()->has_transition(PruneTransition::get_class_type())) {
@@ -2762,7 +2790,7 @@ get_hidden_ancestor() const {
 NodePath NodePath::
 get_stashed_ancestor() const {
   if (!has_arcs()) {
-    return NodePath();
+    return NodePath::not_found();
   }
 
   if (arc()->get_graph_type() != _graph_type) {

+ 22 - 14
panda/src/sgmanip/nodePath.h

@@ -21,7 +21,6 @@
 
 #include <pandabase.h>
 
-#include "nodePathBase.h"
 #include "nodePathCollection.h"
 
 #include <allTransitionsWrapper.h>
@@ -135,24 +134,30 @@ class GraphicsStateGuardianBase;
 //               to a GeomNode).  It thus unambiguously defines
 //               instances, especially when it is rooted at the top of
 //               the graph.
-//
-//               This class does not have any data members or
-//               additional virtual functions; it's just interface.
-//               All of the data is defined in the base class,
-//               NodePathBase.  This is important so that
-//               NodePathCollection can work correctly without knowing
-//               exactly what a NodePath is.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA NodePath : public NodePathBase {
+class EXPCL_PANDA NodePath : public ArcChain {
 PUBLISHED:
+  // This enumeration is returned by get_error_type() for an empty
+  // NodePath to report the reason it's empty.
+  enum ErrorType {
+    ET_ok = 0,     // i.e. not empty, or never assigned to anything.
+    ET_not_found,  // returned from a failed find() or similar function.
+    ET_removed,    // remove_node() was previously called on this NodePath.
+    ET_fail,       // general failure return from some function.
+  };
+
   INLINE NodePath(TypeHandle graph_type = RenderRelation::get_class_type());
   INLINE NodePath(Node *top_node, TypeHandle graph_type = RenderRelation::get_class_type());
   INLINE NodePath(const ArcChain &chain, TypeHandle graph_type);
 
-  INLINE NodePath(const NodePathBase &copy);
+  INLINE NodePath(const NodePath &copy);
   INLINE void operator = (const NodePath &copy);
   INLINE ~NodePath();
 
+  INLINE static NodePath not_found();
+  INLINE static NodePath removed();
+  INLINE static NodePath fail();
+
   INLINE bool operator == (const NodePath &other) const;
   INLINE bool operator != (const NodePath &other) const;
   INLINE int compare_to(const NodePath &other) const;
@@ -179,6 +184,7 @@ PUBLISHED:
   // Methods to query a NodePath's contents.
 
   INLINE bool is_empty() const;
+  INLINE ErrorType get_error_type() const;
   INLINE bool is_singleton() const;
   INLINE bool has_arcs() const;
   int get_num_nodes() const;
@@ -547,17 +553,19 @@ private:
   void r_adjust_all_priorities(NodeRelation *arc, int adjustment);
   void r_clear_wrt_cache(NodeRelation *arc);
 
-  // It's important that there are no data members in this class.  Put
-  // them in NodePathBase instead.
+private:
+  TypeHandle _graph_type;
+  ErrorType _error_type;
+  static int _max_search_depth;
 
 public:
   static TypeHandle get_class_type() {
     return _type_handle;
   }
   static void init_type() {
-    NodePathBase::init_type();
+    ArcChain::init_type();
     register_type(_type_handle, "NodePath",
-                  NodePathBase::get_class_type());
+                  ArcChain::get_class_type());
   }
 
 private:

+ 0 - 80
panda/src/sgmanip/nodePathBase.I

@@ -1,80 +0,0 @@
-// Filename: nodePathBase.I
-// Created by:  drose (06Mar00)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://www.panda3d.org/license.txt .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////
-//     Function: NodePathBase::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE NodePathBase::
-NodePathBase(TypeHandle graph_type) :
-  _graph_type(graph_type)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: NodePathBase::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE NodePathBase::
-NodePathBase(Node *top_node, TypeHandle graph_type) :
-  ArcChain(top_node),
-  _graph_type(graph_type)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: NodePathBase::Constructor
-//       Access: Public
-//  Description: This constructor creates a new NodePathBase given an
-//               ArcChain, which is a more primitive version of a
-//               NodePath.  Some graph-traversal operations generate
-//               ArcChains, so it's useful to be able to use one of
-//               these to create a NodePath.
-////////////////////////////////////////////////////////////////////
-INLINE NodePathBase::
-NodePathBase(const ArcChain &chain, TypeHandle graph_type) :
-  ArcChain(chain),
-  _graph_type(graph_type)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: NodePathBase::Copy Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE NodePathBase::
-NodePathBase(const NodePathBase &copy) :
-  ArcChain(copy),
-  _graph_type(copy._graph_type)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: NodePathBase::Copy Assignment Operator
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void NodePathBase::
-operator = (const NodePathBase &copy) {
-  ArcChain::operator = (copy);
-  _graph_type = copy._graph_type;
-}

+ 0 - 22
panda/src/sgmanip/nodePathBase.cxx

@@ -1,22 +0,0 @@
-// Filename: nodePathBase.cxx
-// Created by:  drose (06Mar00)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://www.panda3d.org/license.txt .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "nodePathBase.h"
-
-int NodePathBase::_max_search_depth = 10000;
-TypeHandle NodePathBase::_type_handle;

+ 0 - 69
panda/src/sgmanip/nodePathBase.h

@@ -1,69 +0,0 @@
-// Filename: nodePathBase.h
-// Created by:  drose (06Mar00)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://www.panda3d.org/license.txt .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#ifndef NODEPATHBASE_H
-#define NODEPATHBASE_H
-
-#include <pandabase.h>
-
-#include <node.h>
-#include <pt_Node.h>
-#include <arcChain.h>
-#include <renderRelation.h>
-
-////////////////////////////////////////////////////////////////////
-//       Class : NodePathBase
-// Description : This is the base class for NodePath so we can defined
-//               NodePathCollections as collections of something.  All
-//               of the interface for NodePath is defined at that
-//               level; this just defines the things that are stored
-//               here.
-////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA NodePathBase : public ArcChain {
-public:
-  INLINE NodePathBase(TypeHandle graph_type = RenderRelation::get_class_type());
-  INLINE NodePathBase(Node *top_node, TypeHandle graph_type = RenderRelation::get_class_type());
-  INLINE NodePathBase(const ArcChain &chain, TypeHandle graph_type);
-  INLINE NodePathBase(const NodePathBase &copy);
-  INLINE void operator = (const NodePathBase &copy);
-
-protected:
-  // Most of the interesting part of NodePathBase is inherited from
-  // ArcChain.  This gives us a sharable linked list of arcs, with a
-  // single node on top.
-
-  TypeHandle _graph_type;
-  static int _max_search_depth;
-
-public:
-  static TypeHandle get_class_type() {
-    return _type_handle;
-  }
-  static void init_type() {
-    ArcChain::init_type();
-    register_type(_type_handle, "NodePathBase",
-                  ArcChain::get_class_type());
-  }
-
-private:
-  static TypeHandle _type_handle;
-};
-
-#include "nodePathBase.I"
-
-#endif

+ 43 - 8
panda/src/sgmanip/nodePathCollection.cxx

@@ -22,6 +22,7 @@
 #include "findApproxLevel.h"
 
 #include <indent.h>
+#include <renderRelation.h>
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePathCollection::Constructor
@@ -30,6 +31,7 @@
 ////////////////////////////////////////////////////////////////////
 NodePathCollection::
 NodePathCollection() {
+  _graph_type = RenderRelation::get_class_type();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -39,7 +41,8 @@ NodePathCollection() {
 ////////////////////////////////////////////////////////////////////
 NodePathCollection::
 NodePathCollection(const NodePathCollection &copy) :
-  _node_paths(copy._node_paths)
+  _node_paths(copy._node_paths),
+  _graph_type(copy._graph_type)
 {
 }
 
@@ -51,6 +54,7 @@ NodePathCollection(const NodePathCollection &copy) :
 void NodePathCollection::
 operator = (const NodePathCollection &copy) {
   _node_paths = copy._node_paths;
+  _graph_type = copy._graph_type;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -60,14 +64,24 @@ operator = (const NodePathCollection &copy) {
 ////////////////////////////////////////////////////////////////////
 void NodePathCollection::
 add_path(const NodePath &node_path) {
+  if (_node_paths.empty()) {
+    // If this is the first NodePath added to the collection, it
+    // defines our graph_type.
+    _graph_type = node_path.get_graph_type();
+
+  } else {
+    // Otherwise, the graph_type must match what's already there.
+    nassertv(node_path.get_graph_type() == _graph_type);
+  }
+
   // If the pointer to our internal array is shared by any other
   // NodePathCollections, we have to copy the array now so we won't
   // inadvertently modify any of our brethren NodePathCollection
   // objects.
 
   if (_node_paths.get_ref_count() > 1) {
-    PTA(NodePathBase) old_node_paths = _node_paths;
-    _node_paths = PTA(NodePathBase)(0);
+    PTA(ArcChain) old_node_paths = _node_paths;
+    _node_paths = PTA(ArcChain)(0);
     _node_paths.v() = old_node_paths.v();
   }
 
@@ -85,7 +99,7 @@ bool NodePathCollection::
 remove_path(const NodePath &node_path) {
   int path_index = -1;
   for (int i = 0; path_index == -1 && i < (int)_node_paths.size(); i++) {
-    if ((const NodePath &)_node_paths[i] == node_path) {
+    if (_node_paths[i] == node_path) {
       path_index = i;
     }
   }
@@ -101,8 +115,8 @@ remove_path(const NodePath &node_path) {
   // objects.
 
   if (_node_paths.get_ref_count() > 1) {
-    PTA(NodePathBase) old_node_paths = _node_paths;
-    _node_paths = PTA(NodePathBase)(0);
+    PTA(ArcChain) old_node_paths = _node_paths;
+    _node_paths = PTA(ArcChain)(0);
     _node_paths.v() = old_node_paths.v();
   }
 
@@ -120,6 +134,16 @@ remove_path(const NodePath &node_path) {
 ////////////////////////////////////////////////////////////////////
 void NodePathCollection::
 add_paths_from(const NodePathCollection &other) {
+  if (_node_paths.empty()) {
+    // If this is the first NodePath added to the collection, it
+    // defines our graph_type.
+    _graph_type = other.get_graph_type();
+
+  } else {
+    // Otherwise, the graph_type must match what's already there.
+    nassertv(other.get_graph_type() == _graph_type);
+  }
+
   int other_num_paths = other.get_num_paths();
   for (int i = 0; i < other_num_paths; i++) {
     add_path(other.get_path(i));
@@ -231,7 +255,7 @@ NodePath NodePathCollection::
 get_path(int index) const {
   nassertr(index >= 0 && index < (int)_node_paths.size(), NodePath());
 
-  return NodePath(_node_paths[index]);
+  return NodePath(_node_paths[index], _graph_type);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -245,7 +269,18 @@ NodePath NodePathCollection::
 operator [] (int index) const {
   nassertr(index >= 0 && index < (int)_node_paths.size(), NodePath());
 
-  return NodePath(_node_paths[index]);
+  return NodePath(_node_paths[index], _graph_type);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: NodePathCollection::get_graph_type
+//       Access: Public
+//  Description: Returns the type of graph that all the NodePaths in
+//               the collection represent.
+////////////////////////////////////////////////////////////////////
+TypeHandle NodePathCollection::
+get_graph_type() const {
+  return _graph_type;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 7 - 3
panda/src/sgmanip/nodePathCollection.h

@@ -23,8 +23,7 @@
 
 // We don't include NodePath in the header file, so NodePath can
 // include us.
-#include "nodePathBase.h"
-
+#include <arcChain.h>
 #include <pointerToArray.h>
 
 class NodePath;
@@ -35,6 +34,9 @@ class NodePath;
 //               for returning from functions that need to return
 //               multiple NodePaths (for instance,
 //               NodePaths::get_children).
+//
+//               All the NodePaths added to a NodePathCollection must
+//               share the same graph_type.
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA NodePathCollection {
 PUBLISHED:
@@ -55,6 +57,7 @@ PUBLISHED:
   int get_num_paths() const;
   NodePath get_path(int index) const;
   NodePath operator [] (int index) const;
+  TypeHandle get_graph_type() const;
 
   // Handy operations on many NodePaths at once.
   INLINE void ls() const;
@@ -74,8 +77,9 @@ PUBLISHED:
   void write(ostream &out, int indent_level = 0) const;
 
 private:
-  typedef PTA(NodePathBase) NodePaths;
+  typedef PTA(ArcChain) NodePaths;
   NodePaths _node_paths;
+  TypeHandle _graph_type;
 };
 
 INLINE ostream &operator << (ostream &out, const NodePathCollection &col) {

+ 0 - 1
panda/src/sgmanip/sgmanip_composite1.cxx

@@ -2,6 +2,5 @@
 #include "config_sgmanip.cxx"
 #include "findApproxLevel.cxx"
 #include "findApproxPath.cxx"
-#include "nodePathBase.cxx"
 #include "nodePathCollection.cxx"
 #include "nodePathLerps.cxx"