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