open_toontown_panda3d/panda/src/graph/arcChain.h

201 lines
6.6 KiB
C++

// Filename: arcChain.h
// Created by: drose (05Jan01)
//
////////////////////////////////////////////////////////////////////
//
// 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 ARCCHAIN_H
#define ARCCHAIN_H
#include <pandabase.h>
#include "nodeRelation.h"
#include "node.h"
#include <pointerTo.h>
#include <referenceCount.h>
#include <notify.h>
#include <typedObject.h>
////////////////////////////////////////////////////////////////////
// Class : ArcChain
// Description : This defines a singly-linked chain of arcs from one
// point (e.g. the root of the scene graph) to another
// point (e.g. a leaf), although no assumption is made
// about the relationship between the arcs. It is
// simply a list of arcs that may only be lengthened or
// shortened, or copied.
//
// This list may be copied by reference using the copy
// constructor; the new copy may be appended to without
// modifying the source (but individual nodes may not be
// modified).
//
// This serves as the fundamental implementation of
// NodePaths, for instance, and also is used during
// render traversals to manage the list of arcs
// traversed so far (and thus compute unambiguous
// wrt's).
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA ArcChain {
protected:
// We maintain our own linked list structure here instead of using
// some STL structure, so we can efficiently copy-construct these
// things by sharing the initial part of the list.
// We have a singly-linked list whose head is the bottom arc of the
// path, and whose tail is the top arc of the path. Thus, we can
// copy the entire path by simply copying the head pointer, and we
// can then append to or shorten our own path without affecting the
// paths we're sharing ArcComponents with. Very LISPy.
// Normally, an ArcChain represents a list of arcs from the root of
// some graph down to a leaf. This kind of structure works pretty
// well because the ArcChain keeps a reference count to each arc,
// which in turn keeps a reference count to each child node. This
// means each node in the chain is reference counted, *except* the
// top node.
// To ensure that we also reference count the top node, we allow
// each ArcComponent to store either a pointer to an arc or, if it
// is the last node in the chain (and *only* if it is the last node
// in the chain), a pointer to a node. Thus, the last ArcComponent
// in the chain will store a reference-counting pointer to the
// chain's top node.
class EXPCL_PANDA ArcComponent : public ReferenceCount {
public:
INLINE_GRAPH ArcComponent(Node *node);
INLINE_GRAPH ArcComponent(NodeRelation *arc, ArcComponent *next);
INLINE_GRAPH ArcComponent(const ArcComponent &copy);
void operator = (const ArcComponent &copy);
INLINE_GRAPH ~ArcComponent();
INLINE_GRAPH bool has_arc() const;
INLINE_GRAPH NodeRelation *get_arc() const;
INLINE_GRAPH Node *get_node() const;
INLINE_GRAPH bool is_top_node() const;
INLINE_GRAPH bool is_top_arc() const;
INLINE_GRAPH ArcComponent *get_next() const;
INLINE_GRAPH void set_next(ArcComponent *next);
private:
union {
// These are plain pointers instead of PT's, because they are
// stored in a union. We manage the reference counts by hand in
// the constructors and destructor.
NodeRelation *_arc;
Node *_node;
} _p;
PT(ArcComponent) _next;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
ReferenceCount::init_type();
register_type(_type_handle, "ArcChain::ArcComponent",
ReferenceCount::get_class_type());
}
private:
static TypeHandle _type_handle;
};
PT(ArcComponent) _head;
// This is a supporting class for iterating through all the arcs via
// begin() .. end().
class EXPCL_PANDA ForwardIterator {
public:
INLINE_GRAPH ForwardIterator(ArcComponent *comp = NULL);
INLINE_GRAPH NodeRelation *operator * () const;
INLINE_GRAPH void operator ++();
INLINE_GRAPH bool operator == (const ForwardIterator &other) const;
INLINE_GRAPH bool operator != (const ForwardIterator &other) const;
private:
ArcComponent *_comp;
};
public:
typedef ForwardIterator iterator;
typedef ForwardIterator const_iterator;
INLINE_GRAPH ArcChain();
INLINE_GRAPH ArcChain(Node *top_node);
INLINE_GRAPH ArcChain(const ArcChain &copy);
INLINE_GRAPH void operator = (const ArcChain &copy);
// Methods to query an ArcChain's contents.
PUBLISHED:
INLINE_GRAPH bool is_empty() const;
INLINE_GRAPH bool is_singleton() const;
INLINE_GRAPH bool has_arcs() const;
int get_num_nodes() const;
Node *get_node(int index) const;
INLINE_GRAPH int get_num_arcs() const;
NodeRelation *get_arc(int index) const;
Node *get_top_node() const;
INLINE_GRAPH Node *node() const;
INLINE_GRAPH NodeRelation *arc() const;
public:
// Methods to make an ArcChain behave like an STL container.
INLINE_GRAPH const_iterator begin() const;
INLINE_GRAPH const_iterator end() const;
INLINE_GRAPH bool empty() const;
INLINE_GRAPH void push_back(NodeRelation *arc);
INLINE_GRAPH void pop_back();
INLINE_GRAPH NodeRelation *back() const;
INLINE_GRAPH bool operator == (const ArcChain &other) const;
INLINE_GRAPH bool operator != (const ArcChain &other) const;
INLINE_GRAPH bool operator < (const ArcChain &other) const;
INLINE_GRAPH int compare_to(const ArcChain &other) const;
INLINE_GRAPH void output(ostream &out) const;
private:
void r_output(ostream &out, ArcComponent *comp) const;
static int r_compare_to(const ArcComponent *a, const ArcComponent *v);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
ArcComponent::init_type();
register_type(_type_handle, "ArcChain");
}
private:
static TypeHandle _type_handle;
};
INLINE_GRAPH ostream &operator << (ostream &out, const ArcChain &arc_chain);
#ifndef DONT_INLINE_GRAPH
#include "arcChain.I"
#endif
#endif