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_COMMAND_REPOSITORY_HPP
00040 #define ORO_COMMAND_REPOSITORY_HPP
00041
00042 #include "DataSourceArgsCommand.hpp"
00043 #include "OperationFactory.hpp"
00044 #include "CommandC.hpp"
00045 #include "LocalCommand.hpp"
00046 #ifdef ORO_REMOTING
00047 #include "RemoteCommand.hpp"
00048 #endif
00049 #include "Logger.hpp"
00050 #include <boost/static_assert.hpp>
00051 #include <boost/type_traits/function_traits.hpp>
00052
00053 namespace RTT
00054 {
00060 class RTT_API CommandRepository
00061 : public OperationFactory<DispatchInterface*>
00062 {
00063 template<class T>
00064 inline T* getpointer(T& t) {
00065 return &t;
00066 }
00067 template<class T>
00068 inline T* getpointer(T* t) {
00069 return t;
00070 }
00071
00072 typedef std::map<std::string,DispatchInterface*> SimpleCommands;
00073 SimpleCommands simplecommands;
00074 public:
00075 typedef CommandFactory Factory;
00076
00077 ~CommandRepository();
00078
00089 template<class Signature>
00090 DispatchInterface* getCommand( std::string name )
00091 {
00092 Logger::In in("CommandRepository::getCommand");
00093 if ( simplecommands.count(name) ) {
00094 if ( dynamic_cast< detail::CommandBase<Signature>* >(simplecommands[name]) )
00095 return simplecommands[name]->clone();
00096 else
00097 log(Error) << "Command '"<< name <<"' found, but has wrong Signature."<<endlog();
00098 return 0;
00099 }
00100
00101 #ifdef ORO_REMOTING
00102 if ( this->hasMember(name ) ) {
00103 return new detail::RemoteCommand<Signature>(this, name);
00104 }
00105 #endif
00106 log(Warning) << "No such command: "<< name <<endlog();
00107 return 0;
00108 }
00109
00113 void clear();
00114
00119 std::vector<std::string> getCommands() const;
00120
00125 bool hasCommand(const std::string& name) const;
00126
00130 void removeCommand(const std::string& name);
00131
00141 template<class CommandT>
00142 bool addCommand( CommandT* com )
00143 {
00144 Logger::In in("CommandRepository");
00145 if ( simplecommands.count( com->getName() ) ) {
00146 log(Error) << "Failed to addCommand: '"<< com->getName() <<"' already added." <<endlog();
00147 return false;
00148 }
00149 if ( com->getName().empty() || !com->ready() ) {
00150 log(Error) << "Failed to addCommand: '"<< com->getName() <<"' was not ready() or has no name." <<endlog();
00151 return false;
00152 }
00153 simplecommands[com->getName()] = com->getCommandImpl()->clone();
00154 this->add(com->getName(), 0);
00155 return true;
00156 }
00157
00158
00167 template<class CommandT>
00168 bool addCommand( CommandT com, const char* description)
00169 {
00170 Logger::In in("CommandRepository");
00171 typedef typename boost::remove_pointer<CommandT>::type CommandVT;
00172 typedef typename boost::add_pointer<CommandVT>::type CommandPT;
00173 typedef typename CommandVT::Signature ComSig;
00174 BOOST_STATIC_ASSERT( boost::function_traits<typename CommandVT::Signature>::arity == 0 );
00175
00176 CommandPT c = this->getpointer(com);
00177 detail::LocalCommand<ComSig>* lc = dynamic_cast<detail::LocalCommand<ComSig>*>( c->getCommandImpl() );
00178
00179 if ( !lc ) {
00180 log(Error) << "Failed to addCommand: '"<< c->getName() <<"' is not a local command." <<endlog();
00181 return false;
00182 }
00183
00184 if ( this->addCommand( c ) == false )
00185 return false;
00186
00187 this->add( c->getName(), new detail::OperationFactoryPart0<DispatchInterface*, detail::DataSourceArgsCommand<ComSig> >(
00188 detail::DataSourceArgsCommand<ComSig>(lc->getCommandFunction(),
00189 lc->getConditionFunction(),
00190 lc->getCommandProcessor(), lc->isInverted() ), description) );
00191 return true;
00192 }
00193
00206 template<class CommandT>
00207 bool addCommand( CommandT com, const char* description,
00208 const char* arg1, const char* arg1_description)
00209 {
00210 Logger::In in("CommandRepository");
00211 typedef typename boost::remove_pointer<CommandT>::type CommandVT;
00212 typedef typename boost::add_pointer<CommandVT>::type CommandPT;
00213 typedef typename CommandVT::Signature ComSig;
00214 BOOST_STATIC_ASSERT( boost::function_traits<typename CommandVT::Signature>::arity == 1 );
00215
00216 CommandPT c = this->getpointer(com);
00217 detail::LocalCommand<ComSig>* lc = dynamic_cast<detail::LocalCommand<ComSig>*>( c->getCommandImpl() );
00218 if ( !lc ) {
00219 log(Error) << "Failed to addCommand: '"<< c->getName() <<"' is not a local command." <<endlog();
00220 return false;
00221 }
00222 if ( this->addCommand( c ) == false )
00223 return false;
00224 this->add( c->getName(), new detail::OperationFactoryPart1<DispatchInterface*, detail::DataSourceArgsCommand<ComSig> >(
00225 detail::DataSourceArgsCommand<ComSig>(lc->getCommandFunction(),
00226 lc->getConditionFunction(),
00227 lc->getCommandProcessor(), lc->isInverted() ),
00228 description, arg1, arg1_description) );
00229 return true;
00230 }
00231
00246 template<class CommandT>
00247 bool addCommand( CommandT com, const char* description,
00248 const char* arg1, const char* arg1_description,
00249 const char* arg2, const char* arg2_description)
00250 {
00251 Logger::In in("CommandRepository");
00252 typedef typename boost::remove_pointer<CommandT>::type CommandVT;
00253 typedef typename boost::add_pointer<CommandVT>::type CommandPT;
00254 typedef typename CommandVT::Signature ComSig;
00255 BOOST_STATIC_ASSERT( boost::function_traits<typename CommandVT::Signature>::arity == 2 );
00256
00257 CommandPT c = this->getpointer(com);
00258 detail::LocalCommand<ComSig>* lc = dynamic_cast<detail::LocalCommand<ComSig>*>( c->getCommandImpl() );
00259 if ( !lc ) {
00260 log(Error) << "Failed to addCommand: '"<< c->getName() <<"' is not a local command." <<endlog();
00261 return false;
00262 }
00263 if ( this->addCommand( c ) == false )
00264 return false;
00265 this->add( c->getName(), new detail::OperationFactoryPart2<DispatchInterface*, detail::DataSourceArgsCommand<ComSig> >(
00266 detail::DataSourceArgsCommand<ComSig>(lc->getCommandFunction(),
00267 lc->getConditionFunction(),
00268 lc->getCommandProcessor(), lc->isInverted() ),
00269 description, arg1, arg1_description,
00270 arg2, arg2_description) );
00271 return true;
00272 }
00273
00274
00291 template<class CommandT>
00292 bool addCommand( CommandT com, const char* description,
00293 const char* arg1, const char* arg1_description,
00294 const char* arg2, const char* arg2_description,
00295 const char* arg3, const char* arg3_description)
00296 {
00297 Logger::In in("CommandRepository");
00298 typedef typename boost::remove_pointer<CommandT>::type CommandVT;
00299 typedef typename boost::add_pointer<CommandVT>::type CommandPT;
00300 typedef typename CommandVT::Signature ComSig;
00301 BOOST_STATIC_ASSERT( boost::function_traits<typename CommandVT::Signature>::arity == 3 );
00302
00303 CommandPT c = this->getpointer(com);
00304 detail::LocalCommand<ComSig>* lc = dynamic_cast<detail::LocalCommand<ComSig>*>( c->getCommandImpl() );
00305 if ( !lc ) {
00306 log(Error) << "Failed to addCommand: '"<< c->getName() <<"' is not a local command." <<endlog();
00307 return false;
00308 }
00309 if ( this->addCommand( c ) == false )
00310 return false;
00311 this->add( c->getName(), new detail::OperationFactoryPart3<DispatchInterface*, detail::DataSourceArgsCommand<ComSig> >(
00312 detail::DataSourceArgsCommand<ComSig>(lc->getCommandFunction(),
00313 lc->getConditionFunction(),
00314 lc->getCommandProcessor(), lc->isInverted() ),
00315 description, arg1, arg1_description,
00316 arg2, arg2_description,
00317 arg3, arg3_description) );
00318 return true;
00319 }
00320
00339 template<class CommandT>
00340 bool addCommand( CommandT com, const char* description,
00341 const char* arg1, const char* arg1_description,
00342 const char* arg2, const char* arg2_description,
00343 const char* arg3, const char* arg3_description,
00344 const char* arg4, const char* arg4_description)
00345 {
00346 Logger::In in("CommandRepository");
00347 typedef typename boost::remove_pointer<CommandT>::type CommandVT;
00348 typedef typename boost::add_pointer<CommandVT>::type CommandPT;
00349 typedef typename CommandVT::Signature ComSig;
00350 BOOST_STATIC_ASSERT( boost::function_traits<typename CommandVT::Signature>::arity == 4 );
00351
00352 CommandPT c = this->getpointer(com);
00353 detail::LocalCommand<ComSig>* lc = dynamic_cast<detail::LocalCommand<ComSig>*>( c->getCommandImpl() );
00354 if ( !lc ) {
00355 log(Error) << "Failed to addCommand: '"<< c->getName() <<"' is not a local command." <<endlog();
00356 return false;
00357 }
00358 if ( this->addCommand( c ) == false )
00359 return false;
00360 this->add( c->getName(), new detail::OperationFactoryPart4<DispatchInterface*, detail::DataSourceArgsCommand<ComSig> >(
00361 detail::DataSourceArgsCommand<ComSig>(lc->getCommandFunction(),
00362 lc->getConditionFunction(),
00363 lc->getCommandProcessor(), lc->isInverted() ),
00364 description, arg1, arg1_description,
00365 arg2, arg2_description,
00366 arg3, arg3_description,
00367 arg4, arg4_description) );
00368 return true;
00369 }
00370
00379 DispatchInterface* getCommand( std::string name,
00380 const std::vector<DataSourceBase::shared_ptr>& args) const
00381 {
00382 return this->produce(name, args);
00383 }
00384
00390 template<class CommandT,class CompT>
00391 bool addCommandDS( DataSource< boost::weak_ptr<CompT> >* wp, CommandT c, const char* description)
00392 {
00393 using namespace detail;
00394 typedef typename CommandT::Signature ComSig;
00395 if ( this->hasMember(c.getName() ) )
00396 return false;
00397 typedef FunctorDS0<ComSig> CommandF;
00398 typedef detail::DataSourceArgsCommand<ComSig,
00399 CommandF> DSComm;
00400 this->add( c.getName(), new detail::OperationFactoryPart0<DispatchInterface*, DSComm>(
00401 DSComm( CommandF(wp, c.getCommandFunction()),
00402 CommandF(wp, c.getConditionFunction()),
00403 c.getCommandProcessor(), c.isInverted() ),
00404 description) );
00405 return true;
00406 }
00407
00413 template<class CommandT, class CompT>
00414 bool addCommandDS( DataSource<boost::weak_ptr<CompT> >* wp, CommandT c, const char* description,
00415 const char* arg1, const char* arg1_description)
00416 {
00417 using namespace detail;
00418 typedef typename CommandT::Signature ComSig;
00419 typedef FunctorDS1<ComSig> CommandF;
00420 typedef detail::DataSourceArgsCommand<ComSig,
00421 CommandF> DSComm;
00422 if ( this->hasMember(c.getName() ) )
00423 return false;
00424 this->add( c.getName(), new detail::OperationFactoryPart1<DispatchInterface*, DSComm, typename DSComm::traits::arg2_type>(
00425 DSComm( CommandF(wp, c.getCommandFunction()),
00426 CommandF(wp, c.getConditionFunction()),
00427 c.getCommandProcessor(), c.isInverted() ),
00428 description, arg1, arg1_description) );
00429 return true;
00430 }
00431
00440 ConditionInterface* getCondition( std::string name,
00441 const std::vector<DataSourceBase::shared_ptr>& args) const
00442 {
00443 DispatchInterface* di = this->produce(name, args);
00444 ConditionInterface* ret = di->createCondition();
00445 delete di;
00446 return ret;
00447 }
00448
00457 CommandC create(std::string name) {
00458 return CommandC( this, name );
00459 }
00460
00461
00462 };
00463
00464 }
00465
00466
00467 #endif