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 #ifndef RtcInPort_h
00052 #define RtcInPort_h
00053
00054 #include <string>
00055 #include <vector>
00056 #include <iostream>
00057 #include <rtm/BufferBase.h>
00058 #include <rtm/RingBuffer.h>
00059 #include <rtm/PortCallBack.h>
00060 #include <rtm/RTC.h>
00061
00062 #define TIMEOUT_TICK_USEC 10
00063 #define USEC_PER_SEC 1000000
00064
00065 namespace RTC
00066 {
00099 template <class DataType,
00100 template <class DataType> class Buffer = RingBuffer >
00101 class InPort
00102 : public Buffer<DataType>
00103 {
00104 public:
00130 InPort(const char* name, DataType& value,
00131 int bufsize=64,
00132 bool read_block = false, bool write_block = false,
00133 int read_timeout = 0, int write_timeout = 0)
00134 : Buffer<DataType>(bufsize),
00135 m_name(name), m_value(value),
00136 m_readBlock(read_block), m_readTimeout(read_timeout),
00137 m_writeBlock(write_block), m_writeTimeout(write_timeout),
00138 m_OnWrite(NULL), m_OnWriteConvert(NULL),
00139 m_OnRead(NULL), m_OnReadConvert(NULL),
00140 m_OnOverflow(NULL), m_OnUnderflow(NULL)
00141 {
00142 };
00143
00144
00158 virtual ~InPort(){};
00159
00160
00161
00162 virtual const char* name()
00163 {
00164 return m_name.c_str();
00165 }
00166
00167
00193 bool write(const DataType& value)
00194 {
00195 if (m_OnWrite != NULL) (*m_OnWrite)(value);
00196
00197 long int timeout = m_writeTimeout;
00198
00199 timeval tm_cur, tm_pre;
00200 ACE_Time_Value tt;
00201 tt = ACE_OS::gettimeofday();
00202 tm_pre = tt.operator timeval();
00203
00204
00205 while (m_writeBlock && this->isFull())
00206 {
00207 if (m_writeTimeout < 0)
00208 {
00209 usleep(TIMEOUT_TICK_USEC);
00210 continue;
00211 }
00212
00213
00214 ACE_Time_Value tt;
00215 tt = ACE_OS::gettimeofday();
00216 tm_cur = tt.operator timeval();
00217 long int sec (tm_cur.tv_sec - tm_pre.tv_sec);
00218 long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00219
00220 timeout -= (sec * USEC_PER_SEC + usec);
00221 if (timeout < 0) break;
00222
00223 tm_pre = tm_cur;
00224 usleep(TIMEOUT_TICK_USEC);
00225 }
00226
00227 if (this->isFull() && m_OnOverflow != NULL)
00228 {
00229 (*m_OnOverflow)(value);
00230 return false;
00231 }
00232
00233 if (m_OnWriteConvert == NULL)
00234 {
00235 this->put(value);
00236 }
00237 else
00238 {
00239 this->put((*m_OnWriteConvert)(value));
00240 }
00241 return true;
00242 }
00243
00244
00270 DataType read()
00271 {
00272 if (m_OnRead != NULL) (*m_OnRead)();
00273
00274 long int timeout = m_readTimeout;
00275
00276 timeval tm_cur, tm_pre;
00277 ACE_Time_Value tt;
00278 tt = ACE_OS::gettimeofday();
00279 tm_pre = tt.operator timeval();
00280
00281
00282 while (m_readBlock && this->isEmpty())
00283 {
00284 if (m_readTimeout < 0)
00285 {
00286 usleep(TIMEOUT_TICK_USEC);
00287 continue;
00288 }
00289
00290
00291 ACE_Time_Value tt;
00292 tt = ACE_OS::gettimeofday();
00293 tm_cur = tt.operator timeval();
00294 long int sec (tm_cur.tv_sec - tm_pre.tv_sec);
00295 long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00296
00297 timeout -= (sec * USEC_PER_SEC + usec);
00298 if (timeout < 0) break;
00299
00300 tm_pre = tm_cur;
00301 usleep(TIMEOUT_TICK_USEC);
00302 }
00303
00304 if (this->isEmpty() && m_OnUnderflow != NULL)
00305 {
00306 m_value = (*m_OnUnderflow)();
00307 return m_value;
00308 }
00309
00310 if (m_OnReadConvert == NULL)
00311 {
00312 m_value = this->get();
00313 return m_value;
00314 }
00315 else
00316 {
00317 m_value = (*m_OnReadConvert)(this->get());
00318 return m_value;
00319 }
00320
00321 return m_value;
00322 }
00323
00324
00325
00339 virtual void init(DataType& value)
00340 {
00341
00342 }
00343
00344
00361 void update()
00362 {
00363 try
00364 {
00365 m_value = this->get();
00366 }
00367 catch (...)
00368 {
00369 if (m_OnUnderflow != NULL) (*m_OnUnderflow)();
00370 }
00371 return;
00372 };
00373
00374
00390 void operator>>(DataType& rhs)
00391 {
00392 rhs = read();
00393 return;
00394 }
00395
00396
00397 void operator<<(DataType& value)
00398 {
00399 write(value);
00400 return;
00401 }
00402
00403
00415
00416
00417
00418
00419
00420
00421
00433
00434
00435
00436
00437
00438
00439
00451
00452
00453
00454
00455
00456
00457
00484 inline void setOnWrite(OnWrite<DataType>* on_write)
00485 {
00486 m_OnWrite = on_write;
00487 }
00488
00489 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00490 {
00491 m_OnWriteConvert = on_wconvert;
00492 }
00493
00494 inline void setOnRead(OnRead<DataType>* on_read)
00495 {
00496 m_OnRead = on_read;
00497 }
00498
00499 inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00500 {
00501 m_OnReadConvert = on_rconvert;
00502 }
00503
00504 inline void setOnOverflow(OnOverflow<DataType>* on_overflow)
00505 {
00506 m_OnOverflow = on_overflow;
00507 }
00508
00509 inline void setOnUnderflow(OnUnderflow<DataType>* on_underflow)
00510 {
00511 m_OnUnderflow = on_underflow;
00512 }
00513
00514
00515 private:
00523 std::string m_name;
00524
00532 DataType& m_value;
00533
00541
00542
00543 bool m_readBlock;
00544 long int m_readTimeout;
00545 bool m_writeBlock;
00546 long int m_writeTimeout;
00547
00555 OnWrite<DataType>* m_OnWrite;
00556
00564 OnWriteConvert<DataType>* m_OnWriteConvert;
00565
00573 OnRead<DataType>* m_OnRead;
00574
00582 OnReadConvert<DataType>* m_OnReadConvert;
00583
00591 OnOverflow<DataType>* m_OnOverflow;
00592
00601 OnUnderflow<DataType>* m_OnUnderflow;
00602
00603
00604 };
00605
00606 };
00607
00608 #endif // RtcInPort_h