Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/egg/eggNameUniquifier.cxx

Go to the documentation of this file.
00001 // Filename: eggNameUniquifier.cxx
00002 // Created by:  drose (09Nov00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "eggNameUniquifier.h"
00020 #include "eggNode.h"
00021 #include "eggGroupNode.h"
00022 
00023 #include <notify.h>
00024 
00025 TypeHandle EggNameUniquifier::_type_handle;
00026 
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: EggNameUniquifier::Constructor
00030 //       Access: Public
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 EggNameUniquifier::
00034 EggNameUniquifier() {
00035   _index = 0;
00036 }
00037 
00038 ////////////////////////////////////////////////////////////////////
00039 //     Function: EggNameUniquifier::Destructor
00040 //       Access: Public
00041 //  Description:
00042 ////////////////////////////////////////////////////////////////////
00043 EggNameUniquifier::
00044 ~EggNameUniquifier() {
00045 }
00046 
00047 ////////////////////////////////////////////////////////////////////
00048 //     Function: EggNameUniquifier::clear
00049 //       Access: Public
00050 //  Description: Empties the table of used named and prepares the
00051 //               Uniquifier for a new tree.
00052 ////////////////////////////////////////////////////////////////////
00053 void EggNameUniquifier::
00054 clear() {
00055   _categories.clear();
00056   _index = 0;
00057 }
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: EggNameUniquifier::uniquify
00061 //       Access: Public
00062 //  Description: Begins the traversal from the indicated node.
00063 ////////////////////////////////////////////////////////////////////
00064 void EggNameUniquifier::
00065 uniquify(EggNode *node) {
00066   string category = get_category(node);
00067 
00068   if (!category.empty()) {
00069     string name = filter_name(node);
00070 
00071     UsedNames &names = _categories[category];
00072     bool inserted = false;
00073     if (!name.empty()) {
00074       inserted = names.insert(UsedNames::value_type(name, node)).second;
00075     }
00076 
00077     while (!inserted) {
00078       _index++;
00079       name = generate_name(node, category, _index);
00080       inserted = names.insert(UsedNames::value_type(name, node)).second;
00081     }
00082 
00083     node->set_name(name);
00084   }
00085 
00086   if (node->is_of_type(EggGroupNode::get_class_type())) {
00087     EggGroupNode *group;
00088     DCAST_INTO_V(group, node);
00089 
00090     EggGroupNode::iterator ci;
00091     for (ci = group->begin(); ci != group->end(); ++ci) {
00092       EggNode *child = (*ci);
00093       nassertv(child != (EggNode *)NULL);
00094       uniquify(child);
00095     }
00096   }
00097 }
00098 
00099 ////////////////////////////////////////////////////////////////////
00100 //     Function: EggNameUniquifier::get_node
00101 //       Access: Public
00102 //  Description: Returns the node associated with the given category
00103 //               and name, or NULL if the name has not been used.
00104 ////////////////////////////////////////////////////////////////////
00105 EggNode *EggNameUniquifier::
00106 get_node(const string &category, const string &name) const {
00107   Categories::const_iterator ci;
00108   ci = _categories.find(category);
00109   if (ci == _categories.end()) {
00110     return (EggNode *)NULL;
00111   }
00112 
00113   const UsedNames &names = (*ci).second;
00114   UsedNames::const_iterator ni;
00115   ni = names.find(name);
00116   if (ni == names.end()) {
00117     return (EggNode *)NULL;
00118   }
00119 
00120   return (*ni).second;
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: EggNameUniquifier::has_name
00125 //       Access: Public
00126 //  Description: Returns true if the name has been used for the
00127 //               indicated category already, false otherwise.
00128 ////////////////////////////////////////////////////////////////////
00129 bool EggNameUniquifier::
00130 has_name(const string &category, const string &name) const {
00131   Categories::const_iterator ci;
00132   ci = _categories.find(category);
00133   if (ci == _categories.end()) {
00134     return false;
00135   }
00136 
00137   const UsedNames &names = (*ci).second;
00138   UsedNames::const_iterator ni;
00139   ni = names.find(name);
00140   if (ni == names.end()) {
00141     return false;
00142   }
00143 
00144   return true;
00145 }
00146 
00147 ////////////////////////////////////////////////////////////////////
00148 //     Function: EggNameUniquifier::add_name
00149 //       Access: Public
00150 //  Description: Adds the name to the indicated category.  This name
00151 //               will not be used for any other egg node within this
00152 //               category.  Returns true if the name was added, or
00153 //               false if it was already in use for the category.
00154 ////////////////////////////////////////////////////////////////////
00155 bool EggNameUniquifier::
00156 add_name(const string &category, const string &name, EggNode *node) {
00157   UsedNames &names = _categories[category];
00158   bool inserted = names.insert(UsedNames::value_type(name, node)).second;
00159   return inserted;
00160 }
00161 
00162 ////////////////////////////////////////////////////////////////////
00163 //     Function: EggNameUniquifier::filter_name
00164 //       Access: Public, Virtual
00165 //  Description: Returns the name of the given node, or at least the
00166 //               name it should be.  This provides a hook to adjust
00167 //               the name before attempting to uniquify it, if
00168 //               desired, for instance to remove invalid characters.
00169 ////////////////////////////////////////////////////////////////////
00170 string EggNameUniquifier::
00171 filter_name(EggNode *node) {
00172   return node->get_name();
00173 }
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: EggNameUniquifier::generate_name
00177 //       Access: Public, Virtual
00178 //  Description: Generates a new name for the given node when its
00179 //               existing name clashes with some other node.  This
00180 //               function will be called repeatedly, if necessary,
00181 //               until it returns a name that actually is unique.
00182 //
00183 //               The category is the string returned by
00184 //               get_category(), and index is a uniquely-generated
00185 //               number that may be useful for synthesizing the name.
00186 ////////////////////////////////////////////////////////////////////
00187 string EggNameUniquifier::
00188 generate_name(EggNode *node, const string &category, int index) {
00189   string name = filter_name(node);
00190 
00191   ostringstream str;
00192   if (name.empty()) {
00193     str << category << index;
00194   } else {
00195     str << name << "." << category << index;
00196   }
00197   return str.str();
00198 }

Generated on Fri May 2 00:37:44 2003 for Panda by doxygen1.3