00001 /*!@file Psycho/StimController.H an abstract class to support control 00002 of our psycho display system from an external device */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00006 // University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: David Berg <dberg@usc.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Psycho/StimController.H $ 00036 00037 #ifndef PSYCHO_STIMCONTROLLER_H_FEFINED 00038 #define PSYCHO_STIMCONTROLLER_H_FEFINED 00039 00040 #include "Component/ModelComponent.H" 00041 #include "Util/WorkThreadServer.H" 00042 #include "Psycho/DisplayController.H" 00043 #include "Psycho/StimListener.H" 00044 00045 // ###################################################################### 00046 //!a class to control psychodisplay from a host sending commands 00047 // ###################################################################### 00048 /*! A ModelComponent that coordinates communication between the SDL 00049 display code and an external system. An object of this type 00050 initiates two threads, one to listen for commands from a host, and 00051 one to render them to the screen using SDL. The calling program can also 00052 pass in data which can be incorporated into the next display.*/ 00053 class StimController : public ModelComponent 00054 { 00055 public: 00056 //!constructor 00057 StimController(OptionManager& mgr, 00058 const std::string& descrName = " StimController", 00059 const std::string& tagName = "StimController"); 00060 00061 //!destructor 00062 virtual ~StimController(); 00063 00064 //!initialize our object with a stimulus controller and listener 00065 void initialize(const StimListener* const sl); 00066 00067 //!set the event log for our components 00068 void setEventLog(const nub::soft_ref<EventLog>& elog); 00069 00070 //!set the handle to a psycho display 00071 void setDisplay(const nub::soft_ref<PsychoDisplay>& display); 00072 00073 //! return a reference to the current listener 00074 rutz::shared_ptr<StimListener> getStimListener(); 00075 00076 //! return a reference to the current Controller 00077 rutz::shared_ptr<DisplayController> getDispController(); 00078 00079 //! pause the display, we will still recieve commands, but stop 00080 //! processing them until unpaused. 00081 void pauseDisplay(const bool pausestate); 00082 00083 protected: 00084 //!start our module 00085 void start2(); 00086 00087 //stop and clean up 00088 void stop1(); 00089 00090 private: 00091 //!prohibit assignment 00092 StimController& operator=(const StimController& d); 00093 00094 //!prohibit copy constuctor 00095 StimController(const StimController& d); 00096 00097 //!thread to listen for commands 00098 rutz::shared_ptr<StimListener> itsListener; 00099 00100 //!thread to display commands 00101 rutz::shared_ptr<DisplayController> itsController; 00102 00103 //!thread-safe shared buffer 00104 rutz::shared_ptr<SharedBuffer<StimData> > itsBuffer; 00105 00106 //!A WorkThreadServer for our tasks. 00107 WorkThreadServer itsThreadServer; 00108 }; 00109 00110 // ###################################################################### 00111 //inline methods for StimController 00112 // ###################################################################### 00113 StimController::StimController(OptionManager& mgr, 00114 const std::string& descrName, 00115 const std::string& tagName) : 00116 ModelComponent(mgr,descrName,tagName), 00117 itsBuffer(new SharedBuffer<StimData>()), 00118 itsListener(), 00119 itsController(new DisplayController()), 00120 itsThreadServer("Stimulus Controller",2) 00121 { 00122 } 00123 00124 // ###################################################################### 00125 StimController::~StimController() 00126 { 00127 00128 } 00129 00130 // ###################################################################### 00131 void initialize(const StimListener* const sl) 00132 { 00133 itsController = rutz::make_shared(sl); 00134 } 00135 00136 // ###################################################################### 00137 void StimController::setEventLog(const nub::soft_ref<EventLog>& log) 00138 { 00139 if (itsListener.is_valid() && itsController.is_valid()) 00140 { 00141 itsListener->setEventLog(log); 00142 itsController->setEventLog(log); 00143 } 00144 else 00145 LFATAL("Must initialize with a DisplayController and StimListener"); 00146 } 00147 00148 // ###################################################################### 00149 void StimController::setDisplay(const nub::soft_ref<PsychoDisplay>& disp) 00150 { 00151 if (itsListener.is_valid() && itsController.is_valid()) 00152 itsController->setDisplay(disp); 00153 else 00154 LFATAL("Must initialize with a DisplayController and StimListener"); 00155 00156 } 00157 00158 // ###################################################################### 00159 void StimController::start2() 00160 { 00161 itsListener->setBuffer(itsBuffer); 00162 itsController->setBuffer(itsBuffer); 00163 itsListener->start(); 00164 itsController->start(); 00165 itsThreadServer.enqueueJob(itsListener); 00166 itsThreadServer.enqueueJob(itsController); 00167 } 00168 00169 // ###################################################################### 00170 void StimController::stop1() 00171 { 00172 itsListener->stop(); 00173 itsBuffer->stopWaiting(); 00174 itsController->stop(); 00175 } 00176 00177 // ###################################################################### 00178 rutz::shared_ptr<StimListener> StimController::getStimListener() 00179 { 00180 return itsListener; 00181 } 00182 00183 // ###################################################################### 00184 rutz::shared_ptr<DisplayController> StimController::getDispController() 00185 { 00186 return itsController; 00187 } 00188 00189 // ###################################################################### 00190 void StimController::pauseDisplay(const bool pausestate) 00191 { 00192 itsController->pause(pausestate); 00193 } 00194 00195 00196 #endif 00197 // ###################################################################### 00198 /* So things look consistent in everyone's emacs... */ 00199 /* Local Variables: */ 00200 /* indent-tabs-mode: nil */ 00201 /* End: */