Panda3D
Loading...
Searching...
No Matches
attribNodeRegistry.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 attribNodeRegistry.cxx
10 * @author drose
11 * @date 2007-07-07
12 */
13
14#include "attribNodeRegistry.h"
15#include "lightMutexHolder.h"
16
17AttribNodeRegistry * TVOLATILE AttribNodeRegistry::_global_ptr;
18
19/**
20 *
21 */
22AttribNodeRegistry::
23AttribNodeRegistry() {
24}
25
26/**
27 * Adds the indicated NodePath to the registry. The name and type of the node
28 * are noted at the time of this call; if the name changes later, it will not
29 * update the registry index.
30 *
31 * The NodePath must reference some kind of an attribute node, such as a
32 * LightNode or a PlaneNode. When bam files that reference an attribute node
33 * of the same type and the same name are loaded, they will quietly be
34 * redirected to reference this NodePath.
35 *
36 * If there is already a node matching the indicated name and type, it will be
37 * replaced.
38 */
40add_node(const NodePath &attrib_node) {
41 nassertv(!attrib_node.is_empty());
42 LightMutexHolder holder(_lock);
43
44 std::pair<Entries::iterator, bool> result = _entries.insert(Entry(attrib_node));
45 if (!result.second) {
46 // Replace an existing node.
47 (*result.first)._node = attrib_node;
48 }
49}
50
51/**
52 * Removes the indicated NodePath from the registry. The name of the node
53 * must not have changed since the matching call to add_node(), or it will not
54 * be successfully removed.
55 *
56 * Returns true if the NodePath is found and removed, false if it is not found
57 * (for instance, because the name has changed).
58 */
60remove_node(const NodePath &attrib_node) {
61 nassertr(!attrib_node.is_empty(), false);
62 LightMutexHolder holder(_lock);
63 Entries::iterator ei = _entries.find(Entry(attrib_node));
64 if (ei != _entries.end()) {
65 _entries.erase(ei);
66 return true;
67 }
68 return false;
69}
70
71/**
72 * Looks up the indicated NodePath in the registry. If there is a node
73 * already in the registry with the matching name and type, returns that
74 * NodePath instead; otherwise, returns the original NodePath.
75 */
77lookup_node(const NodePath &orig_node) const {
78 nassertr(!orig_node.is_empty(), orig_node);
79
80 LightMutexHolder holder(_lock);
81 Entries::const_iterator ei = _entries.find(Entry(orig_node));
82 if (ei != _entries.end()) {
83 return (*ei)._node;
84 }
85 return orig_node;
86}
87
88/**
89 * Returns the total number of nodes in the registry.
90 */
92get_num_nodes() const {
93 LightMutexHolder holder(_lock);
94 return _entries.size();
95}
96
97/**
98 * Returns the nth NodePath recorded in the registry.
99 */
101get_node(int n) const {
102 LightMutexHolder holder(_lock);
103 nassertr(n >= 0 && n < (int)_entries.size(), NodePath());
104 return _entries[n]._node;
105}
106
107/**
108 * Returns the type of the nth node, as recorded in the registry.
109 */
111get_node_type(int n) const {
112 LightMutexHolder holder(_lock);
113 nassertr(n >= 0 && n < (int)_entries.size(), TypeHandle::none());
114 return _entries[n]._type;
115}
116
117/**
118 * Returns the name of the nth node, as recorded in the registry. This will
119 * be the node name as it was at the time the node was recorded; if the node
120 * has changed names since then, this will still return the original name.
121 */
123get_node_name(int n) const {
124 LightMutexHolder holder(_lock);
125 nassertr(n >= 0 && n < (int)_entries.size(), std::string());
126 return _entries[n]._name;
127}
128
129/**
130 * Returns the index number of the indicated NodePath in the registry
131 * (assuming its name hasn't changed since it was recorded in the registry),
132 * or -1 if the NodePath cannot be found (for instance, because its name has
133 * changed).
134 */
136find_node(const NodePath &attrib_node) const {
137 nassertr(!attrib_node.is_empty(), -1);
138 LightMutexHolder holder(_lock);
139 Entries::const_iterator ei = _entries.find(Entry(attrib_node));
140 if (ei != _entries.end()) {
141 return ei - _entries.begin();
142 }
143 return -1;
144}
145
146/**
147 * Returns the index number of the node with the indicated type and name in
148 * the registry, or -1 if there is no such node in the registry.
149 */
151find_node(TypeHandle type, const std::string &name) const {
152 LightMutexHolder holder(_lock);
153 Entries::const_iterator ei = _entries.find(Entry(type, name));
154 if (ei != _entries.end()) {
155 return ei - _entries.begin();
156 }
157 return -1;
158}
159
160/**
161 * Removes the nth node from the registry.
162 */
164remove_node(int n) {
165 LightMutexHolder holder(_lock);
166 nassertv(n >= 0 && n < (int)_entries.size());
167 _entries.erase(_entries.begin() + n);
168}
169
170/**
171 * Removes all nodes from the registry.
172 */
174clear() {
175 LightMutexHolder holder(_lock);
176 _entries.clear();
177}
178
179/**
180 *
181 */
182void AttribNodeRegistry::
183output(std::ostream &out) const {
184 LightMutexHolder holder(_lock);
185
186 typedef pmap<TypeHandle, int> Counts;
187 Counts counts;
188
189 Entries::const_iterator ei;
190 for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
191 TypeHandle type = (*ei)._type;
192 Counts::iterator ci = counts.insert(Counts::value_type(type, 0)).first;
193 ++((*ci).second);
194 }
195
196 out << _entries.size() << " entries";
197
198 if (!counts.empty()) {
199 Counts::iterator ci = counts.begin();
200 out << " (" << (*ci).first << ":" << (*ci).second;
201 ++ci;
202 while (ci != counts.end()) {
203 out << ", " << (*ci).first << ":" << (*ci).second;
204 ++ci;
205 }
206 out << ")";
207 }
208}
209
210/**
211 *
212 */
213void AttribNodeRegistry::
214write(std::ostream &out) const {
215 LightMutexHolder holder(_lock);
216
217 Entries::const_iterator ei;
218 for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
219 const Entry &entry = (*ei);
220 out << entry._type << ", \"" << entry._name << "\": " << entry._node
221 << "\n";
222 }
223}
224
225/**
226 *
227 */
228void AttribNodeRegistry::
229make_global_ptr() {
230 AttribNodeRegistry *ptr = new AttribNodeRegistry;
232 ((void * TVOLATILE &)_global_ptr, nullptr, (void *)ptr);
233 if (result != nullptr) {
234 // Someone else got there first.
235 delete ptr;
236 }
237 assert(_global_ptr != nullptr);
238}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static Pointer compare_and_exchange_ptr(Pointer &mem, Pointer old_value, Pointer new_value)
Atomic compare and exchange.
This global object records NodePaths that are referenced by scene graph attribs, such as ClipPlaneAtt...
void clear()
Removes all nodes from the registry.
int find_node(const NodePath &attrib_node) const
Returns the index number of the indicated NodePath in the registry (assuming its name hasn't changed ...
bool remove_node(const NodePath &attrib_node)
Removes the indicated NodePath from the registry.
std::string get_node_name(int n) const
Returns the name of the nth node, as recorded in the registry.
get_num_nodes
Returns the total number of nodes in the registry.
TypeHandle get_node_type(int n) const
Returns the type of the nth node, as recorded in the registry.
NodePath lookup_node(const NodePath &orig_node) const
Looks up the indicated NodePath in the registry.
get_node
Returns the nth NodePath recorded in the registry.
void add_node(const NodePath &attrib_node)
Adds the indicated NodePath to the registry.
Similar to MutexHolder, but for a light mutex.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition nodePath.h:159
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition nodePath.I:188
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
size_type_0 size() const
Returns the number of elements in the ordered vector.
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.