Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

InPort.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00019 /*
00020  * $Log: InPort.h,v $
00021  * Revision 1.6.4.2  2007/08/20 05:15:39  n-ando
00022  * Now default buffer is RingBuffer instead of NullBuffer.
00023  *
00024  * Revision 1.6.4.1  2007/07/20 15:54:50  n-ando
00025  * Now ACE_OS::gettimeofday() is used for win32 porting.
00026  *
00027  * Revision 1.6  2007/01/06 17:47:51  n-ando
00028  * Some changes.
00029  * - Callback declarations are changed.
00030  * - Return value of write().
00031  *
00032  * Revision 1.5  2006/12/02 18:37:29  n-ando
00033  * A trivial fix.
00034  *
00035  * Revision 1.4  2006/11/07 09:26:12  n-ando
00036  * Renamed RtcInPort.h to InPort.h.
00037  *
00038  * Revision 1.3  2005/05/27 07:29:32  n-ando
00039  * - InPort/OutPort interface was changed.
00040  *   Exception RTM::InPort::Disconnected -> RTM:PortBase::Disconnected
00041  *
00042  * Revision 1.2  2005/05/16 06:12:15  n-ando
00043  * - Time variables of "m_Value" were initialized in constructors.
00044  *
00045  * Revision 1.1.1.1  2005/05/12 09:06:18  n-ando
00046  * Public release.
00047  *
00048  *
00049  */
00050 
00051 #ifndef RtcInPort_h
00052 #define RtcInPort_h
00053 
00054 #include <string>
00055 #include <vector>
00056 #include <iostream>
00057 #include <rtm/BufferBase.h>
00058 #include <rtm/RingBuffer.h>
00059 #include <rtm/PortCallBack.h>
00060 #include <rtm/RTC.h>
00061 
00062 #define TIMEOUT_TICK_USEC 10
00063 #define USEC_PER_SEC 1000000
00064 
00065 namespace RTC
00066 {
00099   template <class DataType,
00100             template <class DataType> class Buffer = RingBuffer >
00101   class InPort
00102     : public Buffer<DataType>
00103   {
00104   public:
00130     InPort(const char* name, DataType& value,
00131            int bufsize=64, 
00132            bool read_block = false, bool write_block = false,
00133            int read_timeout = 0, int write_timeout = 0)
00134       : Buffer<DataType>(bufsize),
00135         m_name(name), m_value(value),
00136         m_readBlock(read_block),   m_readTimeout(read_timeout),
00137         m_writeBlock(write_block), m_writeTimeout(write_timeout),
00138         m_OnWrite(NULL), m_OnWriteConvert(NULL),
00139         m_OnRead(NULL),  m_OnReadConvert(NULL),
00140         m_OnOverflow(NULL), m_OnUnderflow(NULL)
00141     {
00142     };
00143     
00144     
00158     virtual ~InPort(){};
00159 
00160 
00161 
00162     virtual const char* name()
00163     {
00164       return m_name.c_str();
00165     }
00166 
00167 
00193     bool write(const DataType& value)
00194     {
00195       if (m_OnWrite != NULL) (*m_OnWrite)(value);      
00196 
00197       long int timeout = m_writeTimeout;
00198 
00199       timeval tm_cur, tm_pre;
00200       ACE_Time_Value tt;
00201       tt = ACE_OS::gettimeofday();
00202       tm_pre = tt.operator timeval();
00203 
00204       // blocking and timeout wait
00205       while (m_writeBlock && this->isFull())
00206         {
00207           if (m_writeTimeout < 0) 
00208             {
00209               usleep(TIMEOUT_TICK_USEC);
00210               continue;
00211             }
00212 
00213           // timeout wait
00214           ACE_Time_Value tt;
00215           tt = ACE_OS::gettimeofday();
00216           tm_cur = tt.operator timeval();
00217           long int sec (tm_cur.tv_sec  - tm_pre.tv_sec);
00218           long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00219 
00220           timeout -= (sec * USEC_PER_SEC + usec);
00221           if (timeout < 0) break;
00222 
00223           tm_pre = tm_cur;
00224           usleep(TIMEOUT_TICK_USEC);
00225         }
00226 
00227       if (this->isFull() && m_OnOverflow != NULL)
00228         {
00229           (*m_OnOverflow)(value);
00230           return false;
00231         }
00232 
00233       if (m_OnWriteConvert == NULL) 
00234         {
00235           this->put(value);
00236         }
00237       else
00238         {
00239           this->put((*m_OnWriteConvert)(value));
00240         }
00241       return true;
00242     }
00243     
00244 
00270     DataType read()
00271     {
00272       if (m_OnRead != NULL) (*m_OnRead)();      
00273 
00274       long int timeout = m_readTimeout;
00275 
00276       timeval tm_cur, tm_pre;
00277       ACE_Time_Value tt;
00278       tt = ACE_OS::gettimeofday();
00279       tm_pre = tt.operator timeval();
00280 
00281       // blocking and timeout wait
00282       while (m_readBlock && this->isEmpty())
00283         {
00284           if (m_readTimeout < 0)
00285             {
00286               usleep(TIMEOUT_TICK_USEC);
00287               continue;
00288             }
00289 
00290           // timeout wait
00291           ACE_Time_Value tt;
00292           tt = ACE_OS::gettimeofday();
00293           tm_cur = tt.operator timeval();
00294           long int sec (tm_cur.tv_sec  - tm_pre.tv_sec);
00295           long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00296 
00297           timeout -= (sec * USEC_PER_SEC + usec);
00298           if (timeout < 0) break;
00299 
00300           tm_pre = tm_cur;
00301           usleep(TIMEOUT_TICK_USEC);
00302         }
00303 
00304       if (this->isEmpty() && m_OnUnderflow != NULL)
00305         {
00306           m_value = (*m_OnUnderflow)();
00307           return m_value;
00308         }
00309 
00310       if (m_OnReadConvert == NULL) 
00311         {
00312           m_value = this->get();
00313           return m_value;
00314         }
00315       else
00316         {
00317           m_value = (*m_OnReadConvert)(this->get());
00318           return m_value;
00319         }
00320       // never comes here
00321       return m_value;
00322     }
00323 
00324 
00325 
00339     virtual void init(DataType& value)
00340     {
00341       //      m_buffer.init(value);
00342     }
00343     
00344     
00361     void update()
00362     {
00363       try
00364         {
00365           m_value = this->get();
00366         }
00367       catch (...)
00368         {
00369           if (m_OnUnderflow != NULL) (*m_OnUnderflow)();
00370         }
00371       return;
00372     };
00373     
00374     
00390     void operator>>(DataType& rhs)
00391     {
00392       rhs = read();
00393       return;
00394     }
00395     
00396 
00397     void operator<<(DataType& value)
00398     {
00399       write(value);
00400       return;
00401     }
00402 
00403     
00415     /*
00416     virtual int getNewDataLen()
00417     {
00418       return m_buffer->new_data_len();
00419     }
00420     */    
00421     
00433     /*
00434     virtual std::vector<T> getNewList()
00435     {
00436       return m_buffer.get_new_list();
00437     }
00438     */
00439     
00451     /*
00452     virtual std::vector<T> getNewListReverse()
00453     {
00454       return m_buffer.get_new_rlist();
00455     }
00456     */
00457 
00484     inline void setOnWrite(OnWrite<DataType>* on_write)
00485     {
00486       m_OnWrite = on_write;
00487     }
00488 
00489     inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00490     {
00491       m_OnWriteConvert = on_wconvert;
00492     }
00493 
00494     inline void setOnRead(OnRead<DataType>* on_read)
00495     {
00496       m_OnRead = on_read;
00497     }
00498 
00499     inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00500     {
00501       m_OnReadConvert = on_rconvert;
00502     }
00503 
00504     inline void setOnOverflow(OnOverflow<DataType>* on_overflow)
00505     {
00506       m_OnOverflow = on_overflow;
00507     }
00508 
00509     inline void setOnUnderflow(OnUnderflow<DataType>* on_underflow)
00510     {
00511       m_OnUnderflow = on_underflow;
00512     }
00513 
00514 
00515   private:
00523     std::string m_name;
00524 
00532     DataType& m_value;
00533     
00541     //    Buffer<DataType> m_buffer;
00542 
00543     bool m_readBlock;
00544     long int m_readTimeout;
00545     bool m_writeBlock;
00546     long int m_writeTimeout;
00547 
00555     OnWrite<DataType>* m_OnWrite;
00556 
00564     OnWriteConvert<DataType>* m_OnWriteConvert;
00565 
00573     OnRead<DataType>* m_OnRead;
00574 
00582     OnReadConvert<DataType>* m_OnReadConvert;
00583 
00591     OnOverflow<DataType>* m_OnOverflow;
00592 
00601     OnUnderflow<DataType>* m_OnUnderflow;
00602 
00603     
00604   };
00605   
00606 }; // End of namesepace RTM
00607 
00608 #endif // RtcInPort_h

Generated on Fri Sep 21 12:03:45 2007 for OpenRTM by  doxygen 1.4.1