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_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
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);
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);
00235 }
00236 }
00237
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
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