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
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
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