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 #ifndef RtcInPort_h
00049 #define RtcInPort_h
00050
00051 #include <string>
00052 #include <vector>
00053 #include <iostream>
00054
00055 #include <rtm/BufferBase.h>
00056 #include <rtm/PortCallBack.h>
00057 #include <rtm/RTC.h>
00058
00059 #define TIMEOUT_TICK_USEC 10
00060 #define USEC_PER_SEC 1000000
00061
00062 namespace RTC
00063 {
00096 template <class DataType,
00097 template <class DataType> class Buffer = NullBuffer >
00098 class InPort
00099 : public Buffer<DataType>
00100 {
00101 public:
00127 InPort(const char* name, DataType& value,
00128 int bufsize=64,
00129 bool read_block = false, bool write_block = false,
00130 int read_timeout = 0, int write_timeout = 0)
00131 : Buffer<DataType>(bufsize),
00132 m_name(name), m_value(value),
00133 m_readBlock(read_block), m_readTimeout(read_timeout),
00134 m_writeBlock(write_block), m_writeTimeout(write_timeout),
00135 m_OnWrite(NULL), m_OnWriteConvert(NULL),
00136 m_OnRead(NULL), m_OnReadConvert(NULL),
00137 m_OnOverflow(NULL), m_OnUnderflow(NULL)
00138 {
00139 };
00140
00141
00155 virtual ~InPort(){};
00156
00157
00158
00159 virtual const char* name()
00160 {
00161 return m_name.c_str();
00162 }
00163
00164
00190 bool write(const DataType& value)
00191 {
00192 if (m_OnWrite != NULL) (*m_OnWrite)(value);
00193
00194 long int timeout = m_writeTimeout;
00195
00196 timeval tm_cur, tm_pre;
00197 ACE_Time_Value tt;
00198 tt = ACE_OS::gettimeofday();
00199 tm_pre = tt.operator timeval();
00200
00201
00202 while (m_writeBlock && this->isFull())
00203 {
00204 if (m_writeTimeout < 0)
00205 {
00206 usleep(TIMEOUT_TICK_USEC);
00207 continue;
00208 }
00209
00210
00211 ACE_Time_Value tt;
00212 tt = ACE_OS::gettimeofday();
00213 tm_cur = tt.operator timeval();
00214 long int sec (tm_cur.tv_sec - tm_pre.tv_sec);
00215 long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00216
00217 timeout -= (sec * USEC_PER_SEC + usec);
00218 if (timeout < 0) break;
00219
00220 tm_pre = tm_cur;
00221 usleep(TIMEOUT_TICK_USEC);
00222 }
00223
00224 if (this->isFull() && m_OnOverflow != NULL)
00225 {
00226 (*m_OnOverflow)(value);
00227 return false;
00228 }
00229
00230 if (m_OnWriteConvert == NULL)
00231 {
00232 this->put(value);
00233 }
00234 else
00235 {
00236 this->put((*m_OnWriteConvert)(value));
00237 }
00238 return true;
00239 }
00240
00241
00267 DataType read()
00268 {
00269 if (m_OnRead != NULL) (*m_OnRead)();
00270
00271 long int timeout = m_readTimeout;
00272
00273 timeval tm_cur, tm_pre;
00274 ACE_Time_Value tt;
00275 tt = ACE_OS::gettimeofday();
00276 tm_pre = tt.operator timeval();
00277
00278
00279 while (m_readBlock && this->isEmpty())
00280 {
00281 if (m_readTimeout < 0)
00282 {
00283 usleep(TIMEOUT_TICK_USEC);
00284 continue;
00285 }
00286
00287
00288 ACE_Time_Value tt;
00289 tt = ACE_OS::gettimeofday();
00290 tm_cur = tt.operator timeval();
00291 long int sec (tm_cur.tv_sec - tm_pre.tv_sec);
00292 long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00293
00294 timeout -= (sec * USEC_PER_SEC + usec);
00295 if (timeout < 0) break;
00296
00297 tm_pre = tm_cur;
00298 usleep(TIMEOUT_TICK_USEC);
00299 }
00300
00301 if (this->isEmpty() && m_OnUnderflow != NULL)
00302 {
00303 m_value = (*m_OnUnderflow)();
00304 return m_value;
00305 }
00306
00307 if (m_OnReadConvert == NULL)
00308 {
00309 m_value = this->get();
00310 return m_value;
00311 }
00312 else
00313 {
00314 m_value = (*m_OnReadConvert)(this->get());
00315 return m_value;
00316 }
00317
00318 return m_value;
00319 }
00320
00321
00322
00336 virtual void init(DataType& value)
00337 {
00338
00339 }
00340
00341
00358 void update()
00359 {
00360 try
00361 {
00362 m_value = this->get();
00363 }
00364 catch (...)
00365 {
00366 if (m_OnUnderflow != NULL) (*m_OnUnderflow)();
00367 }
00368 return;
00369 };
00370
00371
00387 void operator>>(DataType& rhs)
00388 {
00389 rhs = read();
00390 return;
00391 }
00392
00393
00394 void operator<<(DataType& value)
00395 {
00396 write(value);
00397 return;
00398 }
00399
00400
00412
00413
00414
00415
00416
00417
00418
00430
00431
00432
00433
00434
00435
00436
00448
00449
00450
00451
00452
00453
00454
00481 inline void setOnWrite(OnWrite<DataType>* on_write)
00482 {
00483 m_OnWrite = on_write;
00484 }
00485
00486 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00487 {
00488 m_OnWriteConvert = on_wconvert;
00489 }
00490
00491 inline void setOnRead(OnRead<DataType>* on_read)
00492 {
00493 m_OnRead = on_read;
00494 }
00495
00496 inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00497 {
00498 m_OnReadConvert = on_rconvert;
00499 }
00500
00501 inline void setOnOverflow(OnOverflow<DataType>* on_overflow)
00502 {
00503 m_OnOverflow = on_overflow;
00504 }
00505
00506 inline void setOnUnderflow(OnUnderflow<DataType>* on_underflow)
00507 {
00508 m_OnUnderflow = on_underflow;
00509 }
00510
00511
00512 private:
00520 std::string m_name;
00521
00529 DataType& m_value;
00530
00538
00539
00540 bool m_readBlock;
00541 long int m_readTimeout;
00542 bool m_writeBlock;
00543 long int m_writeTimeout;
00544
00552 OnWrite<DataType>* m_OnWrite;
00553
00561 OnWriteConvert<DataType>* m_OnWriteConvert;
00562
00570 OnRead<DataType>* m_OnRead;
00571
00579 OnReadConvert<DataType>* m_OnReadConvert;
00580
00588 OnOverflow<DataType>* m_OnOverflow;
00589
00598 OnUnderflow<DataType>* m_OnUnderflow;
00599
00600
00601 };
00602
00603 };
00604
00605 #endif // RtcInPort_h