00001
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
00246 while (m_writeBlock && this->isFull())
00247 {
00248 if (m_writeTimeout < 0)
00249 {
00250 usleep(TIMEOUT_TICK_USEC);
00251 continue;
00252 }
00253
00254
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
00340 while (m_readBlock && this->isEmpty())
00341 {
00342 if (m_readTimeout < 0)
00343 {
00344 usleep(TIMEOUT_TICK_USEC);
00345 continue;
00346 }
00347
00348
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
00379 return m_value;
00380 }
00381
00403 virtual void init(DataType& value)
00404 {
00405
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
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
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
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 };
00821
00822 #endif // RtcInPort_h