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  */
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 }
ordered_vector::size
size_type_0 size() const
Returns the number of elements in the ordered vector.
Definition: ordered_vector.I:221
LightMutexHolder
Similar to MutexHolder, but for a light mutex.
Definition: lightMutexHolder.h:25
attribNodeRegistry.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AttribNodeRegistry::clear
void clear()
Removes all nodes from the registry.
Definition: attribNodeRegistry.cxx:174
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_node
get_node
Returns the nth NodePath recorded in the registry.
Definition: attribNodeRegistry.h:44
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
pmap
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
AttribNodeRegistry::get_num_nodes
get_num_nodes
Returns the total number of nodes in the registry.
Definition: attribNodeRegistry.h:44
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_type
TypeHandle get_node_type(int n) const
Returns the type of the nth node, as recorded in the registry.
Definition: attribNodeRegistry.cxx:111
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
lightMutexHolder.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AttribNodeRegistry::add_node
void add_node(const NodePath &attrib_node)
Adds the indicated NodePath to the registry.
Definition: attribNodeRegistry.cxx:40
AttribNodeRegistry
This global object records NodePaths that are referenced by scene graph attribs, such as ClipPlaneAtt...
Definition: attribNodeRegistry.h:33
ordered_vector::end
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
Definition: ordered_vector.I:50
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
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::remove_node
bool remove_node(const NodePath &attrib_node)
Removes the indicated NodePath from the registry.
Definition: attribNodeRegistry.cxx:60
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::clear
void clear()
Removes all elements from the ordered vector.
Definition: ordered_vector.I:412
NodePath::is_empty
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188