InPort.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00020 #ifndef RtcInPort_h
00021 #define RtcInPort_h
00022 
00023 #include <string>
00024 #include <vector>
00025 #include <iostream>
00026 #include <rtm/BufferBase.h>
00027 #include <rtm/RingBuffer.h>
00028 #include <rtm/PortCallBack.h>
00029 #include <rtm/RTC.h>
00030 
00031 #define TIMEOUT_TICK_USEC 10
00032 #define USEC_PER_SEC 1000000
00033 
00034 namespace RTC
00035 {
00074   template <class DataType,
00075             template <class DataType> class Buffer = RingBuffer >
00076   class InPort
00077     : public Buffer<DataType>
00078   {
00079   public:
00131     InPort(const char* name, DataType& value,
00132            int bufsize=64, 
00133            bool read_block = false, bool write_block = false,
00134            int read_timeout = 0, int write_timeout = 0)
00135       : Buffer<DataType>(bufsize),
00136         m_name(name), m_value(value),
00137         m_readBlock(read_block),   m_readTimeout(read_timeout),
00138         m_writeBlock(write_block), m_writeTimeout(write_timeout),
00139         m_OnWrite(NULL), m_OnWriteConvert(NULL),
00140         m_OnRead(NULL),  m_OnReadConvert(NULL),
00141         m_OnOverflow(NULL), m_OnUnderflow(NULL)
00142     {
00143     };
00144     
00160     virtual ~InPort(){};
00161     
00181     virtual const char* name()
00182     {
00183       return m_name.c_str();
00184     }
00185     
00234     bool write(const DataType& value)
00235     {
00236       if (m_OnWrite != NULL) (*m_OnWrite)(value);      
00237       
00238       long int timeout = m_writeTimeout;
00239       
00240       timeval tm_cur, tm_pre;
00241       ACE_Time_Value tt;
00242       tt = ACE_OS::gettimeofday();
00243       tm_pre = tt.operator timeval();
00244       
00245       // blocking and timeout wait
00246       while (m_writeBlock && this->isFull())
00247         {
00248           if (m_writeTimeout < 0) 
00249             {
00250               usleep(TIMEOUT_TICK_USEC);
00251               continue;
00252             }
00253           
00254           // timeout wait
00255           ACE_Time_Value tt;
00256           tt = ACE_OS::gettimeofday();
00257           tm_cur = tt.operator timeval();
00258           long int sec (tm_cur.tv_sec  - tm_pre.tv_sec);
00259           long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00260           
00261           timeout -= (sec * USEC_PER_SEC + usec);
00262           if (timeout < 0) break;
00263           
00264           tm_pre = tm_cur;
00265           usleep(TIMEOUT_TICK_USEC);
00266         }
00267       
00268       if (this->isFull() && m_OnOverflow != NULL)
00269         {
00270           (*m_OnOverflow)(value);
00271           return false;
00272         }
00273       
00274       if (m_OnWriteConvert == NULL) 
00275         {
00276           this->put(value);
00277         }
00278       else
00279         {
00280           this->put((*m_OnWriteConvert)(value));
00281         }
00282       return true;
00283     }
00284     
00328     DataType read()
00329     {
00330       if (m_OnRead != NULL) (*m_OnRead)();
00331       
00332       long int timeout = m_readTimeout;
00333       
00334       timeval tm_cur, tm_pre;
00335       ACE_Time_Value tt;
00336       tt = ACE_OS::gettimeofday();
00337       tm_pre = tt.operator timeval();
00338       
00339       // blocking and timeout wait
00340       while (m_readBlock && this->isEmpty())
00341         {
00342           if (m_readTimeout < 0)
00343             {
00344               usleep(TIMEOUT_TICK_USEC);
00345               continue;
00346             }
00347           
00348           // timeout wait
00349           ACE_Time_Value tt;
00350           tt = ACE_OS::gettimeofday();
00351           tm_cur = tt.operator timeval();
00352           long int sec (tm_cur.tv_sec  - tm_pre.tv_sec);
00353           long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00354           
00355           timeout -= (sec * USEC_PER_SEC + usec);
00356           if (timeout < 0) break;
00357           
00358           tm_pre = tm_cur;
00359           usleep(TIMEOUT_TICK_USEC);
00360         }
00361       
00362       if (this->isEmpty() && m_OnUnderflow != NULL)
00363         {
00364           m_value = (*m_OnUnderflow)();
00365           return m_value;
00366         }
00367       
00368       if (m_OnReadConvert == NULL) 
00369         {
00370           m_value = this->get();
00371           return m_value;
00372         }
00373       else
00374         {
00375           m_value = (*m_OnReadConvert)(this->get());
00376           return m_value;
00377         }
00378       // never comes here
00379       return m_value;
00380     }
00381     
00403     virtual void init(DataType& value)
00404     {
00405       //      m_buffer.init(value);
00406     }
00407     
00430     void update()
00431     {
00432       try
00433         {
00434           m_value = this->get();
00435         }
00436       catch (...)
00437         {
00438           if (m_OnUnderflow != NULL) (*m_OnUnderflow)();
00439         }
00440       return;
00441     };
00442     
00463     void operator>>(DataType& rhs)
00464     {
00465       rhs = read();
00466       return;
00467     }
00468     
00488     void operator<<(DataType& value)
00489     {
00490       write(value);
00491       return;
00492     }
00493     
00494     /***
00495      * @if jp
00496      *
00497      * @brief 未読の新しいデータ数を取得する
00498      *
00499      * @else
00500      *
00501      * @brief Get number of new unread data
00502      *
00503      * @endif
00504      */
00505     /*
00506       virtual int getNewDataLen()
00507       {
00508       return m_buffer->new_data_len();
00509       }
00510     */
00511     
00512     /***
00513      * @if jp
00514      *
00515      * @brief 未読の新しいデータを取得する
00516      *
00517      * @else
00518      *
00519      * @brief Get new unread data
00520      *
00521      * @endif
00522      */
00523     /*
00524       virtual std::vector<T> getNewList()
00525       {
00526       return m_buffer.get_new_list();
00527       }
00528     */
00529     
00530     /***
00531      * @if jp
00532      *
00533      * @brief 未読の新しいデータを逆順(新->古)で取得する
00534      *
00535      * @else
00536      *
00537      * @brief Get new unread data backwards by date (new->old)
00538      *
00539      * @endif
00540      */
00541     /*
00542       virtual std::vector<T> getNewListReverse()
00543       {
00544       return m_buffer.get_new_rlist();
00545       }
00546     */
00547     
00593     inline void setOnWrite(OnWrite<DataType>* on_write)
00594     {
00595       m_OnWrite = on_write;
00596     }
00597     
00621     inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00622     {
00623       m_OnWriteConvert = on_wconvert;
00624     }
00625     
00647     inline void setOnRead(OnRead<DataType>* on_read)
00648     {
00649       m_OnRead = on_read;
00650     }
00651     
00675     inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00676     {
00677       m_OnReadConvert = on_rconvert;
00678     }
00679     
00701     inline void setOnOverflow(OnOverflow<DataType>* on_overflow)
00702     {
00703       m_OnOverflow = on_overflow;
00704     }
00705     
00727     inline void setOnUnderflow(OnUnderflow<DataType>* on_underflow)
00728     {
00729       m_OnUnderflow = on_underflow;
00730     }
00731     
00732   private:
00740     std::string m_name;
00741     
00749     DataType& m_value;
00750     
00758     //    Buffer<DataType> m_buffer;
00759     
00760     bool m_readBlock;
00761     long int m_readTimeout;
00762     bool m_writeBlock;
00763     long int m_writeTimeout;
00764     
00772     OnWrite<DataType>* m_OnWrite;
00773     
00781     OnWriteConvert<DataType>* m_OnWriteConvert;
00782     
00790     OnRead<DataType>* m_OnRead;
00791     
00799     OnReadConvert<DataType>* m_OnReadConvert;
00800     
00808     OnOverflow<DataType>* m_OnOverflow;
00809     
00818     OnUnderflow<DataType>* m_OnUnderflow;
00819   };
00820 }; // End of namesepace RTM
00821 
00822 #endif // RtcInPort_h

Generated on Wed May 21 05:17:34 2008 for OpenRTM by  doxygen 1.5.3