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 #if defined(__GNUC__) && (__GNUC__ <= 3 && __GNUC_MINOR__ <= 3)
00236 : InPortBase(name, ::CORBA_Util::toRepositoryIdOfStruct<DataType>()),
00237 #else
00238 : InPortBase(name, ::CORBA_Util::toRepositoryId<DataType>()),
00239 #endif
00240 m_name(name), m_value(value),
00241 m_OnRead(NULL), m_OnReadConvert(NULL)
00242 {
00243 }
00244
00260 virtual ~InPort(void){};
00261
00281 virtual const char* name()
00282 {
00283 return m_name.c_str();
00284 }
00285
00286
00311 virtual bool isNew()
00312 {
00313 RTC_TRACE(("isNew()"));
00314
00315
00316
00317
00318 int r(0);
00319 {
00320 Guard guard(m_connectorsMutex);
00321 if (m_connectors.size() == 0)
00322 {
00323 RTC_DEBUG(("no connectors"));
00324 return false;
00325 }
00326 r = m_connectors[0]->getBuffer()->readable();
00327 }
00328
00329 if (r > 0)
00330 {
00331 RTC_DEBUG(("isNew() = true, readable data: %d", r));
00332 return true;
00333 }
00334
00335 RTC_DEBUG(("isNew() = false, no readable data"));
00336 return false;
00337 }
00338
00362 virtual bool isEmpty()
00363 {
00364 RTC_TRACE(("isEmpty()"));
00365 int r(0);
00366
00367 {
00368 Guard guard(m_connectorsMutex);
00369 if (m_connectors.size() == 0)
00370 {
00371 RTC_DEBUG(("no connectors"));
00372 return true;
00373 }
00374
00375
00376
00377 r = m_connectors[0]->getBuffer()->readable();
00378 }
00379
00380 if (r == 0)
00381 {
00382 RTC_DEBUG(("isEmpty() = true, buffer is empty"));
00383 return true;
00384 }
00385
00386 RTC_DEBUG(("isEmpty() = false, data exists in the buffer"));
00387 return false;
00388 }
00389
00464 bool read()
00465 {
00466 RTC_TRACE(("DataType read()"));
00467
00468 if (m_OnRead != NULL)
00469 {
00470 (*m_OnRead)();
00471 RTC_TRACE(("OnRead called"));
00472 }
00473
00474 cdrMemoryStream cdr;
00475 ReturnCode ret;
00476 {
00477 Guard guard(m_connectorsMutex);
00478 if (m_connectors.size() == 0)
00479 {
00480 RTC_DEBUG(("no connectors"));
00481 return false;
00482 }
00483
00484
00485
00486
00487 ret = m_connectors[0]->read(cdr);
00488 }
00489 if (ret == PORT_OK)
00490 {
00491 RTC_DEBUG(("data read succeeded"));
00492 m_value <<= cdr;
00493 if (m_OnReadConvert != 0)
00494 {
00495 m_value = (*m_OnReadConvert)(m_value);
00496 RTC_DEBUG(("OnReadConvert called"));
00497 return true;
00498 }
00499 return true;
00500 }
00501 else if (ret == BUFFER_EMPTY)
00502 {
00503 RTC_WARN(("buffer empty"));
00504 return false;
00505 }
00506 else if (ret == BUFFER_TIMEOUT)
00507 {
00508 RTC_WARN(("buffer read timeout"));
00509 return false;
00510 }
00511 RTC_ERROR(("unknown retern value from buffer.read()"));
00512 return false;
00513 }
00514
00515
00538 virtual void update()
00539 {
00540 this->read();
00541 };
00542
00563 void operator>>(DataType& rhs)
00564 {
00565 this->read();
00566 rhs = m_value;
00567 return;
00568 }
00569
00591 inline void setOnRead(OnRead<DataType>* on_read)
00592 {
00593 m_OnRead = on_read;
00594 }
00595
00619 inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00620 {
00621 m_OnReadConvert = on_rconvert;
00622 }
00623
00624 private:
00625 std::string m_typename;
00633 std::string m_name;
00634
00642 DataType& m_value;
00643
00651 OnRead<DataType>* m_OnRead;
00652
00660 OnReadConvert<DataType>* m_OnReadConvert;
00661
00662 };
00663 };
00664
00665 #endif // RTC_INPORT_H