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 \
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

View File

@ -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();

View File

@ -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);
}

View File

@ -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) {

View File

@ -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:

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 <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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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) {

View File

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