Panda3D
|
00001 // Filename: internalNameCollection.cxx 00002 // Created by: drose (16Mar02) 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 "internalNameCollection.h" 00016 00017 #include "indent.h" 00018 00019 //////////////////////////////////////////////////////////////////// 00020 // Function: InternalNameCollection::Constructor 00021 // Access: Published 00022 // Description: 00023 //////////////////////////////////////////////////////////////////// 00024 InternalNameCollection:: 00025 InternalNameCollection() { 00026 } 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: InternalNameCollection::Copy Constructor 00030 // Access: Published 00031 // Description: 00032 //////////////////////////////////////////////////////////////////// 00033 InternalNameCollection:: 00034 InternalNameCollection(const InternalNameCollection ©) : 00035 _names(copy._names) 00036 { 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: InternalNameCollection::Copy Assignment Operator 00041 // Access: Published 00042 // Description: 00043 //////////////////////////////////////////////////////////////////// 00044 void InternalNameCollection:: 00045 operator = (const InternalNameCollection ©) { 00046 _names = copy._names; 00047 } 00048 00049 //////////////////////////////////////////////////////////////////// 00050 // Function: InternalNameCollection::add_name 00051 // Access: Published 00052 // Description: Adds a new InternalName to the collection. 00053 //////////////////////////////////////////////////////////////////// 00054 void InternalNameCollection:: 00055 add_name(InternalName *name) { 00056 // If the pointer to our internal array is shared by any other 00057 // InternalNameCollections, we have to copy the array now so we won't 00058 // inadvertently modify any of our brethren InternalNameCollection 00059 // objects. 00060 00061 if (_names.get_ref_count() > 1) { 00062 InternalNames old_names = _names; 00063 _names = InternalNames::empty_array(0); 00064 _names.v() = old_names.v(); 00065 } 00066 00067 _names.push_back(name); 00068 } 00069 00070 //////////////////////////////////////////////////////////////////// 00071 // Function: InternalNameCollection::remove_name 00072 // Access: Published 00073 // Description: Removes the indicated InternalName from the collection. 00074 // Returns true if the name was removed, false if it was 00075 // not a member of the collection. 00076 //////////////////////////////////////////////////////////////////// 00077 bool InternalNameCollection:: 00078 remove_name(InternalName *name) { 00079 int name_index = -1; 00080 for (int i = 0; name_index == -1 && i < (int)_names.size(); i++) { 00081 if (_names[i] == name) { 00082 name_index = i; 00083 } 00084 } 00085 00086 if (name_index == -1) { 00087 // The indicated name was not a member of the collection. 00088 return false; 00089 } 00090 00091 // If the pointer to our internal array is shared by any other 00092 // InternalNameCollections, we have to copy the array now so we won't 00093 // inadvertently modify any of our brethren InternalNameCollection 00094 // objects. 00095 00096 if (_names.get_ref_count() > 1) { 00097 InternalNames old_names = _names; 00098 _names = InternalNames::empty_array(0); 00099 _names.v() = old_names.v(); 00100 } 00101 00102 _names.erase(_names.begin() + name_index); 00103 return true; 00104 } 00105 00106 //////////////////////////////////////////////////////////////////// 00107 // Function: InternalNameCollection::add_names_from 00108 // Access: Published 00109 // Description: Adds all the InternalNames indicated in the other 00110 // collection to this name. The other names are simply 00111 // appended to the end of the names in this list; 00112 // duplicates are not automatically removed. 00113 //////////////////////////////////////////////////////////////////// 00114 void InternalNameCollection:: 00115 add_names_from(const InternalNameCollection &other) { 00116 int other_num_names = other.get_num_names(); 00117 for (int i = 0; i < other_num_names; i++) { 00118 add_name(other.get_name(i)); 00119 } 00120 } 00121 00122 00123 //////////////////////////////////////////////////////////////////// 00124 // Function: InternalNameCollection::remove_names_from 00125 // Access: Published 00126 // Description: Removes from this collection all of the InternalNames 00127 // listed in the other collection. 00128 //////////////////////////////////////////////////////////////////// 00129 void InternalNameCollection:: 00130 remove_names_from(const InternalNameCollection &other) { 00131 InternalNames new_names; 00132 int num_names = get_num_names(); 00133 for (int i = 0; i < num_names; i++) { 00134 PT(InternalName) name = get_name(i); 00135 if (!other.has_name(name)) { 00136 new_names.push_back(name); 00137 } 00138 } 00139 _names = new_names; 00140 } 00141 00142 //////////////////////////////////////////////////////////////////// 00143 // Function: InternalNameCollection::remove_duplicate_names 00144 // Access: Published 00145 // Description: Removes any duplicate entries of the same InternalNames 00146 // on this collection. If a InternalName appears multiple 00147 // times, the first appearance is retained; subsequent 00148 // appearances are removed. 00149 //////////////////////////////////////////////////////////////////// 00150 void InternalNameCollection:: 00151 remove_duplicate_names() { 00152 InternalNames new_names; 00153 00154 int num_names = get_num_names(); 00155 for (int i = 0; i < num_names; i++) { 00156 PT(InternalName) name = get_name(i); 00157 bool duplicated = false; 00158 00159 for (int j = 0; j < i && !duplicated; j++) { 00160 duplicated = (name == get_name(j)); 00161 } 00162 00163 if (!duplicated) { 00164 new_names.push_back(name); 00165 } 00166 } 00167 00168 _names = new_names; 00169 } 00170 00171 //////////////////////////////////////////////////////////////////// 00172 // Function: InternalNameCollection::has_name 00173 // Access: Published 00174 // Description: Returns true if the indicated InternalName appears in 00175 // this collection, false otherwise. 00176 //////////////////////////////////////////////////////////////////// 00177 bool InternalNameCollection:: 00178 has_name(InternalName *name) const { 00179 for (int i = 0; i < get_num_names(); i++) { 00180 if (name == get_name(i)) { 00181 return true; 00182 } 00183 } 00184 return false; 00185 } 00186 00187 //////////////////////////////////////////////////////////////////// 00188 // Function: InternalNameCollection::clear 00189 // Access: Published 00190 // Description: Removes all InternalNames from the collection. 00191 //////////////////////////////////////////////////////////////////// 00192 void InternalNameCollection:: 00193 clear() { 00194 _names.clear(); 00195 } 00196 00197 //////////////////////////////////////////////////////////////////// 00198 // Function: InternalNameCollection::get_num_names 00199 // Access: Published 00200 // Description: Returns the number of InternalNames in the collection. 00201 //////////////////////////////////////////////////////////////////// 00202 int InternalNameCollection:: 00203 get_num_names() const { 00204 return _names.size(); 00205 } 00206 00207 //////////////////////////////////////////////////////////////////// 00208 // Function: InternalNameCollection::get_name 00209 // Access: Published 00210 // Description: Returns the nth InternalName in the collection. 00211 //////////////////////////////////////////////////////////////////// 00212 InternalName *InternalNameCollection:: 00213 get_name(int index) const { 00214 nassertr(index >= 0 && index < (int)_names.size(), NULL); 00215 00216 return _names[index]; 00217 } 00218 00219 //////////////////////////////////////////////////////////////////// 00220 // Function: InternalNameCollection::operator [] 00221 // Access: Published 00222 // Description: Returns the nth InternalName in the collection. This is 00223 // the same as get_name(), but it may be a more 00224 // convenient way to access it. 00225 //////////////////////////////////////////////////////////////////// 00226 InternalName *InternalNameCollection:: 00227 operator [] (int index) const { 00228 nassertr(index >= 0 && index < (int)_names.size(), NULL); 00229 00230 return _names[index]; 00231 } 00232 00233 //////////////////////////////////////////////////////////////////// 00234 // Function: InternalNameCollection::size 00235 // Access: Published 00236 // Description: Returns the number of names in the collection. This 00237 // is the same thing as get_num_names(). 00238 //////////////////////////////////////////////////////////////////// 00239 int InternalNameCollection:: 00240 size() const { 00241 return _names.size(); 00242 } 00243 00244 //////////////////////////////////////////////////////////////////// 00245 // Function: InternalNameCollection::output 00246 // Access: Published 00247 // Description: Writes a brief one-line description of the 00248 // InternalNameCollection to the indicated output stream. 00249 //////////////////////////////////////////////////////////////////// 00250 void InternalNameCollection:: 00251 output(ostream &out) const { 00252 if (get_num_names() == 1) { 00253 out << "1 InternalName"; 00254 } else { 00255 out << get_num_names() << " InternalNames"; 00256 } 00257 } 00258 00259 //////////////////////////////////////////////////////////////////// 00260 // Function: InternalNameCollection::write 00261 // Access: Published 00262 // Description: Writes a complete multi-line description of the 00263 // InternalNameCollection to the indicated output stream. 00264 //////////////////////////////////////////////////////////////////// 00265 void InternalNameCollection:: 00266 write(ostream &out, int indent_level) const { 00267 for (int i = 0; i < get_num_names(); i++) { 00268 indent(out, indent_level) << *get_name(i) << "\n"; 00269 } 00270 }