Panda3D

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
17 AttribNodeRegistry * TVOLATILE AttribNodeRegistry::_global_ptr;
18
19 /**
20 *
21 */
22 AttribNodeRegistry::
23 AttribNodeRegistry() {
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 */
39 void AttribNodeRegistry::
40 add_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 */
59 bool AttribNodeRegistry::
60 remove_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 */
76 NodePath AttribNodeRegistry::
77 lookup_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 */
91 int AttribNodeRegistry::
92 get_num_nodes() const {
93 LightMutexHolder holder(_lock);
94 return _entries.size();
95 }
96
97 /**
98 * Returns the nth NodePath recorded in the registry.
99 */
100 NodePath AttribNodeRegistry::
101 get_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 */
110 TypeHandle AttribNodeRegistry::
111 get_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 */
122 std::string AttribNodeRegistry::
123 get_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 */
135 int AttribNodeRegistry::
136 find_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 */
150 int AttribNodeRegistry::
151 find_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 */
163 void AttribNodeRegistry::
164 remove_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 */
173 void AttribNodeRegistry::
174 clear() {
175 LightMutexHolder holder(_lock);
176 _entries.clear();
177 }
178
179 /**
180 *
181 */
182 void AttribNodeRegistry::
183 output(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 */
213 void AttribNodeRegistry::
214 write(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 */
228 void AttribNodeRegistry::
229 make_global_ptr() {
230 AttribNodeRegistry *ptr = new AttribNodeRegistry;
231 void *result = AtomicAdjust::compare_and_exchange_ptr
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 }
attribNodeRegistry.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AtomicAdjustDummyImpl::compare_and_exchange_ptr
static Pointer compare_and_exchange_ptr(Pointer &mem, Pointer old_value, Pointer new_value)
Atomic compare and exchange.
Definition: atomicAdjustDummyImpl.I:109
AttribNodeRegistry
This global object records NodePaths that are referenced by scene graph attribs, such as ClipPlaneAtt...
Definition: attribNodeRegistry.h:33
AttribNodeRegistry::clear
void clear()
Removes all nodes from the registry.
Definition: attribNodeRegistry.cxx:174
AttribNodeRegistry::find_node
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 ...
Definition: attribNodeRegistry.cxx:136
AttribNodeRegistry::remove_node
bool remove_node(const NodePath &attrib_node)
Removes the indicated NodePath from the registry.
Definition: attribNodeRegistry.cxx:60
AttribNodeRegistry::get_node_name
std::string get_node_name(int n) const
Returns the name of the nth node, as recorded in the registry.
Definition: attribNodeRegistry.cxx:123
AttribNodeRegistry::get_num_nodes
get_num_nodes
Returns the total number of nodes in the registry.
Definition: attribNodeRegistry.h:44
AttribNodeRegistry::get_node_type
TypeHandle get_node_type(int n) const
Returns the type of the nth node, as recorded in the registry.
Definition: attribNodeRegistry.cxx:111
AttribNodeRegistry::lookup_node
NodePath lookup_node(const NodePath &orig_node) const
Looks up the indicated NodePath in the registry.
Definition: attribNodeRegistry.cxx:77
AttribNodeRegistry::get_node
get_node
Returns the nth NodePath recorded in the registry.
Definition: attribNodeRegistry.h:44
AttribNodeRegistry::add_node
void add_node(const NodePath &attrib_node)
Adds the indicated NodePath to the registry.
Definition: attribNodeRegistry.cxx:40
LightMutexHolder
Similar to MutexHolder, but for a light mutex.
Definition: lightMutexHolder.h:25
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
NodePath::is_empty
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
ordered_vector::begin
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
Definition: ordered_vector.I:41
ordered_vector::size
size_type_0 size() const
Returns the number of elements in the ordered vector.
Definition: ordered_vector.I:221
ordered_vector::end
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
Definition: ordered_vector.I:50
ordered_vector::clear
void clear()
Removes all elements from the ordered vector.
Definition: ordered_vector.I:412
pmap
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
lightMutexHolder.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.