Panda3D

factoryBase.cxx

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 &params) {
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 &params) {
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 &params) {
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 &params) {
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 
 All Classes Functions Variables Enumerations