00001 
00020 #ifndef RTC_INPORT_H
00021 #define RTC_INPORT_H
00022 
00023 #include <string>
00024 #include <vector>
00025 #include <iostream>
00026 
00027 #include <coil/TimeValue.h>
00028 #include <coil/Time.h>
00029 #include <coil/OS.h>
00030 
00031 #include <rtm/RTC.h>
00032 #include <rtm/Typename.h>
00033 #include <rtm/InPortBase.h>
00034 #include <rtm/CdrBufferBase.h>
00035 #include <rtm/PortCallback.h>
00036 #include <rtm/InPortConnector.h>
00037 
00038 namespace RTC
00039 {
00174   template <class DataType>
00175   class InPort
00176     : public InPortBase
00177   {
00178   public:
00179     DATAPORTSTATUS_ENUM
00231     InPort(const char* name, DataType& value,
00232            int bufsize=64, 
00233            bool read_block = false, bool write_block = false,
00234            int read_timeout = 0, int write_timeout = 0)
00235       : InPortBase(name, toTypename<DataType>()),
00236         m_name(name), m_value(value),
00237         m_OnRead(NULL),  m_OnReadConvert(NULL)
00238     {
00239     }
00240     
00256     virtual ~InPort(void){};
00257 
00277     virtual const char* name()
00278     {
00279       return m_name.c_str();
00280     }
00281 
00282     
00307     virtual bool isNew()
00308     {
00309       RTC_TRACE(("isNew()"));
00310 
00311       
00312       
00313       
00314       int r(0);
00315       {
00316         Guard guard(m_connectorsMutex);
00317         if (m_connectors.size() == 0)
00318           {
00319             RTC_DEBUG(("no connectors"));
00320             return false;
00321           }
00322         r = m_connectors[0]->getBuffer()->readable();
00323       }
00324       
00325       if (r > 0)
00326         {
00327           RTC_DEBUG(("isNew() = true, readable data: %d", r));
00328           return true;
00329         }
00330       
00331       RTC_DEBUG(("isNew() = false, no readable data"));
00332       return false;
00333     }
00334 
00358     virtual bool isEmpty()
00359     {
00360       RTC_TRACE(("isEmpty()"));
00361       int r(0);
00362 
00363       {
00364         Guard guard(m_connectorsMutex);
00365         if (m_connectors.size() == 0)
00366           {
00367             RTC_DEBUG(("no connectors"));
00368             return true;
00369           }
00370         
00371         
00372         
00373         r = m_connectors[0]->getBuffer()->readable();
00374       }
00375 
00376       if (r == 0)
00377         {
00378           RTC_DEBUG(("isEmpty() = true, buffer is empty"));
00379           return true;
00380         }
00381       
00382       RTC_DEBUG(("isEmpty() = false, data exists in the buffer"));
00383       return false;
00384     }
00385 
00460     bool read()
00461     {
00462       RTC_TRACE(("DataType read()"));
00463 
00464       if (m_OnRead != NULL) 
00465         {
00466           (*m_OnRead)();
00467           RTC_TRACE(("OnRead called"));
00468         }
00469 
00470       cdrMemoryStream cdr;
00471       ReturnCode ret;
00472       {
00473         Guard guard(m_connectorsMutex);
00474         if (m_connectors.size() == 0)
00475           {
00476             RTC_DEBUG(("no connectors"));
00477             return false;
00478           }
00479         
00480         
00481         
00482         
00483         ret = m_connectors[0]->read(cdr);
00484       }
00485       if (ret == PORT_OK)
00486         {
00487           RTC_DEBUG(("data read succeeded"));
00488           m_value <<= cdr;
00489           if (m_OnReadConvert != 0) 
00490             {
00491               m_value = (*m_OnReadConvert)(m_value);
00492               RTC_DEBUG(("OnReadConvert called"));
00493               return true;
00494             }
00495           return true;
00496         }
00497       else if (ret == BUFFER_EMPTY)
00498         {
00499           RTC_WARN(("buffer empty"));
00500           return false;
00501         }
00502       else if (ret == BUFFER_TIMEOUT)
00503         {
00504           RTC_WARN(("buffer read timeout"));
00505           return false;
00506         }
00507       RTC_ERROR(("unknown retern value from buffer.read()"));
00508       return false;
00509     }
00510     
00511 
00534     virtual void update()
00535     {
00536       this->read();
00537     };
00538     
00559     void operator>>(DataType& rhs)
00560     {
00561       this->read();
00562       rhs = m_value;
00563       return;
00564     }
00565     
00587     inline void setOnRead(OnRead<DataType>* on_read)
00588     {
00589       m_OnRead = on_read;
00590     }
00591     
00615     inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00616     {
00617       m_OnReadConvert = on_rconvert;
00618     }
00619     
00620   private:
00621     std::string m_typename;
00629     std::string m_name;
00630     
00638     DataType& m_value;
00639     
00647     OnRead<DataType>* m_OnRead;
00648     
00656     OnReadConvert<DataType>* m_OnReadConvert;
00657    
00658   };
00659 }; 
00660 
00661 #endif // RTC_INPORT_H