Panda3D
eggGroupUniquifier.cxx
1 // Filename: eggGroupUniquifier.cxx
2 // Created by: drose (22Feb01)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "eggGroupUniquifier.h"
16 #include "eggGroup.h"
17 
18 #include "pnotify.h"
19 
20 #include <ctype.h>
21 
22 TypeHandle EggGroupUniquifier::_type_handle;
23 
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function: EggGroupUniquifier::Constructor
27 // Access: Public
28 // Description: If filter_names is true, then the group names will be
29 // coerced into a fairly safe, standard convention that
30 // uses no characters other than a-z, A-Z, 0-9, and
31 // underscore. If filter_names is false, the group
32 // names will be left unchanged.
33 ////////////////////////////////////////////////////////////////////
35 EggGroupUniquifier(bool filter_names)
36  : _filter_names(filter_names)
37 {
38 }
39 
40 ////////////////////////////////////////////////////////////////////
41 // Function: EggGroupUniquifier::get_category
42 // Access: Public
43 // Description: Returns the category name into which the given node
44 // should be collected, or the empty string if the
45 // node's name should be left alone.
46 ////////////////////////////////////////////////////////////////////
49  if (node->is_of_type(EggGroup::get_class_type()) && node->has_name()) {
50  return "group";
51  }
52 
53  return string();
54 }
55 
56 ////////////////////////////////////////////////////////////////////
57 // Function: EggGroupUniquifier::filter_name
58 // Access: Public, Virtual
59 // Description: Returns the name of the given node, or at least the
60 // name it should be. This provides a hook to adjust
61 // the name before attempting to uniquify it, if
62 // desired, for instance to remove invalid characters.
63 ////////////////////////////////////////////////////////////////////
66  string name = node->get_name();
67  if (!_filter_names) {
68  return name;
69  }
70  nassertr(!name.empty(), string());
71 
72  string result;
73 
74  // First, replace characters not A-Z, a-z, 0-9, or '_' with
75  // underscore, and remove consecutive underscores.
76  string::const_iterator pi;
77  bool last_underscore = false;
78  for (pi = name.begin(); pi != name.end(); ++pi) {
79  if (isalnum(*pi)) {
80  result += *pi;
81  last_underscore = false;
82 
83  } else if (!last_underscore) {
84  result += '_';
85  last_underscore = true;
86  }
87  }
88 
89  // Next, ensure the name does not begin with a digit.
90  nassertr(!result.empty(), string());
91  if (isdigit(result[0])) {
92  result = "_" + result;
93  }
94 
95  return result;
96 }
97 
98 ////////////////////////////////////////////////////////////////////
99 // Function: EggGroupUniquifier::generate_name
100 // Access: Public, Virtual
101 // Description: Generates a new name for the given node when its
102 // existing name clashes with some other node. This
103 // function will be called repeatedly, if necessary,
104 // until it returns a name that actually is unique.
105 //
106 // The category is the string returned by
107 // get_category(), and index is a uniquely-generated
108 // number that may be useful for synthesizing the name.
109 ////////////////////////////////////////////////////////////////////
111 generate_name(EggNode *node, const string &category, int index) {
112  ostringstream str;
113  str << node->get_name() << "_group" << index;
114  return str.str();
115 }
virtual string get_category(EggNode *node)
Returns the category name into which the given node should be collected, or the empty string if the n...
virtual string generate_name(EggNode *node, const string &category, int index)
Generates a new name for the given node when its existing name clashes with some other node...
EggGroupUniquifier(bool filter_names=true)
If filter_names is true, then the group names will be coerced into a fairly safe, standard convention...
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:38
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:63
bool has_name() const
Returns true if the Namable has a nonempty name set, false if the name is empty.
Definition: namable.I:75
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
virtual string filter_name(EggNode *node)
Returns the name of the given node, or at least the name it should be.