BufferPort.hpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Thu Mar 2 08:30:17 CET 2006  BufferPort.hpp
00003 
00004                         BufferPort.hpp -  description
00005                            -------------------
00006     begin                : Thu March 02 2006
00007     copyright            : (C) 2006 Peter Soetens
00008     email                : peter.soetens@fmtc.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
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
Generated on Thu Dec 23 13:22:36 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3