ConnectionFactory.hpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Thu Mar 2 08:30:17 CET 2006  ConnectionFactory.hpp 
00003 
00004                         ConnectionFactory.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_CONNECTION_FACTORY_HPP
00040 #define ORO_EXECUTION_CONNECTION_FACTORY_HPP
00041 
00042 #include "ConnectionTypes.hpp"
00043 #include "rtt-config.h"
00044 
00045 namespace RTT
00046 {
00047     class PortInterface;
00048     template<class T>
00049     class BufferConnectionInterface;
00050     template<class T>
00051     class DataConnectionInterface;
00057     template<class T>
00058     class ConnectionFactory
00059     {
00060     public:
00078         BufferConnectionInterface<T>* createBuffer(PortInterface* writer, PortInterface* reader, int size, const T& initial_value = T(), ConnectionTypes::ConnectionType type = ConnectionTypes::lockfree);
00079 
00095         BufferConnectionInterface<T>* createBuffer(int size, const T& initial_value = T(), ConnectionTypes::ConnectionType type = ConnectionTypes::lockfree);
00096 
00113         DataConnectionInterface<T>* createDataObject(PortInterface* writer, PortInterface* reader, const T& initial_value = T(), ConnectionTypes::ConnectionType type = ConnectionTypes::lockfree);
00114 
00129         DataConnectionInterface<T>* createDataObject(const T& initial_value = T(), ConnectionTypes::ConnectionType type = ConnectionTypes::lockfree);
00130 
00131     };
00132 }
00133 #endif
00134 
00135 #ifndef ORO_CONNECTIONFACTORY_INLINE
00136 #define ORO_CONNECTIONFACTORY_INLINE
00137 #include "BufferConnection.hpp"
00138 #include "DataConnection.hpp"
00139 #include "BufferLocked.hpp"
00140 #include "BufferLockFree.hpp"
00141 #include "DataObjectInterfaces.hpp"
00142 
00143 namespace RTT
00144 {
00145 
00146         template<class T>
00147         BufferConnectionInterface<T>* ConnectionFactory<T>::createBuffer(PortInterface* writer, PortInterface* reader, int size, const T& initial_value, ConnectionTypes::ConnectionType type )
00148         {
00149             BufferBase* conn_buffer = 0;
00150             int protocol = 0;
00151             if ( (protocol = writer->serverProtocol()) ) {
00152                 if ( reader->serverProtocol() ) {
00153                     log(Error) << "Can not connect two remote ports." <<endlog();
00154                     log(Error) << "One must be local and one must be remote." <<endlog();
00155                     return 0;
00156                 }
00157                 detail::TypeTransporter* tt =writer->getTypeInfo()->getProtocol( writer->serverProtocol() );
00158                 if (tt)
00159                     conn_buffer = tt->bufferProxy(writer);
00160             }
00161             else {
00162                 if ( (protocol=reader->serverProtocol()) ) {
00163                     detail::TypeTransporter* tt = reader->getTypeInfo()->getProtocol( reader->serverProtocol() );
00164                     if (tt)
00165                         conn_buffer = tt->bufferProxy(reader);
00166                 }
00167             }
00168             // if BufferBase, we already got a remote connection.
00169             if (conn_buffer) {
00170                 BufferInterface<T>* bi = dynamic_cast<BufferInterface<T>*>(conn_buffer);
00171                 if (!bi) {
00172                     log(Error) << "Misconfigured protocol "<<protocol<<": could not dynamic_cast to data type."<<endlog();
00173                     delete conn_buffer;
00174                     return 0;
00175                 }
00176                 BufferConnectionInterface<T>* bci = new BufferConnection<T>( bi );
00177                 bci->addReader(reader);
00178                 bci->addWriter(writer);
00179                 return bci;
00180             }
00181 
00182             WriteBufferPort<T>* wt = dynamic_cast<WriteBufferPort<T>*>( writer );
00183             ReadBufferPort<T>* rt  = dynamic_cast<ReadBufferPort<T>*>( reader );
00184 
00185             if ( wt == 0 || rt == 0 || wt->connection() || rt->connection() ){
00186                 Logger::log() <<Logger::Warning<< "ConnectionFactory could not create a BufferConnection between Writer:"<<writer->getName() <<" and Reader:"
00187                               << reader->getName() <<Logger::endl;
00188                 std::string msg = (wt == 0 ? "Writer is not a WriteBufferPort or has wrong/unknown data type."
00189                                    : (rt == 0 ? "Reader is not a ReadBufferPort or has wrong/unknown data type."
00190                                       : ( wt->connection() ? "Writer already connected. Use connectTo()."
00191                                           : "Reader already connected. Use connectTo()." )));
00192                 Logger::log() << msg  << Logger::endl;
00193                 return 0;
00194             }
00195             
00196             Logger::log() << Logger::Debug<< "Creating a BufferConnection from "<<writer->getName() <<" to "
00197                           << reader->getName() << " with size "<<size<<Logger::endl;
00198             BufferConnectionInterface<T>* bci = this->createBuffer(size, initial_value, type);
00199             bci->addReader(reader);
00200             bci->addWriter(writer);
00201             return bci;
00202         }
00203 
00204         template<class T>
00205         BufferConnectionInterface<T>* ConnectionFactory<T>::createBuffer(int size, const T& initial_value, ConnectionTypes::ConnectionType type )
00206         {
00207             if (type == ConnectionTypes::lockfree)
00208                 return new BufferConnection<T>(new BufferLockFree<T>(size, initial_value) );
00209             if (type == ConnectionTypes::locked)
00210                 return new BufferConnection<T>(new BufferLocked<T>(size, initial_value) );
00211             return 0;
00212         }
00213             
00214 
00215         template<class T>
00216         DataConnectionInterface<T>* ConnectionFactory<T>::createDataObject(PortInterface* writer, PortInterface* reader, const T& initial_value, ConnectionTypes::ConnectionType type)
00217         {
00218             DataSourceBase::shared_ptr conn_data;
00219             int protocol = 0;
00220             if ( (protocol = writer->serverProtocol()) ) {
00221                 if ( reader->serverProtocol() ) {
00222                     log(Error) << "Can not connect two remote ports." <<endlog();
00223                     log(Error) << "One must be local and one must be remote." <<endlog();
00224                     return 0;
00225                 }
00226                 detail::TypeTransporter* tt = writer->getTypeInfo()->getProtocol( writer->serverProtocol() );
00227                 if (tt)
00228                     conn_data = tt->dataProxy(writer); // else: let it fail further on.
00229             }
00230             else {
00231                 if ( (protocol=reader->serverProtocol()) ) {
00232                     detail::TypeTransporter* tt = reader->getTypeInfo()->getProtocol( reader->serverProtocol() );
00233                     if (tt)
00234                         conn_data = tt->dataProxy(reader); // else: let it fail further on.
00235                 }
00236             }
00237             // if DataBase, we already got a remote connection.
00238             if (conn_data) {
00239                 DataObjectInterface<T>* bi = dynamic_cast<DataObjectInterface<T>*>( conn_data.get() );
00240                 if (!bi) {
00241                     log(Error) << "Misconfigured protocol "<<protocol<<": could not dynamic_cast to data type."<<endlog();
00242                     delete bi;
00243                     return 0;
00244                 }
00245                 DataConnectionInterface<T>* bci = new DataConnection<T>( bi );
00246                 // the remote one of these will fail to add.
00247                 bci->addReader(reader);
00248                 bci->addWriter(writer);
00249                 return bci;
00250             }
00251 
00252             WriteDataPort<T>* wt = dynamic_cast<WriteDataPort<T>*>( writer );
00253             ReadDataPort<T>* rt  = dynamic_cast<ReadDataPort<T>*>( reader );
00254 
00255             if ( wt == 0 || rt == 0 || wt->connection() || rt->connection() ) {
00256                 Logger::log() <<Logger::Warning<< "ConnectionFactory could not create a DataConnection between Writer:"<<writer->getName() <<" and Reader:"
00257                               << reader->getName() << Logger::nl;
00258                 std::string msg = (wt == 0 ? "Writer is not a WriteDataPort or has wrong/unknown data type."
00259                                    : (rt == 0 ? "Reader is not a ReadDataPort or has wrong/unknown data type."
00260                                       : ( wt->connection() ? "Writer already connected. Use connectTo()."
00261                                           : "Reader already connected. Use connectTo()" )));
00262                 Logger::log() << msg  << Logger::endl;
00263                 return 0;
00264             }
00265 
00266             Logger::log() << Logger::Debug<< "Creating a DataConnection from "<<writer->getName() <<" to "
00267                           << reader->getName() <<Logger::endl;
00268             DataConnectionInterface<T>* dci = this->createDataObject(initial_value, type);
00269             dci->addReader( reader );
00270             dci->addWriter( writer );
00271             return dci;
00272         }
00273 
00274         template<class T>
00275         DataConnectionInterface<T>* ConnectionFactory<T>::createDataObject(const T& initial_value, ConnectionTypes::ConnectionType type)
00276         {
00277             if (type == ConnectionTypes::lockfree)
00278                 return new DataConnection<T>( new DataObjectLockFree<T>("DataObject", initial_value) );
00279             if (type == ConnectionTypes::locked)
00280                 return new DataConnection<T>( new DataObjectLocked<T>("DataObject", initial_value) );
00281             return 0;
00282         }
00283 }
00284 #endif

Generated on Tue Mar 25 17:41:41 2008 for OrocosReal-TimeToolkit by  doxygen 1.5.3