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 "BufferConnectionInterface.hpp"
00045 #include "OperationInterface.hpp"
00046 #include "Method.hpp"
00047
00048 namespace RTT
00049 {
00057 template<class T>
00058 class ReadBufferPort
00059 : public virtual PortInterface
00060 {
00061 protected:
00062 typename ReadConnectionInterface<T>::shared_ptr mconn;
00063 public:
00068 ReadBufferPort(const std::string& name) : PortInterface(name), mconn() {}
00069
00070 ~ReadBufferPort() {
00071 if (mconn)
00072 mconn->removeReader(this);
00073 }
00074
00081 bool Pop(T& data)
00082 {
00083 if (mconn)
00084 return mconn->read()->Pop(data);
00085 return false;
00086 }
00087
00092 T front() const {
00093 if (mconn)
00094 return mconn->read()->front();
00095 return T();
00096 }
00097
00101 void clear() {
00102 if (mconn)
00103 return mconn->read()->clear();
00104 }
00105
00111 BufferBase::size_type size() const {
00112 if (mconn)
00113 return mconn->read()->size();
00114 return 0;
00115 }
00116
00122 BufferBase::size_type capacity() const {
00123 if (mconn)
00124 return mconn->read()->capacity();
00125 return 0;
00126 }
00127
00132 bool empty() const {
00133 if (mconn)
00134 return mconn->read()->empty();
00135 return 0;
00136 }
00137
00142 bool full() const {
00143 if (mconn)
00144 return mconn->read()->full();
00145 return 0;
00146 }
00147
00148 virtual PortType getPortType() const { return ReadPort; }
00149
00150 virtual const TypeInfo* getTypeInfo() const { return detail::DataSourceTypeInfo<T>::getTypeInfo(); }
00151
00156 ReadBufferPort& operator=(BufferInterface<T>* impl);
00157
00158 bool connected() const { return mconn; };
00159
00163 virtual bool connect( typename ReadConnectionInterface<T>::shared_ptr conn) {
00164 if ( mconn || !conn )
00165 return false;
00166 mconn = conn;
00167 return true;
00168 }
00169
00170 void disconnect() {
00171 mconn = 0;
00172 }
00173
00174 using PortInterface::connectTo;
00175 bool connectTo( ConnectionInterface::shared_ptr other) {
00176 return other && !mconn && other->addReader( this );
00177 }
00178
00184 virtual ReadInterface<T>* read() const { return mconn ? mconn->read() : 0; }
00185
00186 virtual ConnectionInterface::shared_ptr connection() const { return mconn; }
00187
00188 virtual PortInterface* clone() const {
00189 return new ReadBufferPort<T>( this->getName() );
00190 }
00191
00196 virtual PortInterface* antiClone() const;
00197
00198 virtual TaskObject* createPortObject() {
00199 #ifndef ORO_EMBEDDED
00200 TaskObject* to = new TaskObject( this->getName() );
00201 to->methods()->addMethod( method("ready",&PortInterface::ready, this),
00202 "Check if this port is connected and ready for use.");
00203 to->methods()->addMethod(method("Pop", &ReadBufferPort<T>::Pop, this),
00204 "Pop a single value from the Buffer. Returns false if empty.",
00205 "Val", "The value returned by argument.");
00206 to->methods()->addMethod(method("front", &ReadBufferPort<T>::front, this),
00207 "Get the next to be popped value from the buffer. Returns default value if buffer is empty.");
00208 to->methods()->addMethod(method("size", &ReadBufferPort<T>::size, this),
00209 "Get the used size of the buffer.");
00210 to->methods()->addMethod(method("capacity", &ReadBufferPort<T>::capacity, this),
00211 "Get the capacity of the buffer.");
00212 to->methods()->addMethod(method("empty", &ReadBufferPort<T>::empty, this),
00213 "Inspect if the buffer is empty.");
00214 to->methods()->addMethod(method("full", &ReadBufferPort<T>::full, this),
00215 "Inspect if the buffer is full.");
00216 to->methods()->addMethod(method("clear", &ReadBufferPort<T>::clear, this),
00217 "Clear the contents of the buffer.");
00218 return to;
00219 #else
00220 return 0;
00221 #endif
00222 }
00223 };
00224
00232 template<class T>
00233 class WriteBufferPort
00234 : public virtual PortInterface
00235 {
00236 protected:
00240 typename WriteConnectionInterface<T>::shared_ptr mconn;
00241
00242 size_t buf_size;
00243
00244 T minitial_value;
00245 public:
00253 WriteBufferPort(const std::string& name, size_t preferred_size, const T& initial_value = T() )
00254 : PortInterface(name), mconn(), buf_size(preferred_size), minitial_value(initial_value) {}
00255
00256 ~WriteBufferPort() {
00257 if (mconn)
00258 mconn->removeWriter(this);
00259 }
00260
00266 void setBufferSize(size_t b_size) { buf_size = b_size; }
00267
00274 bool Push(const T& data)
00275 {
00276 if (mconn)
00277 return mconn->write()->Push(data);
00278 return false;
00279 }
00280
00287 void Set(const T& data)
00288 {
00289 minitial_value = data;
00290 }
00291
00295 void clear() {
00296 if (mconn)
00297 return mconn->write()->clear();
00298 }
00299
00305 BufferBase::size_type size() const {
00306 if (mconn)
00307 return mconn->write()->size();
00308 return 0;
00309 }
00310
00316 BufferBase::size_type capacity() const {
00317 if (mconn)
00318 return mconn->write()->capacity();
00319 return 0;
00320 }
00321
00326 bool empty() const {
00327 if (mconn)
00328 return mconn->write()->empty();
00329 return 0;
00330 }
00331
00336 bool full() const {
00337 if (mconn)
00338 return mconn->write()->full();
00339 return 0;
00340 }
00341
00342 bool connected() const { return mconn; };
00343
00347 virtual bool connect(typename WriteConnectionInterface<T>::shared_ptr conn) {
00348 if ( mconn || !conn )
00349 return false;
00350 mconn = conn;
00351 return true;
00352 }
00353
00354 using PortInterface::connectTo;
00355 bool connectTo( ConnectionInterface::shared_ptr other) {
00356 return other && !mconn && other->addWriter( this );
00357 }
00358
00359 void disconnect() {
00360 mconn = 0;
00361 }
00362
00367 virtual WriteInterface<T>* write() const { return mconn ? mconn->write() : 0; }
00368
00369 virtual ConnectionInterface::shared_ptr connection() const { return mconn; }
00370
00371 virtual PortType getPortType() const { return WritePort; }
00372
00373 virtual const TypeInfo* getTypeInfo() const { return detail::DataSourceTypeInfo<T>::getTypeInfo(); }
00374
00379 WriteBufferPort& operator=(BufferInterface<T>* impl);
00380
00381 ConnectionInterface::shared_ptr createConnection(PortInterface* other, ConnectionTypes::ConnectionType con_type = ConnectionTypes::lockfree);
00382
00383 ConnectionInterface::shared_ptr createConnection(ConnectionTypes::ConnectionType con_type = ConnectionTypes::lockfree);
00384
00385 virtual PortInterface* clone() const {
00386 return new WriteBufferPort<T>( this->getName(), buf_size, minitial_value );
00387 }
00388
00389 virtual PortInterface* antiClone() const {
00390 return new ReadBufferPort<T>( this->getName() );
00391 }
00392
00393 virtual TaskObject* createPortObject() {
00394 #ifndef ORO_EMBEDDED
00395 TaskObject* to = new TaskObject( this->getName() );
00396 to->methods()->addMethod( method("ready",&PortInterface::ready, this),
00397 "Check if this port is connected and ready for use.");
00398 to->methods()->addMethod(method("Push", &WriteBufferPort<T>::Push, this),
00399 "Push a single value in the Buffer. Returns false if full().",
00400 "Val", "The value.");
00401 to->methods()->addMethod(method("size", &WriteBufferPort<T>::size, this),
00402 "Get the used size of the buffer.");
00403 to->methods()->addMethod(method("capacity", &WriteBufferPort<T>::capacity, this),
00404 "Get the capacity of the buffer.");
00405 to->methods()->addMethod(method("empty", &WriteBufferPort<T>::empty, this),
00406 "Inspect if the buffer is empty.");
00407 to->methods()->addMethod(method("full", &WriteBufferPort<T>::full, this),
00408 "Inspect if the buffer is full.");
00409 to->methods()->addMethod(method("clear", &WriteBufferPort<T>::clear, this),
00410 "Clear the contents of the buffer.");
00411 return to;
00412 #else
00413 return 0;
00414 #endif
00415 }
00416 };
00417
00418
00427 template<class T>
00428 class BufferPort
00429 : public WriteBufferPort<T>, public ReadBufferPort<T>
00430 {
00431 protected:
00435 typename BufferConnectionInterface<T>::shared_ptr mconn;
00436
00437 public:
00438 typedef PortInterface::PortType PortType;
00439
00444 BufferPort(const std::string& name, size_t prefered_size, const T& initial_value = T())
00445 : PortInterface(name), WriteBufferPort<T>(name,prefered_size, initial_value), ReadBufferPort<T>(name), mconn() {}
00446
00447 ~BufferPort() {
00448 if (mconn) {
00449 mconn->removeReader(this);
00450 mconn->removeWriter(this);
00451 }
00452 }
00453
00457 void clear() {
00458 if (mconn)
00459 return mconn->buffer()->clear();
00460 }
00461
00467 BufferBase::size_type size() const {
00468 if (mconn)
00469 return mconn->buffer()->size();
00470 return 0;
00471 }
00472
00478 BufferBase::size_type capacity() const {
00479 if (mconn)
00480 return mconn->buffer()->capacity();
00481 return 0;
00482 }
00483
00488 bool empty() const {
00489 if (mconn)
00490 return mconn->buffer()->empty();
00491 return 0;
00492 }
00493
00498 bool full() const {
00499 if (mconn)
00500 return mconn->buffer()->full();
00501 return 0;
00502 }
00503
00504 bool connected() const { return mconn; };
00505
00509 bool connect(typename BufferConnectionInterface<T>::shared_ptr conn) {
00510 if ( (mconn && conn != mconn) || !conn )
00511 return false;
00512 mconn = conn;
00513 WriteBufferPort<T>::connect(conn);
00514 ReadBufferPort<T>::connect(conn);
00515 return true;
00516 }
00517
00518 virtual bool connect(typename WriteConnectionInterface<T>::shared_ptr conn) {
00519 if ( this->connect( boost::dynamic_pointer_cast<BufferConnectionInterface<T> >(conn) ) ) {
00520 WriteBufferPort<T>::connect(mconn);
00521 ReadBufferPort<T>::connect(mconn);
00522 return true;
00523 }
00524 return false;
00525 }
00526
00527 virtual bool connect(typename ReadConnectionInterface<T>::shared_ptr conn) {
00528 if ( this->connect( boost::dynamic_pointer_cast<BufferConnectionInterface<T> >(conn) ) ) {
00529 WriteBufferPort<T>::connect(mconn);
00530 ReadBufferPort<T>::connect(mconn);
00531 return true;
00532 }
00533 return false;
00534 }
00535
00536 using PortInterface::connectTo;
00537 bool connectTo( ConnectionInterface::shared_ptr other) {
00538 if ( other && !mconn ) {
00539 return other->addWriter( this ) && other->addReader( this );
00540 }
00541 return false;
00542 }
00543
00544 void disconnect() {
00545 mconn = 0;
00546 WriteBufferPort<T>::disconnect();
00547 ReadBufferPort<T>::disconnect();
00548 }
00549
00554 virtual BufferInterface<T>* buffer() const { return mconn ? mconn->buffer() : 0; }
00555
00556 virtual ConnectionInterface::shared_ptr connection() const { return mconn; }
00557
00558 virtual PortType getPortType() const { return PortInterface::ReadWritePort; }
00559
00560 virtual const TypeInfo* getTypeInfo() const { return detail::DataSourceTypeInfo<T>::getTypeInfo(); }
00561
00566 BufferPort& operator=(BufferInterface<T>* impl);
00567
00568 virtual PortInterface* clone() const {
00569 return new BufferPort<T>( this->getName(), this->buf_size, this->minitial_value );
00570 }
00571
00572 virtual PortInterface* antiClone() const {
00573 return this->clone();
00574 }
00575
00576 virtual TaskObject* createPortObject() {
00577 #ifndef ORO_EMBEDDED
00578 TaskObject* to = new TaskObject( this->getName() );
00579 to->methods()->addMethod( method("ready",&PortInterface::ready, this),
00580 "Check if this port is connected and ready for use.");
00581 to->methods()->addMethod(method("Push", &WriteBufferPort<T>::Push, this),
00582 "Push a single value in the Buffer. Returns false if full().",
00583 "Val", "The value.");
00584 to->methods()->addMethod(method("Pop", &ReadBufferPort<T>::Pop, this),
00585 "Pop a single value from the Buffer. Returns false if empty.",
00586 "Val", "The value returned by argument.");
00587 to->methods()->addMethod(method("front", &ReadBufferPort<T>::front, this),
00588 "Get the next to be popped value from the buffer. Returns default value if buffer is empty.");
00589 to->methods()->addMethod(method("size", &BufferPort<T>::size, this),
00590 "Get the used size of the buffer.");
00591 to->methods()->addMethod(method("capacity", &BufferPort<T>::capacity, this),
00592 "Get the capacity of the buffer.");
00593 to->methods()->addMethod(method("empty", &BufferPort<T>::empty, this),
00594 "Inspect if the buffer is empty.");
00595 to->methods()->addMethod(method("full", &BufferPort<T>::full, this),
00596 "Inspect if the buffer is full.");
00597 to->methods()->addMethod(method("clear", &BufferPort<T>::clear, this),
00598 "Clear the contents of the buffer.");
00599 return to;
00600 #else
00601 return 0;
00602 #endif
00603 }
00604 };
00605 }
00606 #endif
00607
00608 #ifndef ORO_BUFFER_PORT_INLINE
00609 #define ORO_BUFFER_PORT_INLINE
00610
00611 #include "ConnectionFactory.hpp"
00612 #include "BufferConnection.hpp"
00613
00614 namespace RTT
00615 {
00616
00617 template<class T>
00618 PortInterface* ReadBufferPort<T>::antiClone() const {
00619 return new WriteBufferPort<T>( this->getName(), 1 );
00620 }
00621
00622 template<class T>
00623 ReadBufferPort<T>& ReadBufferPort<T>::operator=(BufferInterface<T>* impl)
00624 {
00625 if ( !mconn ) {
00626 ConnectionInterface::shared_ptr con = new BufferConnection<T>(impl);
00627 this->connectTo(con);
00628 con->connect();
00629 } else
00630 mconn->setImplementation(impl);
00631 return *this;
00632 }
00633
00634 template<class T>
00635 WriteBufferPort<T>& WriteBufferPort<T>::operator=(BufferInterface<T>* impl)
00636 {
00637 if ( !mconn ) {
00638 ConnectionInterface::shared_ptr con = new BufferConnection<T>(impl);
00639 this->connectTo(con);
00640 con->connect();
00641 } else
00642 mconn->setImplementation(impl);
00643 return *this;
00644 }
00645
00646 template<class T>
00647 BufferPort<T>& BufferPort<T>::operator=(BufferInterface<T>* impl)
00648 {
00649 if ( !connected() ) {
00650 ConnectionInterface::shared_ptr con = new BufferConnection<T>(impl);
00651 this->connectTo(con);
00652 con->connect();
00653 } else
00654 mconn->setImplementation(impl);
00655 return *this;
00656 }
00657
00658 template<class T>
00659 ConnectionInterface::shared_ptr WriteBufferPort<T>::createConnection(PortInterface* other, ConnectionTypes::ConnectionType con_type )
00660 {
00661 ConnectionFactory<T> cf;
00662 return ConnectionInterface::shared_ptr (cf.createBuffer(this, other, buf_size, minitial_value, con_type));
00663 }
00664
00665 template<class T>
00666 ConnectionInterface::shared_ptr WriteBufferPort<T>::createConnection(ConnectionTypes::ConnectionType con_type )
00667 {
00668 ConnectionFactory<T> cf;
00669 ConnectionInterface::shared_ptr res = cf.createBuffer(buf_size, minitial_value, con_type);
00670 res->addWriter(this);
00671 return res;
00672 }
00673 }
00674 #endif