OperationFactory.hpp

Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: FMTC  do nov 2 13:06:07 CET 2006  OperationFactory.hpp
00003 
00004                         OperationFactory.hpp -  description
00005                            -------------------
00006     begin                : do november 02 2006
00007     copyright            : (C) 2006 FMTC
00008     email                : peter.soetens@fmtc.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 
00039 #ifndef ORO_OPERATION_FACTORY_HPP
00040 #define ORO_OPERATION_FACTORY_HPP
00041 
00042 
00043 #include <boost/bind.hpp>
00044 #include <boost/weak_ptr.hpp>
00045 #include <boost/shared_ptr.hpp>
00046 
00047 #include <vector>
00048 #include <map>
00049 #include <algorithm>
00050 #include <functional>
00051 #include <string>
00052 
00053 #include "mystd.hpp"
00054 
00055 #include "PropertyBag.hpp"
00056 #include "Property.hpp"
00057 #include "DataSourceAdaptor.hpp"
00058 #include "Exceptions.hpp"
00059 #include "DataSource.hpp"
00060 #include "FactoryExceptions.hpp"
00061 #include "ArgumentDescription.hpp"
00062 #include "DispatchInterface.hpp"
00063 
00069 namespace RTT
00070 {
00071     namespace detail {
00072 
00090         template<typename ResultT>
00091         class OperationFactoryPart
00092         {
00093             const char* mdesc;
00094         public:
00095             OperationFactoryPart( const char* desc )
00096                 : mdesc( desc )
00097             {
00098             }
00099 
00100             virtual ~OperationFactoryPart() {};
00101 
00102             virtual std::string description() const
00103             {
00104                 return mdesc;
00105             }
00109             virtual std::string resultType() const = 0;
00110 
00115             virtual std::vector<ArgumentDescription> getArgumentList() const = 0;
00116 
00120             virtual int arity() const = 0;
00121 
00126             virtual ResultT produce( const std::vector<DataSourceBase::shared_ptr>& args ) const = 0;
00127         };
00128 
00129         template<typename ResultT, typename FunctorT>
00130         class OperationFactoryPart0
00131             : public OperationFactoryPart<ResultT>
00132         {
00133             typedef FunctorT fun_t;
00134             fun_t fun;
00135         public:
00136             template<class InitF>
00137             OperationFactoryPart0( InitF f, const char* desc )
00138                 : OperationFactoryPart<ResultT>( desc ), fun( f )
00139             {
00140             }
00141 
00142             std::string resultType() const
00143             {
00144                 return DataSource<typename FunctorT::result_type>::GetType();
00145             }
00146 
00147             int arity() const { return 0; }
00148 
00149             std::vector< ArgumentDescription > getArgumentList( ) const
00150             {
00151                 std::vector< ArgumentDescription > mlist;
00152                 return mlist;
00153             }
00154 
00155             ResultT produce(
00156                             const std::vector<DataSourceBase::shared_ptr>& args) const
00157             {
00158                 if ( ! args.empty() )
00159                     ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 0, args.size() ), ResultT());
00160                 return fun.create();
00161             }
00162         };
00163 
00164         template<typename ResultT, typename FunctorT, typename arg1_type = typename FunctorT::traits::arg1_type>
00165         class OperationFactoryPart1
00166             : public OperationFactoryPart<ResultT>
00167         {
00168             typedef FunctorT fun_t;
00169             fun_t fun;
00170             const char* arg1name;
00171             const char* arg1desc;
00172         public:
00173             template<class InitF>
00174             OperationFactoryPart1( InitF f, const char* desc,
00175                                    const char* a1n, const char* a1d )
00176                 : OperationFactoryPart<ResultT>( desc ),
00177                   fun( f ), arg1name( a1n ), arg1desc( a1d )
00178             {
00179             }
00180 
00181             std::string resultType() const
00182             {
00183                 return DataSource<typename FunctorT::result_type>::GetType();
00184             }
00185 
00186             std::vector< ArgumentDescription > getArgumentList( ) const
00187             {
00188                 std::vector< ArgumentDescription > mlist;
00189                 mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource<arg1_type>::GetType() ) );
00190                 return mlist;
00191             }
00192 
00193             int arity() const { return 1; }
00194 
00195             ResultT produce(
00196                             const std::vector<DataSourceBase::shared_ptr>& args) const
00197             {
00198                 if ( args.size() != 1 )
00199                     ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 1, args.size() ), ResultT());
00200                 typename DataSource<arg1_type>::shared_ptr a =
00201                     AdaptDataSource<arg1_type>()( DataSourceTypeInfo<arg1_type>::getTypeInfo()->convert(args[0]) );
00202                 if ( ! a )
00203                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource<arg1_type>::GetType(), args[0]->getType() ), ResultT());
00204                 return fun.create( a.get() );
00205             }
00206         };
00207 
00208         template<typename ResultT, typename FunctorT>
00209         class OperationFactoryPart2
00210             : public OperationFactoryPart<ResultT>
00211         {
00212             typedef FunctorT fun_t;
00213             typedef typename FunctorT::traits::arg1_type arg1_type;
00214             typedef typename FunctorT::traits::arg2_type arg2_type;
00215             fun_t fun;
00216             const char* arg1name;
00217             const char* arg1desc;
00218             const char* arg2name;
00219             const char* arg2desc;
00220         public:
00221             template<class InitF>
00222             OperationFactoryPart2( InitF f, const char* desc, const char* a1n,
00223                                    const char* a1d, const char* a2n,
00224                                    const char* a2d)
00225                 : OperationFactoryPart<ResultT>( desc ), fun( f ),
00226                   arg1name( a1n ), arg1desc( a1d ), arg2name( a2n ),
00227                   arg2desc( a2d )
00228             {
00229             }
00230 
00231             std::string resultType() const
00232             {
00233                 return DataSource<typename FunctorT::result_type>::GetType();
00234             }
00235 
00236             std::vector< ArgumentDescription > getArgumentList( ) const
00237             {
00238                 std::vector< ArgumentDescription > mlist;
00239                 mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource<arg1_type>::GetType() ) );
00240                 mlist.push_back( ArgumentDescription( arg2name, arg2desc, DataSource<arg2_type>::GetType() ) );
00241                 return mlist;
00242             }
00243 
00244             int arity() const { return 2; }
00245 
00246             ResultT produce(const std::vector<DataSourceBase::shared_ptr>& args) const
00247             {
00248                 if ( args.size() != 2 )
00249                     ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 2, args.size() ), ResultT());
00250 
00251                 typename DataSource<arg1_type>::shared_ptr a =
00252                     AdaptDataSource<arg1_type>()( DataSourceTypeInfo<arg1_type>::getTypeInfo()->convert(args[0]) );
00253                 if ( !a )
00254                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource<arg1_type>::GetType(), args[0]->getType() ), ResultT());
00255                 typename DataSource<arg2_type>::shared_ptr b =
00256                     AdaptDataSource<arg2_type>()( DataSourceTypeInfo<arg2_type>::getTypeInfo()->convert(args[1]) );
00257                 if ( !b )
00258                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 2, DataSource<arg2_type>::GetType(), args[1]->getType() ), ResultT());
00259 
00260                 return fun.create(a.get(), b.get() );
00261             }
00262         };
00263 
00264         template<typename ResultT, typename FunctorT>
00265         class OperationFactoryPart3
00266             : public OperationFactoryPart<ResultT>
00267         {
00268             typedef FunctorT fun_t;
00269             typedef typename FunctorT::traits::arg1_type arg1_type;
00270             typedef typename FunctorT::traits::arg2_type arg2_type;
00271             typedef typename FunctorT::traits::arg3_type arg3_type;
00272 
00273             fun_t fun;
00274             const char* arg1name;
00275             const char* arg1desc;
00276             const char* arg2name;
00277             const char* arg2desc;
00278             const char* arg3name;
00279             const char* arg3desc;
00280         public:
00281             template<class InitF>
00282             OperationFactoryPart3( InitF f, const char* desc, const char* a1n,
00283                                    const char* a1d, const char* a2n,
00284                                    const char* a2d, const char* a3n,
00285                                    const char* a3d )
00286                 : OperationFactoryPart<ResultT>( desc ), fun( f ),
00287                   arg1name( a1n ), arg1desc( a1d ),
00288                   arg2name( a2n ), arg2desc( a2d ),
00289                   arg3name( a3n ), arg3desc( a3d )
00290             {
00291             }
00292 
00293             std::string resultType() const
00294             {
00295                 return DataSource<typename FunctorT::result_type>::GetType();
00296             }
00297 
00298             std::vector< ArgumentDescription > getArgumentList( ) const
00299             {
00300                 std::vector< ArgumentDescription > mlist;
00301                 mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource<arg1_type>::GetType() ) );
00302                 mlist.push_back( ArgumentDescription( arg2name, arg2desc, DataSource<arg2_type>::GetType() ) );
00303                 mlist.push_back( ArgumentDescription( arg3name, arg3desc, DataSource<arg3_type>::GetType() ) );
00304                 return mlist;
00305             }
00306 
00307             int arity() const { return 3; }
00308 
00309             ResultT produce(const std::vector<DataSourceBase::shared_ptr>& args) const
00310             {
00311                 if ( args.size() != 3 )
00312                     ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 3, args.size() ), ResultT());
00313 
00314                 typename DataSource<arg1_type>::shared_ptr a =
00315                     AdaptDataSource<arg1_type>()( DataSourceTypeInfo<arg1_type>::getTypeInfo()->convert(args[0]) );
00316                 if ( !a )
00317                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource<arg1_type>::GetType(), args[0]->getType() ), ResultT());
00318                 typename DataSource<arg2_type>::shared_ptr b =
00319                     AdaptDataSource<arg2_type>()( DataSourceTypeInfo<arg2_type>::getTypeInfo()->convert(args[1]) );
00320                 if ( !b )
00321                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 2, DataSource<arg2_type>::GetType(), args[1]->getType() ), ResultT());
00322                 typename DataSource<arg3_type>::shared_ptr c =
00323                     AdaptDataSource<arg3_type>()( DataSourceTypeInfo<arg3_type>::getTypeInfo()->convert(args[2]) );
00324                 if ( !c )
00325                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 3, DataSource<arg3_type>::GetType(), args[2]->getType() ), ResultT());
00326 
00327                 return fun.create(a.get(), b.get(), c.get() );
00328             }
00329         };
00330 
00331         template<typename ResultT, typename FunctorT>
00332         class OperationFactoryPart4
00333             : public OperationFactoryPart<ResultT>
00334         {
00335             typedef FunctorT fun_t;
00336             typedef typename FunctorT::traits::arg1_type arg1_type;
00337             typedef typename FunctorT::traits::arg2_type arg2_type;
00338             typedef typename FunctorT::traits::arg3_type arg3_type;
00339             typedef typename FunctorT::traits::arg4_type arg4_type;
00340 
00341             fun_t fun;
00342             const char* arg1name;
00343             const char* arg1desc;
00344             const char* arg2name;
00345             const char* arg2desc;
00346             const char* arg3name;
00347             const char* arg3desc;
00348             const char* arg4name;
00349             const char* arg4desc;
00350         public:
00351             template<class InitF>
00352             OperationFactoryPart4( InitF f, const char* desc, const char* a1n,
00353                                    const char* a1d, const char* a2n,
00354                                    const char* a2d, const char* a3n,
00355                                    const char* a3d, const char* a4n,
00356                                    const char* a4d )
00357                 : OperationFactoryPart<ResultT>( desc ), fun( f ),
00358                   arg1name( a1n ), arg1desc( a1d ),
00359                   arg2name( a2n ), arg2desc( a2d ),
00360                   arg3name( a3n ), arg3desc( a3d ),
00361                   arg4name( a4n ), arg4desc( a4d )
00362             {
00363             }
00364 
00365             std::string resultType() const
00366             {
00367                 return DataSource<typename FunctorT::result_type>::GetType();
00368             }
00369 
00370             std::vector< ArgumentDescription > getArgumentList( ) const
00371             {
00372                 std::vector< ArgumentDescription > mlist;
00373                 mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource<arg1_type>::GetType() ) );
00374                 mlist.push_back( ArgumentDescription( arg2name, arg2desc, DataSource<arg2_type>::GetType() ) );
00375                 mlist.push_back( ArgumentDescription( arg3name, arg3desc, DataSource<arg3_type>::GetType() ) );
00376                 mlist.push_back( ArgumentDescription( arg4name, arg4desc, DataSource<arg4_type>::GetType() ) );
00377                 return mlist;
00378             }
00379 
00380             int arity() const { return 4; }
00381 
00382             ResultT produce(const std::vector<DataSourceBase::shared_ptr>& args) const
00383             {
00384                 if ( args.size() != 4 )
00385                     ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 4, args.size() ), ResultT());
00386 
00387                 typename DataSource<arg1_type>::shared_ptr a =
00388                     AdaptDataSource<arg1_type>()( DataSourceTypeInfo<arg1_type>::getTypeInfo()->convert(args[0]) );
00389                 if ( !a )
00390                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource<arg1_type>::GetType(), args[0]->getType() ), ResultT());
00391                 typename DataSource<arg2_type>::shared_ptr b =
00392                     AdaptDataSource<arg2_type>()( DataSourceTypeInfo<arg2_type>::getTypeInfo()->convert(args[1]) );
00393                 if ( !b )
00394                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 2, DataSource<arg2_type>::GetType(), args[1]->getType() ), ResultT());
00395                 typename DataSource<arg3_type>::shared_ptr c =
00396                     AdaptDataSource<arg3_type>()( DataSourceTypeInfo<arg3_type>::getTypeInfo()->convert(args[2]) );
00397                 if ( !c )
00398                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 3, DataSource<arg3_type>::GetType(), args[2]->getType() ), ResultT());
00399                 typename DataSource<arg4_type>::shared_ptr d =
00400                     AdaptDataSource<arg4_type>()( DataSourceTypeInfo<arg4_type>::getTypeInfo()->convert(args[3]) );
00401                 if ( !d )
00402                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 4, DataSource<arg4_type>::GetType(), args[3]->getType() ), ResultT());
00403 
00404                 return fun.create(a.get(), b.get(), c.get(), d.get() );
00405             }
00406         };
00410     }
00411 
00415     template<typename ResultT>
00416     class OperationFactory
00417     {
00418     protected:
00419         typedef std::map<std::string, detail::OperationFactoryPart<ResultT>* > map_t;
00420         map_t data;
00421     public:
00425         typedef std::vector<ArgumentDescription> Descriptions;
00426 
00430         typedef std::vector<DataSourceBase::shared_ptr> Arguments;
00431 
00435         void clear() {
00436             for ( typename map_t::iterator i = data.begin(); i != data.end(); ++i )
00437                 delete i->second;
00438             data.clear();
00439         }
00440 
00444         std::vector<std::string> getNames() const
00445         {
00446             std::vector<std::string> ret;
00447             std::transform( data.begin(), data.end(),
00448                             std::back_inserter( ret ),
00449                             select1st<typename map_t::value_type>() );
00450             return ret;
00451         }
00452 
00456         bool hasMember( const std::string& name ) const
00457         {
00458             return data.find( name ) != data.end();
00459         }
00460 
00468         int getArity( const std::string& name ) const
00469         {
00470             typename map_t::const_iterator i = data.find( name );
00471             if ( i == data.end() || i->second == 0 ) return -1;
00472             return i->second->arity();
00473         }
00482         ResultT produce( const std::string& name, const PropertyBag& args ) const
00483         {
00484             typename map_t::const_iterator i = data.find( name );
00485             if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT());
00486             std::vector<DataSourceBase::shared_ptr> dsVect;
00487             std::transform( args.begin(), args.end(),
00488                             std::back_inserter( dsVect ),
00489                             boost::bind( &PropertyBase::getDataSource, _1));
00490             return i->second->produce(dsVect);
00491         }
00492 
00501         ResultT produce( const std::string& name,
00502                          const std::vector<DataSourceBase::shared_ptr>& args ) const
00503         {
00504             typename map_t::const_iterator i = data.find( name );
00505             if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT());
00506             return i->second->produce( args );
00507         }
00508 
00516         Descriptions getArgumentList( const std::string& name ) const
00517         {
00518             typename map_t::const_iterator i = data.find( name );
00519             if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), Descriptions());
00520             return i->second->getArgumentList();
00521         }
00522 
00530         std::string getResultType( const std::string& name ) const
00531         {
00532             typename map_t::const_iterator i = data.find( name );
00533             if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string());
00534             return i->second->resultType();
00535         }
00536 
00544         std::string getDescription( const std::string& name ) const
00545         {
00546             typename map_t::const_iterator i = data.find( name );
00547             if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string());
00548             return i->second->description();
00549         }
00550 
00557         void add( const std::string& name,
00558                   detail::OperationFactoryPart<ResultT>* part )
00559         {
00560             typename map_t::iterator i = data.find( name );
00561             // XXX, wouldn't it be better to throw ?
00562             if ( i != data.end() )
00563                 delete i->second;
00564             data[name] = part;
00565         }
00566 
00572         void remove( const std::string& name )
00573         {
00574             typename map_t::iterator i = data.find( name );
00575             if ( i != data.end() ) {
00576                 delete i->second;
00577                 data.erase(i);
00578             }
00579         }
00580     };
00581 
00582     typedef OperationFactory<DispatchInterface*> CommandFactory;
00583     typedef OperationFactory<DataSourceBase*> MethodFactory;
00584 }
00585 
00586 #endif
Generated on Thu Dec 23 13:22:38 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3