00001 /*!@file Simulation/SimEventBuffer.H */ 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: Pezhman Firoozfam (pezhman.firoozfam@usc.edu) 00034 // $HeadURL$ svn://isvn.usc.edu/software/invt/trunk/saliency/src/Simulation/SimEventBuffer.H 00035 // 00036 00037 #ifndef SIMULATION_SIMEVENTBUFFER_H_DEFINED 00038 #define SIMULATION_SIMEVENTBUFFER_H_DEFINED 00039 00040 #include <queue> 00041 00042 #include "rutz/mutex.h" 00043 #include "Simulation/SimEventQueue.H" 00044 #include "Simulation/SimEvents.H" 00045 00046 class SimEventBuffer : public SimModule 00047 { 00048 public: 00049 //! Constructor 00050 SimEventBuffer(OptionManager& mgr, 00051 const std::string& descrName = "SimEventBuffer", 00052 const std::string& tagName = "SimEventBuffer"); 00053 00054 //! Destructor 00055 virtual ~SimEventBuffer(); 00056 00057 //! Post an event asynchronously 00058 /*! The event is queued in a buffer and asyncPost returns immediately. 00059 The buffered event is posted to SimEventQueue asynchronously on 00060 next clock tick. 00061 */ 00062 template <class E> inline void asyncPost(rutz::shared_ptr<E> e); 00063 00064 //! Retrieve the next buffered event. 00065 /*! Normally, this is called only when receving 00066 SimEventClockTick event. It returns invalid 00067 rutz::shared_ptr<SimEvent> when buffer is 00068 empty. 00069 */ 00070 rutz::shared_ptr<SimEvent> asyncRetrieve(); 00071 00072 //! Return SimEventBuffer instance 00073 static SimEventBuffer& Instance() 00074 { 00075 if (pThis == NULL) 00076 { 00077 LFATAL("SimEventBuffer instance is not created yet or has been destroyed already"); 00078 } 00079 return *pThis; 00080 } 00081 00082 protected: 00083 //! Callback for when a new clock tick is available 00084 SIMCALLBACK_DECLARE(SimEventBuffer, SimEventClockTick); 00085 00086 private: 00087 std::queue< rutz::shared_ptr<SimEvent> > buffer; 00088 pthread_mutex_t buffer_access_mutex; 00089 static SimEventBuffer* pThis; 00090 }; 00091 00092 template <class E> inline void SimEventBuffer::asyncPost(rutz::shared_ptr<E> e) 00093 { 00094 // reject uninitialized shared_ptr's: 00095 if (e.is_valid() == false) LFATAL("You cannot post invalid events."); 00096 00097 // enforce that E should derive from SimEvent, i.e., a pointer to an 00098 // object of type E should be dyn_cast'able to a pointer to type 00099 // SimEvent: 00100 rutz::shared_ptr<SimEvent> ebase; dyn_cast_to_from(ebase, e); 00101 if (ebase.is_valid() == false) 00102 LFATAL("Passed event of type '%s' does not derive from SimEvent", rutz::demangled_name(typeid(*e))); 00103 00104 // plunge into the appropriate realm: 00105 // if (e->itsSource == 0) LFATAL("Received event [%s] with invalid source", e->toString().c_str()); 00106 00107 // lock the buffer and queue the event 00108 { 00109 GVX_MUTEX_LOCK(&buffer_access_mutex); 00110 buffer.push(ebase); 00111 } 00112 } 00113 00114 // ###################################################################### 00115 /* So things look consistent in everyone's emacs... */ 00116 /* Local Variables: */ 00117 /* mode: c++ */ 00118 /* indent-tabs-mode: nil */ 00119 /* End: */ 00120 00121 #endif // SIMULATION_SIMEVENTBUFFER_H_DEFINED