00001 /*!@file Simulation/SimModule.H A module in a simulation framework */ 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: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Simulation/SimModule.H $ 00035 // $Id: SimModule.H 13390 2010-05-12 04:10:03Z rand $ 00036 // 00037 00038 #ifndef SIMULATION_SIMMODULE_H_DEFINED 00039 #define SIMULATION_SIMMODULE_H_DEFINED 00040 00041 #include "Component/ModelComponent.H" 00042 #include "Transport/FrameOstream.H" 00043 #include "Simulation/SimCallback.H" 00044 #include "Simulation/SimCallbackClient.H" 00045 #include "Simulation/SimReqHandler.H" 00046 #include "Simulation/SimReqHandlerClient.H" 00047 class SimEventQueue; 00048 00049 00050 //! SimModule is an extension of ModelComponent for simulation modules 00051 /*! In addition to the base functionality inherited from 00052 ModelComponents, SimModule objects can post/check for SimEvent. This 00053 base class merely provides the interface. 00054 00055 PROGRAMMER NOTE: SimModule has ModelComponent as a virtual 00056 base. This is so that some classes can inherit from SimModule as 00057 well as from some other class which itself also virtually derives 00058 from ModelComponent, with sharing of the underlying ModelComponent 00059 virtual base. 00060 00061 The reason for this is for example that, at the time of this 00062 writing, VisualCortex derives from ComplexChannel which derives from 00063 ChannelBase which derives from ModelComponent. To make VisualCortex 00064 a SimModule (so that it can post SimEvents) would then require that 00065 ChannelBase derives from SimModule, which is not desirable since 00066 having an evolve() does not make sense for ChannelBase. So we would 00067 like to keep ChannelBase a standard ModelComponent (non-SimModule) 00068 while still making VisualCortex a SimModule. The solution is that 00069 VisualCortex should derive both from ComplexChannel and from 00070 SimModule. Since both ChannelBase and SimModule derive from 00071 ModelComponent, making that ModelComponent base virtual is necessary 00072 to avoid ending up with two ModelComponent objects inside 00073 VisualCortex. 00074 00075 Here is how to use this virtual base mechanism: 00076 00077 - a protected default constructor was added to ModelComponent which 00078 initializes the rep and sets bogus names; 00079 00080 - a protected init(mgr, descr, tag) function was added to 00081 ModelComponent which does the same as the normal constructor 00082 00083 - in the constructor of the class that virtually derives from 00084 ModelComponent, make sure you call init(). In exchange, you don't 00085 really need to call any ModelComponent c'tor, the default will be 00086 called anyway 00087 00088 - in further concrete derivations of that one, no change 00089 00090 so, for example, what happens when you construct BlueChannel is: 00091 00092 BlueChannel constructor called 00093 First initialize virtual bases -> ModelComponent::ModelComponent() 00094 called. The ModelComponent part is left in a bogus uninitialized state 00095 except that const Impl* rep has been allocated. 00096 00097 Then initialize concrete bases -> SingleChannel constructor called 00098 In there, virtual bases already constructed, so move on to concrete 00099 ones -> ChannelBase constructor called 00100 00101 In there, virtual bases already constructed, so just initialize 00102 data members. Then in the { } of the constructor, 00103 ModelComponent::init() is called, which will fix the manager and names 00104 of the component. Those names will correctly be those passed down from 00105 the BlueChannel constructor. 00106 00107 same thing on the SimModule side: it virtually derives from ModelComponent 00108 and calls ModelComponent::init() 00109 00110 then when you construct, eg, SaliencyMap, first you get 00111 ModelComponent::ModelComponent() and later once the { } constructor code 00112 of SimModule runs, the call to init() will fix the component. 00113 00114 with multiple inheritance, eg VisualCortex derives from ComplexChannel and 00115 SimModule, pretty much the same thing happens, except that init() gets 00116 called twice, once from the ChannelBase c'tor and once from the SimModule 00117 c'tor... One way to avoid this would be to give a default c'tor to 00118 SimModule, but I'd rather not because things really become complicated 00119 then in case one does not know what he is doing (e.g., us 5 years from 00120 now) ;-) 00121 */ 00122 00123 class SimModule : virtual public ModelComponent, public SimCallbackClient, public SimReqHandlerClient { 00124 public: 00125 //! Constructor 00126 SimModule(OptionManager& mgr, const std::string& descrName, const std::string& tagName); 00127 00128 //! Virtual destructor ensures proper destruction of derived classes 00129 virtual ~SimModule(); 00130 00131 protected: 00132 // overload ModelComponent's start to also register our callbacks and request handlers 00133 virtual void start1(); 00134 }; 00135 00136 // ###################################################################### 00137 //! Provide info that SimModule objects need to save() their results 00138 class SimModuleSaveInfo : public ModelComponentSaveInfo { 00139 public: 00140 //! Constructor 00141 SimModuleSaveInfo(nub::ref<FrameOstream> outfs, SimEventQueue& seq) : 00142 ModelComponentSaveInfo(), ofs(outfs), q(&seq) { } 00143 00144 //! Destructor 00145 inline virtual ~SimModuleSaveInfo() { } 00146 00147 // We will save to a FrameOstream 00148 const nub::ref<FrameOstream> ofs; 00149 00150 // May need access to the SimEventQueue to fetch data off it 00151 SimEventQueue *q; 00152 }; 00153 00154 //! SIMMODULEINSTFUNC(ClsName): macro for instantiating Class of type SimMOdule for dynamically loaded modules 00155 #define SIMMODULEINSTFUNC(ClsName) \ 00156 extern "C" nub::ref<SimModule> createModule##ClsName( OptionManager& manager) \ 00157 { return nub::ref<SimModule>(new ClsName(manager)); } 00158 00159 //Used as a function pointer for the SIMModuleInstFunc 00160 typedef nub::ref<SimModule> createSimEventModule(OptionManager& manager); 00161 00162 // ###################################################################### 00163 /* So things look consistent in everyone's emacs... */ 00164 /* Local Variables: */ 00165 /* mode: c++ */ 00166 /* indent-tabs-mode: nil */ 00167 /* End: */ 00168 00169 #endif // SIMULATION_SIMMODULE_H_DEFINED