Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/putil/factoryBase.cxx

Go to the documentation of this file.
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 &params) {
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 &params) {
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 &params) {
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 &params) {
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 

Generated on Fri May 2 00:43:37 2003 for Panda by doxygen1.3