Panda3D
 All Classes Functions Variables Enumerations
eggGroupUniquifier.cxx
00001 // Filename: eggGroupUniquifier.cxx
00002 // Created by:  drose (22Feb01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "eggGroupUniquifier.h"
00016 #include "eggGroup.h"
00017 
00018 #include "pnotify.h"
00019 
00020 #include <ctype.h>
00021 
00022 TypeHandle EggGroupUniquifier::_type_handle;
00023 
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: EggGroupUniquifier::Constructor
00027 //       Access: Public
00028 //  Description: If filter_names is true, then the group names will be
00029 //               coerced into a fairly safe, standard convention that
00030 //               uses no characters other than a-z, A-Z, 0-9, and
00031 //               underscore.  If filter_names is false, the group
00032 //               names will be left unchanged.
00033 ////////////////////////////////////////////////////////////////////
00034 EggGroupUniquifier::
00035 EggGroupUniquifier(bool filter_names)
00036   : _filter_names(filter_names)
00037 {
00038 }
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //     Function: EggGroupUniquifier::get_category
00042 //       Access: Public
00043 //  Description: Returns the category name into which the given node
00044 //               should be collected, or the empty string if the
00045 //               node's name should be left alone.
00046 ////////////////////////////////////////////////////////////////////
00047 string EggGroupUniquifier::
00048 get_category(EggNode *node) {
00049   if (node->is_of_type(EggGroup::get_class_type()) && node->has_name()) {
00050     return "group";
00051   }
00052 
00053   return string();
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: EggGroupUniquifier::filter_name
00058 //       Access: Public, Virtual
00059 //  Description: Returns the name of the given node, or at least the
00060 //               name it should be.  This provides a hook to adjust
00061 //               the name before attempting to uniquify it, if
00062 //               desired, for instance to remove invalid characters.
00063 ////////////////////////////////////////////////////////////////////
00064 string EggGroupUniquifier::
00065 filter_name(EggNode *node) {
00066   string name = node->get_name();
00067   if (!_filter_names) {
00068     return name;
00069   }
00070   nassertr(!name.empty(), string());
00071 
00072   string result;
00073 
00074   // First, replace characters not A-Z, a-z, 0-9, or '_' with
00075   // underscore, and remove consecutive underscores.
00076   string::const_iterator pi;
00077   bool last_underscore = false;
00078   for (pi = name.begin(); pi != name.end(); ++pi) {
00079     if (isalnum(*pi)) {
00080       result += *pi;
00081       last_underscore = false;
00082 
00083     } else if (!last_underscore) {
00084       result += '_';
00085       last_underscore = true;
00086     }
00087   }
00088 
00089   // Next, ensure the name does not begin with a digit.
00090   nassertr(!result.empty(), string());
00091   if (isdigit(result[0])) {
00092     result = "_" + result;
00093   }
00094 
00095   return result;
00096 }
00097 
00098 ////////////////////////////////////////////////////////////////////
00099 //     Function: EggGroupUniquifier::generate_name
00100 //       Access: Public, Virtual
00101 //  Description: Generates a new name for the given node when its
00102 //               existing name clashes with some other node.  This
00103 //               function will be called repeatedly, if necessary,
00104 //               until it returns a name that actually is unique.
00105 //
00106 //               The category is the string returned by
00107 //               get_category(), and index is a uniquely-generated
00108 //               number that may be useful for synthesizing the name.
00109 ////////////////////////////////////////////////////////////////////
00110 string EggGroupUniquifier::
00111 generate_name(EggNode *node, const string &category, int index) {
00112   ostringstream str;
00113   str << node->get_name() << "_group" << index;
00114   return str.str();
00115 }
 All Classes Functions Variables Enumerations