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 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             // try to update from identical type or from const_reference_t.
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             // refresh is just an update of the datasource.
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         // If this property is a proxy:
00414         int p_id = prop->getDataSource()->serverProtocol();
00415         if ( p_id ) {
00416             assert(false); // untested code.
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

Generated on Tue Aug 25 14:17:23 2009 for Orocos Real-Time Toolkit by  doxygen 1.5.8