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 #ifndef RtcInPort_h
00046 #define RtcInPort_h
00047
00048 #include <string>
00049 #include <vector>
00050 #include <iostream>
00051
00052 #include <rtm/BufferBase.h>
00053 #include <rtm/PortCallBack.h>
00054
00055 #define TIMEOUT_TICK_USEC 10
00056 #define USEC_PER_SEC 1000000
00057
00058 namespace RTC
00059 {
00092 template <class DataType,
00093 template <class DataType> class Buffer = NullBuffer >
00094 class InPort
00095 : public Buffer<DataType>
00096 {
00097 public:
00123 InPort(const char* name, DataType& value,
00124 int bufsize=64,
00125 bool read_block = false, bool write_block = false,
00126 int read_timeout = 0, int write_timeout = 0)
00127 : Buffer<DataType>(bufsize),
00128 m_name(name), m_value(value),
00129 m_readBlock(read_block), m_readTimeout(read_timeout),
00130 m_writeBlock(write_block), m_writeTimeout(write_timeout),
00131 m_OnWrite(NULL), m_OnWriteConvert(NULL),
00132 m_OnRead(NULL), m_OnReadConvert(NULL),
00133 m_OnOverflow(NULL), m_OnUnderflow(NULL)
00134 {
00135 };
00136
00137
00151 virtual ~InPort(){};
00152
00153
00154
00155 virtual const char* name()
00156 {
00157 return m_name.c_str();
00158 }
00159
00160
00186 bool write(const DataType& value)
00187 {
00188 if (m_OnWrite != NULL) (*m_OnWrite)(value);
00189
00190 long int timeout = m_writeTimeout;
00191
00192 timeval tm_cur, tm_pre;
00193 gettimeofday(&tm_pre, NULL);
00194
00195
00196 while (m_writeBlock && this->isFull())
00197 {
00198 if (m_writeTimeout < 0)
00199 {
00200 usleep(TIMEOUT_TICK_USEC);
00201 continue;
00202 }
00203
00204
00205 gettimeofday(&tm_cur, NULL);
00206 long int sec (tm_cur.tv_sec - tm_pre.tv_sec);
00207 long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00208
00209 timeout -= (sec * USEC_PER_SEC + usec);
00210 if (timeout < 0) break;
00211
00212 tm_pre = tm_cur;
00213 usleep(TIMEOUT_TICK_USEC);
00214 }
00215
00216 if (this->isFull() && m_OnOverflow != NULL)
00217 {
00218 (*m_OnOverflow)(value);
00219 return false;
00220 }
00221
00222 if (m_OnWriteConvert == NULL)
00223 {
00224 this->put(value);
00225 }
00226 else
00227 {
00228 this->put((*m_OnWriteConvert)(value));
00229 }
00230 return true;
00231 }
00232
00233
00259 DataType read()
00260 {
00261 if (m_OnRead != NULL) (*m_OnRead)();
00262
00263 long int timeout = m_readTimeout;
00264
00265 timeval tm_cur, tm_pre;
00266 gettimeofday(&tm_pre, NULL);
00267
00268
00269 while (m_readBlock && this->isEmpty())
00270 {
00271 if (m_readTimeout < 0)
00272 {
00273 usleep(TIMEOUT_TICK_USEC);
00274 continue;
00275 }
00276
00277
00278 gettimeofday(&tm_cur, NULL);
00279 long int sec (tm_cur.tv_sec - tm_pre.tv_sec);
00280 long int usec(tm_cur.tv_usec - tm_pre.tv_usec);
00281
00282 timeout -= (sec * USEC_PER_SEC + usec);
00283 if (timeout < 0) break;
00284
00285 tm_pre = tm_cur;
00286 usleep(TIMEOUT_TICK_USEC);
00287 }
00288
00289 if (this->isEmpty() && m_OnUnderflow != NULL)
00290 {
00291 m_value = (*m_OnUnderflow)();
00292 return m_value;
00293 }
00294
00295 if (m_OnReadConvert == NULL)
00296 {
00297 m_value = this->get();
00298 return m_value;
00299 }
00300 else
00301 {
00302 m_value = (*m_OnReadConvert)(this->get());
00303 return m_value;
00304 }
00305
00306 return m_value;
00307 }
00308
00309
00310
00324 virtual void init(DataType& value)
00325 {
00326
00327 }
00328
00329
00346 void update()
00347 {
00348 try
00349 {
00350 m_value = this->get();
00351 }
00352 catch (...)
00353 {
00354 if (m_OnUnderflow != NULL) (*m_OnUnderflow)();
00355 }
00356 return;
00357 };
00358
00359
00375 void operator>>(DataType& rhs)
00376 {
00377 rhs = read();
00378 return;
00379 }
00380
00381
00382 void operator<<(DataType& value)
00383 {
00384 write(value);
00385 return;
00386 }
00387
00388
00400
00401
00402
00403
00404
00405
00406
00418
00419
00420
00421
00422
00423
00424
00436
00437
00438
00439
00440
00441
00442
00469 inline void setOnWrite(OnWrite<DataType>* on_write)
00470 {
00471 m_OnWrite = on_write;
00472 }
00473
00474 inline void setOnWriteConvert(OnWriteConvert<DataType>* on_wconvert)
00475 {
00476 m_OnWriteConvert = on_wconvert;
00477 }
00478
00479 inline void setOnRead(OnRead<DataType>* on_read)
00480 {
00481 m_OnRead = on_read;
00482 }
00483
00484 inline void setOnReadConvert(OnReadConvert<DataType>* on_rconvert)
00485 {
00486 m_OnReadConvert = on_rconvert;
00487 }
00488
00489 inline void setOnOverflow(OnOverflow<DataType>* on_overflow)
00490 {
00491 m_OnOverflow = on_overflow;
00492 }
00493
00494 inline void setOnUnderflow(OnUnderflow<DataType>* on_underflow)
00495 {
00496 m_OnUnderflow = on_underflow;
00497 }
00498
00499
00500 private:
00508 std::string m_name;
00509
00517 DataType& m_value;
00518
00526
00527
00528 bool m_readBlock;
00529 long int m_readTimeout;
00530 bool m_writeBlock;
00531 long int m_writeTimeout;
00532
00540 OnWrite<DataType>* m_OnWrite;
00541
00549 OnWriteConvert<DataType>* m_OnWriteConvert;
00550
00558 OnRead<DataType>* m_OnRead;
00559
00567 OnReadConvert<DataType>* m_OnReadConvert;
00568
00576 OnOverflow<DataType>* m_OnOverflow;
00577
00586 OnUnderflow<DataType>* m_OnUnderflow;
00587
00588
00589 };
00590
00591 };
00592
00593 #endif // RtcInPort_h