$search
00001 /*************************************************************************** 00002 tag: Peter Soetens Mon Jan 19 14:11:19 CET 2004 Property.hpp 00003 00004 Property.hpp - description 00005 ------------------- 00006 begin : Mon January 19 2004 00007 copyright : (C) 2004 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 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 // need to do this on the clone() in order to have access to set()/rvalue() of the data source. 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 // need to do this on the datasource in order to have access to set()/rvalue() of the data source. 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 // wrong assignment: mark not ready. 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