DataPort.hpp
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_DATA_PORT_INTERFACE_HPP
00040 #define ORO_EXECUTION_DATA_PORT_INTERFACE_HPP
00041
00042 #include <string>
00043 #include "Logger.hpp"
00044 #include "PortInterface.hpp"
00045 #include "DataConnection.hpp"
00046 #include "OperationInterface.hpp"
00047 #include "Method.hpp"
00048 #include "ConnectionTypes.hpp"
00049 #include "TaskObject.hpp"
00050
00051 namespace RTT
00052 {
00053 template<class T>
00054 class DataPortBase
00055 : public PortInterface
00056 {
00057 typedef T DataType;
00058 public:
00063 DataPortBase(const std::string& name) : PortInterface(name), mconn() {}
00064
00065 ~DataPortBase() {
00066 if (mconn)
00067 mconn->removePort(this);
00068 }
00069
00074 DataPortBase<T>& operator=(DataObjectInterface<T>* impl);
00075
00076 ConnectionInterface::shared_ptr createConnection(DataSourceBase::shared_ptr data);
00077
00078 virtual ConnectionModel getConnectionModel() const { return Data; }
00079
00080 virtual const TypeInfo* getTypeInfo() const { return detail::DataSourceTypeInfo<T>::getTypeInfo(); }
00081
00082 bool connect(ConnectionInterface::shared_ptr conn)
00083 {
00084 if ( mconn || !conn )
00085 return false;
00086 mconn = boost::dynamic_pointer_cast< DataConnection<T> > (conn);
00087 return (mconn);
00088 }
00089
00090 virtual ConnectionInterface::shared_ptr connection() const { return mconn; }
00091
00092 bool connected() const { return mconn; };
00093
00094 using PortInterface::connectTo;
00095 bool connectTo( ConnectionInterface::shared_ptr other) {
00096 return other && !mconn && other->addPort( this );
00097 }
00098
00099 void disconnect() {
00100 mconn = 0;
00101 }
00102
00108 const DataObjectInterface<T>* data() const { return mconn ? mconn->data() : 0; }
00109
00115 DataObjectInterface<T>* data() { return mconn ? mconn->data() : 0; }
00116
00117 protected:
00121 mutable typename DataConnection<T>::shared_ptr mconn;
00122 };
00123
00131 template<class T>
00132 class ReadDataPort
00133 : public DataPortBase<T>
00134 {
00135 using DataPortBase<T>::mconn;
00136 public:
00137 using DataPortBase<T>::operator=;
00138 typedef T DataType;
00139
00144 ReadDataPort(const std::string& name) : DataPortBase<T>(name) {}
00145
00151 T Get() const
00152 {
00153 #ifndef ORO_EMBEDDED
00154 try {
00155 #endif
00156 if ( mconn )
00157 return mconn->data()->Get();
00158 #ifndef ORO_EMBEDDED
00159 } catch (...) {
00160 mconn = 0;
00161 }
00162 #endif
00163 return T();
00164 }
00165
00172 void Get(T& result)
00173 {
00174 #ifndef ORO_EMBEDDED
00175 try {
00176 #endif
00177 if ( mconn )
00178 return mconn->data()->Get(result);
00179 #ifndef ORO_EMBEDDED
00180 } catch (...) {
00181 mconn = 0;
00182 }
00183 #endif
00184 }
00185
00186 virtual PortInterface::PortType getPortType() const { return PortInterface::ReadPort; }
00187
00188 virtual PortInterface* clone() const {
00189 return new ReadDataPort<T>( this->getName() );
00190 }
00191
00192 virtual PortInterface* antiClone() const;
00193
00194 virtual TaskObject* createPortObject() {
00195 #ifndef ORO_EMBEDDED
00196 typedef T (ReadDataPort<T>::*GetType)(void) const;
00197 GetType get_type = &ReadDataPort<T>::Get;
00198 TaskObject* to = new TaskObject( this->getName() );
00199 to->methods()->addMethod( method("ready",&PortInterface::ready, this),
00200 "Check if this port is connected and ready for use.");
00201 to->methods()->addMethod( method("Get",get_type, this),
00202 "Get the current value of this Read Data Port");
00203 return to;
00204 #else
00205 return 0;
00206 #endif
00207 }
00208
00209 };
00210
00218 template<class T>
00219 class WriteDataPort
00220 : public DataPortBase<T>
00221 {
00222 using DataPortBase<T>::mconn;
00223 public:
00224 using DataPortBase<T>::operator=;
00225 typedef T DataType;
00226
00234 WriteDataPort(const std::string& name, const DataType& initial_value = DataType() )
00235 : DataPortBase<T>(name), minitial_value(initial_value) {}
00236
00243 void Set(const T& data )
00244 {
00245 #ifndef ORO_EMBEDDED
00246 try {
00247 #endif
00248 if ( mconn )
00249 {
00250 mconn->data()->Set(data);
00251 mconn->signal();
00252 return;
00253 }
00254
00255 #ifndef ORO_EMBEDDED
00256 } catch (...) {
00257 mconn = 0;
00258 }
00259 #endif
00260 minitial_value = data;
00261 }
00262
00263 virtual PortInterface::PortType getPortType() const { return PortInterface::WritePort; }
00264
00265 virtual PortInterface* clone() const {
00266 return new WriteDataPort<T>( this->getName(), minitial_value );
00267 }
00268
00269 virtual PortInterface* antiClone() const {
00270 return new ReadDataPort<T>( this->getName() );
00271 }
00272
00273 ConnectionInterface::shared_ptr createConnection(ConnectionTypes::ConnectionType con_type);
00274
00275 virtual TaskObject* createPortObject() {
00276 #ifndef ORO_EMBEDDED
00277 TaskObject* to = new TaskObject( this->getName() );
00278 to->methods()->addMethod( method("ready",&PortInterface::ready, this),
00279 "Check if this port is connected and ready for use.");
00280 to->methods()->addMethod( method("Set",&WriteDataPort<T>::Set, this),
00281 "Set the current value of this Write Data Port",
00282 "Value", "The new value.");
00283 return to;
00284 #else
00285 return 0;
00286 #endif
00287 }
00288
00289 protected:
00290 DataType minitial_value;
00291 };
00292
00293
00299 template<class T>
00300 class DataPort
00301 : public DataPortBase<T>
00302 {
00303 protected:
00304 T minitial_value;
00305 using DataPortBase<T>::mconn;
00306 public:
00307 using DataPortBase<T>::operator=;
00308 typedef T DataType;
00316 DataPort(const std::string& name, const DataType& initial_value = DataType() )
00317 : DataPortBase<T>(name), minitial_value(initial_value)
00318 {}
00319
00326 void Set(const DataType& data )
00327 {
00328 #ifndef ORO_EMBEDDED
00329 try {
00330 #endif
00331 if ( mconn ) {
00332 mconn->data()->Set(data);
00333 mconn->signal();
00334 return;
00335 }
00336 #ifndef ORO_EMBEDDED
00337 } catch (...) {
00338 mconn = 0;
00339 }
00340 #endif
00341 minitial_value = data;
00342 }
00343
00350 DataType Get() const
00351 {
00352 #ifndef ORO_EMBEDDED
00353 try {
00354 #endif
00355 if ( mconn )
00356 return mconn->data()->Get();
00357 #ifndef ORO_EMBEDDED
00358 } catch (...) {
00359 mconn = 0;
00360 }
00361 #endif
00362 return minitial_value;
00363 }
00364
00372 void Get(DataType& result)
00373 {
00374 #ifndef ORO_EMBEDDED
00375 try {
00376 #endif
00377 if ( mconn )
00378 return mconn->data()->Get(result);
00379 #ifndef ORO_EMBEDDED
00380 } catch (...) {
00381 mconn = 0;
00382 }
00383 #endif
00384 result = minitial_value;
00385 }
00386
00387 virtual PortInterface::PortType getPortType() const { return PortInterface::ReadWritePort; }
00388
00389 virtual PortInterface* clone() const {
00390 return new DataPort<T>( this->getName(), this->minitial_value );
00391 }
00392
00393 virtual PortInterface* antiClone() const {
00394 return this->clone();
00395 }
00396
00397 virtual TaskObject* createPortObject() {
00398 #ifndef ORO_EMBEDDED
00399 typedef T (DataPort<T>::*GetType)(void) const;
00400 GetType get_type = &DataPort<T>::Get;
00401 TaskObject* to = new TaskObject( this->getName() );
00402 to->methods()->addMethod( method("ready",&PortInterface::ready, this),
00403 "Check if this port is connected and ready for use.");
00404 to->methods()->addMethod( method("Get", get_type, this),
00405 "Get the current value of this Data Port");
00406 to->methods()->addMethod( method("Set",&DataPort<T>::Set, this),
00407 "Set the current value of this Data Port",
00408 "Value", "The new value.");
00409 return to;
00410 #else
00411 return 0;
00412 #endif
00413 }
00414
00415 ConnectionInterface::shared_ptr createConnection(ConnectionTypes::ConnectionType con_type);
00416 };
00417 }
00418 #endif
00419
00420 #ifndef ORO_DATA_PORT_INLINE
00421 #define ORO_DATA_PORT_INLINE
00422
00423 #include "ConnectionFactory.hpp"
00424 #include "DataConnection.hpp"
00425
00426 namespace RTT
00427 {
00428 template<class T>
00429 DataPortBase<T>& DataPortBase<T>::operator=(DataObjectInterface<T>* impl)
00430 {
00431 if ( !mconn ) {
00432 ConnectionInterface::shared_ptr con = new DataConnection<T>(impl);
00433 this->connectTo(con);
00434 con->connect();
00435 } else
00436 mconn->setImplementation(impl);
00437 return *this;
00438 }
00439
00440 template<class T>
00441 PortInterface* ReadDataPort<T>::antiClone() const {
00442 return new WriteDataPort<T>( this->getName() );
00443 }
00444
00445 template<class T>
00446 ConnectionInterface::shared_ptr DataPortBase<T>::createConnection(DataSourceBase::shared_ptr data)
00447 {
00448 DataObjectInterface<T>* doi = dynamic_cast< DataObjectInterface<T>* >( data.get() );
00449 if (!doi)
00450 {
00451
00452 log(Error) << "Dynamic cast failed for "
00453 << "'" << typeid(data.get()).name() << "', '"
00454 << data->getType() << "', '"
00455 << data->getTypeName() << "'"
00456 << ". Do your typenames not match?" << endlog();
00457 TypeInfoRepository::Instance()->logTypeInfo();
00458 }
00459
00460
00461
00462
00463
00464
00465 assert(doi && "Dynamic cast failed! See log file for details.");
00466 ConnectionInterface::shared_ptr ci( new DataConnection<T>( doi ) );
00467 ci->addPort(this);
00468 return ci;
00469 }
00470
00471 template<class T>
00472 ConnectionInterface::shared_ptr WriteDataPort<T>::createConnection(ConnectionTypes::ConnectionType con_type)
00473 {
00474 ConnectionFactory<T> cf;
00475 ConnectionInterface::shared_ptr res = cf.createDataObject(minitial_value, con_type);
00476 res->addPort(this);
00477 return res;
00478 }
00479
00480 template<class T>
00481 ConnectionInterface::shared_ptr DataPort<T>::createConnection(ConnectionTypes::ConnectionType con_type)
00482 {
00483 ConnectionFactory<T> cf;
00484 ConnectionInterface::shared_ptr res = cf.createDataObject(minitial_value, con_type);
00485 res->addPort(this);
00486 return res;
00487 }
00488
00489 }
00490
00491 #endif