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>* create() const
00374 {
00375 return new Property<T>( _name, _description, T() );
00376 }
00377
00378 virtual base::DataSourceBase::shared_ptr getDataSource() const {
00379 return _value;
00380 }
00381
00382 typename internal::AssignableDataSource<DataSourceType>::shared_ptr getAssignableDataSource() const {
00383 return _value;
00384 }
00385
00386 virtual std::string getType() const {
00387 return internal::DataSource<T>::GetType();
00388 }
00389
00390 virtual const types::TypeInfo* getTypeInfo() const {
00391 return internal::DataSource<T>::GetTypeInfo();
00392 }
00393 protected:
00394 typename internal::AssignableDataSource<DataSourceType>::shared_ptr _value;
00395 };
00396
00397
00401 template<>
00402 RTT_API bool Property<PropertyBag>::update( const Property<PropertyBag>& orig);
00403
00404 template<>
00405 RTT_API bool Property<PropertyBag>::refresh( const Property<PropertyBag>& orig);
00406
00407 template<>
00408 RTT_API bool Property<PropertyBag>::copy( const Property<PropertyBag>& orig);
00409
00410 template<typename T>
00411 std::ostream& operator<<(std::ostream &os, Property<T> &p)
00412 {
00413 #ifdef OS_HAVE_STREAMS
00414 os << p.getDataSource();
00415 #endif
00416 return os;
00417 }
00418
00419 template<class T>
00420 Property<T>* Property<T>::narrow( base::PropertyBase* prop ) {
00421 Property<T>* res = dynamic_cast<Property<T>*>( prop );
00422 return res;
00423 }
00424 }
00425
00426 #include "base/PropertyIntrospection.hpp"
00427
00428 namespace RTT
00429 {
00430 template< class T>
00431 void Property<T>::identify( base::PropertyIntrospection* pi)
00432 {
00433 pi->introspect( *this );
00434 }
00435
00436 template< class T>
00437 void Property<T>::identify( base::PropertyBagVisitor* pi)
00438 {
00439 return base::PropertyBase::identify(pi);
00440 }
00441
00442 template<>
00443 RTT_API void Property<PropertyBag>::identify( base::PropertyBagVisitor* pbi);
00444 }
00445
00446 #endif