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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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() {
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 }
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
size_type_0 size() const
Returns the number of elements in the ordered vector.
void clear()
Removes all elements from the ordered vector.
This global object records NodePaths that are referenced by scene graph attribs, such as ClipPlaneAtt...
bool remove_node(const NodePath &attrib_node)
Removes the indicated NodePath from the registry.
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
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 ...
Similar to MutexHolder, but for a light mutex.
void add_node(const NodePath &attrib_node)
Adds the indicated NodePath to the registry.
std::string get_node_name(int n) const
Returns the name 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.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
void clear()
Removes all nodes from the registry.
TypeHandle get_node_type(int n) const
Returns the type of the nth node, as recorded in the registry.
static Pointer compare_and_exchange_ptr(Pointer &mem, Pointer old_value, Pointer new_value)
Atomic compare and exchange.