00001
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #ifndef RtcInPort_h
00055 #define RtcInPort_h
00056
00057 #include <string>
00058 #include <vector>
00059 #include <iostream>
00060 #include <rtm/BufferBase.h>
00061 #include <rtm/RingBuffer.h>
00062 #include <rtm/PortCallBack.h>
00063 #include <rtm/RTC.h>
00064
00065 #define TIMEOUT_TICK_USEC 10
00066 #define USEC_PER_SEC 1000000
00067
00068 namespace RTC
00069 {
00102 template <class DataType,
00103 template <class DataType> class Buffer = RingBuffer >
00104 class InPort
00105 : public Buffer<DataType>
00106 {
00107 public:
00133 InPort(const char* name, DataType& value,
00134 int bufsize=64,
00135 bool read_block = false, bool write_block = false,
00136 int read_timeout = 0, int write_timeout = 0)
00137 : Buffer<DataType>(bufsize),
00138 m_name(name), m_value(value),
00139 m_readBlock(read_block), m_readTimeout(read_timeout),
00140 m_writeBlock(write_block), m_writeTimeout(write_timeout),
00141 m_OnWrite(NULL), m_OnWriteConvert(NULL),
00142 m_OnRead(NULL), m_OnReadConvert(NULL),
00143 m_OnOverflow(NULL), m_OnUnderflow(NULL)
00144 {
00145 };
00146
00147
00161 virtual ~InPort(){};
00162
00163
00164
00165 virtual const char* name()
00166 {
00167 return m_name.c_str();
00168 }
00169
00170
00196 bool write(const DataType& value)
00197 {
00198 if (m_OnWrite != NULL) (*m_OnWrite)(value);
00199
00200 long int timeout = m_writeTimeout;
00201
00202 timeval tm_cur, tm_pre;
00203 ACE_Time_Value tt;
00204 tt = ACE_OS::gettimeofday();
00205 tm_pre = tt.operator timeval();
00206
00207
00208 while (m_writeBlock && this->isFull())
00209 {
00210 if (m_writeTimeout < 0)
00211 {
00212 usleep(TIMEOUT_TICK_USEC);
00213 continue;
00214 }
00215
00216
00217 ACE_Time_Value tt;
00218 tt = ACE_OS::gettimeofday();
00219 tm_cur = tt.operator timeval();
00220 long int sec (tm_cur.tv_sec - tm_pre.tv_sec);
00221 long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00222
00223 timeout -= (sec * USEC_PER_SEC + usec);
00224 if (timeout < 0) break;
00225
00226 tm_pre = tm_cur;
00227 usleep(TIMEOUT_TICK_USEC);
00228 }
00229
00230 if (this->isFull() && m_OnOverflow != NULL)
00231 {
00232 (*m_OnOverflow)(value);
00233 return false;
00234 }
00235
00236 if (m_OnWriteConvert == NULL)
00237 {
00238 this->put(value);
00239 }
00240 else
00241 {
00242 this->put((*m_OnWriteConvert)(value));
00243 }
00244 return true;
00245 }
00246
00247
00273 DataType read()
00274 {
00275 if (m_OnRead != NULL) (*m_OnRead)();
00276
00277 long int timeout = m_readTimeout;
00278
00279 timeval tm_cur, tm_pre;
00280 ACE_Time_Value tt;
00281 tt = ACE_OS::gettimeofday();
00282 tm_pre = tt.operator timeval();
00283
00284
00285 while (m_readBlock && this->isEmpty())
00286 {
00287 if (m_readTimeout < 0)
00288 {
00289 usleep(TIMEOUT_TICK_USEC);
00290 continue;
00291 }
00292
00293
00294 ACE_Time_Value tt;
00295 tt = ACE_OS::gettimeofday();
00296 tm_cur = tt.operator timeval();
00297 long int sec (tm_cur.tv_sec - tm_pre.tv_sec);
00298 long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00299
00300 timeout -= (sec * USEC_PER_SEC + usec);
00301 if (timeout < 0) break;
00302
00303 tm_pre = tm_cur;
00304 usleep(TIMEOUT_TICK_USEC);
00305 }
00306
00307 if (this->isEmpty() && m_OnUnderflow != NULL)
00308 {
00309 m_value = (*m_OnUnderflow)();
00310 return m_value;
00311 }
00312
00313 if (m_OnReadConvert == NULL)
00314 {
00315 m_value = this->get();
00316 return m_value;
00317 }
00318 else
00319 {
00320 m_value = (*m_OnReadConvert)(this->get());
00321 return m_value;
00322 }
00323
00324 return m_value;
00325 }
00326
00327
00328
00342 virtual void init(DataType& value)
00343 {
00344
00345 }
00346
00347
00364 void update()
00365 {
00366 try
00367 {
00368 m_value = this->get();
00369 }
00370 catch (...)
00371 {
00372 if (m_OnUnderflow != NULL) (*m_OnUnderflow)();
00373 }
00374 return;
00375 };
00376
00377
00393 void operator>>(DataType& rhs)
00394 {
00395 rhs = read();
00396 return;
00397 }
00398
00399
00400 void operator<<(DataType& value)
00401 {
00402 write(value);
00403 return;
00404 }
00405
00406
00418
00419
00420
00421
00422
00423
00424
00436
00437
00438
00439
00440
00441
00442
00454
00455
00456
00457
00458
00459
00460
00487 inline void setOnWrite(OnWrite<DataType>* on_write)
00488 {
00489 m_OnWrite = on_write;
00490 }
00491
00492 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00493 {
00494 m_OnWriteConvert = on_wconvert;
00495 }
00496
00497 inline void setOnRead(OnRead<DataType>* on_read)
00498 {
00499 m_OnRead = on_read;
00500 }
00501
00502 inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00503 {
00504 m_OnReadConvert = on_rconvert;
00505 }
00506
00507 inline void setOnOverflow(OnOverflow<DataType>* on_overflow)
00508 {
00509 m_OnOverflow = on_overflow;
00510 }
00511
00512 inline void setOnUnderflow(OnUnderflow<DataType>* on_underflow)
00513 {
00514 m_OnUnderflow = on_underflow;
00515 }
00516
00517
00518 private:
00526 std::string m_name;
00527
00535 DataType& m_value;
00536
00544
00545
00546 bool m_readBlock;
00547 long int m_readTimeout;
00548 bool m_writeBlock;
00549 long int m_writeTimeout;
00550
00558 OnWrite<DataType>* m_OnWrite;
00559
00567 OnWriteConvert<DataType>* m_OnWriteConvert;
00568
00576 OnRead<DataType>* m_OnRead;
00577
00585 OnReadConvert<DataType>* m_OnReadConvert;
00586
00594 OnOverflow<DataType>* m_OnOverflow;
00595
00604 OnUnderflow<DataType>* m_OnUnderflow;
00605
00606
00607 };
00608
00609 };
00610
00611 #endif // RtcInPort_h