00001 // Filename: factoryBase.cxx 00002 // Created by: drose (08May00) 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 "factoryBase.h" 00016 #include "indent.h" 00017 #include "config_util.h" 00018 00019 //////////////////////////////////////////////////////////////////// 00020 // Function: FactoryBase::Constructor 00021 // Access: Public 00022 // Description: 00023 //////////////////////////////////////////////////////////////////// 00024 FactoryBase:: 00025 FactoryBase() { 00026 } 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: FactoryBase::Destructor 00030 // Access: Public 00031 // Description: 00032 //////////////////////////////////////////////////////////////////// 00033 FactoryBase:: 00034 ~FactoryBase() { 00035 } 00036 00037 //////////////////////////////////////////////////////////////////// 00038 // Function: FactoryBase::make_instance 00039 // Access: Public 00040 // Description: Attempts to create a new instance of some class of 00041 // the indicated type, or some derivative if necessary. 00042 // If an instance of the exact type cannot be created, 00043 // the specified preferred will specify which derived 00044 // class will be preferred. 00045 //////////////////////////////////////////////////////////////////// 00046 TypedObject *FactoryBase:: 00047 make_instance(TypeHandle handle, const FactoryParams ¶ms) { 00048 TypedObject *instance = (TypedObject *)NULL; 00049 00050 instance = make_instance_exact(handle, params); 00051 if (instance == (TypedObject *)NULL) { 00052 // Can't create an exact instance; try for a derived type. 00053 instance = make_instance_more_specific(handle, params); 00054 } 00055 00056 if (util_cat.is_debug()) { 00057 util_cat.debug() 00058 << "make_instance(" << handle << ", params) returns " 00059 << (void *)instance; 00060 if (instance != (TypedObject *)NULL) { 00061 util_cat.debug(false) 00062 << ", of type " << instance->get_type(); 00063 } 00064 util_cat.debug(false) << "\n"; 00065 } 00066 return instance; 00067 } 00068 00069 //////////////////////////////////////////////////////////////////// 00070 // Function: FactoryBase::make_instance_more_general 00071 // Access: Public 00072 // Description: Attempts to create an instance of the type requested, 00073 // or some base type of the type requested. Returns the 00074 // new instance created, or NULL if the instance could 00075 // not be created. 00076 //////////////////////////////////////////////////////////////////// 00077 TypedObject *FactoryBase:: 00078 make_instance_more_general(TypeHandle handle, const FactoryParams ¶ms) { 00079 TypedObject *object = make_instance_exact(handle, params); 00080 00081 if (object == (TypedObject *)NULL) { 00082 // Recursively search through the entire inheritance tree until we 00083 // find something we know about. 00084 if (handle.get_num_parent_classes() == 0) { 00085 return NULL; 00086 } 00087 00088 int num_parents = handle.get_num_parent_classes(); 00089 for (int i = 0; i < num_parents && object == (TypedObject *)NULL; i++) { 00090 object = make_instance_more_general(handle.get_parent_class(i), params); 00091 } 00092 } 00093 00094 if (util_cat.is_debug()) { 00095 util_cat.debug() 00096 << "make_instance(" << handle << ", params) returns " 00097 << (void *)object; 00098 if (object != (TypedObject *)NULL) { 00099 util_cat.debug(false) 00100 << ", of type " << object->get_type(); 00101 } 00102 util_cat.debug(false) << "\n"; 00103 } 00104 00105 return object; 00106 } 00107 00108 //////////////////////////////////////////////////////////////////// 00109 // Function: FactoryBase::find_registered_type 00110 // Access: Public 00111 // Description: Returns the TypeHandle given, if it is a registered 00112 // type, or if it is not registered, searches for the 00113 // nearest ancestor of the indicated type that is 00114 // registered and returns it. If no ancestor of the 00115 // indicated type is registered, returns 00116 // TypeHandle::none(). 00117 //////////////////////////////////////////////////////////////////// 00118 TypeHandle FactoryBase:: 00119 find_registered_type(TypeHandle handle) { 00120 Creators::const_iterator ci = _creators.find(handle); 00121 if (ci != _creators.end()) { 00122 // This type is registered. 00123 return handle; 00124 } 00125 00126 // Recursively search through the entire inheritance tree until we 00127 // find something we know about. 00128 if (handle.get_num_parent_classes() == 0) { 00129 return TypeHandle::none(); 00130 } 00131 00132 int num_parents = handle.get_num_parent_classes(); 00133 for (int i = 0; i < num_parents; i++) { 00134 TypeHandle result = find_registered_type(handle.get_parent_class(i)); 00135 if (result != TypeHandle::none()) { 00136 return result; 00137 } 00138 } 00139 00140 // No known types. 00141 return TypeHandle::none(); 00142 } 00143 00144 //////////////////////////////////////////////////////////////////// 00145 // Function: FactoryBase::register_factory 00146 // Access: Public 00147 // Description: Registers a new kind of thing the Factory will be 00148 // able to create. 00149 //////////////////////////////////////////////////////////////////// 00150 void FactoryBase:: 00151 register_factory(TypeHandle handle, BaseCreateFunc *func) { 00152 nassertv(handle != TypeHandle::none()); 00153 nassertv(func != (BaseCreateFunc *)NULL); 00154 _creators[handle] = func; 00155 } 00156 00157 //////////////////////////////////////////////////////////////////// 00158 // Function: FactoryBase::get_num_types 00159 // Access: Public 00160 // Description: Returns the number of different types the Factory 00161 // knows how to create. 00162 //////////////////////////////////////////////////////////////////// 00163 int FactoryBase:: 00164 get_num_types() const { 00165 return _creators.size(); 00166 } 00167 00168 //////////////////////////////////////////////////////////////////// 00169 // Function: FactoryBase::get_type 00170 // Access: Public 00171 // Description: Returns the nth type the Factory knows how to create. 00172 // This is not a terribly efficient function; it's 00173 // included primarily for debugging output. Normally 00174 // you wouldn't need to traverse the list of the 00175 // Factory's types. 00176 //////////////////////////////////////////////////////////////////// 00177 TypeHandle FactoryBase:: 00178 get_type(int n) const { 00179 nassertr(n >= 0 && n < get_num_types(), TypeHandle::none()); 00180 Creators::const_iterator ci; 00181 for (ci = _creators.begin(); ci != _creators.end(); ++ci) { 00182 if (n == 0) { 00183 return (*ci).first; 00184 } 00185 n--; 00186 } 00187 00188 // We shouldn't get here. 00189 nassertr(false, TypeHandle::none()); 00190 return TypeHandle::none(); 00191 } 00192 00193 //////////////////////////////////////////////////////////////////// 00194 // Function: FactoryBase::clear_preferred 00195 // Access: Public 00196 // Description: Empties the list of preferred types. 00197 //////////////////////////////////////////////////////////////////// 00198 void FactoryBase:: 00199 clear_preferred() { 00200 _preferred.clear(); 00201 } 00202 00203 //////////////////////////////////////////////////////////////////// 00204 // Function: FactoryBase::add_preferred 00205 // Access: Public 00206 // Description: Adds the indicated type to the end of the list of 00207 // preferred types. On the next call to 00208 // make_instance(), if the exact type requested cannot 00209 // be created, the preferred types are first tried in 00210 // the order specified. 00211 //////////////////////////////////////////////////////////////////// 00212 void FactoryBase:: 00213 add_preferred(TypeHandle handle) { 00214 nassertv(handle != TypeHandle::none()); 00215 _preferred.push_back(handle); 00216 } 00217 00218 //////////////////////////////////////////////////////////////////// 00219 // Function: FactoryBase::get_num_preferred 00220 // Access: Public 00221 // Description: Returns the number of types added to the 00222 // preferred-type list. 00223 //////////////////////////////////////////////////////////////////// 00224 int FactoryBase:: 00225 get_num_preferred() const { 00226 return _preferred.size(); 00227 } 00228 00229 //////////////////////////////////////////////////////////////////// 00230 // Function: FactoryBase::get_preferred 00231 // Access: Public 00232 // Description: Returns the nth type added to the preferred-type 00233 // list. 00234 //////////////////////////////////////////////////////////////////// 00235 TypeHandle FactoryBase:: 00236 get_preferred(int n) const { 00237 nassertr(n >= 0 && n < get_num_preferred(), TypeHandle::none()); 00238 return _preferred[n]; 00239 } 00240 00241 //////////////////////////////////////////////////////////////////// 00242 // Function: FactoryBase::write_types 00243 // Access: Public 00244 // Description: Writes a list of all known types the Factory can 00245 // create to the indicated output stream, one per line. 00246 //////////////////////////////////////////////////////////////////// 00247 void FactoryBase:: 00248 write_types(ostream &out, int indent_level) const { 00249 Creators::const_iterator ci; 00250 for (ci = _creators.begin(); ci != _creators.end(); ++ci) { 00251 indent(out, indent_level) << (*ci).first << "\n"; 00252 } 00253 } 00254 00255 00256 //////////////////////////////////////////////////////////////////// 00257 // Function: FactoryBase::Copy Constructor 00258 // Access: Private 00259 // Description: Don't copy Factories. 00260 //////////////////////////////////////////////////////////////////// 00261 FactoryBase:: 00262 FactoryBase(const FactoryBase &) { 00263 } 00264 00265 //////////////////////////////////////////////////////////////////// 00266 // Function: FactoryBase::Copy Assignment Operator 00267 // Access: Private 00268 // Description: Don't copy Factories. 00269 //////////////////////////////////////////////////////////////////// 00270 void FactoryBase:: 00271 operator = (const FactoryBase &) { 00272 } 00273 00274 //////////////////////////////////////////////////////////////////// 00275 // Function: FactoryBase::make_instance_exact 00276 // Access: Private 00277 // Description: Attempts to create an instance of the exact type 00278 // requested by the given handle. Returns the new 00279 // instance created, or NULL if the instance could not 00280 // be created. 00281 //////////////////////////////////////////////////////////////////// 00282 TypedObject *FactoryBase:: 00283 make_instance_exact(TypeHandle handle, const FactoryParams ¶ms) { 00284 Creators::const_iterator ci = _creators.find(handle); 00285 if (ci == _creators.end()) { 00286 return NULL; 00287 } 00288 00289 BaseCreateFunc *func = (BaseCreateFunc *)((*ci).second); 00290 nassertr(func != (BaseCreateFunc *)NULL, NULL); 00291 return (*func)(params); 00292 } 00293 00294 //////////////////////////////////////////////////////////////////// 00295 // Function: FactoryBase::make_instance_more_specific 00296 // Access: Private 00297 // Description: Attempts to create an instance of some derived type 00298 // of the type requested by the given handle. Returns 00299 // the new instance created, or NULL if the instance 00300 // could not be created. 00301 //////////////////////////////////////////////////////////////////// 00302 TypedObject *FactoryBase:: 00303 make_instance_more_specific(TypeHandle handle, const FactoryParams ¶ms) { 00304 // First, walk through the established preferred list. Maybe one 00305 // of these qualifies. 00306 00307 Preferred::const_iterator pi; 00308 for (pi = _preferred.begin(); pi != _preferred.end(); ++pi) { 00309 TypeHandle ptype = (*pi); 00310 if (ptype.is_derived_from(handle)) { 00311 TypedObject *object = make_instance_exact(ptype, params); 00312 if (object != (TypedObject *)NULL) { 00313 return object; 00314 } 00315 } 00316 } 00317 00318 // No, we couldn't create anything on the preferred list, so create 00319 // the first thing we know about that derives from the indicated 00320 // type. 00321 Creators::const_iterator ci; 00322 for (ci = _creators.begin(); ci != _creators.end(); ++ci) { 00323 TypeHandle ctype = (*ci).first; 00324 if (ctype.is_derived_from(handle)) { 00325 BaseCreateFunc *func = (BaseCreateFunc *)((*ci).second); 00326 nassertr(func != (BaseCreateFunc *)NULL, NULL); 00327 TypedObject *object = (*func)(params); 00328 if (object != (TypedObject *)NULL) { 00329 return object; 00330 } 00331 } 00332 } 00333 00334 return NULL; 00335 } 00336