Panda3D
eggNameUniquifier.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 eggNameUniquifier.cxx
10  * @author drose
11  * @date 2000-11-09
12  */
13 
14 #include "eggNameUniquifier.h"
15 #include "eggNode.h"
16 #include "eggGroupNode.h"
17 #include "config_egg.h"
18 #include "dcast.h"
19 
20 #include "pnotify.h"
21 
22 using std::string;
23 
24 TypeHandle EggNameUniquifier::_type_handle;
25 
26 
27 /**
28  *
29  */
30 EggNameUniquifier::
31 EggNameUniquifier() {
32  _index = 0;
33 }
34 
35 /**
36  *
37  */
38 EggNameUniquifier::
39 ~EggNameUniquifier() {
40 }
41 
42 /**
43  * Empties the table of used named and prepares the Uniquifier for a new tree.
44  */
46 clear() {
47  _categories.clear();
48  _index = 0;
49 }
50 
51 /**
52  * Begins the traversal from the indicated node.
53  */
55 uniquify(EggNode *node) {
56  string category = get_category(node);
57  if (egg_cat.is_debug()) {
58  egg_cat.debug()
59  << "Uniquifying " << node->get_name() << ", category = " << category
60  << "\n";
61  }
62 
63  if (!category.empty()) {
64  string name = filter_name(node);
65 
66  UsedNames &names = _categories[category];
67  bool inserted = false;
68  if (!name.empty()) {
69  inserted = names.insert(UsedNames::value_type(name, node)).second;
70  }
71 
72  while (!inserted) {
73  _index++;
74  name = generate_name(node, category, _index);
75  inserted = names.insert(UsedNames::value_type(name, node)).second;
76  }
77 
78  if (egg_cat.is_debug()) {
79  egg_cat.debug()
80  << "Uniquifying " << node->get_name() << " to "
81  << name << "\n";
82  }
83 
84  node->set_name(name);
85  }
86 
87  if (node->is_of_type(EggGroupNode::get_class_type())) {
88  EggGroupNode *group;
89  DCAST_INTO_V(group, node);
90 
91  EggGroupNode::iterator ci;
92  for (ci = group->begin(); ci != group->end(); ++ci) {
93  EggNode *child = (*ci);
94  nassertv(child != nullptr);
95  uniquify(child);
96  }
97  }
98 }
99 
100 /**
101  * Returns the node associated with the given category and name, or NULL if
102  * the name has not been used.
103  */
105 get_node(const string &category, const string &name) const {
106  Categories::const_iterator ci;
107  ci = _categories.find(category);
108  if (ci == _categories.end()) {
109  return nullptr;
110  }
111 
112  const UsedNames &names = (*ci).second;
113  UsedNames::const_iterator ni;
114  ni = names.find(name);
115  if (ni == names.end()) {
116  return nullptr;
117  }
118 
119  return (*ni).second;
120 }
121 
122 /**
123  * Returns true if the name has been used for the indicated category already,
124  * false otherwise.
125  */
127 has_name(const string &category, const string &name) const {
128  Categories::const_iterator ci;
129  ci = _categories.find(category);
130  if (ci == _categories.end()) {
131  return false;
132  }
133 
134  const UsedNames &names = (*ci).second;
135  UsedNames::const_iterator ni;
136  ni = names.find(name);
137  if (ni == names.end()) {
138  return false;
139  }
140 
141  return true;
142 }
143 
144 /**
145  * Adds the name to the indicated category. This name will not be used for
146  * any other egg node within this category. Returns true if the name was
147  * added, or false if it was already in use for the category.
148  */
150 add_name(const string &category, const string &name, EggNode *node) {
151  UsedNames &names = _categories[category];
152  bool inserted = names.insert(UsedNames::value_type(name, node)).second;
153  return inserted;
154 }
155 
156 /**
157  * Returns the name of the given node, or at least the name it should be.
158  * This provides a hook to adjust the name before attempting to uniquify it,
159  * if desired, for instance to remove invalid characters.
160  */
162 filter_name(EggNode *node) {
163  return node->get_name();
164 }
165 
166 /**
167  * Generates a new name for the given node when its existing name clashes with
168  * some other node. This function will be called repeatedly, if necessary,
169  * until it returns a name that actually is unique.
170  *
171  * The category is the string returned by get_category(), and index is a
172  * uniquely-generated number that may be useful for synthesizing the name.
173  */
175 generate_name(EggNode *node, const string &category, int index) {
176  string name = filter_name(node);
177 
178  std::ostringstream str;
179  if (name.empty()) {
180  str << category << index;
181  } else {
182  str << name << "." << category << index;
183  }
184  return str.str();
185 }
A base class for nodes in the hierarchy that are not leaf nodes.
Definition: eggGroupNode.h:46
bool add_name(const std::string &category, const std::string &name, EggNode *node=nullptr)
Adds the name to the indicated category.
virtual std::string filter_name(EggNode *node)
Returns the name of the given node, or at least the name it should be.
EggNode * get_node(const std::string &category, const std::string &name) const
Returns the node associated with the given category and name, or NULL if the name has not been used.
virtual std::string generate_name(EggNode *node, const std::string &category, int index)
Generates a new name for the given node when its existing name clashes with some other node.
void clear()
Empties the table of used named and prepares the Uniquifier for a new tree.
void uniquify(EggNode *node)
Begins the traversal from the indicated node.
bool has_name(const std::string &category, const std::string &name) const
Returns true if the name has been used for the indicated category already, false otherwise.
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:36
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.