Property.hpp

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 "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             // try to update from identical type or from const_reference_t.
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             // refresh is just an update of the datasource.
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         // If this property is a proxy:
00417         int p_id = prop->getDataSource()->serverProtocol();
00418         if ( p_id ) {
00419             assert(false); // untested code.
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
Generated on Thu Dec 23 13:22:38 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3