OutPort.h

説明を見る。
00001 // -*- C++ -*-
00020 #ifndef OutPort_h
00021 #define OutPort_h
00022 
00023 #include <rtm/BufferBase.h>
00024 #include <rtm/RingBuffer.h>
00025 #include <rtm/OutPortBase.h>
00026 #include <rtm/PortCallBack.h>
00027 #include <rtm/RTC.h>
00028 #include <iostream>
00029 
00030 namespace RTC
00031 {
00056   template <class DataType,
00057             template <class DataType> class Buffer = RingBuffer >
00058   class OutPort
00059     : public OutPortBase,
00060       public Buffer<DataType>
00061   {
00062   public:
00086     OutPort(const char* name, DataType& value, long int length = 8)
00087       : OutPortBase(name), Buffer<DataType>(length),
00088         m_value(value),
00089         m_timeoutTick(1000), // timeout tick: 1ms
00090         m_readBlock(false), m_readTimeout(0),
00091         m_writeBlock(false), m_writeTimeout(0),
00092         m_OnWrite(NULL), m_OnWriteConvert(NULL),
00093         m_OnRead(NULL),  m_OnReadConvert(NULL),
00094         m_OnOverflow(NULL), m_OnUnderflow(NULL)
00095     {
00096     }
00097     
00113     virtual ~OutPort()
00114     {
00115     }
00116     
00158     virtual bool write(const DataType& value)
00159     {
00160       if (m_OnWrite != NULL)
00161         {
00162           (*m_OnWrite)(value);
00163         }
00164       
00165       long int timeout = m_writeTimeout;
00166       
00167       timeval tm_cur, tm_pre;
00168       ACE_Time_Value tt;
00169       tt = ACE_OS::gettimeofday();
00170       tm_pre = tt.operator timeval();
00171       
00172       // blocking and timeout wait
00173       long int count(0);
00174       while (m_writeBlock && this->isFull())
00175         {
00176           if (m_writeTimeout < 0) 
00177             {
00178               usleep(m_timeoutTick);
00179               continue;
00180             }
00181           
00182           // timeout wait
00183           ACE_Time_Value tt;
00184           tt = ACE_OS::gettimeofday();
00185           tm_cur = tt.operator timeval();
00186           long int sec (tm_cur.tv_sec  - tm_pre.tv_sec);
00187           long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00188           
00189           timeout -= (sec * usec_per_sec + usec);
00190           if (timeout < 0) break;
00191           
00192           tm_pre = tm_cur;
00193           usleep(m_timeoutTick);
00194           ++count;
00195         }
00196       
00197       if (this->isFull())
00198         {
00199           if (m_OnOverflow != NULL)
00200             (*m_OnOverflow)(value);
00201           return false;
00202         }
00203       
00204       if (m_OnWriteConvert == NULL) 
00205         {
00206           this->put(value);
00207         }
00208       else
00209         {
00210           this->put((*m_OnWriteConvert)(value));
00211         }
00212       notify();
00213       return true;
00214     }
00215     
00237     bool write()
00238     {
00239       return write(m_value);
00240     }
00241     
00267     bool operator<<(DataType& value)
00268     {
00269       return write(value);
00270     }
00271     
00319     bool read(DataType& value)
00320     {
00321       if (m_OnRead != NULL) (*m_OnRead)();      
00322       
00323       long int timeout = m_readTimeout;
00324       timeval tm_cur, tm_pre;
00325       ACE_Time_Value tt;
00326       tt = ACE_OS::gettimeofday();
00327       tm_pre = tt.operator timeval();
00328       
00329       // blocking and timeout wait
00330       while (m_readBlock && this->isEmpty())
00331         {
00332           if (m_readTimeout < 0)
00333             {
00334               usleep(m_timeoutTick);
00335               continue;
00336             }
00337           
00338           // timeout wait
00339           ACE_Time_Value tt;
00340           tt = ACE_OS::gettimeofday();
00341           tm_cur = tt.operator timeval();
00342           long int sec (tm_cur.tv_sec  - tm_pre.tv_sec);
00343           long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00344           
00345           timeout -= (sec * usec_per_sec + usec);
00346           if (timeout < 0) break;
00347           
00348           tm_pre = tm_cur;
00349           usleep(m_timeoutTick);
00350         }
00351       
00352       if (this->isEmpty())
00353         {
00354           if (m_OnUnderflow != NULL)
00355             {
00356               value = (*m_OnUnderflow)();
00357               return false;
00358             }
00359           else
00360             {
00361               return false;
00362             }
00363         }
00364       
00365       if (m_OnReadConvert == NULL) 
00366         {
00367           value = this->get();
00368           return true;
00369         }
00370       else
00371         {
00372           value = (*m_OnReadConvert)(this->get());
00373           return true;
00374         }
00375       // never comes here
00376       return false;
00377     }
00378     
00402     void setReadBlock(bool block)
00403     {
00404       m_readBlock = block;
00405     }
00406     
00431     void setWriteBlock(bool block)
00432     {
00433       m_writeBlock = block;
00434     }
00435     
00459     void setReadTimeout(long int timeout)
00460     {
00461       m_readTimeout = timeout;
00462     }
00463     
00485     void setWriteTimeout(long int timeout)
00486     {
00487       m_writeTimeout = timeout;
00488     }
00489     
00509     inline void setOnWrite(OnWrite<DataType>* on_write)
00510     {
00511       m_OnWrite = on_write;
00512     }
00513     
00538     inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00539     {
00540       m_OnWriteConvert = on_wconvert;
00541     }
00542     
00564     inline void setOnOverflow(OnOverflow<DataType>* on_overflow)
00565     {
00566       m_OnOverflow = on_overflow;
00567     }
00568     
00589     inline void setOnRead(OnRead<DataType>* on_read)
00590     {
00591       m_OnRead = on_read;
00592     }
00593     
00618     inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00619     {
00620       m_OnReadConvert = on_rconvert;
00621     }
00622     
00644     inline void setOnUnderflow(OnUnderflow<DataType>* on_underflow)
00645     {
00646       m_OnUnderflow = on_underflow;
00647     }    
00648     
00649   private:
00657     DataType& m_value;
00658     
00666     long int m_timeoutTick;
00667     
00675     bool m_readBlock;
00676     
00684     long int m_readTimeout;
00685     
00693     bool m_writeBlock;
00694     
00702     long int m_writeTimeout;
00703     
00711     OnWrite<DataType>* m_OnWrite;
00712     
00720     OnWriteConvert<DataType>* m_OnWriteConvert;
00721     
00729     OnRead<DataType>* m_OnRead;
00730     
00738     OnReadConvert<DataType>* m_OnReadConvert;
00739     
00747     OnOverflow<DataType>* m_OnOverflow;
00748     
00757     OnUnderflow<DataType>* m_OnUnderflow;
00758     
00759     static const long int usec_per_sec = 1000000;
00760   };
00761 }; // namespace RTC
00762 
00763 #endif // OutPort_h

OpenRTMに対してWed May 21 05:17:25 2008に生成されました。  doxygen 1.5.3