Go to the documentation of this file.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 #ifndef ORO_PROPERTY_HPP
00039 #define ORO_PROPERTY_HPP
00040
00041 #include "rtt-config.h"
00042 #include "base/PropertyBase.hpp"
00043 #include "PropertyBag.hpp"
00044 #include "internal/DataSources.hpp"
00045 #include <boost/type_traits/remove_const.hpp>
00046 #include <boost/call_traits.hpp>
00047 #include "Logger.hpp"
00048
00049 #include <string>
00050 #include <ostream>
00051
00052 #ifdef ORO_PRAGMA_INTERFACE
00053 #pragma interface
00054 #endif
00055
00056 namespace RTT
00057 {
00075 template<typename T>
00076 class Property
00077 : public base::PropertyBase
00078 {
00079 public:
00085 typedef typename boost::remove_const<typename boost::remove_reference<T>::type>::type value_t;
00086 typedef typename boost::call_traits<value_t>::param_type param_t;
00087 typedef typename boost::call_traits<value_t>::reference reference_t;
00088 typedef typename boost::call_traits<value_t>::const_reference const_reference_t;
00089 typedef value_t DataSourceType;
00090
00095 Property()
00096 {}
00097
00104 explicit Property(const std::string& name)
00105 : base::PropertyBase(name,""), _value( new internal::ValueDataSource<value_t>() )
00106 {
00107 }
00108
00117 Property(const std::string& name, const std::string& description, param_t value = value_t() )
00118 : base::PropertyBase(name, description), _value( new internal::ValueDataSource<value_t>( value ) )
00119 {
00120 }
00121
00127 Property( const Property<T>& orig)
00128 : base::PropertyBase(orig.getName(), orig.getDescription()),
00129 _value( orig._value ? orig._value->clone() : 0 )
00130 {
00131
00132 if (_value)
00133 _value->evaluate();
00134 }
00135
00142 Property( base::PropertyBase* source)
00143 : base::PropertyBase(source ? source->getName() : "", source ? source->getDescription() : ""),
00144 _value( source ? internal::AssignableDataSource<DataSourceType>::narrow(source->getDataSource().get() ) : 0 )
00145 {
00146 if ( source && ! _value ) {
00147 log(Error) <<"Can not initialize Property from "<<source->getName() <<": ";
00148 if ( source->getDataSource() )
00149 log() << "incompatible type ( destination type: "<< getType() << ", source type: "<< source->getDataSource()->getTypeName() << ")."<<endlog();
00150 else
00151 log() << "source Property was not ready."<<endlog();
00152 }
00153 }
00154
00164 Property(const std::string& name, const std::string& description,
00165 typename internal::AssignableDataSource<DataSourceType>::shared_ptr datasource )
00166 : base::PropertyBase(name, description), _value( datasource )
00167 {
00168
00169 if (_value)
00170 _value->evaluate();
00171 }
00172
00178 Property<T>& operator=( param_t value )
00179 {
00180 _value->set( value );
00181 return *this;
00182 }
00183
00188 Property<T>& operator=( base::PropertyBase* source )
00189 {
00190 if ( this == source )
00191 return *this;
00192
00193 if ( source ) {
00194 this->setName( source->getName() );
00195 this->setDescription( source->getDescription() );
00196 typename internal::AssignableDataSource<DataSourceType>::shared_ptr vptr
00197 = internal::AssignableDataSource<DataSourceType>::narrow(source->getDataSource().get() );
00198 if (vptr) {
00199 _value = vptr;
00200 return *this;
00201 }
00202 }
00203
00204 this->setName( "" );
00205 this->setDescription( "" );
00206 _value = 0;
00207 return *this;
00208 }
00209
00214 Property<T>& operator<<=(Property<T> &p)
00215 {
00216 this->update( p );
00217 return *this;
00218 }
00219
00225 Property<T>& doc(const std::string& descr) {
00226 setDescription(descr);
00227 return *this;
00228 }
00229
00234 operator value_t() const
00235 {
00236 return _value->get();
00237 }
00238
00243 DataSourceType get() const
00244 {
00245 return _value->get();
00246 }
00247
00254 reference_t set()
00255 {
00256 return _value->set();
00257 }
00258
00262 void set(param_t v)
00263 {
00264 _value->set(v);
00265 }
00266
00274 reference_t value()
00275 {
00276 return set();
00277 }
00278
00282 const_reference_t rvalue() const
00283 {
00284 return _value->rvalue();
00285 }
00286
00296 static Property<T>* narrow( base::PropertyBase* prop );
00297
00298 virtual void identify( base::PropertyIntrospection* pi);
00299
00300 virtual void identify( base::PropertyBagVisitor* pi);
00301
00302 virtual bool update( const base::PropertyBase* other)
00303 {
00304 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00305 if ( origin != 0 ) {
00306 return this->update( *origin );
00307 }
00308 return false;
00309 }
00310
00311 virtual bool refresh( const base::PropertyBase* other)
00312 {
00313 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00314 if ( origin != 0 && _value ) {
00315 return this->refresh( *origin );
00316 }
00317 return false;
00318 }
00319
00320 virtual bool copy( const base::PropertyBase* other )
00321 {
00322 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00323 if ( origin != 0 && _value ) {
00324 return this->copy( *origin );
00325 }
00326 return false;
00327 }
00328
00332 bool copy( const Property<T>& orig)
00333 {
00334 if ( !ready() )
00335 return false;
00336 _description = orig.getDescription();
00337 _name = orig.getName();
00338 _value->set( orig.rvalue() );
00339 return true;
00340 }
00341
00346 bool update( const Property<T>& orig)
00347 {
00348 if ( !ready() )
00349 return false;
00350 if ( _description.empty() )
00351 _description = orig.getDescription();
00352 _value->set( orig.rvalue() );
00353 return true;
00354 }
00355
00360 bool refresh( const Property<T>& orig)
00361 {
00362 if ( !ready() )
00363 return false;
00364 _value->set( orig.rvalue() );
00365 return true;
00366 }
00367
00368 virtual Property<T>* clone() const
00369 {
00370 return new Property<T>(*this);
00371 }
00372
00373 virtual Property<T>* copy() const
00374 {
00375 return new Property<T>( _name, _description, _value );
00376 }
00377
00378 virtual Property<T>* create() const
00379 {
00380 return new Property<T>( _name, _description, T() );
00381 }
00382
00383 virtual base::DataSourceBase::shared_ptr getDataSource() const {
00384 return _value;
00385 }
00386
00387 typename internal::AssignableDataSource<DataSourceType>::shared_ptr getAssignableDataSource() const {
00388 return _value;
00389 }
00390
00391 virtual std::string getType() const {
00392 return internal::DataSource<T>::GetType();
00393 }
00394
00395 virtual const types::TypeInfo* getTypeInfo() const {
00396 return internal::DataSource<T>::GetTypeInfo();
00397 }
00398 protected:
00399 typename internal::AssignableDataSource<DataSourceType>::shared_ptr _value;
00400 };
00401
00402
00406 template<>
00407 RTT_API bool Property<PropertyBag>::update( const Property<PropertyBag>& orig);
00408
00409 template<>
00410 RTT_API bool Property<PropertyBag>::refresh( const Property<PropertyBag>& orig);
00411
00412 template<>
00413 RTT_API bool Property<PropertyBag>::copy( const Property<PropertyBag>& orig);
00414
00415 template<typename T>
00416 std::ostream& operator<<(std::ostream &os, Property<T> &p)
00417 {
00418 #ifdef OS_HAVE_STREAMS
00419 os << p.getDataSource();
00420 #endif
00421 return os;
00422 }
00423
00424 template<class T>
00425 Property<T>* Property<T>::narrow( base::PropertyBase* prop ) {
00426 Property<T>* res = dynamic_cast<Property<T>*>( prop );
00427 return res;
00428 }
00429 }
00430
00431 #include "base/PropertyIntrospection.hpp"
00432
00433 namespace RTT
00434 {
00435 template< class T>
00436 void Property<T>::identify( base::PropertyIntrospection* pi)
00437 {
00438 pi->introspect( *this );
00439 }
00440
00441 template< class T>
00442 void Property<T>::identify( base::PropertyBagVisitor* pi)
00443 {
00444 return base::PropertyBase::identify(pi);
00445 }
00446
00447 template<>
00448 RTT_API void Property<PropertyBag>::identify( base::PropertyBagVisitor* pbi);
00449 }
00450
00451 #endif