Panda3D
 All Classes Functions Variables Enumerations
materialPool.cxx
00001 // Filename: materialPool.cxx
00002 // Created by:  drose (30Apr01)
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 "materialPool.h"
00016 #include "config_gobj.h"
00017 #include "lightMutexHolder.h"
00018 
00019 MaterialPool *MaterialPool::_global_ptr = (MaterialPool *)NULL;
00020 
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: MaterialPool::write
00024 //       Access: Published, Static
00025 //  Description: Lists the contents of the material pool to the
00026 //               indicated output stream.
00027 ////////////////////////////////////////////////////////////////////
00028 void MaterialPool::
00029 write(ostream &out) {
00030   get_global_ptr()->ns_list_contents(out);
00031 }
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //     Function: MaterialPool::ns_get_material
00035 //       Access: Public
00036 //  Description: The nonstatic implementation of get_material().
00037 ////////////////////////////////////////////////////////////////////
00038 Material *MaterialPool::
00039 ns_get_material(Material *temp) {
00040   LightMutexHolder holder(_lock);
00041 
00042   CPT(Material) cpttemp = temp;
00043   Materials::iterator mi = _materials.find(cpttemp);
00044   if (mi == _materials.end()) {
00045     mi = _materials.insert(Materials::value_type(new Material(*temp), temp)).first;
00046   } else {
00047     if (*(*mi).first != *(*mi).second) {
00048       // The pointer no longer matches its original value.  Save a new
00049       // one.
00050       (*mi).second = temp;
00051     }
00052   }
00053   return (*mi).second;
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: MaterialPool::ns_release_material
00058 //       Access: Private
00059 //  Description: The nonstatic implementation of release_material().
00060 ////////////////////////////////////////////////////////////////////
00061 void MaterialPool::
00062 ns_release_material(Material *temp) {
00063   LightMutexHolder holder(_lock);
00064 
00065   CPT(Material) cpttemp = temp;
00066   _materials.erase(cpttemp);
00067 }
00068 
00069 ////////////////////////////////////////////////////////////////////
00070 //     Function: MaterialPool::ns_release_all_materials
00071 //       Access: Private
00072 //  Description: The nonstatic implementation of release_all_materials().
00073 ////////////////////////////////////////////////////////////////////
00074 void MaterialPool::
00075 ns_release_all_materials() {
00076   LightMutexHolder holder(_lock);
00077 
00078   _materials.clear();
00079 }
00080 
00081 ////////////////////////////////////////////////////////////////////
00082 //     Function: MaterialPool::ns_garbage_collect
00083 //       Access: Private
00084 //  Description: The nonstatic implementation of garbage_collect().
00085 ////////////////////////////////////////////////////////////////////
00086 int MaterialPool::
00087 ns_garbage_collect() {
00088   LightMutexHolder holder(_lock);
00089 
00090   int num_released = 0;
00091   Materials new_set;
00092 
00093   Materials::iterator mi;
00094   for (mi = _materials.begin(); mi != _materials.end(); ++mi) {
00095     const Material *mat1 = (*mi).first;
00096     Material *mat2 = (*mi).second;
00097     if ((*mat1) != (*mat2) || mat2->get_ref_count() == 1) {
00098       if (gobj_cat.is_debug()) {
00099         gobj_cat.debug()
00100           << "Releasing " << *mat1 << "\n";
00101       }
00102       ++num_released;
00103     } else {
00104       new_set.insert(new_set.end(), *mi);
00105     }
00106   }
00107 
00108   _materials.swap(new_set);
00109   return num_released;
00110 }
00111 
00112 ////////////////////////////////////////////////////////////////////
00113 //     Function: MaterialPool::ns_list_contents
00114 //       Access: Private
00115 //  Description: The nonstatic implementation of list_contents().
00116 ////////////////////////////////////////////////////////////////////
00117 void MaterialPool::
00118 ns_list_contents(ostream &out) const {
00119   LightMutexHolder holder(_lock);
00120 
00121   out << _materials.size() << " materials:\n";
00122   Materials::const_iterator mi;
00123   for (mi = _materials.begin(); mi != _materials.end(); ++mi) {
00124     const Material *mat1 = (*mi).first;
00125     Material *mat2 = (*mi).second;
00126     out << "  " << *mat1
00127         << " (count = " << mat2->get_ref_count() << ")\n";
00128   }
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: MaterialPool::get_global_ptr
00133 //       Access: Private, Static
00134 //  Description: Initializes and/or returns the global pointer to the
00135 //               one MaterialPool object in the system.
00136 ////////////////////////////////////////////////////////////////////
00137 MaterialPool *MaterialPool::
00138 get_global_ptr() {
00139   if (_global_ptr == (MaterialPool *)NULL) {
00140     _global_ptr = new MaterialPool;
00141   }
00142   return _global_ptr;
00143 }
 All Classes Functions Variables Enumerations