OpenRTM
1.0.0
|
00001 // -*- C++ -*- 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 { 00088 template <class DataType> 00089 class InPort 00090 : public InPortBase 00091 { 00092 public: 00093 DATAPORTSTATUS_ENUM 00145 InPort(const char* name, DataType& value, 00146 int bufsize=64, 00147 bool read_block = false, bool write_block = false, 00148 int read_timeout = 0, int write_timeout = 0) 00149 #if defined(__GNUC__) && (__GNUC__ <= 3 && __GNUC_MINOR__ <= 3) 00150 : InPortBase(name, ::CORBA_Util::toRepositoryIdOfStruct<DataType>()), 00151 #else 00152 : InPortBase(name, ::CORBA_Util::toRepositoryId<DataType>()), 00153 #endif 00154 m_name(name), m_value(value), 00155 m_OnRead(NULL), m_OnReadConvert(NULL) 00156 { 00157 } 00158 00174 virtual ~InPort(void){}; 00175 00195 virtual const char* name() 00196 { 00197 return m_name.c_str(); 00198 } 00199 00200 00225 virtual bool isNew() 00226 { 00227 RTC_TRACE(("isNew()")); 00228 00229 // In single-buffer mode, all connectors share the same buffer. This 00230 // means that we only need to read from the first connector to get data 00231 // received by any connector. 00232 int r(0); 00233 { 00234 Guard guard(m_connectorsMutex); 00235 if (m_connectors.size() == 0) 00236 { 00237 RTC_DEBUG(("no connectors")); 00238 return false; 00239 } 00240 r = m_connectors[0]->getBuffer()->readable(); 00241 } 00242 00243 if (r > 0) 00244 { 00245 RTC_DEBUG(("isNew() = true, readable data: %d", r)); 00246 return true; 00247 } 00248 00249 RTC_DEBUG(("isNew() = false, no readable data")); 00250 return false; 00251 } 00252 00276 virtual bool isEmpty() 00277 { 00278 RTC_TRACE(("isEmpty()")); 00279 int r(0); 00280 00281 { 00282 Guard guard(m_connectorsMutex); 00283 if (m_connectors.size() == 0) 00284 { 00285 RTC_DEBUG(("no connectors")); 00286 return true; 00287 } 00288 // In single-buffer mode, all connectors share the same buffer. This 00289 // means that we only need to read from the first connector to get data 00290 // received by any connector. 00291 r = m_connectors[0]->getBuffer()->readable(); 00292 } 00293 00294 if (r == 0) 00295 { 00296 RTC_DEBUG(("isEmpty() = true, buffer is empty")); 00297 return true; 00298 } 00299 00300 RTC_DEBUG(("isEmpty() = false, data exists in the buffer")); 00301 return false; 00302 } 00303 00378 bool read() 00379 { 00380 RTC_TRACE(("DataType read()")); 00381 00382 if (m_OnRead != NULL) 00383 { 00384 (*m_OnRead)(); 00385 RTC_TRACE(("OnRead called")); 00386 } 00387 00388 cdrMemoryStream cdr; 00389 ReturnCode ret; 00390 { 00391 Guard guard(m_connectorsMutex); 00392 if (m_connectors.size() == 0) 00393 { 00394 RTC_DEBUG(("no connectors")); 00395 return false; 00396 } 00397 00398 // In single-buffer mode, all connectors share the same buffer. This 00399 // means that we only need to read from the first connector to get data 00400 // received by any connector. 00401 ret = m_connectors[0]->read(cdr); 00402 } 00403 if (ret == PORT_OK) 00404 { 00405 RTC_DEBUG(("data read succeeded")); 00406 m_value <<= cdr; 00407 if (m_OnReadConvert != 0) 00408 { 00409 m_value = (*m_OnReadConvert)(m_value); 00410 RTC_DEBUG(("OnReadConvert called")); 00411 return true; 00412 } 00413 return true; 00414 } 00415 else if (ret == BUFFER_EMPTY) 00416 { 00417 RTC_WARN(("buffer empty")); 00418 return false; 00419 } 00420 else if (ret == BUFFER_TIMEOUT) 00421 { 00422 RTC_WARN(("buffer read timeout")); 00423 return false; 00424 } 00425 RTC_ERROR(("unknown retern value from buffer.read()")); 00426 return false; 00427 } 00428 00429 00452 virtual void update() 00453 { 00454 this->read(); 00455 }; 00456 00477 void operator>>(DataType& rhs) 00478 { 00479 this->read(); 00480 rhs = m_value; 00481 return; 00482 } 00483 00505 inline void setOnRead(OnRead<DataType>* on_read) 00506 { 00507 m_OnRead = on_read; 00508 } 00509 00533 inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert) 00534 { 00535 m_OnReadConvert = on_rconvert; 00536 } 00537 00538 private: 00539 std::string m_typename; 00547 std::string m_name; 00548 00556 DataType& m_value; 00557 00565 OnRead<DataType>* m_OnRead; 00566 00574 OnReadConvert<DataType>* m_OnReadConvert; 00575 00576 }; 00577 }; // End of namesepace RTM 00578 00579 #endif // RTC_INPORT_H