Property.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 #ifndef ORO_PROPERTY_HPP
00039 #define ORO_PROPERTY_HPP
00040
00041 #include "rtt-config.h"
00042 #include "Marshaller.hpp"
00043 #include "PropertyBase.hpp"
00044 #include "PropertyBag.hpp"
00045 #include "PropertyCommands.hpp"
00046 #include "DataSources.hpp"
00047 #include "BuildType.hpp"
00048 #include <boost/type_traits.hpp>
00049
00050 #include <string>
00051 #include <ostream>
00052
00053 #ifdef ORO_PRAGMA_INTERFACE
00054 #pragma interface
00055 #endif
00056
00057 namespace RTT
00058 {
00077 template<typename T>
00078 class RTT_EXPORT Property
00079 : public PropertyBase
00080 {
00081 public:
00087 typedef typename boost::remove_const<typename boost::remove_reference<T>::type>::type value_t;
00088 typedef typename boost::call_traits<value_t>::param_type param_t;
00089 typedef typename boost::call_traits<value_t>::reference reference_t;
00090 typedef typename boost::call_traits<value_t>::const_reference const_reference_t;
00091 typedef value_t DataSourceType;
00092
00097 Property()
00098 {}
00099
00108 Property(const std::string& name, const std::string& description, param_t value = value_t() )
00109 : PropertyBase(name, description), _value( detail::BuildType<value_t>::Value( value ) )
00110 {
00111 }
00112
00118 Property( const Property<T>& orig)
00119 : PropertyBase(orig.getName(), orig.getDescription()),
00120 _value( orig._value ? orig._value->clone() : 0 )
00121 {}
00122
00129 Property( PropertyBase* source)
00130 : PropertyBase(source ? source->getName() : "", source ? source->getDescription() : ""),
00131 _value( source ? AssignableDataSource<DataSourceType>::narrow(source->getDataSource().get() ) : 0 )
00132 {
00133 }
00134
00144 Property(const std::string& name, const std::string& description,
00145 typename AssignableDataSource<DataSourceType>::shared_ptr datasource )
00146 : PropertyBase(name, description), _value( datasource )
00147 {}
00148
00154 Property<T>& operator=( param_t value )
00155 {
00156 _value->set( value );
00157 return *this;
00158 }
00159
00164 Property<T>& operator=( PropertyBase* source )
00165 {
00166 if ( source ) {
00167 this->setName( source->getName() );
00168 this->setDescription( source->getDescription() );
00169 typename AssignableDataSource<DataSourceType>::shared_ptr vptr
00170 = AssignableDataSource<DataSourceType>::narrow(source->getDataSource().get() );
00171 if (vptr)
00172 _value = vptr;
00173 else
00174 _value = detail::BuildType<value_t>::Value() ;
00175 } else {
00176 this->setName( "" );
00177 this->setDescription( "" );
00178 _value = 0;
00179 }
00180 return *this;
00181 }
00182
00187 Property<T>& operator<<=(Property<T> &p)
00188 {
00189 this->update( p );
00190 return *this;
00191 }
00192
00197 operator value_t() const
00198 {
00199 return _value->get();
00200 }
00201
00206 DataSourceType get() const
00207 {
00208 return _value->get();
00209 }
00210
00217 reference_t set()
00218 {
00219 return _value->set();
00220 }
00221
00225 void set(param_t v)
00226 {
00227 _value->set(v);
00228 }
00229
00237 reference_t value()
00238 {
00239 return set();
00240 }
00241
00245 const_reference_t rvalue() const
00246 {
00247 return _value->rvalue();
00248 }
00249
00259 static Property<T>* narrow( PropertyBase* prop );
00260
00261 virtual void identify( PropertyIntrospection* pi);
00262
00263 virtual void identify( PropertyBagVisitor* pi);
00264
00265 virtual bool update( const PropertyBase* other)
00266 {
00267 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00268 if ( origin != 0 ) {
00269 return this->update( *origin );
00270 }
00271 return false;
00272 }
00273
00274 virtual CommandInterface* updateCommand( const PropertyBase* other)
00275 {
00276
00277 const Property<T>* origin = dynamic_cast<const Property<T>* >( other );
00278 if ( origin != 0 && _value )
00279 return new detail::UpdatePropertyCommand<T>(this, origin);
00280 return 0;
00281 }
00282
00283 virtual bool refresh( const PropertyBase* other)
00284 {
00285 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00286 if ( origin != 0 && _value ) {
00287 return this->refresh( *origin );
00288 }
00289 return false;
00290 }
00291
00292 virtual CommandInterface* refreshCommand( const PropertyBase* other)
00293 {
00294 if ( !_value )
00295 return 0;
00296
00297 DataSourceBase::shared_ptr sourcebase = other->getDataSource();
00298 return _value->updateCommand( sourcebase.get() );
00299 }
00300
00301 virtual bool copy( const PropertyBase* other )
00302 {
00303 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00304 if ( origin != 0 && _value ) {
00305 return this->copy( *origin );
00306 }
00307 return false;
00308 }
00309
00310 virtual CommandInterface* copyCommand( const PropertyBase* other)
00311 {
00312 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00313 if ( origin != 0 && _value )
00314 return new detail::CopyPropertyCommand<T>(this, origin);
00315 return 0;
00316 }
00317
00321 bool copy( const Property<T>& orig)
00322 {
00323 if ( !ready() )
00324 return false;
00325 _description = orig.getDescription();
00326 _name = orig.getName();
00327 *this = orig.rvalue();
00328 return true;
00329 }
00330
00335 bool update( const Property<T>& orig)
00336 {
00337 if ( !ready() )
00338 return false;
00339 if ( _description.empty() )
00340 _description = orig.getDescription();
00341 *this = orig.rvalue();
00342 return true;
00343 }
00344
00349 bool refresh( const Property<T>& orig)
00350 {
00351 if ( !ready() )
00352 return false;
00353 *this = orig.rvalue();
00354 return true;
00355 }
00356
00357 virtual Property<T>* clone() const
00358 {
00359 return new Property<T>(*this);
00360 }
00361
00362 virtual Property<T>* create() const
00363 {
00364 return new Property<T>( _name, _description );
00365 }
00366
00367 virtual DataSourceBase::shared_ptr getDataSource() const {
00368 return _value;
00369 }
00370
00371 typename AssignableDataSource<DataSourceType>::shared_ptr getAssignableDataSource() const {
00372 return _value;
00373 }
00374
00375 virtual std::string getType() const {
00376 return DataSource<T>::GetType();
00377 }
00378
00379 virtual const TypeInfo* getTypeInfo() const {
00380 return DataSource<T>::GetTypeInfo();
00381 }
00382 protected:
00383 typename AssignableDataSource<DataSourceType>::shared_ptr _value;
00384 };
00385
00386
00390 template<>
00391 bool Property<PropertyBag>::update( const Property<PropertyBag>& orig);
00392
00393 template<>
00394 bool Property<PropertyBag>::refresh( const Property<PropertyBag>& orig);
00395
00396 template<>
00397 bool Property<PropertyBag>::copy( const Property<PropertyBag>& orig);
00398
00399 template<typename T>
00400 std::ostream& operator<<(std::ostream &os, Property<T> &p)
00401 {
00402 #ifdef OS_HAVE_STREAMS
00403 os << p.getDataSource();
00404 #endif
00405 return os;
00406 }
00407
00408 template<class T>
00409 Property<T>* Property<T>::narrow( PropertyBase* prop ) {
00410 Property<T>* res = dynamic_cast<Property<T>*>( prop );
00411 if (res)
00412 return res->clone();
00413
00414 int p_id = prop->getDataSource()->serverProtocol();
00415 if ( p_id ) {
00416 assert(false);
00417 #if 0
00418 T result;
00419 void* ret = propbase->getDataSource()->getBlob(p_id);
00420 if( A n y Conversion<T>::update( any.in() , result ) ) {
00421 return new Property<T>( propbase->getName(), propbase->getDescription(), result );
00422 }
00423 #endif
00424 }
00425 return 0;
00426 }
00427
00428 #ifndef ORO_EMBEDDED
00429 extern template class Property<double>;
00430 extern template class Property<bool>;
00431 extern template class Property<float>;
00432 extern template class Property<int>;
00433 extern template class Property<unsigned int>;
00434 extern template class Property<std::string>;
00435 extern template class Property<const std::string &>;
00436 #endif
00437 }
00438
00439 #include "PropertyIntrospection.hpp"
00440
00441 namespace RTT
00442 {
00443 template< class T>
00444 void Property<T>::identify( PropertyIntrospection* pi)
00445 {
00446 pi->introspect( *this );
00447 }
00448
00449 template< class T>
00450 void Property<T>::identify( PropertyBagVisitor* pi)
00451 {
00452 return PropertyBase::identify(pi);
00453 }
00454
00455 template<>
00456 void Property<PropertyBag>::identify( PropertyBagVisitor* pbi);
00457 }
00458
00459 #endif