distinction between empty and error nodepaths

This commit is contained in:
David Rose 2001-06-18 15:56:59 +00:00
parent 4bbf01b805
commit a51271948f
11 changed files with 206 additions and 235 deletions

View File

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

View File

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

View File

@ -26,7 +26,10 @@
// this object. // this object.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE NodePath:: 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. // empty NodePath.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE NodePath:: INLINE NodePath::
NodePath(Node *top_node, TypeHandle graph_type) : NodePathBase(top_node, graph_type) { NodePath(Node *top_node, TypeHandle graph_type) :
nassertv(verify_connectivity()); 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:: INLINE NodePath::
NodePath(const ArcChain &chain, TypeHandle graph_type) : 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: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE NodePath:: 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:: INLINE void NodePath::
operator = (const NodePath &copy) { 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() { ~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 // Function: NodePath::Equality Operator
// Access: Public // Access: Public
@ -120,7 +172,10 @@ operator != (const NodePath &other) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE int NodePath:: INLINE int NodePath::
compare_to(const NodePath &other) const { 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(); 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 // Function: NodePath::is_singleton
// Access: Public // Access: Public
@ -243,6 +309,7 @@ get_num_arcs() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE Node *NodePath:: INLINE Node *NodePath::
node() const { node() const {
nassertr(_error_type == ET_ok, (Node *)NULL);
if (is_empty()) { if (is_empty()) {
return (Node *)NULL; return (Node *)NULL;
} }
@ -257,6 +324,7 @@ node() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE NodeRelation *NodePath:: INLINE NodeRelation *NodePath::
arc() const { arc() const {
nassertr(_error_type == ET_ok, (NodeRelation *)NULL);
if (!has_arcs()) { if (!has_arcs()) {
// A singleton or empty list. // A singleton or empty list.
return (NodeRelation *)NULL; return (NodeRelation *)NULL;
@ -288,9 +356,9 @@ get_num_children() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath:: INLINE NodePath NodePath::
get_child(int n) const { get_child(int n) const {
nassertr(verify_connectivity(), NodePath()); nassertr(verify_connectivity(), NodePath::fail());
nassertr(!is_empty(), NodePath()); nassertr(!is_empty(), NodePath::fail());
nassertr(n >= 0 && n < get_num_children(), NodePath()); nassertr(n >= 0 && n < get_num_children(), NodePath::fail());
NodePath result(*this); NodePath result(*this);
result.extend_by(node()->get_child(_graph_type, n)); result.extend_by(node()->get_child(_graph_type, n));
@ -317,7 +385,7 @@ has_parent() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath:: INLINE NodePath NodePath::
get_parent() const { get_parent() const {
nassertr(has_parent(), NodePath()); nassertr(has_parent(), NodePath::fail());
NodePath parent(*this); NodePath parent(*this);
parent.shorten(); parent.shorten();
return parent; return parent;
@ -333,11 +401,12 @@ get_parent() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath:: INLINE NodePath NodePath::
find_path_down_to(Node *dnode) const { find_path_down_to(Node *dnode) const {
nassertr(_error_type == ET_ok, *this);
NodePath result(*this); NodePath result(*this);
if (result.extend_down_to(dnode)) { if (result.extend_down_to(dnode)) {
return result; return result;
} }
return NodePath(); return NodePath::not_found();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -350,11 +419,12 @@ find_path_down_to(Node *dnode) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath:: INLINE NodePath NodePath::
find(const string &path) const { find(const string &path) const {
nassertr(_error_type == ET_ok, *this);
NodePath result(*this); NodePath result(*this);
if (result.extend_by(path)) { if (result.extend_by(path)) {
return result; return result;
} }
return NodePath(); return NodePath::not_found();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -366,8 +436,8 @@ find(const string &path) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE NodePath NodePath:: INLINE NodePath NodePath::
attach_new_node(const string &name, int sort) const { attach_new_node(const string &name, int sort) const {
nassertr(verify_connectivity(), NodePath()); nassertr(verify_connectivity(), NodePath::fail());
nassertr(!is_empty(), NodePath(_graph_type)); nassertr(!is_empty(), *this);
return attach_new_node(new NamedNode(name), sort); return attach_new_node(new NamedNode(name), sort);
} }

View File

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

View File

@ -21,7 +21,6 @@
#include <pandabase.h> #include <pandabase.h>
#include "nodePathBase.h"
#include "nodePathCollection.h" #include "nodePathCollection.h"
#include <allTransitionsWrapper.h> #include <allTransitionsWrapper.h>
@ -135,24 +134,30 @@ class GraphicsStateGuardianBase;
// to a GeomNode). It thus unambiguously defines // to a GeomNode). It thus unambiguously defines
// instances, especially when it is rooted at the top of // instances, especially when it is rooted at the top of
// the graph. // 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: 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(TypeHandle graph_type = RenderRelation::get_class_type());
INLINE NodePath(Node *top_node, 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 ArcChain &chain, TypeHandle graph_type);
INLINE NodePath(const NodePathBase &copy); INLINE NodePath(const NodePath &copy);
INLINE void operator = (const NodePath &copy); INLINE void operator = (const NodePath &copy);
INLINE ~NodePath(); 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 bool operator != (const NodePath &other) const; INLINE bool operator != (const NodePath &other) const;
INLINE int compare_to(const NodePath &other) const; INLINE int compare_to(const NodePath &other) const;
@ -179,6 +184,7 @@ PUBLISHED:
// Methods to query a NodePath's contents. // Methods to query a NodePath's contents.
INLINE bool is_empty() const; INLINE bool is_empty() const;
INLINE ErrorType get_error_type() const;
INLINE bool is_singleton() const; INLINE bool is_singleton() const;
INLINE bool has_arcs() const; INLINE bool has_arcs() const;
int get_num_nodes() const; int get_num_nodes() const;
@ -547,17 +553,19 @@ private:
void r_adjust_all_priorities(NodeRelation *arc, int adjustment); void r_adjust_all_priorities(NodeRelation *arc, int adjustment);
void r_clear_wrt_cache(NodeRelation *arc); void r_clear_wrt_cache(NodeRelation *arc);
// It's important that there are no data members in this class. Put private:
// them in NodePathBase instead. TypeHandle _graph_type;
ErrorType _error_type;
static int _max_search_depth;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;
} }
static void init_type() { static void init_type() {
NodePathBase::init_type(); ArcChain::init_type();
register_type(_type_handle, "NodePath", register_type(_type_handle, "NodePath",
NodePathBase::get_class_type()); ArcChain::get_class_type());
} }
private: private:

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// 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;
}

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "nodePathBase.h"
int NodePathBase::_max_search_depth = 10000;
TypeHandle NodePathBase::_type_handle;

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#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

View File

@ -22,6 +22,7 @@
#include "findApproxLevel.h" #include "findApproxLevel.h"
#include <indent.h> #include <indent.h>
#include <renderRelation.h>
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: NodePathCollection::Constructor // Function: NodePathCollection::Constructor
@ -30,6 +31,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
NodePathCollection:: NodePathCollection::
NodePathCollection() { NodePathCollection() {
_graph_type = RenderRelation::get_class_type();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -39,7 +41,8 @@ NodePathCollection() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
NodePathCollection:: NodePathCollection::
NodePathCollection(const NodePathCollection &copy) : 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:: void NodePathCollection::
operator = (const NodePathCollection &copy) { operator = (const NodePathCollection &copy) {
_node_paths = copy._node_paths; _node_paths = copy._node_paths;
_graph_type = copy._graph_type;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -60,14 +64,24 @@ operator = (const NodePathCollection &copy) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void NodePathCollection:: void NodePathCollection::
add_path(const NodePath &node_path) { 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 // If the pointer to our internal array is shared by any other
// NodePathCollections, we have to copy the array now so we won't // NodePathCollections, we have to copy the array now so we won't
// inadvertently modify any of our brethren NodePathCollection // inadvertently modify any of our brethren NodePathCollection
// objects. // objects.
if (_node_paths.get_ref_count() > 1) { if (_node_paths.get_ref_count() > 1) {
PTA(NodePathBase) old_node_paths = _node_paths; PTA(ArcChain) old_node_paths = _node_paths;
_node_paths = PTA(NodePathBase)(0); _node_paths = PTA(ArcChain)(0);
_node_paths.v() = old_node_paths.v(); _node_paths.v() = old_node_paths.v();
} }
@ -85,7 +99,7 @@ bool NodePathCollection::
remove_path(const NodePath &node_path) { remove_path(const NodePath &node_path) {
int path_index = -1; int path_index = -1;
for (int i = 0; path_index == -1 && i < (int)_node_paths.size(); i++) { 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; path_index = i;
} }
} }
@ -101,8 +115,8 @@ remove_path(const NodePath &node_path) {
// objects. // objects.
if (_node_paths.get_ref_count() > 1) { if (_node_paths.get_ref_count() > 1) {
PTA(NodePathBase) old_node_paths = _node_paths; PTA(ArcChain) old_node_paths = _node_paths;
_node_paths = PTA(NodePathBase)(0); _node_paths = PTA(ArcChain)(0);
_node_paths.v() = old_node_paths.v(); _node_paths.v() = old_node_paths.v();
} }
@ -120,6 +134,16 @@ remove_path(const NodePath &node_path) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void NodePathCollection:: void NodePathCollection::
add_paths_from(const NodePathCollection &other) { 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(); int other_num_paths = other.get_num_paths();
for (int i = 0; i < other_num_paths; i++) { for (int i = 0; i < other_num_paths; i++) {
add_path(other.get_path(i)); add_path(other.get_path(i));
@ -231,7 +255,7 @@ NodePath NodePathCollection::
get_path(int index) const { get_path(int index) const {
nassertr(index >= 0 && index < (int)_node_paths.size(), NodePath()); 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 { operator [] (int index) const {
nassertr(index >= 0 && index < (int)_node_paths.size(), NodePath()); 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;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

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

View File

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