ComponentFactory.H

Go to the documentation of this file.
00001 /*!@file Component/ComponentFactory.H Factory to create ModelComponent objects from a key string */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Component/ComponentFactory.H $
00035 // $Id: ComponentFactory.H 8274 2007-04-19 17:44:48Z rjpeters $
00036 //
00037 
00038 #ifndef COMPONENT_COMPONENTFACTORY_H_DEFINED
00039 #define COMPONENT_COMPONENTFACTORY_H_DEFINED
00040 
00041 #include "nub/ref.h"
00042 #include "rutz/factory.h"
00043 
00044 class OptionManager;
00045 
00046 /// Factory to create ModelComponent-derivative objects from a key string.
00047 /** The template class P should be some class that is derived from
00048     ModelComponent, and that is also the root of some sub-tree of the
00049     full inheritance graph.
00050 
00051     Here's a quick overview of how ComponentFactory can be used with
00052     plugins and dynamic loading. You would use this system when you
00053     have multiple concrete classes derived from a base class, and you
00054     want to be able to select a particular concrete type to use at run
00055     time, based on some user input (e.g. a string passed to a
00056     command-line option). First, you create a ComponentFactory that is
00057     going to build products derived from a different type. Then, you
00058     install a PluginFallback for that factory that tells it "if you
00059     don't already know about the type, then first try to load an
00060     appropriately-named plugin module, and then try again to see if
00061     that plugin has now informed you about the type".
00062 
00063     For an example of all this, see Media/FrameSeries.C, where we use
00064     the factories defined in Transport/FrameIstreamFactory.H. We
00065     populate the factories with some statically-known types, and then
00066     we install a PluginFallback. The PluginFallback essentially says,
00067     if we get --in=foobar on the command line, and our factory doesn't
00068     know anything about 'foobar' yet, then it should look for a plugin
00069     library named <plugins>/FrameIstream/foobar.so, and it should try
00070     to find an init function named frameistream_foobar_init() in that
00071     library. Presumably, that function frameistream_foobar_init() will
00072     then tell the factory how to make a 'foobar', and so when the
00073     PluginFallback returns, the factory can try again to make a
00074     'foobar'.
00075 
00076     To actually try out a plugin, try the following:
00077     \verbatim
00078     make bin/ezvision
00079     make plugins
00080     ./bin/ezvision --in=tests/inputs/mpegclip1.mpg -T --out=display --out=debug
00081     \endverbatim
00082 
00083     and within the log output you will see something like this:
00084     \verbatim
00085     Plugin::loadPlugin: opening /lab/rjpeters/projects/saliency/lib/invt/plugins/FrameOstream/debug.so
00086     Plugin::loadPlugin: running frameostream_debug_init() from /lab/rjpeters/projects/saliency/lib/invt/plugins/FrameOstream/debug.so
00087     debug::frameostream_debug_init: Hello from frameostream_debug_init()!
00088     \endverbatim
00089 
00090     and then you will start seeing output from the DebugOstream that
00091     is built by --out=debug.
00092 */
00093 template <class P>
00094 class ComponentFactory : public rutz::factory<nub::ref<P> >
00095 {
00096 public:
00097   typedef nub::ref<P> ProductType;
00098 
00099   ComponentFactory(const char* keydescr, bool nocase = false)
00100     :
00101     rutz::factory<nub::ref<P> >(keydescr, nocase)
00102   {}
00103 
00104   template <class T>
00105   void registerType(const char* name, OptionManager& mgr)
00106   {
00107     this->register_creator(new ComponentCreator<T>(mgr), name);
00108   }
00109 
00110   nub::ref<P> createObj(const char* type) const
00111   {
00112     return this->new_checked_object(rutz::fstring(type));
00113   }
00114 
00115 private:
00116   /// Creator class that creates ModelComponent derivatives on demand.
00117   /** The only trick here is that we have to store a reference to an
00118       OptionManager, since (by convention) all ModelComponent classes
00119       take an OptionManager as the first arg to their constructor. */
00120   template <class T>
00121   class ComponentCreator : public rutz::creator_base<nub::ref<P> >
00122   {
00123   public:
00124     ComponentCreator(OptionManager& mgr)
00125       : itsManager(mgr) {}
00126 
00127     ComponentCreator(const ComponentCreator& that)
00128       : rutz::creator_base<nub::ref<P> >(that),
00129         itsManager(that.itsManager) {}
00130 
00131     virtual ~ComponentCreator() {}
00132 
00133     virtual rutz::creator_base<nub::ref<P> >* clone() const
00134     { return new ComponentCreator(*this); }
00135 
00136     virtual nub::ref<P> create()
00137     { return nub::ref<P>(new T(itsManager)); }
00138 
00139   private:
00140     OptionManager& itsManager;
00141   };
00142 };
00143 
00144 // ######################################################################
00145 /* So things look consistent in everyone's emacs... */
00146 /* Local Variables: */
00147 /* mode: c++ */
00148 /* indent-tabs-mode: nil */
00149 /* End: */
00150 
00151 #endif // COMPONENT_COMPONENTFACTORY_H_DEFINED
Generated on Sun May 8 08:04:42 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3