Panda3D
|
00001 // Filename: modelPool.cxx 00002 // Created by: drose (12Mar02) 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 "modelPool.h" 00016 #include "loader.h" 00017 #include "config_pgraph.h" 00018 #include "lightMutexHolder.h" 00019 00020 00021 ModelPool *ModelPool::_global_ptr = (ModelPool *)NULL; 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: ModelPool::write 00025 // Access: Published, Static 00026 // Description: Lists the contents of the model pool to the 00027 // indicated output stream. 00028 // Helps with debugging. 00029 //////////////////////////////////////////////////////////////////// 00030 void ModelPool:: 00031 write(ostream &out) { 00032 get_ptr()->ns_list_contents(out); 00033 } 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Function: ModelPool::ns_has_model 00037 // Access: Private 00038 // Description: The nonstatic implementation of has_model(). 00039 //////////////////////////////////////////////////////////////////// 00040 bool ModelPool:: 00041 ns_has_model(const Filename &filename) { 00042 LightMutexHolder holder(_lock); 00043 Models::const_iterator ti; 00044 ti = _models.find(filename); 00045 if (ti != _models.end() && (*ti).second != (ModelRoot *)NULL) { 00046 // This model was previously loaded. 00047 return true; 00048 } 00049 00050 return false; 00051 } 00052 00053 //////////////////////////////////////////////////////////////////// 00054 // Function: ModelPool::ns_load_model 00055 // Access: Private 00056 // Description: The nonstatic implementation of load_model(). 00057 //////////////////////////////////////////////////////////////////// 00058 ModelRoot *ModelPool:: 00059 ns_load_model(const Filename &filename, const LoaderOptions &options) { 00060 { 00061 LightMutexHolder holder(_lock); 00062 Models::const_iterator ti; 00063 ti = _models.find(filename); 00064 if (ti != _models.end()) { 00065 // This model was previously loaded. 00066 return (*ti).second; 00067 } 00068 } 00069 00070 LoaderOptions new_options(options); 00071 new_options.set_flags((new_options.get_flags() | LoaderOptions::LF_no_ram_cache) & 00072 ~(LoaderOptions::LF_search | LoaderOptions::LF_report_errors)); 00073 00074 Loader *model_loader = Loader::get_global_ptr(); 00075 PT(PandaNode) panda_node = model_loader->load_sync(filename, new_options); 00076 PT(ModelRoot) node; 00077 00078 if (panda_node.is_null()) { 00079 // This model was not found. 00080 00081 } else { 00082 if (panda_node->is_of_type(ModelRoot::get_class_type())) { 00083 node = DCAST(ModelRoot, panda_node); 00084 00085 } else { 00086 // We have to construct a ModelRoot node to put it under. 00087 node = new ModelRoot(filename); 00088 node->add_child(panda_node); 00089 } 00090 node->set_fullpath(filename); 00091 } 00092 00093 { 00094 LightMutexHolder holder(_lock); 00095 00096 // Look again, in case someone has just loaded the model in 00097 // another thread. 00098 Models::const_iterator ti; 00099 ti = _models.find(filename); 00100 if (ti != _models.end()) { 00101 // This model was previously loaded. 00102 return (*ti).second; 00103 } 00104 00105 _models[filename] = node; 00106 } 00107 00108 return node; 00109 } 00110 00111 //////////////////////////////////////////////////////////////////// 00112 // Function: ModelPool::ns_add_model 00113 // Access: Private 00114 // Description: The nonstatic implementation of add_model(). 00115 //////////////////////////////////////////////////////////////////// 00116 void ModelPool:: 00117 ns_add_model(const Filename &filename, ModelRoot *model) { 00118 LightMutexHolder holder(_lock); 00119 // We blow away whatever model was there previously, if any. 00120 _models[filename] = model; 00121 } 00122 00123 //////////////////////////////////////////////////////////////////// 00124 // Function: ModelPool::ns_release_model 00125 // Access: Private 00126 // Description: The nonstatic implementation of release_model(). 00127 //////////////////////////////////////////////////////////////////// 00128 void ModelPool:: 00129 ns_release_model(const Filename &filename) { 00130 LightMutexHolder holder(_lock); 00131 Models::iterator ti; 00132 ti = _models.find(filename); 00133 if (ti != _models.end()) { 00134 _models.erase(ti); 00135 } 00136 } 00137 00138 //////////////////////////////////////////////////////////////////// 00139 // Function: ModelPool::ns_add_model 00140 // Access: Private 00141 // Description: The nonstatic implementation of add_model(). 00142 //////////////////////////////////////////////////////////////////// 00143 void ModelPool:: 00144 ns_add_model(ModelRoot *model) { 00145 LightMutexHolder holder(_lock); 00146 // We blow away whatever model was there previously, if any. 00147 _models[model->get_fullpath()] = model; 00148 } 00149 00150 //////////////////////////////////////////////////////////////////// 00151 // Function: ModelPool::ns_release_model 00152 // Access: Private 00153 // Description: The nonstatic implementation of release_model(). 00154 //////////////////////////////////////////////////////////////////// 00155 void ModelPool:: 00156 ns_release_model(ModelRoot *model) { 00157 LightMutexHolder holder(_lock); 00158 Models::iterator ti; 00159 ti = _models.find(model->get_fullpath()); 00160 if (ti != _models.end()) { 00161 _models.erase(ti); 00162 } 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: ModelPool::ns_release_all_models 00167 // Access: Private 00168 // Description: The nonstatic implementation of release_all_models(). 00169 //////////////////////////////////////////////////////////////////// 00170 void ModelPool:: 00171 ns_release_all_models() { 00172 LightMutexHolder holder(_lock); 00173 _models.clear(); 00174 } 00175 00176 //////////////////////////////////////////////////////////////////// 00177 // Function: ModelPool::ns_garbage_collect 00178 // Access: Private 00179 // Description: The nonstatic implementation of garbage_collect(). 00180 //////////////////////////////////////////////////////////////////// 00181 int ModelPool:: 00182 ns_garbage_collect() { 00183 LightMutexHolder holder(_lock); 00184 00185 int num_released = 0; 00186 Models new_set; 00187 00188 Models::iterator ti; 00189 for (ti = _models.begin(); ti != _models.end(); ++ti) { 00190 ModelRoot *node = (*ti).second; 00191 if (node == (ModelRoot *)NULL || 00192 node->get_model_ref_count() == 1) { 00193 if (loader_cat.is_debug()) { 00194 loader_cat.debug() 00195 << "Releasing " << (*ti).first << "\n"; 00196 } 00197 ++num_released; 00198 } else { 00199 new_set.insert(new_set.end(), *ti); 00200 } 00201 } 00202 00203 _models.swap(new_set); 00204 return num_released; 00205 } 00206 00207 //////////////////////////////////////////////////////////////////// 00208 // Function: ModelPool::ns_list_contents 00209 // Access: Private 00210 // Description: The nonstatic implementation of list_contents(). 00211 //////////////////////////////////////////////////////////////////// 00212 void ModelPool:: 00213 ns_list_contents(ostream &out) const { 00214 LightMutexHolder holder(_lock); 00215 00216 out << "model pool contents:\n"; 00217 00218 Models::const_iterator ti; 00219 int num_models = 0; 00220 for (ti = _models.begin(); ti != _models.end(); ++ti) { 00221 if ((*ti).second != NULL) { 00222 ++num_models; 00223 out << (*ti).first << "\n" 00224 << " (count = " << (*ti).second->get_model_ref_count() 00225 << ")\n"; 00226 } 00227 } 00228 00229 out << "total number of models: " << num_models << " (plus " 00230 << _models.size() - num_models << " entries for nonexistent files)\n"; 00231 } 00232 00233 //////////////////////////////////////////////////////////////////// 00234 // Function: ModelPool::get_ptr 00235 // Access: Private, Static 00236 // Description: Initializes and/or returns the global pointer to the 00237 // one ModelPool object in the system. 00238 //////////////////////////////////////////////////////////////////// 00239 ModelPool *ModelPool:: 00240 get_ptr() { 00241 if (_global_ptr == (ModelPool *)NULL) { 00242 _global_ptr = new ModelPool; 00243 } 00244 return _global_ptr; 00245 }