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 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 ( this == source )
00167 return *this;
00168
00169 if ( source ) {
00170 this->setName( source->getName() );
00171 this->setDescription( source->getDescription() );
00172 typename AssignableDataSource<DataSourceType>::shared_ptr vptr
00173 = AssignableDataSource<DataSourceType>::narrow(source->getDataSource().get() );
00174 if (vptr)
00175 _value = vptr;
00176 else
00177 _value = detail::BuildType<value_t>::Value() ;
00178 } else {
00179 this->setName( "" );
00180 this->setDescription( "" );
00181 _value = 0;
00182 }
00183 return *this;
00184 }
00185
00190 Property<T>& operator<<=(Property<T> &p)
00191 {
00192 this->update( p );
00193 return *this;
00194 }
00195
00200 operator value_t() const
00201 {
00202 return _value->get();
00203 }
00204
00209 DataSourceType get() const
00210 {
00211 return _value->get();
00212 }
00213
00220 reference_t set()
00221 {
00222 return _value->set();
00223 }
00224
00228 void set(param_t v)
00229 {
00230 _value->set(v);
00231 }
00232
00240 reference_t value()
00241 {
00242 return set();
00243 }
00244
00248 const_reference_t rvalue() const
00249 {
00250 return _value->rvalue();
00251 }
00252
00262 static Property<T>* narrow( PropertyBase* prop );
00263
00264 virtual void identify( PropertyIntrospection* pi);
00265
00266 virtual void identify( PropertyBagVisitor* pi);
00267
00268 virtual bool update( const PropertyBase* other)
00269 {
00270 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00271 if ( origin != 0 ) {
00272 return this->update( *origin );
00273 }
00274 return false;
00275 }
00276
00277 virtual CommandInterface* updateCommand( const PropertyBase* other)
00278 {
00279
00280 const Property<T>* origin = dynamic_cast<const Property<T>* >( other );
00281 if ( origin != 0 && _value )
00282 return new detail::UpdatePropertyCommand<T>(this, origin);
00283 return 0;
00284 }
00285
00286 virtual bool refresh( const PropertyBase* other)
00287 {
00288 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00289 if ( origin != 0 && _value ) {
00290 return this->refresh( *origin );
00291 }
00292 return false;
00293 }
00294
00295 virtual CommandInterface* refreshCommand( const PropertyBase* other)
00296 {
00297 if ( !_value )
00298 return 0;
00299
00300 DataSourceBase::shared_ptr sourcebase = other->getDataSource();
00301 return _value->updateCommand( sourcebase.get() );
00302 }
00303
00304 virtual bool copy( const PropertyBase* other )
00305 {
00306 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00307 if ( origin != 0 && _value ) {
00308 return this->copy( *origin );
00309 }
00310 return false;
00311 }
00312
00313 virtual CommandInterface* copyCommand( const PropertyBase* other)
00314 {
00315 const Property<T>* origin = dynamic_cast< const Property<T>* >( other );
00316 if ( origin != 0 && _value )
00317 return new detail::CopyPropertyCommand<T>(this, origin);
00318 return 0;
00319 }
00320
00324 bool copy( const Property<T>& orig)
00325 {
00326 if ( !ready() )
00327 return false;
00328 _description = orig.getDescription();
00329 _name = orig.getName();
00330 *this = orig.rvalue();
00331 return true;
00332 }
00333
00338 bool update( const Property<T>& orig)
00339 {
00340 if ( !ready() )
00341 return false;
00342 if ( _description.empty() )
00343 _description = orig.getDescription();
00344 *this = orig.rvalue();
00345 return true;
00346 }
00347
00352 bool refresh( const Property<T>& orig)
00353 {
00354 if ( !ready() )
00355 return false;
00356 *this = orig.rvalue();
00357 return true;
00358 }
00359
00360 virtual Property<T>* clone() const
00361 {
00362 return new Property<T>(*this);
00363 }
00364
00365 virtual Property<T>* create() const
00366 {
00367 return new Property<T>( _name, _description );
00368 }
00369
00370 virtual DataSourceBase::shared_ptr getDataSource() const {
00371 return _value;
00372 }
00373
00374 typename AssignableDataSource<DataSourceType>::shared_ptr getAssignableDataSource() const {
00375 return _value;
00376 }
00377
00378 virtual std::string getType() const {
00379 return DataSource<T>::GetType();
00380 }
00381
00382 virtual const TypeInfo* getTypeInfo() const {
00383 return DataSource<T>::GetTypeInfo();
00384 }
00385 protected:
00386 typename AssignableDataSource<DataSourceType>::shared_ptr _value;
00387 };
00388
00389
00393 template<>
00394 RTT_API bool Property<PropertyBag>::update( const Property<PropertyBag>& orig);
00395
00396 template<>
00397 RTT_API bool Property<PropertyBag>::refresh( const Property<PropertyBag>& orig);
00398
00399 template<>
00400 RTT_API bool Property<PropertyBag>::copy( const Property<PropertyBag>& orig);
00401
00402 template<typename T>
00403 std::ostream& operator<<(std::ostream &os, Property<T> &p)
00404 {
00405 #ifdef OS_HAVE_STREAMS
00406 os << p.getDataSource();
00407 #endif
00408 return os;
00409 }
00410
00411 template<class T>
00412 Property<T>* Property<T>::narrow( PropertyBase* prop ) {
00413 Property<T>* res = dynamic_cast<Property<T>*>( prop );
00414 if (res)
00415 return res->clone();
00416
00417 int p_id = prop->getDataSource()->serverProtocol();
00418 if ( p_id ) {
00419 assert(false);
00420 #if 0
00421 T result;
00422 void* ret = propbase->getDataSource()->getBlob(p_id);
00423 if( A n y Conversion<T>::update( any.in() , result ) ) {
00424 return new Property<T>( propbase->getName(), propbase->getDescription(), result );
00425 }
00426 #endif
00427 }
00428 return 0;
00429 }
00430
00431 #if !defined(ORO_EMBEDDED) && defined(__GNUC__)
00432 extern template class Property<double>;
00433 extern template class Property<bool>;
00434 extern template class Property<float>;
00435 extern template class Property<int>;
00436 extern template class Property<unsigned int>;
00437 extern template class Property<std::string>;
00438 extern template class Property<const std::string &>;
00439 #endif
00440 }
00441
00442 #include "PropertyIntrospection.hpp"
00443
00444 namespace RTT
00445 {
00446 template< class T>
00447 void Property<T>::identify( PropertyIntrospection* pi)
00448 {
00449 pi->introspect( *this );
00450 }
00451
00452 template< class T>
00453 void Property<T>::identify( PropertyBagVisitor* pi)
00454 {
00455 return PropertyBase::identify(pi);
00456 }
00457
00458 template<>
00459 RTT_API void Property<PropertyBag>::identify( PropertyBagVisitor* pbi);
00460 }
00461
00462 #endif