00001
00020 #ifndef RtcInPort_h
00021 #define RtcInPort_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 {
00078 template <class DataType>
00079 class InPort
00080 : public InPortBase
00081 {
00082 public:
00083 DATAPORTSTATUS_ENUM
00135 InPort(const char* name, DataType& value,
00136 int bufsize=64,
00137 bool read_block = false, bool write_block = false,
00138 int read_timeout = 0, int write_timeout = 0)
00139 : InPortBase(name, toTypename<DataType>()),
00140 m_name(name), m_value(value),
00141 m_readBlock(read_block), m_readTimeout(read_timeout),
00142 m_writeBlock(write_block), m_writeTimeout(write_timeout),
00143 m_OnWrite(NULL), m_OnWriteConvert(NULL),
00144 m_OnRead(NULL), m_OnReadConvert(NULL),
00145 m_OnOverflow(NULL), m_OnUnderflow(NULL)
00146 {
00147 }
00148
00164 virtual ~InPort(void){};
00165
00185 virtual const char* name()
00186 {
00187 return m_name.c_str();
00188 }
00189
00190
00215 virtual bool isNew()
00216 {
00217 RTC_TRACE(("isNew()"));
00218 if (m_connectors.size() == 0)
00219 {
00220 RTC_DEBUG(("no connectors"));
00221 return false;
00222 }
00223 int r(m_connectors[0]->getBuffer()->readable());
00224 if (r > 0)
00225 {
00226 RTC_DEBUG(("isNew() = true, readable data: %d", r));
00227 return true;
00228 }
00229
00230 RTC_DEBUG(("isNew() = false, no readable data"));
00231 return false;
00232 }
00233
00257 virtual bool isEmpty()
00258 {
00259 RTC_TRACE(("isEmpty()"));
00260
00261 if (m_connectors.size() == 0)
00262 {
00263 RTC_DEBUG(("no connectors"));
00264 return true;
00265 }
00266 int r(m_connectors[0]->getBuffer()->readable());
00267 if (r == 0)
00268 {
00269 RTC_DEBUG(("isEmpty() = true, buffer is empty"));
00270 return true;
00271 }
00272
00273 RTC_DEBUG(("isEmpty() = false, data exists in the buffer"));
00274 return false;
00275 }
00276
00351 DataType read()
00352 {
00353 RTC_TRACE(("DataType read()"))
00354
00355 if (m_OnRead != NULL)
00356 {
00357 (*m_OnRead)();
00358 RTC_TRACE(("OnRead called"))
00359 }
00360
00361 if (m_connectors.size() == 0)
00362 {
00363 RTC_DEBUG(("no connectors"));
00364 return m_value;
00365 }
00366
00367 cdrMemoryStream cdr;
00368
00369 ReturnCode ret(m_connectors[0]->read(cdr));
00370 if (ret == PORT_OK)
00371 {
00372 RTC_DEBUG(("data read succeeded"));
00373 m_value <<= cdr;
00374 if (m_OnReadConvert != 0)
00375 {
00376 m_value = (*m_OnReadConvert)(m_value);
00377 RTC_DEBUG(("OnReadConvert called"));
00378 return m_value;
00379 }
00380 return m_value;
00381 }
00382 else if (ret == BUFFER_EMPTY)
00383 {
00384 RTC_WARN(("buffer empty"));
00385 return m_value;
00386 }
00387 else if (ret == BUFFER_TIMEOUT)
00388 {
00389 RTC_WARN(("buffer read timeout"));
00390 return m_value;
00391 }
00392 RTC_ERROR(("unknown retern value from buffer.read()"));
00393 return m_value;
00394 }
00395
00418 virtual void update()
00419 {
00420 this->read();
00421 };
00422
00443 void operator>>(DataType& rhs)
00444 {
00445 rhs = read();
00446 return;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00548 inline void setOnWrite(OnWrite<DataType>* on_write)
00549 {
00550 m_OnWrite = on_write;
00551 }
00552
00576 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00577 {
00578 m_OnWriteConvert = on_wconvert;
00579 }
00580
00602 inline void setOnRead(OnRead<DataType>* on_read)
00603 {
00604 m_OnRead = on_read;
00605 }
00606
00630 inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00631 {
00632 m_OnReadConvert = on_rconvert;
00633 }
00634
00656 inline void setOnOverflow(OnOverflow<DataType>* on_overflow)
00657 {
00658 m_OnOverflow = on_overflow;
00659 }
00660
00682 inline void setOnUnderflow(OnUnderflow<DataType>* on_underflow)
00683 {
00684 m_OnUnderflow = on_underflow;
00685 }
00686
00687 private:
00688 std::string m_typename;
00696 std::string m_name;
00697
00705 DataType& m_value;
00706
00707 bool m_readBlock;
00708 long int m_readTimeout;
00709 bool m_writeBlock;
00710 long int m_writeTimeout;
00711
00719 OnWrite<DataType>* m_OnWrite;
00720
00728 OnWriteConvert<DataType>* m_OnWriteConvert;
00729
00737 OnRead<DataType>* m_OnRead;
00738
00746 OnReadConvert<DataType>* m_OnReadConvert;
00747
00755 OnOverflow<DataType>* m_OnOverflow;
00756
00765 OnUnderflow<DataType>* m_OnUnderflow;
00766
00767
00768 };
00769 };
00770
00771 #endif // RtcInPort_h