00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef ORO_EXECUTION_BUFFER_PORT_HPP
00040 #define ORO_EXECUTION_BUFFER_PORT_HPP
00041
00042 #include <string>
00043 #include "PortInterface.hpp"
00044 #include "BufferConnection.hpp"
00045 #include "OperationInterface.hpp"
00046 #include "Method.hpp"
00047 #include "TaskObject.hpp"
00048
00049 namespace RTT
00050 {
00051 template<class T>
00052 class BufferPortBase
00053 : public PortInterface
00054 {
00055 protected:
00056 mutable typename BufferConnection<T>::shared_ptr mconn;
00057
00061 virtual bool connect( typename ConnectionInterface::shared_ptr conn) {
00062 if ( mconn || !conn )
00063 return false;
00064 mconn = boost::dynamic_pointer_cast< BufferConnection<T> >(conn);
00065 return (mconn);
00066 }
00067
00068 public:
00073 BufferPortBase(const std::string& name) : PortInterface(name), mconn() {}
00074
00075 ~BufferPortBase() {
00076 if (mconn)
00077 mconn->removePort(this);
00078 }
00079
00083 void clear() {
00084 #ifndef ORO_EMBEDDED
00085 try {
00086 #endif
00087 if ( mconn )
00088 return mconn->buffer()->clear();
00089 #ifndef ORO_EMBEDDED
00090 } catch (...) {
00091 mconn = 0;
00092 }
00093 #endif
00094 }
00095
00101 BufferBase::size_type size() const {
00102 #ifndef ORO_EMBEDDED
00103 try {
00104 #endif
00105 if ( mconn )
00106 return mconn->buffer()->size();
00107 #ifndef ORO_EMBEDDED
00108 } catch (...) {
00109 mconn = 0;
00110 }
00111 #endif
00112 return 0;
00113 }
00114
00120 BufferBase::size_type capacity() const {
00121 #ifndef ORO_EMBEDDED
00122 try {
00123 #endif
00124 if ( mconn )
00125 return mconn->buffer()->capacity();
00126 #ifndef ORO_EMBEDDED
00127 } catch (...) {
00128 mconn = 0;
00129 }
00130 #endif
00131 return 0;
00132 }
00133
00138 bool empty() const {
00139 #ifndef ORO_EMBEDDED
00140 try {
00141 #endif
00142 if ( mconn )
00143 return mconn->buffer()->empty();
00144 #ifndef ORO_EMBEDDED
00145 } catch (...) {
00146 mconn = 0;
00147 }
00148 #endif
00149 return true;
00150 }
00151
00156 bool full() const {
00157 #ifndef ORO_EMBEDDED
00158 try {
00159 #endif
00160 if ( mconn )
00161 return mconn->buffer()->full();
00162 #ifndef ORO_EMBEDDED
00163 } catch (...) {
00164 mconn = 0;
00165 }
00166 #endif
00167 return false;
00168 }
00169
00170 virtual ConnectionModel getConnectionModel() const { return Buffered; }
00171
00172 virtual const TypeInfo* getTypeInfo() const { return detail::DataSourceTypeInfo<T>::getTypeInfo(); }
00173
00178 BufferPortBase<T>& operator=(BufferInterface<T>* impl);
00179
00180 bool connected() const { return mconn; };
00181
00182 void disconnect() {
00183 mconn = 0;
00184 }
00185
00186 using PortInterface::connectTo;
00187 bool connectTo( ConnectionInterface::shared_ptr other) {
00188 return other && !mconn && other->addPort( this );
00189 }
00190
00195 virtual BufferInterface<T>* buffer() { return mconn ? mconn->buffer() : 0; }
00196
00197 virtual const BufferInterface<T>* buffer() const { return mconn ? mconn->buffer() : 0; }
00198
00199 virtual ConnectionInterface::shared_ptr connection() const { return mconn; }
00200
00201 ConnectionInterface::shared_ptr createConnection(BufferBase::shared_ptr impl) {
00202 typename BufferInterface<T>::shared_ptr buf = boost::dynamic_pointer_cast< BufferInterface<T> >( impl );
00203 ConnectionInterface::shared_ptr ci( new BufferConnection<T>( buf ) );
00204 ci->addPort(this);
00205 return ci;
00206 }
00207
00208 virtual TaskObject* createPortObject() {
00209 #ifndef ORO_EMBEDDED
00210 TaskObject* to = new TaskObject( this->getName() );
00211 to->methods()->addMethod( method("ready",&PortInterface::ready, this),
00212 "Check if this port is connected and ready for use.");
00213 to->methods()->addMethod(method("size", &BufferPortBase<T>::size, this),
00214 "Get the used size of the buffer.");
00215 to->methods()->addMethod(method("capacity", &BufferPortBase<T>::capacity, this),
00216 "Get the capacity of the buffer.");
00217 to->methods()->addMethod(method("empty", &BufferPortBase<T>::empty, this),
00218 "Inspect if the buffer is empty.");
00219 to->methods()->addMethod(method("full", &BufferPortBase<T>::full, this),
00220 "Inspect if the buffer is full.");
00221 to->methods()->addMethod(method("clear", &BufferPortBase<T>::clear, this),
00222 "Clear the contents of the buffer.");
00223 return to;
00224 #else
00225 return 0;
00226 #endif
00227 }
00228 };
00229
00237 template<class T>
00238 class ReadBufferPort
00239 : public BufferPortBase<T>
00240 {
00241 using BufferPortBase<T>::mconn;
00242 public:
00243 using BufferPortBase<T>::operator=;
00244
00249 ReadBufferPort(const std::string& name) : BufferPortBase<T>(name){}
00250
00257 bool Pop(T& data)
00258 {
00259 #ifndef ORO_EMBEDDED
00260 try {
00261 #endif
00262 if ( mconn )
00263 return mconn->buffer()->Pop(data);
00264 #ifndef ORO_EMBEDDED
00265 } catch (...) {
00266 mconn = 0;
00267 }
00268 #endif
00269 return false;
00270 }
00271
00276 T front() const {
00277 #ifndef ORO_EMBEDDED
00278 try {
00279 #endif
00280 if ( mconn )
00281 return mconn->buffer()->front();
00282 #ifndef ORO_EMBEDDED
00283 } catch (...) {
00284 mconn = 0;
00285 }
00286 #endif
00287 return T();
00288 }
00289
00290 virtual PortInterface::PortType getPortType() const { return PortInterface::ReadPort; }
00291
00292 virtual PortInterface* clone() const {
00293 return new ReadBufferPort<T>( this->getName() );
00294 }
00295
00300 virtual PortInterface* antiClone() const;
00301
00302 virtual TaskObject* createPortObject() {
00303 #ifndef ORO_EMBEDDED
00304 TaskObject* to = BufferPortBase<T>::createPortObject();
00305 to->methods()->addMethod(method("Pop", &ReadBufferPort<T>::Pop, this),
00306 "Pop a single value from the Buffer. Returns false if empty.",
00307 "Val", "The value returned by argument.");
00308 to->methods()->addMethod(method("front", &ReadBufferPort<T>::front, this),
00309 "Get the next to be popped value from the buffer. Returns default value if buffer is empty.");
00310 return to;
00311 #else
00312 return 0;
00313 #endif
00314 }
00315 };
00316
00324 template<class T>
00325 class WriteBufferPort
00326 : public BufferPortBase<T>
00327 {
00328 protected:
00329 size_t buf_size;
00330
00331 T minitial_value;
00332 using BufferPortBase<T>::mconn;
00333 public:
00334 using BufferPortBase<T>::operator=;
00342 WriteBufferPort(const std::string& name, size_t preferred_size, const T& initial_value = T() )
00343 : BufferPortBase<T>(name), buf_size(preferred_size), minitial_value(initial_value) {}
00344
00350 void setBufferSize(size_t b_size) { buf_size = b_size; }
00351
00358 bool Push(const T& data)
00359 {
00360 #ifndef ORO_EMBEDDED
00361 try {
00362 #endif
00363 if ( mconn && mconn->buffer()->Push(data) ) {
00364 mconn->signal();
00365 return true;
00366 }
00367
00368 #ifndef ORO_EMBEDDED
00369 } catch (...) {
00370 mconn = 0;
00371 }
00372 #endif
00373 return false;
00374 }
00375
00382 void Set(const T& data)
00383 {
00384 minitial_value = data;
00385 }
00386
00387 virtual PortInterface::PortType getPortType() const { return PortInterface::WritePort; }
00388
00389 ConnectionInterface::shared_ptr createConnection(ConnectionTypes::ConnectionType con_type = ConnectionTypes::lockfree);
00390
00391 virtual PortInterface* clone() const {
00392 return new WriteBufferPort<T>( this->getName(), buf_size, minitial_value );
00393 }
00394
00395 virtual PortInterface* antiClone() const {
00396 return new ReadBufferPort<T>( this->getName() );
00397 }
00398
00399 virtual TaskObject* createPortObject() {
00400 #ifndef ORO_EMBEDDED
00401 TaskObject* to = BufferPortBase<T>::createPortObject();
00402 to->methods()->addMethod(method("Push", &WriteBufferPort<T>::Push, this),
00403 "Push a single value in the Buffer. Returns false if full().",
00404 "Val", "The value.");
00405 return to;
00406 #else
00407 return 0;
00408 #endif
00409 }
00410 };
00411
00412
00421 template<class T>
00422 class BufferPort
00423 : public BufferPortBase<T>
00424 {
00425 protected:
00426 size_t buf_size;
00427
00428 T minitial_value;
00429 using BufferPortBase<T>::mconn;
00430 public:
00431 using BufferPortBase<T>::operator=;
00432
00433 typedef PortInterface::PortType PortType;
00434 typedef PortInterface::ConnectionModel ConnectionModel;
00435
00440 BufferPort(const std::string& name, size_t prefered_size, const T& initial_value = T())
00441 : BufferPortBase<T>(name), buf_size(prefered_size), minitial_value(initial_value)
00442 {}
00443
00449 void setBufferSize(size_t b_size) { buf_size = b_size; }
00450
00457 bool Pop(T& data)
00458 {
00459 #ifndef ORO_EMBEDDED
00460 try {
00461 #endif
00462 if ( mconn )
00463 return mconn->buffer()->Pop(data);
00464 #ifndef ORO_EMBEDDED
00465 } catch (...) {
00466 mconn = 0;
00467 }
00468 #endif
00469 return false;
00470 }
00471
00476 T front() const {
00477 #ifndef ORO_EMBEDDED
00478 try {
00479 #endif
00480 if ( mconn )
00481 return mconn->buffer()->front();
00482 #ifndef ORO_EMBEDDED
00483 } catch (...) {
00484 mconn = 0;
00485 }
00486 #endif
00487 return T();
00488 }
00489
00496 bool Push(const T& data)
00497 {
00498 #ifndef ORO_EMBEDDED
00499 try {
00500 #endif
00501 if ( mconn && mconn->buffer()->Push(data) ) {
00502 mconn->signal();
00503 return true;
00504 }
00505 #ifndef ORO_EMBEDDED
00506 } catch (...) {
00507 mconn = 0;
00508 }
00509 #endif
00510 return false;
00511 }
00512
00519 void Set(const T& data)
00520 {
00521 minitial_value = data;
00522 }
00523
00524
00525 virtual PortInterface::PortType getPortType() const { return PortInterface::ReadWritePort; }
00526
00527 virtual PortInterface* clone() const {
00528 return new BufferPort<T>( this->getName(), this->buf_size, this->minitial_value );
00529 }
00530
00531 virtual PortInterface* antiClone() const {
00532 return this->clone();
00533 }
00534
00535 virtual TaskObject* createPortObject() {
00536 #ifndef ORO_EMBEDDED
00537 TaskObject* to = BufferPortBase<T>::createPortObject();
00538 to->methods()->addMethod(method("Push", &BufferPort<T>::Push, this),
00539 "Push a single value in the Buffer. Returns false if full().",
00540 "Val", "The value.");
00541 to->methods()->addMethod(method("Pop", &BufferPort<T>::Pop, this),
00542 "Pop a single value from the Buffer. Returns false if empty.",
00543 "Val", "The value returned by argument.");
00544 to->methods()->addMethod(method("front", &BufferPort<T>::front, this),
00545 "Get the next to be popped value from the buffer. Returns default value if buffer is empty.");
00546 return to;
00547 #else
00548 return 0;
00549 #endif
00550 }
00551
00552 ConnectionInterface::shared_ptr createConnection(ConnectionTypes::ConnectionType con_type);
00553 };
00554 }
00555 #endif
00556
00557 #ifndef ORO_BUFFER_PORT_INLINE
00558 #define ORO_BUFFER_PORT_INLINE
00559
00560 #include "ConnectionFactory.hpp"
00561 #include "BufferConnection.hpp"
00562
00563 namespace RTT
00564 {
00565
00566 template<class T>
00567 PortInterface* ReadBufferPort<T>::antiClone() const {
00568 return new WriteBufferPort<T>( this->getName(), 1 );
00569 }
00570
00571 template<class T>
00572 BufferPortBase<T>& BufferPortBase<T>::operator=(BufferInterface<T>* impl)
00573 {
00574 if ( !mconn ) {
00575 ConnectionInterface::shared_ptr con = new BufferConnection<T>( typename BufferInterface<T>::shared_ptr(impl) );
00576 this->connectTo(con);
00577 con->connect();
00578 } else
00579 mconn->setImplementation(impl);
00580 return *this;
00581 }
00582
00583 template<class T>
00584 ConnectionInterface::shared_ptr WriteBufferPort<T>::createConnection(ConnectionTypes::ConnectionType con_type )
00585 {
00586 ConnectionFactory<T> cf;
00587 ConnectionInterface::shared_ptr res = cf.createBuffer(buf_size, minitial_value, con_type);
00588 res->addPort(this);
00589 return res;
00590 }
00591
00592 template<class T>
00593 ConnectionInterface::shared_ptr BufferPort<T>::createConnection(ConnectionTypes::ConnectionType con_type )
00594 {
00595 ConnectionFactory<T> cf;
00596 ConnectionInterface::shared_ptr res = cf.createBuffer(buf_size, minitial_value, con_type);
00597 res->addPort(this);
00598 return res;
00599 }
00600 }
00601 #endif