Panda3D

textureCollection.cxx

00001 // Filename: textureCollection.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 "textureCollection.h"
00016 #include "indent.h"
00017 
00018 #ifdef HAVE_PYTHON
00019 #include "py_panda.h"
00020 #endif
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: TextureCollection::Constructor
00024 //       Access: Published
00025 //  Description:
00026 ////////////////////////////////////////////////////////////////////
00027 TextureCollection::
00028 TextureCollection() {
00029 }
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: TextureCollection::Copy Constructor
00033 //       Access: Published
00034 //  Description:
00035 ////////////////////////////////////////////////////////////////////
00036 TextureCollection::
00037 TextureCollection(const TextureCollection &copy) :
00038   _textures(copy._textures)
00039 {
00040 }
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function: TextureCollection::Copy Assignment Operator
00044 //       Access: Published
00045 //  Description:
00046 ////////////////////////////////////////////////////////////////////
00047 void TextureCollection::
00048 operator = (const TextureCollection &copy) {
00049   _textures = copy._textures;
00050 }
00051 
00052 #ifdef HAVE_PYTHON
00053 ////////////////////////////////////////////////////////////////////
00054 //     Function: TextureCollection::Constructor
00055 //       Access: Published
00056 //  Description: This special constructor accepts a Python list of
00057 //               Textures.  Since this constructor accepts a generic
00058 //               PyObject *, it should be the last constructor listed
00059 //               in the class record.
00060 ////////////////////////////////////////////////////////////////////
00061 TextureCollection::
00062 TextureCollection(PyObject *self, PyObject *sequence) {
00063   // We have to pre-initialize self's "this" pointer when we receive
00064   // self in the constructor--the caller can't initialize this for us.
00065   ((Dtool_PyInstDef *)self)->_ptr_to_object = this;
00066 
00067   if (!PySequence_Check(sequence)) {
00068     // If passed with a non-sequence, this isn't the right constructor.
00069     PyErr_SetString(PyExc_TypeError, "TextureCollection constructor requires a sequence");
00070     return;
00071   }
00072 
00073   int size = PySequence_Size(sequence);
00074   for (int i = 0; i < size; ++i) {
00075     PyObject *item = PySequence_GetItem(sequence, i);
00076     if (item == NULL) {
00077       return;
00078     }
00079     PyObject *result = PyObject_CallMethod(self, (char *)"addTexture", (char *)"O", item);
00080     Py_DECREF(item);
00081     if (result == NULL) {
00082       // Unable to add item--probably it wasn't of the appropriate type.
00083       ostringstream stream;
00084       stream << "Element " << i << " in sequence passed to TextureCollection constructor could not be added";
00085       string str = stream.str();
00086       PyErr_SetString(PyExc_TypeError, str.c_str());
00087       return;
00088     }
00089     Py_DECREF(result);
00090   }
00091 }
00092 #endif  // HAVE_PYTHON
00093 
00094 #ifdef HAVE_PYTHON
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: TextureCollection::__reduce__
00097 //       Access: Published
00098 //  Description: This special Python method is implement to provide
00099 //               support for the pickle module.
00100 ////////////////////////////////////////////////////////////////////
00101 PyObject *TextureCollection::
00102 __reduce__(PyObject *self) const {
00103   // Here we will return a 4-tuple: (Class, (args), None, iterator),
00104   // where iterator is an iterator that will yield successive
00105   // Textures.
00106 
00107   // We should return at least a 2-tuple, (Class, (args)): the
00108   // necessary class object whose constructor we should call
00109   // (e.g. this), and the arguments necessary to reconstruct this
00110   // object.
00111 
00112   PyObject *this_class = PyObject_Type(self);
00113   if (this_class == NULL) {
00114     return NULL;
00115   }
00116 
00117   // Since a TextureCollection is itself an iterator, we can simply
00118   // pass it as the fourth tuple component.
00119   PyObject *result = Py_BuildValue("(O()OO)", this_class, Py_None, self);
00120   Py_DECREF(this_class);
00121   return result;
00122 }
00123 #endif  // HAVE_PYTHON
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: TextureCollection::add_texture
00127 //       Access: Published
00128 //  Description: Adds a new Texture to the collection.
00129 ////////////////////////////////////////////////////////////////////
00130 void TextureCollection::
00131 add_texture(Texture *texture) {
00132   // If the pointer to our internal array is shared by any other
00133   // TextureCollections, we have to copy the array now so we won't
00134   // inadvertently modify any of our brethren TextureCollection
00135   // objects.
00136 
00137   if (_textures.get_ref_count() > 1) {
00138     Textures old_textures = _textures;
00139     _textures = Textures::empty_array(0);
00140     _textures.v() = old_textures.v();
00141   }
00142 
00143   _textures.push_back(texture);
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: TextureCollection::remove_texture
00148 //       Access: Published
00149 //  Description: Removes the indicated Texture from the collection.
00150 //               Returns true if the texture was removed, false if it was
00151 //               not a member of the collection.
00152 ////////////////////////////////////////////////////////////////////
00153 bool TextureCollection::
00154 remove_texture(Texture *texture) {
00155   int texture_index = -1;
00156   for (int i = 0; texture_index == -1 && i < (int)_textures.size(); i++) {
00157     if (_textures[i] == texture) {
00158       texture_index = i;
00159     }
00160   }
00161 
00162   if (texture_index == -1) {
00163     // The indicated texture was not a member of the collection.
00164     return false;
00165   }
00166 
00167   // If the pointer to our internal array is shared by any other
00168   // TextureCollections, we have to copy the array now so we won't
00169   // inadvertently modify any of our brethren TextureCollection
00170   // objects.
00171 
00172   if (_textures.get_ref_count() > 1) {
00173     Textures old_textures = _textures;
00174     _textures = Textures::empty_array(0);
00175     _textures.v() = old_textures.v();
00176   }
00177 
00178   _textures.erase(_textures.begin() + texture_index);
00179   return true;
00180 }
00181 
00182 ////////////////////////////////////////////////////////////////////
00183 //     Function: TextureCollection::add_textures_from
00184 //       Access: Published
00185 //  Description: Adds all the Textures indicated in the other
00186 //               collection to this texture.  The other textures are simply
00187 //               appended to the end of the textures in this list;
00188 //               duplicates are not automatically removed.
00189 ////////////////////////////////////////////////////////////////////
00190 void TextureCollection::
00191 add_textures_from(const TextureCollection &other) {
00192   int other_num_textures = other.get_num_textures();
00193   for (int i = 0; i < other_num_textures; i++) {
00194     add_texture(other.get_texture(i));
00195   }
00196 }
00197 
00198 
00199 ////////////////////////////////////////////////////////////////////
00200 //     Function: TextureCollection::remove_textures_from
00201 //       Access: Published
00202 //  Description: Removes from this collection all of the Textures
00203 //               listed in the other collection.
00204 ////////////////////////////////////////////////////////////////////
00205 void TextureCollection::
00206 remove_textures_from(const TextureCollection &other) {
00207   Textures new_textures;
00208   int num_textures = get_num_textures();
00209   for (int i = 0; i < num_textures; i++) {
00210     PT(Texture) texture = get_texture(i);
00211     if (!other.has_texture(texture)) {
00212       new_textures.push_back(texture);
00213     }
00214   }
00215   _textures = new_textures;
00216 }
00217 
00218 ////////////////////////////////////////////////////////////////////
00219 //     Function: TextureCollection::remove_duplicate_textures
00220 //       Access: Published
00221 //  Description: Removes any duplicate entries of the same Textures
00222 //               on this collection.  If a Texture appears multiple
00223 //               times, the first appearance is retained; subsequent
00224 //               appearances are removed.
00225 ////////////////////////////////////////////////////////////////////
00226 void TextureCollection::
00227 remove_duplicate_textures() {
00228   Textures new_textures;
00229 
00230   int num_textures = get_num_textures();
00231   for (int i = 0; i < num_textures; i++) {
00232     PT(Texture) texture = get_texture(i);
00233     bool duplicated = false;
00234 
00235     for (int j = 0; j < i && !duplicated; j++) {
00236       duplicated = (texture == get_texture(j));
00237     }
00238 
00239     if (!duplicated) {
00240       new_textures.push_back(texture);
00241     }
00242   }
00243 
00244   _textures = new_textures;
00245 }
00246 
00247 ////////////////////////////////////////////////////////////////////
00248 //     Function: TextureCollection::has_texture
00249 //       Access: Published
00250 //  Description: Returns true if the indicated Texture appears in
00251 //               this collection, false otherwise.
00252 ////////////////////////////////////////////////////////////////////
00253 bool TextureCollection::
00254 has_texture(Texture *texture) const {
00255   for (int i = 0; i < get_num_textures(); i++) {
00256     if (texture == get_texture(i)) {
00257       return true;
00258     }
00259   }
00260   return false;
00261 }
00262 
00263 ////////////////////////////////////////////////////////////////////
00264 //     Function: TextureCollection::clear
00265 //       Access: Published
00266 //  Description: Removes all Textures from the collection.
00267 ////////////////////////////////////////////////////////////////////
00268 void TextureCollection::
00269 clear() {
00270   _textures.clear();
00271 }
00272 
00273 ////////////////////////////////////////////////////////////////////
00274 //     Function: TextureCollection::find_texture
00275 //       Access: Published
00276 //  Description: Returns the texture in the collection with the
00277 //               indicated name, if any, or NULL if no texture has
00278 //               that name.
00279 ////////////////////////////////////////////////////////////////////
00280 Texture *TextureCollection::
00281 find_texture(const string &name) const {
00282   int num_textures = get_num_textures();
00283   for (int i = 0; i < num_textures; i++) {
00284     Texture *texture = get_texture(i);
00285     if (texture->get_name() == name) {
00286       return texture;
00287     }
00288   }
00289   return NULL;
00290 }
00291 
00292 ////////////////////////////////////////////////////////////////////
00293 //     Function: TextureCollection::get_num_textures
00294 //       Access: Published
00295 //  Description: Returns the number of Textures in the collection.
00296 ////////////////////////////////////////////////////////////////////
00297 int TextureCollection::
00298 get_num_textures() const {
00299   return _textures.size();
00300 }
00301 
00302 ////////////////////////////////////////////////////////////////////
00303 //     Function: TextureCollection::get_texture
00304 //       Access: Published
00305 //  Description: Returns the nth Texture in the collection.
00306 ////////////////////////////////////////////////////////////////////
00307 Texture *TextureCollection::
00308 get_texture(int index) const {
00309   nassertr(index >= 0 && index < (int)_textures.size(), NULL);
00310 
00311   return _textures[index];
00312 }
00313 
00314 ////////////////////////////////////////////////////////////////////
00315 //     Function: TextureCollection::operator []
00316 //       Access: Published
00317 //  Description: Returns the nth Texture in the collection.  This is
00318 //               the same as get_texture(), but it may be a more
00319 //               convenient way to access it.
00320 ////////////////////////////////////////////////////////////////////
00321 Texture *TextureCollection::
00322 operator [] (int index) const {
00323   nassertr(index >= 0 && index < (int)_textures.size(), NULL);
00324 
00325   return _textures[index];
00326 }
00327 
00328 ////////////////////////////////////////////////////////////////////
00329 //     Function: TextureCollection::size
00330 //       Access: Published
00331 //  Description: Returns the number of textures in the collection.  This
00332 //               is the same thing as get_num_textures().
00333 ////////////////////////////////////////////////////////////////////
00334 int TextureCollection::
00335 size() const {
00336   return _textures.size();
00337 }
00338 
00339 ////////////////////////////////////////////////////////////////////
00340 //     Function: TextureCollection::output
00341 //       Access: Published
00342 //  Description: Writes a brief one-line description of the
00343 //               TextureCollection to the indicated output stream.
00344 ////////////////////////////////////////////////////////////////////
00345 void TextureCollection::
00346 output(ostream &out) const {
00347   if (get_num_textures() == 1) {
00348     out << "1 Texture";
00349   } else {
00350     out << get_num_textures() << " Textures";
00351   }
00352 }
00353 
00354 ////////////////////////////////////////////////////////////////////
00355 //     Function: TextureCollection::write
00356 //       Access: Published
00357 //  Description: Writes a complete multi-line description of the
00358 //               TextureCollection to the indicated output stream.
00359 ////////////////////////////////////////////////////////////////////
00360 void TextureCollection::
00361 write(ostream &out, int indent_level) const {
00362   for (int i = 0; i < get_num_textures(); i++) {
00363     indent(out, indent_level) << *get_texture(i) << "\n";
00364   }
00365 }
 All Classes Functions Variables Enumerations