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.3  2007/09/21 09:15:16  n-ando
00022  * Now InPort's default buffer is RingBuffer.
00023  *
00024  * Revision 1.6.4.2  2007/08/20 05:15:39  n-ando
00025  * Now default buffer is RingBuffer instead of NullBuffer.
00026  *
00027  * Revision 1.6.4.1  2007/07/20 15:54:50  n-ando
00028  * Now ACE_OS::gettimeofday() is used for win32 porting.
00029  *
00030  * Revision 1.6  2007/01/06 17:47:51  n-ando
00031  * Some changes.
00032  * - Callback declarations are changed.
00033  * - Return value of write().
00034  *
00035  * Revision 1.5  2006/12/02 18:37:29  n-ando
00036  * A trivial fix.
00037  *
00038  * Revision 1.4  2006/11/07 09:26:12  n-ando
00039  * Renamed RtcInPort.h to InPort.h.
00040  *
00041  * Revision 1.3  2005/05/27 07:29:32  n-ando
00042  * - InPort/OutPort interface was changed.
00043  *   Exception RTM::InPort::Disconnected -> RTM:PortBase::Disconnected
00044  *
00045  * Revision 1.2  2005/05/16 06:12:15  n-ando
00046  * - Time variables of "m_Value" were initialized in constructors.
00047  *
00048  * Revision 1.1.1.1  2005/05/12 09:06:18  n-ando
00049  * Public release.
00050  *
00051  *
00052  */
00053 
00054 #ifndef RtcInPort_h
00055 #define RtcInPort_h
00056 
00057 #include <string>
00058 #include <vector>
00059 #include <iostream>
00060 #include <rtm/BufferBase.h>
00061 #include <rtm/RingBuffer.h>
00062 #include <rtm/PortCallBack.h>
00063 #include <rtm/RTC.h>
00064 
00065 #define TIMEOUT_TICK_USEC 10
00066 #define USEC_PER_SEC 1000000
00067 
00068 namespace RTC
00069 {
00102   template <class DataType,
00103             template <class DataType> class Buffer = RingBuffer >
00104   class InPort
00105     : public Buffer<DataType>
00106   {
00107   public:
00133     InPort(const char* name, DataType& value,
00134            int bufsize=64, 
00135            bool read_block = false, bool write_block = false,
00136            int read_timeout = 0, int write_timeout = 0)
00137       : Buffer<DataType>(bufsize),
00138         m_name(name), m_value(value),
00139         m_readBlock(read_block),   m_readTimeout(read_timeout),
00140         m_writeBlock(write_block), m_writeTimeout(write_timeout),
00141         m_OnWrite(NULL), m_OnWriteConvert(NULL),
00142         m_OnRead(NULL),  m_OnReadConvert(NULL),
00143         m_OnOverflow(NULL), m_OnUnderflow(NULL)
00144     {
00145     };
00146     
00147     
00161     virtual ~InPort(){};
00162 
00163 
00164 
00165     virtual const char* name()
00166     {
00167       return m_name.c_str();
00168     }
00169 
00170 
00196     bool write(const DataType& value)
00197     {
00198       if (m_OnWrite != NULL) (*m_OnWrite)(value);      
00199 
00200       long int timeout = m_writeTimeout;
00201 
00202       timeval tm_cur, tm_pre;
00203       ACE_Time_Value tt;
00204       tt = ACE_OS::gettimeofday();
00205       tm_pre = tt.operator timeval();
00206 
00207       // blocking and timeout wait
00208       while (m_writeBlock && this->isFull())
00209         {
00210           if (m_writeTimeout < 0) 
00211             {
00212               usleep(TIMEOUT_TICK_USEC);
00213               continue;
00214             }
00215 
00216           // timeout wait
00217           ACE_Time_Value tt;
00218           tt = ACE_OS::gettimeofday();
00219           tm_cur = tt.operator timeval();
00220           long int sec (tm_cur.tv_sec  - tm_pre.tv_sec);
00221           long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00222 
00223           timeout -= (sec * USEC_PER_SEC + usec);
00224           if (timeout < 0) break;
00225 
00226           tm_pre = tm_cur;
00227           usleep(TIMEOUT_TICK_USEC);
00228         }
00229 
00230       if (this->isFull() && m_OnOverflow != NULL)
00231         {
00232           (*m_OnOverflow)(value);
00233           return false;
00234         }
00235 
00236       if (m_OnWriteConvert == NULL) 
00237         {
00238           this->put(value);
00239         }
00240       else
00241         {
00242           this->put((*m_OnWriteConvert)(value));
00243         }
00244       return true;
00245     }
00246     
00247 
00273     DataType read()
00274     {
00275       if (m_OnRead != NULL) (*m_OnRead)();      
00276 
00277       long int timeout = m_readTimeout;
00278 
00279       timeval tm_cur, tm_pre;
00280       ACE_Time_Value tt;
00281       tt = ACE_OS::gettimeofday();
00282       tm_pre = tt.operator timeval();
00283 
00284       // blocking and timeout wait
00285       while (m_readBlock && this->isEmpty())
00286         {
00287           if (m_readTimeout < 0)
00288             {
00289               usleep(TIMEOUT_TICK_USEC);
00290               continue;
00291             }
00292 
00293           // timeout wait
00294           ACE_Time_Value tt;
00295           tt = ACE_OS::gettimeofday();
00296           tm_cur = tt.operator timeval();
00297           long int sec (tm_cur.tv_sec  - tm_pre.tv_sec);
00298           long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00299 
00300           timeout -= (sec * USEC_PER_SEC + usec);
00301           if (timeout < 0) break;
00302 
00303           tm_pre = tm_cur;
00304           usleep(TIMEOUT_TICK_USEC);
00305         }
00306 
00307       if (this->isEmpty() && m_OnUnderflow != NULL)
00308         {
00309           m_value = (*m_OnUnderflow)();
00310           return m_value;
00311         }
00312 
00313       if (m_OnReadConvert == NULL) 
00314         {
00315           m_value = this->get();
00316           return m_value;
00317         }
00318       else
00319         {
00320           m_value = (*m_OnReadConvert)(this->get());
00321           return m_value;
00322         }
00323       // never comes here
00324       return m_value;
00325     }
00326 
00327 
00328 
00342     virtual void init(DataType& value)
00343     {
00344       //      m_buffer.init(value);
00345     }
00346     
00347     
00364     void update()
00365     {
00366       try
00367         {
00368           m_value = this->get();
00369         }
00370       catch (...)
00371         {
00372           if (m_OnUnderflow != NULL) (*m_OnUnderflow)();
00373         }
00374       return;
00375     };
00376     
00377     
00393     void operator>>(DataType& rhs)
00394     {
00395       rhs = read();
00396       return;
00397     }
00398     
00399 
00400     void operator<<(DataType& value)
00401     {
00402       write(value);
00403       return;
00404     }
00405 
00406     
00418     /*
00419     virtual int getNewDataLen()
00420     {
00421       return m_buffer->new_data_len();
00422     }
00423     */    
00424     
00436     /*
00437     virtual std::vector<T> getNewList()
00438     {
00439       return m_buffer.get_new_list();
00440     }
00441     */
00442     
00454     /*
00455     virtual std::vector<T> getNewListReverse()
00456     {
00457       return m_buffer.get_new_rlist();
00458     }
00459     */
00460 
00487     inline void setOnWrite(OnWrite<DataType>* on_write)
00488     {
00489       m_OnWrite = on_write;
00490     }
00491 
00492     inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00493     {
00494       m_OnWriteConvert = on_wconvert;
00495     }
00496 
00497     inline void setOnRead(OnRead<DataType>* on_read)
00498     {
00499       m_OnRead = on_read;
00500     }
00501 
00502     inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00503     {
00504       m_OnReadConvert = on_rconvert;
00505     }
00506 
00507     inline void setOnOverflow(OnOverflow<DataType>* on_overflow)
00508     {
00509       m_OnOverflow = on_overflow;
00510     }
00511 
00512     inline void setOnUnderflow(OnUnderflow<DataType>* on_underflow)
00513     {
00514       m_OnUnderflow = on_underflow;
00515     }
00516 
00517 
00518   private:
00526     std::string m_name;
00527 
00535     DataType& m_value;
00536     
00544     //    Buffer<DataType> m_buffer;
00545 
00546     bool m_readBlock;
00547     long int m_readTimeout;
00548     bool m_writeBlock;
00549     long int m_writeTimeout;
00550 
00558     OnWrite<DataType>* m_OnWrite;
00559 
00567     OnWriteConvert<DataType>* m_OnWriteConvert;
00568 
00576     OnRead<DataType>* m_OnRead;
00577 
00585     OnReadConvert<DataType>* m_OnReadConvert;
00586 
00594     OnOverflow<DataType>* m_OnOverflow;
00595 
00604     OnUnderflow<DataType>* m_OnUnderflow;
00605 
00606     
00607   };
00608   
00609 }; // End of namesepace RTM
00610 
00611 #endif // RtcInPort_h

Generated on Fri Oct 5 05:15:59 2007 for OpenRTM by  doxygen 1.4.1