Panda3D
Loading...
Searching...
No Matches
nodePathComponent.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file nodePathComponent.cxx
10 * @author drose
11 * @date 2002-02-25
12 */
13
14#include "nodePathComponent.h"
15#include "lightMutexHolder.h"
16
17// We start the key counters off at 1, since 0 is reserved for an empty
18// NodePath (and also for an unassigned key).
19int NodePathComponent::_next_key = 1;
20LightMutex NodePathComponent::_key_lock("NodePathComponent::_key_lock");
21TypeHandle NodePathComponent::_type_handle;
22TypeHandle NodePathComponent::CData::_type_handle;
23
24
25/**
26 *
27 */
28CycleData *NodePathComponent::CData::
29make_copy() const {
30 return new CData(*this);
31}
32
33/**
34 * Constructs a new NodePathComponent from the indicated node. Don't try to
35 * call this directly; ask the PandaNode to do it for you.
36 */
37NodePathComponent::
38NodePathComponent(PandaNode *node, NodePathComponent *next,
39 int pipeline_stage, Thread *current_thread) :
40 _node(node),
41 _key(0)
42{
43#ifdef DO_MEMORY_USAGE
44 MemoryUsage::update_type(this, get_class_type());
45#endif
46
47 for (int pipeline_stage_i = pipeline_stage;
48 pipeline_stage_i >= 0;
49 --pipeline_stage_i) {
50 CDStageWriter cdata(_cycler, pipeline_stage_i, current_thread);
51 cdata->_next = next;
52
53 if (next != nullptr) {
54 cdata->_length = next->get_length(pipeline_stage_i, current_thread) + 1;
55 }
56 }
57}
58
59/**
60 * Returns an index number that is guaranteed to be unique for this particular
61 * NodePathComponent, and not to be reused for the lifetime of the application
62 * (barring integer overflow).
63 */
65get_key() const {
66 LightMutexHolder holder(_key_lock);
67 if (_key == 0) {
68 // The first time someone asks for a particular component's key, we make
69 // it up on the spot. This helps keep us from wasting index numbers
70 // generating a unique number for *every* component in the world (we only
71 // have 4.2 billion 32-bit integers, after all)
72 ((NodePathComponent *)this)->_key = _next_key++;
73 }
74 return _key;
75}
76
77/**
78 * Returns true if this component represents the top node in the path.
79 */
81is_top_node(int pipeline_stage, Thread *current_thread) const {
82 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
83 return (cdata->_next == nullptr);
84}
85
86/**
87 * Returns the length of the path to this node.
88 */
90get_length(int pipeline_stage, Thread *current_thread) const {
91 CDStageReader cdata(_cycler, pipeline_stage, current_thread);
92 return cdata->_length;
93}
94
95/**
96 * Checks that the length indicated by the component is one more than the
97 * length of its predecessor. If this is broken, fixes it and returns true
98 * indicating the component has been changed; otherwise, returns false.
99 */
101fix_length(int pipeline_stage, Thread *current_thread) {
102 CDLockedStageReader cdata(_cycler, pipeline_stage, current_thread);
103
104 int length_should_be = 1;
105 if (cdata->_next != nullptr) {
106 length_should_be = cdata->_next->get_length(pipeline_stage, current_thread) + 1;
107 }
108
109 if (cdata->_length == length_should_be) {
110 return false;
111 }
112
113 CDStageWriter cdataw(_cycler, pipeline_stage, cdata);
114 cdataw->_length = length_should_be;
115 return true;
116}
117
118/**
119 * The recursive implementation of NodePath::output(), this writes the names
120 * of each node component in order from beginning to end, by first walking to
121 * the end of the linked list and then outputting from there.
122 */
124output(std::ostream &out) const {
125 Thread *current_thread = Thread::get_current_thread();
126 int pipeline_stage = current_thread->get_pipeline_stage();
127
128 PandaNode *node = get_node();
129 NodePathComponent *next = get_next(pipeline_stage, current_thread);
130 if (next != nullptr) {
131 // This is not the head of the list; keep going up.
132 next->output(out);
133 out << "/";
134
135 PandaNode *parent_node = next->get_node();
136 if (parent_node->find_stashed(node) >= 0) {
137 // The node is stashed.
138 out << "@@";
139
140 } else if (node->find_parent(parent_node) < 0) {
141 // Oops, there's an error. This shouldn't happen.
142 out << ".../";
143 }
144 }
145
146 // Now output this component.
147 if (node->has_name()) {
148 out << node->get_name();
149 } else {
150 out << "-" << node->get_type();
151 }
152 // out << "[" << this->get_length() << "]";
153}
154
155/**
156 * Sets the next pointer in the path.
157 */
158void NodePathComponent::
159set_next(NodePathComponent *next, int pipeline_stage, Thread *current_thread) {
160 nassertv(next != nullptr);
161 CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
162 cdata->_next = next;
163}
164
165/**
166 * Severs any connection to the next pointer in the path and makes this
167 * component a top node.
168 */
169void NodePathComponent::
170set_top_node(int pipeline_stage, Thread *current_thread) {
171 CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
172 cdata->_next = nullptr;
173}
This class is similar to CycleDataLockedReader, except it allows reading from a particular stage of t...
This class is similar to CycleDataReader, except it allows reading from a particular stage of the pip...
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
A single page of data maintained by a PipelineCycler.
Definition cycleData.h:50
Similar to MutexHolder, but for a light mutex.
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition lightMutex.h:41
static void update_type(ReferenceCount *ptr, TypeHandle type)
Associates the indicated type with the given pointer.
Definition memoryUsage.I:55
bool has_name() const
Returns true if the Namable has a nonempty name set, false if the name is empty.
Definition namable.I:44
This is one component of a NodePath.
PandaNode * get_node() const
Returns the node referenced by this component.
bool fix_length(int pipeline_stage, Thread *current_thread)
Checks that the length indicated by the component is one more than the length of its predecessor.
bool is_top_node(int pipeline_stage, Thread *current_thread) const
Returns true if this component represents the top node in the path.
int get_key() const
Returns an index number that is guaranteed to be unique for this particular NodePathComponent,...
NodePathComponent * get_next(int pipeline_stage, Thread *current_thread) const
Returns the next component in the path.
int get_length(int pipeline_stage, Thread *current_thread) const
Returns the length of the path to this node.
void output(std::ostream &out) const
The recursive implementation of NodePath::output(), this writes the names of each node component in o...
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
int find_stashed(PandaNode *node, Thread *current_thread=Thread::get_current_thread()) const
Returns the index of the indicated stashed node, if it is a stashed child, or -1 if it is not.
Definition pandaNode.I:178
int find_parent(PandaNode *node, Thread *current_thread=Thread::get_current_thread()) const
Returns the index of the indicated parent node, if it is a parent, or -1 if it is not.
Definition pandaNode.I:44
A thread; that is, a lightweight process.
Definition thread.h:46
get_pipeline_stage
Returns the Pipeline stage number associated with this thread.
Definition thread.h:105
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition thread.h:109
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.