From 469e4c74c204d6f7b80ffee32017c279f59eb9ba Mon Sep 17 00:00:00 2001 From: psoetens Date: Thu, 20 Jul 2006 09:29:40 +0000 Subject: [PATCH] Patch for Project #104: Commands and Methods : Away with the Template* classes The TaskContext interface has been changed to the 'CommandRepository' and 'MethodRepository' for commands and methods. Use the commands.pl script to convert your app. git-svn-id: https://svn.mech.kuleuven.be/repos/orocos/orocos-trunk@5146 ce417995-dfc9-0310-95a0-acdaff106893 --- .../current/include/TemplateTypeInfo.hpp | 10 +- .../common/current/include/TypeInfoName.hpp | 7 + .../corelib/common/current/include/Types.hpp | 5 + .../corelib/events/current/include/Event.hpp | 1 - .../current/cdl/program_parser.cdl | 2 +- .../current/include/FunctionFactory.hpp | 39 +- .../current/include/TaskBrowser.hpp | 15 +- .../current/src/CommandParser.cxx | 115 +-- .../current/src/ExpressionParser.cxx | 121 +-- .../current/src/FunctionFactory.cxx | 101 +- .../current/src/GenericTaskContext.cxx | 62 +- .../current/src/ProgramGraphParser.cxx | 11 +- .../current/src/StateGraphParser.cxx | 3 +- .../current/src/TaskBrowser.cxx | 161 +-- .../current/src/ValueChangeParser.cxx | 1 + .../current/include/CommandDispatch.hpp | 3 +- .../current/include/StateMachine.hpp | 11 + .../current/include/StateMachineTask.hpp | 4 +- .../current/src/CommandDispatch.cxx | 2 +- .../current/src/ProgramTask.cxx | 41 +- .../current/src/StateMachineTask.cxx | 103 +- .../current/doc/orocos-task-context.xml | 387 +++---- .../current/include/BindStorage.hpp | 1 - .../current/include/BufferPort.hpp | 269 ++++- .../task_context/current/include/Command.hpp | 62 +- .../task_context/current/include/CommandC.hpp | 5 +- .../current/include/CommandDS.hpp | 7 + .../current/include/CommandDSFunctors.hpp | 16 +- .../current/include/CommandFunctors.hpp | 20 +- .../current/include/CommandRepository.hpp | 324 ++++++ .../task_context/current/include/DataPort.hpp | 30 +- .../current/include/DataSourceArgsCommand.hpp | 161 +++ .../current/include/DataSourceArgsMethod.hpp | 104 ++ .../current/include/DataSourceStorage.hpp | 165 +++ .../current/include/EventService.hpp | 32 +- .../task_context/current/include/Invoker.hpp | 15 +- .../current/include/LocalCommand.hpp | 10 +- .../current/include/LocalMethod.hpp | 2 + .../task_context/current/include/Method.hpp | 22 + .../task_context/current/include/MethodC.hpp | 4 +- .../current/include/MethodRepository.hpp | 258 +++++ .../task_context/current/include/NA.hpp | 17 +- .../current/include/OperationFactory.hpp | 956 +++++++++--------- .../current/include/OperationInterface.hpp | 731 +------------ .../current/include/PortInterface.hpp | 8 +- .../current/include/RemoteCommand.hpp | 155 +++ .../current/include/TaskContext.hpp | 32 +- .../task_context/current/include/TaskCore.hpp | 27 +- .../task_context/current/include/UnMember.hpp | 33 + .../task_context/current/src/CommandC.cxx | 10 +- .../task_context/current/src/MethodC.cxx | 8 +- .../current/src/PortInterface.cxx | 2 +- .../task_context/current/src/TaskContext.cxx | 46 +- packages/templates/allpackages/current.ect | 11 - packages/templates/dist-packages/current.ect | 10 - tests/dispatch_test.cpp | 73 +- tests/dispatch_test.hpp | 4 +- tests/function_test.cpp | 91 +- tests/function_test.hpp | 5 +- tests/generictask_test.cpp | 118 +-- tests/generictask_test.hpp | 8 +- tests/logger_test.cpp | 14 + tests/logger_test.hpp | 2 + tests/program_test.cpp | 94 +- tests/program_test.hpp | 6 +- tests/state_test.cpp | 106 +- tests/state_test.hpp | 3 +- tests/template_factory_test.cpp | 116 +-- tests/template_factory_test.hpp | 8 +- tests/types_test.cpp | 41 +- tests/types_test.hpp | 2 +- 71 files changed, 2942 insertions(+), 2507 deletions(-) create mode 100644 packages/execution/task_context/current/include/CommandRepository.hpp create mode 100644 packages/execution/task_context/current/include/DataSourceArgsCommand.hpp create mode 100644 packages/execution/task_context/current/include/DataSourceArgsMethod.hpp create mode 100644 packages/execution/task_context/current/include/DataSourceStorage.hpp create mode 100644 packages/execution/task_context/current/include/MethodRepository.hpp create mode 100644 packages/execution/task_context/current/include/RemoteCommand.hpp diff --git a/packages/corelib/common/current/include/TemplateTypeInfo.hpp b/packages/corelib/common/current/include/TemplateTypeInfo.hpp index eb525da4b..04091f0a5 100644 --- a/packages/corelib/common/current/include/TemplateTypeInfo.hpp +++ b/packages/corelib/common/current/include/TemplateTypeInfo.hpp @@ -187,7 +187,15 @@ namespace ORO_CoreLib // A variable starts its life as unbounded. Logger::log() << Logger::Debug << "Building Variable of type " << tname <( new detail::UnboundDataSource >() ); - //return new ScriptAttribute(); + } + + DataSourceBase::shared_ptr construct(const std::vector& args) const + { + // It must start its life as unbounded. + Logger::log() << Logger::Debug << "Constructor of " << tname < >(); + return DataSourceBase::shared_ptr(); } AttributeBase* buildAttribute( DataSourceBase::shared_ptr in) const diff --git a/packages/corelib/common/current/include/TypeInfoName.hpp b/packages/corelib/common/current/include/TypeInfoName.hpp index afefa30ce..f8f62989d 100644 --- a/packages/corelib/common/current/include/TypeInfoName.hpp +++ b/packages/corelib/common/current/include/TypeInfoName.hpp @@ -94,6 +94,13 @@ namespace ORO_CoreLib return 0; } + DataSourceBase::shared_ptr construct(const std::vector& ) const { + Logger::In loc("TypeInfoName"); + Logger::log() << Logger::Error << "Can not construct value of "<& args) const = 0; /** * build an alias with b as the value. If b is of the wrong type, * 0 will be returned.. diff --git a/packages/corelib/events/current/include/Event.hpp b/packages/corelib/events/current/include/Event.hpp index 4479d0145..d60025992 100644 --- a/packages/corelib/events/current/include/Event.hpp +++ b/packages/corelib/events/current/include/Event.hpp @@ -102,7 +102,6 @@ namespace ORO_CoreLib Event() : signal_base_type() { - Logger::log() << Logger::Debug << "Nameless Event Created." << Logger::endl; } const std::string& getName() const { return mname; } diff --git a/packages/execution/program_parser/current/cdl/program_parser.cdl b/packages/execution/program_parser/current/cdl/program_parser.cdl index e1ef12612..793e0ed16 100644 --- a/packages/execution/program_parser/current/cdl/program_parser.cdl +++ b/packages/execution/program_parser/current/cdl/program_parser.cdl @@ -21,11 +21,11 @@ is very powerful." compile PeerParser.cxx compile PropertyParser.cxx compile FunctionFactory.cxx - compile TaskBrowser.cxx compile ProgramLoader.cxx compile GenericTaskContext.cxx compile StatementProcessor.cxx compile ParserScriptingAccess.cxx + compile TaskBrowser.cxx requires OROPKG_SUPPORT_BOOST requires OROPKG_SUPPORT_BOOST_GRAPH diff --git a/packages/execution/program_parser/current/include/FunctionFactory.hpp b/packages/execution/program_parser/current/include/FunctionFactory.hpp index d7e126bcb..788ad630b 100644 --- a/packages/execution/program_parser/current/include/FunctionFactory.hpp +++ b/packages/execution/program_parser/current/include/FunctionFactory.hpp @@ -29,11 +29,12 @@ #ifndef FUNCTIONFACTORY_HPP #define FUNCTIONFACTORY_HPP -#include "CommandFactoryInterface.hpp" +#include "OperationFactory.hpp" #include "corelib/Property.hpp" #include #include #include "ProgramInterface.hpp" +#include "DispatchInterface.hpp" namespace ORO_Execution { @@ -47,41 +48,25 @@ namespace ORO_Execution * a FunctionGraph in a Processor. */ class FunctionFactory - : public CommandFactoryInterface + : public detail::OperationFactoryPart { - typedef std::map map_t; - map_t funcmap; + ProgramInterfacePtr func; ExecutionEngine* proc; public: - FunctionFactory(ExecutionEngine* procs); - ~FunctionFactory(); + FunctionFactory(ProgramInterfacePtr func, ExecutionEngine* procs); - void addFunction(const std::string& name, ProgramInterfacePtr f ) ; - - bool hasCommand(const std::string& com) const ; - - std::vector getCommandList() const; - - std::string getResultType( const std::string& com ) const; - std::string getDescription( const std::string& com ) const; + std::string resultType() const; + std::string description() const; ORO_CoreLib::PropertyBag - getArgumentSpec( const std::string& command ) const; - - std::vector< ArgumentDescription > getArgumentList( const std::string& command ) const; + getArgumentSpec() const; - int getArity( const std::string& foo ) const; - ComCon create( const std::string& command, - const ORO_CoreLib::PropertyBag& args, - bool nodispatch ) const; + std::vector< ArgumentDescription > getArgumentList() const; - ComCon create(const std::string& command, - const std::vector& args, - bool nodispatch ) const; + int arity() const; - ComCon create(const std::string& command, - const std::vector& args, - bool nodispatch ) const; + DispatchInterface* produce(const std::vector& args + ) const; }; } diff --git a/packages/execution/program_parser/current/include/TaskBrowser.hpp b/packages/execution/program_parser/current/include/TaskBrowser.hpp index 1e8f72c2b..0a1d08847 100644 --- a/packages/execution/program_parser/current/include/TaskBrowser.hpp +++ b/packages/execution/program_parser/current/include/TaskBrowser.hpp @@ -30,9 +30,7 @@ #define ORO_TASKBROWSER_HPP -#include "MethodFactoryInterface.hpp" -#include "DataSourceFactoryInterface.hpp" -#include "CommandFactoryInterface.hpp" +#include "OperationInterface.hpp" #include "DispatchInterface.hpp" #include #include @@ -71,9 +69,6 @@ namespace ORO_Execution ORO_CoreLib::ConditionInterface* condition; DispatchInterface* command; ORO_CoreLib::DataSource::shared_ptr accepted; - const CommandFactoryInterface* command_fact; - const DataSourceFactoryInterface* datasource_fact; - const MethodFactoryInterface* method_fact; int debug; /* A static variable for holding the line. */ @@ -109,11 +104,9 @@ namespace ORO_Execution static void find_completes(); - static void find_command(std::string::size_type startpos); + static void find_ops(std::string::size_type startpos); static void find_peers(std::string::size_type startpos); - static void find_datasource(std::string::size_type startpos); - static void find_method(std::string::size_type startpos); static void find_attribute(std::string::size_type startpos); @@ -182,7 +175,7 @@ namespace ORO_Execution /** * Print the synopsis of a command. */ - void printCommand( const std::string c ); + void printCommand( const std::string c, OperationInterface* ops ); /** * Print the synopsis of a DataSource. @@ -192,7 +185,7 @@ namespace ORO_Execution /** * Print the synopsis of a Method. */ - void printMethod( const std::string m ); + void printMethod( const std::string m, OperationInterface* ops ); /** * Print a program listing of a loaded program centered at line \a line. diff --git a/packages/execution/program_parser/current/src/CommandParser.cxx b/packages/execution/program_parser/current/src/CommandParser.cxx index 39de09ea2..3ca93f0d0 100644 --- a/packages/execution/program_parser/current/src/CommandParser.cxx +++ b/packages/execution/program_parser/current/src/CommandParser.cxx @@ -42,8 +42,6 @@ #include "corelib/CommandDataSource.hpp" #include "corelib/ConditionTrue.hpp" #include "corelib/ConditionOnce.hpp" -#include "execution/GlobalCommandFactory.hpp" -#include "execution/CommandFactoryInterface.hpp" #include "execution/AsynchCommandDecorator.hpp" @@ -124,33 +122,23 @@ namespace ORO_Execution peer = peerparser.peer(); peerparser.reset(); - const GlobalCommandFactory* gcf = - peer->commands(); - const GlobalMethodFactory* gmf = - peer->methods(); - const GlobalDataSourceFactory* gdf = - peer->datasources(); - const CommandFactoryInterface* cfi = gcf->getObjectFactory( mcurobject ); - const MethodFactoryInterface* mfi = gmf->getObjectFactory( mcurobject ); - const DataSourceFactoryInterface* dfi = gdf->getObjectFactory( mcurobject ); - - // In case the object is not found : - if ( ! cfi && ! mfi && ! dfi) { - if ( mcurobject == "this" ) - mcurobject = mcurmethod; - else - mcurobject = mcurobject + "." + mcurmethod; - throw parse_exception_no_such_component( peer->getName(), mcurobject ); - } - - // In case the method/command is not found : - if ( !( ( cfi && cfi->hasCommand(mcurmethod)) || ( mfi && mfi->hasMember(mcurmethod)) || ( dfi && dfi->hasMember(mcurmethod)) ) ) - throw parse_exception_no_such_method_on_component( mcurobject, mcurmethod ); + OperationInterface* obj = 0; + if (mcurobject != "this") + if ( (obj = peer->getObject(mcurobject)) == 0 ) + throw parse_exception_no_such_component( peer->getName(), mcurobject+"."+mcurmethod ); + else { + if ( obj->methods()->hasMember(mcurmethod) == false && obj->commands()->hasMember(mcurmethod) == false) + throw parse_exception_no_such_method_on_component( mcurobject, mcurmethod ); + } + else { + if ( peer->methods()->hasMember(mcurmethod) == false && peer->commands()->hasMember(mcurmethod) == false) + throw parse_exception_no_such_method_on_component( peer->getName(), mcurmethod ); + } - // we found it ! - argsparser = new ArgumentsParser( expressionparser, peer, + // ok object and method are found. + argsparser = new ArgumentsParser( expressionparser, peer, mcurobject, mcurmethod ); - arguments = argsparser->parser(); + arguments = argsparser->parser(); } void CommandParser::seencallcommand() @@ -161,62 +149,37 @@ namespace ORO_Execution mcurobject = argsparser->objectname(); mcurmethod = argsparser->methodname(); - const GlobalCommandFactory* gcf = - peer->commands(); - const GlobalMethodFactory* gmf = - peer->methods(); - const GlobalDataSourceFactory* gdf = - peer->datasources(); - const CommandFactoryInterface* cfi = gcf->getObjectFactory( mcurobject ); - const MethodFactoryInterface* mfi = gmf->getObjectFactory( mcurobject ); - const DataSourceFactoryInterface* dfi = gdf->getObjectFactory( mcurobject ); - - // cfi should exist, because otherwise we would have noticed in - // seenstartofcall()... - assert( cfi || mfi || dfi); + OperationInterface* obj = 0; + CommandRepository::Factory* cfi = 0; + MethodRepository::Factory* mfi = 0; + if ( mcurobject != "this" ) { + obj = peer->getObject(mcurobject); + assert(obj); + mfi = obj->methods(); + cfi = obj->commands(); + } else { + mfi = peer->methods(); + cfi = peer->commands(); + } + assert(mfi); + assert(cfi); ComCon comcon; - if ( cfi && cfi->hasCommand( mcurmethod ) ) + if ( cfi->hasMember( mcurmethod ) ) try { // check if dispatching is required: + // This check is done, here but we always dispatch anyway, + // to allow CommandProcessor policies to be in effect. if ( peer->engine()->commands() != context->engine()->commands() || mdispatch ) { // different, dispatch: - comcon = cfi->create( mcurmethod, argsparser->result(), false ); - dcom = dynamic_cast( comcon.first ); - assert( dcom ); + dcom = cfi->produce( mcurmethod, argsparser->result() );// ,false ); } else { // within same execution engine, no dispatch: - comcon = cfi->create( mcurmethod, argsparser->result(), true ); + dcom = cfi->produce( mcurmethod, argsparser->result() );//, true ); } - - } - catch( const wrong_number_of_args_exception& e ) - { - throw parse_exception_wrong_number_of_arguments - (mcurobject, mcurmethod, e.wanted, e.received ); - } - catch( const wrong_types_of_args_exception& e ) - { - throw parse_exception_wrong_type_of_argument - ( mcurobject, mcurmethod, e.whicharg, e.expected_, e.received_ ); - } - catch( ... ) - { - assert( false ); - } - else if ( mfi && mfi->hasMember( mcurmethod ) ) - try - { - // if the method returns a boolean, construct it as a command - // which accepts/rejects the result. - DataSourceBase* dsb = mfi->create( mcurmethod, argsparser->result() ); - DataSource* dsb_res = DataSource::narrow( dsb ); - if ( dsb_res == 0 ) - comcon.first = new CommandDataSource( dsb ); - else - comcon.first = new CommandDataSourceBool( dsb_res ); - comcon.second = new ConditionTrue(); + comcon.first = dcom; + comcon.second = dcom->createCondition(); } catch( const wrong_number_of_args_exception& e ) { @@ -232,12 +195,12 @@ namespace ORO_Execution { assert( false ); } - else if ( dfi && dfi->hasMember( mcurmethod ) ) + else if ( mfi->hasMember( mcurmethod ) ) try { // if the method returns a boolean, construct it as a command // which accepts/rejects the result. - DataSourceBase* dsb = dfi->create( mcurmethod, argsparser->result() ); + DataSourceBase* dsb = mfi->produce( mcurmethod, argsparser->result() ); DataSource* dsb_res = DataSource::narrow( dsb ); if ( dsb_res == 0 ) comcon.first = new CommandDataSource( dsb ); @@ -259,8 +222,6 @@ namespace ORO_Execution { assert( false ); } - else - assert(false); mcurobject.clear(); mcurmethod.clear(); diff --git a/packages/execution/program_parser/current/src/ExpressionParser.cxx b/packages/execution/program_parser/current/src/ExpressionParser.cxx index a98a75fce..5a630d9d1 100644 --- a/packages/execution/program_parser/current/src/ExpressionParser.cxx +++ b/packages/execution/program_parser/current/src/ExpressionParser.cxx @@ -116,43 +116,33 @@ namespace ORO_Execution //cout << "DCP saw method "<< mmethod <<" of object "<getName()<dataFactory; - const GlobalMethodFactory& gmf = - peer->methodFactory; - const DataSourceFactoryInterface* dfi = gdsf.getObjectFactory( mobject ); - const MethodFactoryInterface* mfi = gmf.getObjectFactory( mobject ); - if ( ! dfi && ! mfi ) - if ( mobject != "this") - throw_( iter_t(), std::string("Task '")+peer->getName()+"' has no object '"+mobject+"'." ); - else - throw_( iter_t(), std::string("Task '")+peer->getName()+"' has no object or method '"+mmethod+"'." ); - // throw parse_exception_no_such_component( mobject ); + OperationInterface* ops = peer->getObject(mobject); + if ( mobject != "this" && ops == 0) + throw_( iter_t(), std::string("Task '")+peer->getName()+"' has no object '"+mobject+"'." ); - // One of both must have the method - if ( !( ( dfi && dfi->hasMember(mmethod)) || ( mfi && mfi->hasMember(mmethod)) ) ) - if ( mobject != "this") + if ( ops && ops->methods()->hasMember(mmethod) == false ) throw parse_exception_no_such_method_on_component( mobject, mmethod ); - else - throw parse_exception_no_such_method_on_component( peer->getName(), mmethod ); - - // create an argument parser for the call.. - // Store the peer in the ArgumentsParser ! - ArgumentsParser* argspar = - new ArgumentsParser( expressionparser, peer, - mobject, mmethod ); - // we no longer need these two.. - mobject.clear(); - mmethod.clear(); - - // keep hold of the argspar, we're still going to need it after - // it's done its work.. ( in seendatacall(), that is.. ) - argparsers.push( argspar ); - - // set the arguments parser to the parser provided by the - // ArgumentsParser we just created.. - arguments = argspar->parser(); - }; + + if ( !ops && peer->methods()->hasMember(mmethod) == false ) + throw parse_exception_no_such_method_on_component( peer->getName(), mmethod ); + + // create an argument parser for the call.. + // Store the peer in the ArgumentsParser ! + ArgumentsParser* argspar = + new ArgumentsParser( expressionparser, peer, + mobject, mmethod ); + // we no longer need these two.. + mobject.clear(); + mmethod.clear(); + + // keep hold of the argspar, we're still going to need it after + // it's done its work.. ( in seendatacall(), that is.. ) + argparsers.push( argspar ); + + // set the arguments parser to the parser provided by the + // ArgumentsParser we just created.. + arguments = argspar->parser(); + } void DataCallParser::seendatacall() { @@ -164,51 +154,32 @@ namespace ORO_Execution TaskContext* peer = argspar->peer(); delete argspar; - const GlobalDataSourceFactory& gdsf = - peer->dataFactory; - const GlobalMethodFactory& gmf = - peer->methodFactory; - const DataSourceFactoryInterface* dfi = gdsf.getObjectFactory( obj ); - const MethodFactoryInterface* mfi = gmf.getObjectFactory( obj ); - + OperationInterface* ops = peer->getObject(obj); // we already checked for the existence of this object and method // in seendataname().. - if ( dfi && dfi->hasMember(meth) ) { - try - { - ret = dfi->create( meth, args ); - } - catch( const wrong_number_of_args_exception& e ) - { - throw parse_exception_wrong_number_of_arguments - (obj, meth, e.wanted, e.received ); - } - catch( const wrong_types_of_args_exception& e ) - { - throw parse_exception_wrong_type_of_argument - (obj, meth, e.whicharg, e.expected_, e.received_ ); - } - } else if (mfi && mfi->hasMember(meth)) { - try - { - ret = mfi->create( meth, args ); - } - catch( const wrong_number_of_args_exception& e ) - { - throw parse_exception_wrong_number_of_arguments - (obj, meth, e.wanted, e.received ); - } - catch( const wrong_types_of_args_exception& e ) - { - throw parse_exception_wrong_type_of_argument - (obj, meth, e.whicharg, e.expected_, e.received_ ); - } - } else - assert( false ); + try { + if ( ops ) + ret = ops->methods()->produce( meth, args ); + else + ret = peer->methods()->produce( meth, args ); + } + catch( const wrong_number_of_args_exception& e ) + { + throw parse_exception_wrong_number_of_arguments + (obj, meth, e.wanted, e.received ); + } + catch( const wrong_types_of_args_exception& e ) + { + throw parse_exception_wrong_type_of_argument + (obj, meth, e.whicharg, e.expected_, e.received_ ); + } + catch(...) { + assert(false); + } assert( ret.get() ); - }; + } DataCallParser::~DataCallParser() { diff --git a/packages/execution/program_parser/current/src/FunctionFactory.cxx b/packages/execution/program_parser/current/src/FunctionFactory.cxx index d932d7b6f..77d22e4fe 100644 --- a/packages/execution/program_parser/current/src/FunctionFactory.cxx +++ b/packages/execution/program_parser/current/src/FunctionFactory.cxx @@ -50,64 +50,28 @@ namespace ORO_Execution using namespace boost; using namespace ORO_CoreLib; - FunctionFactory::FunctionFactory(ExecutionEngine* procs) : proc(procs) {} - FunctionFactory::~FunctionFactory() { - while( !funcmap.empty() ) { - funcmap.erase(funcmap.begin()); - } - } - - void FunctionFactory::addFunction(const std::string& name, shared_ptr f ) - { - funcmap[name] = f; - } - - bool FunctionFactory::hasCommand(const std::string& com) const { - return funcmap.count(com); - } - - std::vector FunctionFactory::getCommandList() const { - std::vector ret; - std::transform( funcmap.begin(), funcmap.end(), - std::back_inserter( ret ), - ORO_std::select1st() ); - return ret; - } + FunctionFactory::FunctionFactory(ProgramInterfacePtr pi, ExecutionEngine* procs) + : detail::OperationFactoryPart("A function."), func(pi), proc(procs) {} - std::string FunctionFactory::getResultType( const std::string& com ) const { - if ( hasCommand(com) ) - return std::string("bool"); - throw name_not_found_exception(); - } - - std::string FunctionFactory::getDescription( const std::string& com ) const { - if ( hasCommand(com) ) - return std::string("A function with name ") + com; - throw name_not_found_exception(); + std::string FunctionFactory::resultType() const { + return std::string("bool"); } ORO_CoreLib::PropertyBag - FunctionFactory::getArgumentSpec( const std::string& command ) const + FunctionFactory::getArgumentSpec() const { - if ( !hasCommand(command) ) - throw name_not_found_exception(); - shared_ptr orig = funcmap.find(command)->second; - std::vector origlist = orig->getArguments(); + std::vector origlist = func->getArguments(); PropertyBag ret; for ( std::vector::const_iterator it = origlist.begin(); it != origlist.end(); ++it) - ret.add( new Property("na", "Type Not available") ); + ret.add( (*it)->getDataSource()->getTypeInfo()->buildProperty("arg","Function Argument.")); return ret; } - std::vector< ArgumentDescription > FunctionFactory::getArgumentList( const std::string& command ) const + std::vector< ArgumentDescription > FunctionFactory::getArgumentList() const { - if ( !hasCommand(command) ) - throw name_not_found_exception(); - - shared_ptr orig = funcmap.find(command)->second; - std::vector origlist = orig->getArguments(); + std::vector origlist = func->getArguments(); std::vector< ArgumentDescription > mlist; for ( std::vector::const_iterator it = origlist.begin(); it != origlist.end(); ++it) @@ -115,44 +79,17 @@ namespace ORO_Execution return mlist; } - int FunctionFactory::getArity( const std::string& foo ) const + int FunctionFactory::arity( ) const { - map_t::const_iterator orig = funcmap.find(foo); - if ( orig == funcmap.end() ) - return -1; - return orig->second->getArguments().size(); - } - - ComCon FunctionFactory::create( const std::string& command, - const ORO_CoreLib::PropertyBag& args, - bool d) const { - std::vector dsVect; - std::transform( args.begin(), args.end(), - std::back_inserter( dsVect ), - bind( &ORO_CoreLib::PropertyBase::getDataSource, _1)); - return this->create( command, dsVect, d ); - } - - ComCon FunctionFactory::create( - const std::string& command, - const std::vector& args, - bool d) const { - std::vector dsVect; - for( std::vector::const_iterator i = args.begin(); i != args.end(); ++i ) - dsVect.push_back( DataSourceBase::shared_ptr( *i )); - return this->create( command, dsVect, d ); + return func->getArguments().size(); } - ComCon FunctionFactory::create( - const std::string& command, - const std::vector& args, - bool nodispatch) const { - // We ignore asyn, since we CommandExecFunction is always asyn itself. - if ( !hasCommand(command) ) - throw name_not_found_exception(command); + DispatchInterface* FunctionFactory::produce( + const std::vector& args + ) const { // check if correct number of args : - shared_ptr orig = funcmap.find(command)->second; + shared_ptr orig = func; std::vector origlist = orig->getArguments(); if ( args.size() != origlist.size() ) throw wrong_number_of_args_exception( origlist.size(), args.size() ); @@ -187,7 +124,7 @@ namespace ORO_Execution icom->add( ret ); else { delete icom; - return ComCon(); + return 0; } } #endif @@ -197,11 +134,7 @@ namespace ORO_Execution // the command gets ownership of the new function : // this command is a DispatchInterface... - CommandExecFunction* ecom = new CommandExecFunction( icom, fcopy, proc->getProgramProcessor() ); - ConditionInterface* con = ecom->createCondition(); - // first init, then dispatch the function. - // init->execute() : once(asyn), ecom->execute() : until done (syn) - return ComCon(ecom, con); + return new CommandExecFunction( icom, fcopy, proc->getProgramProcessor() ); } } diff --git a/packages/execution/program_parser/current/src/GenericTaskContext.cxx b/packages/execution/program_parser/current/src/GenericTaskContext.cxx index f5e2cb8a9..986cf6891 100644 --- a/packages/execution/program_parser/current/src/GenericTaskContext.cxx +++ b/packages/execution/program_parser/current/src/GenericTaskContext.cxx @@ -33,7 +33,7 @@ #include // To create commands, methods, etc : -#include +#include namespace ORO_Execution { @@ -43,37 +43,35 @@ namespace ORO_Execution // See Task Infrastructure Chapter. // Register our methods : - TemplateMethodFactory* mfact = newMethodFactory( this ); - mfact->add( "assert", - method( &GenericTaskContext::assertion, "Assert will get your program in the error state if the argument is false.", - "MustBeTrue", "The result of a boolean expression which must be true.") ); - mfact->add( "start", - method( &GenericTaskContext::start, "Start this GenericTaskContext." ) ); - mfact->add( "stop", - method( &GenericTaskContext::stop, "Stop this GenericTaskContext." ) ); - mfact->add( "readProperties", - method( &GenericTaskContext::readProperties, "Read Properties from a file.", - "Filename", "A CPF formatted XML file.") ); - mfact->add( "writeProperties", - method( &GenericTaskContext::writeProperties, "Write or update Properties to a file.", - "Filename", "A CPF formatted XML file.") ); - mfact->add( "loadProgram", - method( &GenericTaskContext::loadProgram, "Load an Orocos Program Script from a file.", - "Filename", "An ops file.") ); - mfact->add( "loadStateMachine", - method( &GenericTaskContext::loadStateMachine, "Load an Orocos State Description from a file.", - "Filename", "An osd file.") ); - mfact->add( "unloadProgram", - method( &GenericTaskContext::unloadProgram, "Unload an Orocos Program Script from a file.", - "ProgramName", "The Program's name.") ); - mfact->add( "unloadStateMachine", - method( &GenericTaskContext::unloadStateMachine, "Unload an Orocos State Description from a file.", - "StateMachineName", "A name of a Root StateMachine instantiation.") ); - mfact->add( "isRunning", - method( &GenericTaskContext::isRunning, "Is this GenericTaskContext started ?" ) ); - mfact->add( "update", - method( &GenericTaskContext::trigger, "Invoke the update method. Only succeeds if the task isRunning()." ) ); - this->methods()->registerObject("this", mfact); + methods()->addMethod( method("assert", + &GenericTaskContext::assertion, this), "Assert will get your program in the error state if the argument is false.", + "MustBeTrue", "The result of a boolean expression which must be true."); + methods()->addMethod( method("start", + &GenericTaskContext::start, this), "Start this GenericTaskContext." ); + methods()->addMethod( method("stop", + &GenericTaskContext::stop, this), "Stop this GenericTaskContext." ); + methods()->addMethod( method("readProperties", + &GenericTaskContext::readProperties, this), "Read Properties from a file.", + "Filename", "A CPF formatted XML file."); + methods()->addMethod( method("writeProperties", + &GenericTaskContext::writeProperties, this), "Write or update Properties to a file.", + "Filename", "A CPF formatted XML file."); + methods()->addMethod( method("loadProgram", + &GenericTaskContext::loadProgram, this), "Load an Orocos Program Script from a file.", + "Filename", "An ops file."); + methods()->addMethod( method("loadStateMachine", + &GenericTaskContext::loadStateMachine, this), "Load an Orocos State Description from a file.", + "Filename", "An osd file."); + methods()->addMethod( method("unloadProgram", + &GenericTaskContext::unloadProgram, this), "Unload an Orocos Program Script from a file.", + "ProgramName", "The Program's name."); + methods()->addMethod( method("unloadStateMachine", + &GenericTaskContext::unloadStateMachine, this), "Unload an Orocos State Description from a file.", + "StateMachineName", "A name of a Root StateMachine instantiation."); + methods()->addMethod( method("isRunning", + &GenericTaskContext::isRunning, this), "Is this GenericTaskContext started ?" ); + methods()->addMethod( method("update", + &GenericTaskContext::trigger, this), "Invoke the update method. Only succeeds if the task isRunning()." ); } GenericTaskContext::~GenericTaskContext() diff --git a/packages/execution/program_parser/current/src/ProgramGraphParser.cxx b/packages/execution/program_parser/current/src/ProgramGraphParser.cxx index db4ba2797..5cb533f5b 100644 --- a/packages/execution/program_parser/current/src/ProgramGraphParser.cxx +++ b/packages/execution/program_parser/current/src/ProgramGraphParser.cxx @@ -406,7 +406,7 @@ namespace ORO_Execution if ( mfuncs.count( funcdef ) ) throw parse_exception_semantic_error("function " + funcdef + " redefined."); - if ( exportf && rootc->commands()->hasCommand("this", funcdef )) + if ( exportf && rootc->commands()->hasMember( funcdef )) throw parse_exception_semantic_error("exported function " + funcdef + " is already defined in "+ rootc->getName()+".");; mfuncs[funcdef] = program_builder->startFunction( funcdef ); @@ -441,10 +441,9 @@ namespace ORO_Execution // export the function in the context's interface. if (exportf) { - FunctionFactory* cfi = new FunctionFactory( rootc->getExecutionEngine() ); // execute in the processor which has the command. std::map dummy; - cfi->addFunction( mfunc->getName() , ProgramInterfacePtr(mfunc->copy(dummy)) ); - rootc->commands()->registerObject("this", cfi ); + FunctionFactory* cfi = new FunctionFactory(ProgramInterfacePtr(mfunc->copy(dummy)), rootc->getExecutionEngine() ); // execute in the processor which has the command. + rootc->commands()->add(mfunc->getName(), cfi ); Logger::log() << Logger::Info << "Exported Function '" << mfunc->getName() << "' added to task '"<< rootc->getName() << "'" <eventService.hasEvent(ename) == false ) + if ( peer->events()->hasEvent(ename) == false ) throw parse_exception_semantic_error("emitting Event " + ename + " but it is not defined in Task "+peer->getName()+"."); // Parse the event's args in the programs context. @@ -589,7 +588,7 @@ namespace ORO_Execution assert( argsparser ); try { - DataSourceBase::shared_ptr emitds = peer->eventService.setupEmit( argsparser->methodname(), callfnargs); + DataSourceBase::shared_ptr emitds = peer->events()->setupEmit( argsparser->methodname(), callfnargs); assert( emitds ); program_builder->setCommand( new CommandDataSource( emitds ) ); program_builder->proceedToNext( new ConditionTrue(), mpositer.get_position().line - ln_offset ); diff --git a/packages/execution/program_parser/current/src/StateGraphParser.cxx b/packages/execution/program_parser/current/src/StateGraphParser.cxx index a6be806a4..2e7b7279e 100644 --- a/packages/execution/program_parser/current/src/StateGraphParser.cxx +++ b/packages/execution/program_parser/current/src/StateGraphParser.cxx @@ -662,8 +662,7 @@ namespace ORO_Execution if ( curtemplate ) { // remove all 'this' data factories - curtemplate->getTaskContext()->dataFactory.unregisterObject( "this" ); - curtemplate->getTaskContext()->methodFactory.unregisterObject( "this" ); + curtemplate->getTaskContext()->methods()->clear(); // remove temporary subMachine peers from current task. for( StateMachine::ChildList::const_iterator it= curtemplate->getChildren().begin(); diff --git a/packages/execution/program_parser/current/src/TaskBrowser.cxx b/packages/execution/program_parser/current/src/TaskBrowser.cxx index 19a186044..ef71eb626 100644 --- a/packages/execution/program_parser/current/src/TaskBrowser.cxx +++ b/packages/execution/program_parser/current/src/TaskBrowser.cxx @@ -264,17 +264,9 @@ namespace ORO_Execution // comp.replace( comp.find(" "),1,"" ); // try if it is an object : - if ( peer->commandFactory.getObjectFactory( object ) ) { + if ( peer->getObject( object ) ) { // fill with new ones. - find_command( startpos ); - } - if ( peer->dataFactory.getObjectFactory( object ) ) { - // fill with new ones. - find_datasource( startpos ); - } - if ( peer->methodFactory.getObjectFactory( object ) ) { - // fill with new ones. - find_method( startpos ); + find_ops( startpos ); } find_attribute( startpos ); @@ -293,21 +285,11 @@ namespace ORO_Execution } } // Only complete peers and objects, not "this" methods. - comps = peer->commandFactory.getObjectList(); + comps = peer->getObjectList(); for (std::vector::iterator i = comps.begin(); i!= comps.end(); ++i ) { if ( i->find( comp ) == 0 )//&& *i != "this" ) completes.push_back( peerpath+*i + "." ); // +"." } - comps = peer->dataFactory.getObjectList(); - for (std::vector::iterator i = comps.begin(); i!= comps.end(); ++i ) { - if ( i->find( comp ) == 0 )//&& *i != "this" ) - completes.push_back( peerpath+*i + "." ); // +"." - } - comps = peer->methodFactory.getObjectList(); - for (std::vector::iterator i = comps.begin(); i!= comps.end(); ++i ) { - if ( i->find( comp ) == 0 )//&& *i != "this" ) - completes.push_back( peerpath+*i + "." ); // +"." - } comps = peer->getPeerList(); for (TaskContext::PeerList::iterator i = comps.begin(); i!= comps.end(); ++i ) { if ( i->find( comp ) == 0 )//&& *i != "this" ) @@ -333,28 +315,8 @@ namespace ORO_Execution } } - void TaskBrowser::find_command(std::string::size_type startpos) + void TaskBrowser::find_ops(std::string::size_type startpos) { -#if 0 - std::string::size_type pos; - if ( (pos = text.find( "(", startpos )) != std::string::npos ) { - std::string _method( text, startpos, pos - 1); // remove "(" - //cout << "FoundMethod : "<< _method <commandFactory.getObjectFactory( component )->hasCommand( _method ) ) { - // complete : - method = _method; - return; // nothing to do - } else { - cerr << "Illegal method" << endl; - } - } -#endif // no brace found, thus build completion list : std::string _method; if (startpos != std::string::npos ) @@ -365,8 +327,9 @@ namespace ORO_Execution while ( _method.find(" ") != std::string::npos ) _method.replace( _method.find(" "),1,"" ); + // commands: std::vector comps; - comps = peer->commandFactory.getObjectFactory( object )->getCommandList(); + comps = peer->getObject( object )->commands()->getNames(); for (std::vector::iterator i = comps.begin(); i!= comps.end(); ++i ) { if ( i->find( _method ) == 0 ) if ( object == "this" ) @@ -374,40 +337,10 @@ namespace ORO_Execution else completes.push_back( peerpath +object+"."+ *i ); } - } - - void TaskBrowser::find_datasource(std::string::size_type startpos) - { -#if 0 - std::string::size_type pos; - if ( (pos = text.find( "(", startpos )) != std::string::npos ) { - std::string _datasource( text, startpos, pos - 1); // remove "(" - //cout << "FoundDatasource : "<< _datasource <dataFactory.getObjectFactory( component )->hasMember( _datasource ) ) { - datasource = _datasource; - } - } -#endif - // no brace found, thus build completion list : - std::string _datasource; - if (startpos != std::string::npos) - _datasource = text.substr( startpos ); - //cout << "FoundDatasource2 : "<< _datasource << endl; - - // strip white spaces from _datasource - while ( _datasource.find(" ") != std::string::npos ) - _datasource.replace( _datasource.find(" "),1,"" ); - - std::vector comps; - comps = peer->dataFactory.getObjectFactory(object)->getNames(); + // methods: + comps = peer->getObject( object )->methods()->getNames(); for (std::vector::iterator i = comps.begin(); i!= comps.end(); ++i ) { - if ( i->find( _datasource ) == 0 ) + if ( i->find( _method ) == 0 ) if ( object == "this" ) completes.push_back( peerpath + *i ); else @@ -428,7 +361,7 @@ namespace ORO_Execution _method.replace( _method.find(" "),1,"" ); // try if it is a command : - if ( peer->methodFactory.getObjectFactory( object )->hasMember( _method ) ) { + if ( peer->methods()->getObject( object )->hasMember( _method ) ) { method = _method; } } @@ -444,7 +377,7 @@ namespace ORO_Execution _method.replace( _method.find(" "),1,"" ); std::vector comps; - comps = peer->methodFactory.getObjectFactory(object)->getNames(); + comps = peer->getObject(object)->methods()->getNames(); for (std::vector::iterator i = comps.begin(); i!= comps.end(); ++i ) { if ( i->find( _method ) == 0 ) if ( object == "this" ) @@ -543,7 +476,7 @@ namespace ORO_Execution } TaskBrowser::TaskBrowser( TaskContext* _c ) - : condition(0), command(0), command_fact(0), datasource_fact(0), + : condition(0), command(0), debug(0), line_read(0), lastc(0), storedname(""), storedline(-1) @@ -904,24 +837,13 @@ namespace ORO_Execution { cout << " Got :"<< comm <commandFactory.getObjectFactory( comm ); - datasource_fact = taskcontext->dataFactory.getObjectFactory( comm ); - method_fact = taskcontext->methodFactory.getObjectFactory( comm ); - if ( command_fact ) // only commandobject name was typed - { - std::vector methods = command_fact->getCommandList(); - std::for_each( methods.begin(), methods.end(), boost::bind(&TaskBrowser::printCommand, this, _1) ); - } - - if ( datasource_fact ) // only datasource_fact name was typed - { - std::vector methods = datasource_fact->getNames(); - std::for_each( methods.begin(), methods.end(), boost::bind(&TaskBrowser::printSource, this, _1) ); - } - if ( method_fact ) // only method_fact name was typed + OperationInterface* ops = taskcontext->getObject( comm ); + if ( ops ) // only object name was typed { - std::vector methods = method_fact->getNames(); - std::for_each( methods.begin(), methods.end(), boost::bind(&TaskBrowser::printMethod, this, _1) ); + std::vector methods = ops->commands()->getNames(); + std::for_each( methods.begin(), methods.end(), boost::bind(&TaskBrowser::printCommand, this, _1, ops) ); + methods = ops->methods()->getNames(); + std::for_each( methods.begin(), methods.end(), boost::bind(&TaskBrowser::printMethod, this, _1, ops) ); } // Minor hack : also check if it was an attribute of current TC, for example, // if both the object and attribute with that name exist. the if @@ -932,7 +854,7 @@ namespace ORO_Execution return; } - if ( command_fact || datasource_fact || method_fact ) + if ( ops ) return; Parser _parser; @@ -1043,7 +965,7 @@ namespace ORO_Execution return; } - if ( command->execute() == false ) { + if ( command->dispatch() == false ) { cerr << "Command not accepted by"<getName()<<"'s Processor !" << nl; delete command; delete condition; @@ -1360,16 +1282,10 @@ namespace ORO_Execution cout <commandFactory.getObjectList(); - std::vector objlist2 = peer->dataFactory.getObjectList(); - objlist.insert(objlist.end(), objlist2.begin(), objlist2.end() ); - objlist2 = peer->methodFactory.getObjectList(); - objlist.insert(objlist.end(), objlist2.begin(), objlist2.end() ); - sort(objlist.begin(), objlist.end() ); - std::vector::iterator new_end = unique(objlist.begin(), objlist.end()); + objlist = peer->getObjectList(); cout <(cout, " ")); + copy(objlist.begin(), objlist.end(), std::ostream_iterator(cout, " ")); } else { cout << "(none)" < args; - args = command_fact->getArgumentList( m ); + args = ops->commands()->getArgumentList( m ); cout << " Command : bool " << coloron << m << coloroff<< "( "; for (std::vector::iterator it = args.begin(); it != args.end(); ++it) { cout << it->type <<" "; @@ -1418,35 +1334,16 @@ namespace ORO_Execution cout << " "; } cout << ")"<getDescription( m )<::iterator it = args.begin(); it != args.end(); ++it) - cout <<" "<< it->name <<" : " << it->description << nl; - } - - void TaskBrowser::printSource( const std::string m ) - { - std::vector args; - args = datasource_fact->getArgumentList( m ); - cout << " DataSource : "<< datasource_fact->getResultType(m)<<" " << coloron << m << coloroff<< "( "; - for (std::vector::iterator it = args.begin(); it != args.end(); ++it) { - cout << it->type <<" "; - cout << coloron << it->name << coloroff; - if ( it+1 != args.end() ) - cout << ", "; - else - cout << " "; - } - cout << ")"<getDescription( m )<commands()->getDescription( m )<::iterator it = args.begin(); it != args.end(); ++it) cout <<" "<< it->name <<" : " << it->description << nl; } - void TaskBrowser::printMethod( const std::string m ) + void TaskBrowser::printMethod( const std::string m, OperationInterface* ops ) { std::vector args; - args = method_fact->getArgumentList( m ); - cout << " Method : "<< method_fact->getResultType(m)<<" " << coloron << m << coloroff<< "( "; + args = ops->methods()->getArgumentList( m ); + cout << " Method : "<< ops->methods()->getResultType(m)<<" " << coloron << m << coloroff<< "( "; for (std::vector::iterator it = args.begin(); it != args.end(); ++it) { cout << it->type <<" "; cout << coloron << it->name << coloroff; @@ -1456,7 +1353,7 @@ namespace ORO_Execution cout << " "; } cout << ")"<getDescription( m )<methods()->getDescription( m )<::iterator it = args.begin(); it != args.end(); ++it) cout <<" "<< it->name <<" : " << it->description << nl; } diff --git a/packages/execution/program_parser/current/src/ValueChangeParser.cxx b/packages/execution/program_parser/current/src/ValueChangeParser.cxx index 84a2293d5..80d6a666e 100644 --- a/packages/execution/program_parser/current/src/ValueChangeParser.cxx +++ b/packages/execution/program_parser/current/src/ValueChangeParser.cxx @@ -375,6 +375,7 @@ namespace ORO_Execution // collect RHS : DataSourceBase::shared_ptr expr = expressionparser.getResult(); + assert( expr ); expressionparser.dropResult(); //assert( !expressionparser.hasResult() ); diff --git a/packages/execution/program_processor/current/include/CommandDispatch.hpp b/packages/execution/program_processor/current/include/CommandDispatch.hpp index 1b2036ca9..08be4ce07 100644 --- a/packages/execution/program_processor/current/include/CommandDispatch.hpp +++ b/packages/execution/program_processor/current/include/CommandDispatch.hpp @@ -61,9 +61,10 @@ namespace ORO_Execution struct Dispatcher : public ORO_CoreLib::CommandInterface { bool mexecuted, mvalid; CommandDispatch* cd; + // trick: set mvalid to true internally but return in valid(): mexecuted && mvalid. Dispatcher(CommandDispatch* c) : mexecuted(false), mvalid(true), cd(c) {} void readArguments() {} - bool execute() { mexecuted=true; return mvalid=cd->com->execute();} + bool execute() { mvalid=cd->com->execute(); mexecuted=true; return mvalid;} void reset() { mexecuted=false; mvalid=true; } virtual Dispatcher* clone() const { return new Dispatcher(cd); } } dispatcher; diff --git a/packages/execution/program_processor/current/include/StateMachine.hpp b/packages/execution/program_processor/current/include/StateMachine.hpp index 14db96fbe..8999d9d02 100644 --- a/packages/execution/program_processor/current/include/StateMachine.hpp +++ b/packages/execution/program_processor/current/include/StateMachine.hpp @@ -159,6 +159,17 @@ namespace ORO_Execution return copy->getName() == state; } + /** + * Check if the state machine is in a given state + * and not in the entry or exit program. + */ + bool inStrictState(const std::string& state) const { + StateInterface* copy = this->currentState(); + if (copy == 0) + return false; + return copy->getName() == state && !this->inTransition(); + } + /** * Return name of current state, empty string if not active. */ diff --git a/packages/execution/program_processor/current/include/StateMachineTask.hpp b/packages/execution/program_processor/current/include/StateMachineTask.hpp index 27081db23..5b9236b2a 100644 --- a/packages/execution/program_processor/current/include/StateMachineTask.hpp +++ b/packages/execution/program_processor/current/include/StateMachineTask.hpp @@ -52,8 +52,8 @@ namespace ORO_Execution //VariableDataSource _this; bool true_gen() const; - CommandFactoryInterface* createCommandFactory(); - MethodFactoryInterface* createMethodFactory(); + void createCommandFactory(); + void createMethodFactory(); public: StateMachineTask* copy(StateMachinePtr newsc, std::map& replacements, bool instantiate ); diff --git a/packages/execution/program_processor/current/src/CommandDispatch.cxx b/packages/execution/program_processor/current/src/CommandDispatch.cxx index eaac8c489..faf5ee0f9 100644 --- a/packages/execution/program_processor/current/src/CommandDispatch.cxx +++ b/packages/execution/program_processor/current/src/CommandDispatch.cxx @@ -74,7 +74,7 @@ namespace ORO_Execution else { //Logger::log() < @@ -42,26 +43,32 @@ namespace ORO_Execution : TaskContext( prog->getName(), ee ), program( new ValueDataSource(prog) ) // was: VariableDataSource. { + DataSource* ptr = program.get(); // Commands : - TemplateCommandFactory< DataSource >* fact = - newCommandFactory( static_cast< DataSource* >( program.get() ) ); - - fact->add("start", command_ds(&ProgramInterface::start, &ProgramInterface::isRunning,"Start or continue this program.") ); - fact->add("pause", command_ds(&ProgramInterface::pause, &ProgramInterface::isPaused,"Pause this program.") ); - fact->add("step", command_ds(&ProgramInterface::step, &ProgramInterface::stepDone,"Step a paused program.") ); - fact->add("stop", command_ds(&ProgramInterface::stop, &ProgramInterface::isStopped,"Stop and reset this program.") ); - - this->commands()->registerObject("this", fact); + commands()->addCommandDS( ptr, + command_ds("start",&ProgramInterface::start, &ProgramInterface::isRunning,engine()->commands()), + "Start or continue this program."); + commands()->addCommandDS( ptr, + command_ds("pause",&ProgramInterface::pause, &ProgramInterface::isPaused,engine()->commands()), + "Pause this program."); + commands()->addCommandDS( ptr, + command_ds("step", &ProgramInterface::step, &ProgramInterface::stepDone,engine()->commands()), + "Step a paused program."); + commands()->addCommandDS( ptr, + command_ds("stop", &ProgramInterface::stop, &ProgramInterface::isStopped,engine()->commands()), + "Stop and reset this program."); // DataSources: - TemplateMethodFactory< DataSource >* dfact = - newMethodFactory( static_cast< DataSource* >( program.get() ) ); - - dfact->add("isRunning", data_ds( &ProgramInterface::isRunning, "Is this program being executed and not paused ?") ); - dfact->add("inError", data_ds(&ProgramInterface::inError,"Has this program executed an erroneous command ?") ); - dfact->add("isPaused", data_ds(&ProgramInterface::isPaused,"Is this program running but paused ?") ); - this->methods()->registerObject("this", dfact); + methods()->addMethodDS( ptr, + method_ds("isRunning",&ProgramInterface::isRunning), + "Is this program being executed and not paused ?"); + methods()->addMethodDS( ptr, + method_ds("inError", &ProgramInterface::inError), + "Has this program executed an erroneous command ?"); + methods()->addMethodDS( ptr, + method_ds("isPaused", &ProgramInterface::isPaused), + "Is this program running but paused ?"); } ProgramTask::~ProgramTask() { diff --git a/packages/execution/program_processor/current/src/StateMachineTask.cxx b/packages/execution/program_processor/current/src/StateMachineTask.cxx index 81c6b3376..ec7d4e072 100644 --- a/packages/execution/program_processor/current/src/StateMachineTask.cxx +++ b/packages/execution/program_processor/current/src/StateMachineTask.cxx @@ -32,67 +32,68 @@ #include "execution/TemplateFactories.hpp" #include "execution/TaskContext.hpp" #include "execution/FactoryExceptions.hpp" +#include "execution/CommandDS.hpp" +#include "execution/Method.hpp" namespace ORO_Execution { using namespace ORO_CoreLib; using namespace ORO_CoreLib::detail; - CommandFactoryInterface* StateMachineTask::createCommandFactory() { + void StateMachineTask::createCommandFactory() { // Add the state specific methods : // Special trick : we store the 'this' pointer in a DataSource, such that when // the created commands are copied, they also get the new this pointer. // This requires template specialisations on the TemplateFactory level. - TemplateCommandFactory< DataSource >* fact = newCommandFactory( static_cast< DataSource* >( _this.get() ) ); - fact->add("activate", - command_ds(&StateMachine::activate, &StateMachine::isStrictlyActive, - "Activate this StateMachine to initial state and enter request Mode.")); - fact->add("deactivate", - command_ds(&StateMachine::deactivate, &StateMachine::isActive, - "Deactivate this StateMachine", true)); - fact->add("start", - command_ds(&StateMachine::automatic, &StateMachine::isAutomatic, - "Start this StateMachine, enter automatic Mode.")); - fact->add("automatic", - command_ds(&StateMachine::automatic, &StateMachine::isAutomatic, - "Start this StateMachine, enter automatic Mode.")); - fact->add("pause", - command_ds(&StateMachine::pause, &StateMachine::isPaused, - "Pause this StateMachine, enter paused Mode.")); - fact->add("step", - command_ds(&StateMachine::step, &StateMachine::stepDone, + DataSource* ptr = _this.get(); + + commands()->addCommandDS(ptr, command_ds("activate", + &StateMachine::activate, &StateMachine::isStrictlyActive, engine()->commands()), + "Activate this StateMachine to initial state and enter request Mode."); + commands()->addCommandDS(ptr, command_ds("deactivate", + &StateMachine::deactivate, &StateMachine::isActive, engine()->commands(),true), + "Deactivate this StateMachine"); + commands()->addCommandDS(ptr, command_ds("start", + &StateMachine::automatic, &StateMachine::isAutomatic, engine()->commands()), + "Start this StateMachine, enter automatic Mode."); + commands()->addCommandDS(ptr, command_ds("automatic", + &StateMachine::automatic, &StateMachine::isAutomatic, engine()->commands()), + "Start this StateMachine, enter automatic Mode."); + commands()->addCommandDS(ptr, command_ds("pause", + &StateMachine::pause, &StateMachine::isPaused, engine()->commands()), + "Pause this StateMachine, enter paused Mode."); + commands()->addCommandDS(ptr, command_ds("step", + &StateMachine::step, &StateMachine::stepDone, engine()->commands()), "Step this StateMachine. When paused, step a single instruction or transition evaluation. \n" - "When in reactive mode, evaluate transitions and go to a next state, or if none, run handle.")); - fact->add("reset", - command_ds(&StateMachine::reset, &StateMachine::inInitialState, - "Reset this StateMachine to the initial state")); - fact->add("stop", - command_ds(&StateMachine::stop, &StateMachine::inFinalState, - "Stop this StateMachine to the final state and enter request Mode.")); - fact->add("reactive", - command_ds(&StateMachine::reactive, &StateMachine::isStrictlyActive, - "Enter reactive mode (see requestState() and step() ).\n Command is done if ready for requestState() or step() command.")); - fact->add("requestState", - command_ds(&StateMachine::requestState, &StateMachine::stepDone, + "When in reactive mode, evaluate transitions and go to a next state, or if none, run handle."); + commands()->addCommandDS(ptr, command_ds("reset", + &StateMachine::reset, &StateMachine::inInitialState, engine()->commands()), + "Reset this StateMachine to the initial state"); + commands()->addCommandDS(ptr, command_ds("stop", + &StateMachine::stop, &StateMachine::inFinalState, engine()->commands()), + "Stop this StateMachine to the final state and enter request Mode."); + commands()->addCommandDS(ptr, command_ds("reactive", + &StateMachine::reactive, &StateMachine::isStrictlyActive, engine()->commands()), + "Enter reactive mode (see requestState() and step() ).\n Command is done if ready for requestState() or step() command."); + commands()->addCommandDS(ptr, command_ds("requestState", + &StateMachine::requestState, &StateMachine::inStrictState, engine()->commands()), "Request to go to a particular state. Will succeed if there exists a valid transition from this state to the requested state.", - "State", "The state to make the transition to.")); - return fact; + "State", "The state to make the transition to."); } - MethodFactoryInterface* StateMachineTask::createMethodFactory() - { - TemplateMethodFactory< DataSource >* f = newMethodFactory(static_cast< DataSource* >( _this.get() )); - f->add("inState", data_ds(&StateMachine::inState, "Is the StateMachine in a given state ?", "State", "State Name") ); - f->add("inError", data_ds(&StateMachine::inError, "Is this StateMachine in error ?") ); - f->add("getState", data_ds(&StateMachine::getCurrentStateName, "The name of the current state. An empty string if not active.") ); - f->add("isActive", data_ds(&StateMachine::isActive, "Is this StateMachine activated (possibly in transition) ?") ); - f->add("isRunning", data_ds(&StateMachine::isAutomatic, "Is this StateMachine running in automatic mode ?") ); - f->add("isReactive", data_ds(&StateMachine::isReactive, "Is this StateMachine ready and waiting for requests or events ?") ); - f->add("isPaused", data_ds(&StateMachine::isPaused, "Is this StateMachine paused ?") ); - f->add("inInitialState", data_ds(&StateMachine::inInitialState, "Is this StateMachine in the initial state ?") ); - f->add("inFinalState", data_ds(&StateMachine::inFinalState, "Is this StateMachine in the final state ?") ); - f->add("inTransition", data_ds(&StateMachine::inTransition, "Is this StateMachine executing a entry|handle|exit program ?") ); - return f; + void StateMachineTask::createMethodFactory() + { + DataSource* ptr = _this.get(); + methods()->addMethodDS(ptr, method_ds("inState", &StateMachine::inState), "Is the StateMachine in a given state ?", "State", "State Name"); + methods()->addMethodDS(ptr, method_ds("inError", &StateMachine::inError), "Is this StateMachine in error ?"); + methods()->addMethodDS(ptr, method_ds("getState", &StateMachine::getCurrentStateName), "The name of the current state. An empty string if not active."); + methods()->addMethodDS(ptr, method_ds("isActive", &StateMachine::isActive), "Is this StateMachine activated (possibly in transition) ?"); + methods()->addMethodDS(ptr, method_ds("isRunning", &StateMachine::isAutomatic), "Is this StateMachine running in automatic mode ?"); + methods()->addMethodDS(ptr, method_ds("isReactive", &StateMachine::isReactive), "Is this StateMachine ready and waiting for requests or events ?"); + methods()->addMethodDS(ptr, method_ds("isPaused", &StateMachine::isPaused), "Is this StateMachine paused ?"); + methods()->addMethodDS(ptr, method_ds("inInitialState", &StateMachine::inInitialState), "Is this StateMachine in the initial state ?"); + methods()->addMethodDS(ptr, method_ds("inFinalState", &StateMachine::inFinalState), "Is this StateMachine in the final state ?"); + methods()->addMethodDS(ptr, method_ds("inTransition", &StateMachine::inTransition), "Is this StateMachine executing a entry|handle|exit program ?"); } StateMachineTask* StateMachineTask::copy(StateMachinePtr newsc, std::map& replacements, bool instantiate ) @@ -103,8 +104,8 @@ namespace ORO_Execution StateMachineTask* tmp = new StateMachineTask( newsc, this->getExecutionEngine() ); replacements[ _this.get() ] = tmp->_this.get(); // put 'newsc' in map - AttributeRepository* dummy = this->attributeRepository.copy( replacements, instantiate ); - tmp->attributeRepository = *dummy; + AttributeRepository* dummy = this->attributes()->copy( replacements, instantiate ); + *(tmp->attributes()) = *dummy; delete dummy; return tmp; @@ -114,8 +115,8 @@ namespace ORO_Execution : TaskContext( statemachine->getName(), ee ), _this( new ValueDataSource( statemachine ) ) // was: VariableDataSource. { - this->commands()->registerObject("this", this->createCommandFactory() ); - this->methods()->registerObject("this", this->createMethodFactory() ); + this->createCommandFactory(); + this->createMethodFactory(); } StateMachineTask::~StateMachineTask() diff --git a/packages/execution/task_context/current/doc/orocos-task-context.xml b/packages/execution/task_context/current/doc/orocos-task-context.xml index c3cf15ba6..1efd07ac7 100644 --- a/packages/execution/task_context/current/doc/orocos-task-context.xml +++ b/packages/execution/task_context/current/doc/orocos-task-context.xml @@ -58,6 +58,12 @@ Went through biggest part of manual to 'prettyfy' examples. Cut out all the developer specific comments. + + 0.25.0 + 18 July 2006 + PS + New command and method semantics. + @@ -82,7 +88,7 @@ Each control component is defined as a "TaskContext", which defines the "context" in which the component task is executed. The context is built by the five Orocos primitives: Event, Property, Command, Method - and Data Flow. This document defines how a user can write his own + and Data Port. This document defines how a user can write his own task context and how it can be used in an application.
@@ -160,15 +166,6 @@ - - Control Kernel - - is an application which uses all of the above - and provides an (although complex) example of how - the &taskpkg; can be used in practice. - - - @@ -532,11 +529,9 @@ cd quit Setting Up a Basic Task Tasks are - implemented by the ORO_Execution::TaskContext class, - which should not be confused with the CoreLib PeriodicActivity - implementations. + implemented by the ORO_Execution::TaskContext class. It is useful speaking of a context because it defines - the context in which the task operates. + the context in which an activity (a program) operates. It defines the interface of the task, its properties, its peer tasks and uses its ORO_Execution::ExecutionEngine to handle its @@ -571,13 +566,9 @@ cd quit The argument is the (unique) name of the task. - A task's interface consists of : Commands, Methods, DataSources, + A task's interface consists of : Commands, Methods, Ports, Attributes and Properties and Events, which are all public. We - will refer to them as members. The - TaskContext exports its interface members (to other tasks) by - means of object factories. Which members are exported is up to - the application. The factories are required to map the interface - of a task to internal, application specific, C++ methods. + will refer to them as members.
@@ -602,7 +593,7 @@ cd quit for new commands in it's queue and execute programs which are running in the task. Thus to start using the task, one needs to start the Execution Engine. As long as it is not started, it will accept no - commands and run no programs. + commands, run no programs and react to no events. </para> <section><title>Task Application Code @@ -748,7 +739,7 @@ cd quit a_task.commands(); a_task.events(); - The meaning of these factories are explained in the following + The meaning of these methods are explained in the following sections. @@ -942,7 +933,7 @@ cd quit A port's connection can be accessed through the connection() method. To access the data within the connection - (the container), a special method is provided by each port. + (i.e. the container), a special method is provided by each port. A DataPort's data container can be accessed by the @@ -1025,19 +1016,25 @@ cd quit The easiest way to access a TaskContext's interface is through Methods. They resemble very much normal C - or C++ functions. They take arguments and return a value. + or C++ functions, but they have the advantage to be + usable in scripting or can be called over a network + connection. They take arguments and return a value. The return value can in return be used as an argument for other Methods or stored in a variable. For all details, we refer to the &orocos; Scripting Manual. - To add a TaskContext's method to the Method Factory, one can use - the TemplateMethodFactory, - to easily create method factories : + To add a TaskContext's method to the method interface, one + proceeds similarly as when creating Data Ports. The + data type is now replaced by a function signature, + for example 'void(int, double)' + which is the signature of a function returning 'void' and + having two arguments: an 'int' and a 'double'. + - #include <execution/TemplateFactories.hpp> + #include <execution/Method.hpp> using namespace ORO_Execution; class MyTask @@ -1049,22 +1046,22 @@ cd quit double changeParameter(double f) { ... } // ... + Method<void(void)> resetMethod; + Method<string(void)> nameMethod; + Method<double(double)> paramMethod; + MyTask(std::string name) - : ORO_Execution::GenericTaskContext(name) + : ORO_Execution::GenericTaskContext(name), + resetMethod("reset", &MyTask::reset, this), + nameMethod("name", &MyTask::getName, this), + resetMethod("changeP", &MyTask::changeParameter, this) { - TemplateMethodFactory<MyTask>* mfact = - newMethodFactory( this ); - mfact->add( "reset", - method( &MyTask::reset, "Reset the system." ) ); - mfact->add( "name", - method( &MyTask::getName, - "Read out the name of the system." ) ); - mfact->add( "changeP", - method( &MyTask::changeParameter, - "Change a parameter, return the old value.", - "New Value", "The new value for the parameter." ) ); - - this->methods()->registerObject("this", mfact); + // Add the method objects to the method interface: + this->methods()->addMethod( &resetMethod, "Reset the system."); + this->methods()->addMethod( &nameMethod, "Read out the name of the system."); + this->methods()->addMethod( &changeP, + "Change a parameter, return the old value.", + "New Value", "The new value for the parameter."); // more additions to follow, see below } @@ -1072,91 +1069,77 @@ cd quit }; - The first statement - - TemplateMethodFactory<MyTask>* mfact = - newMethodFactory( this ); - - constructs a new TemplateMethodFactory, which will create - methods for the object 'this'. You need - to supply the C++ type of the object as a template - parameter, here the class MyTask. - Each Method object created by this TemplateMethodFactory will be - invoked on that object. Any number of methods with - any kind of arguments can be added. - - After this factory is constructed, we add methods - to it using the add() function. The add() function requires a - name for the added method, and information on the method to be - associated with that name. The latter is generated using the - function method(). - - - mfact->add( "reset", - method( &MyTask::reset, "Reset the system." ) ); - - The method() function requires a pointer - to a class function of the earlier provided type - (MyTask), having a number of arguments, - and returning the appropriate result. The function's - signature will automatically define the signature in the - exported API. After the class function pointer follows a C - string containing a description of the function, followed by a - name and description for each of the arguments. + In the above example, we wish to add 3 class functions to the + method interface: reset, getName and changeParameter. This can + be done by constructing a + ORO_Execution::Method object with the + correct function signature for each such class function. Each + Method object is initialised in the constructor with a name + ("reset"), a pointer to the class function + (&MyTask::reset) and a pointer to the class object (this). + This setup allows the method objects resetMethod, nameMethod + and paramMethod to be invoked just like one would call the + functions directly. - - this->methods()->registerObject("this", fact); - - Finally, the factory is stored in the Method interface of - a_task, where it is added to the "this" methods, thus to the - public interface of the task. One may also store the methods - in an object with a different name, which is then intended for - internal use. + + After the method objects are constructed, we add methods to + the method interface using the addMethod() function. The + addMethod() function requires a a method object (&resetMethod), + a description ("Reset the system.") and a name, + description pair for each argument (such as in + changeParameter). - - The method factory, and all other factories of a TaskContext - take ownership of the registered or added objects. You are not - allowed to delete them. - Using this mechanism, any method of any - class can be added to a task's method interface. All methods - are grouped in an object namespace ( here "this" ), - which can be served by different classes ( and thus factories - ). For example, you can add methods for an internal object - using a separate TemplateFactory. + class can be added to a task's method interface. -
- - Template Factories and Classes UML Diagram - - - - - - - This diagram demonstrates how TemplateFactories - can be applied to your class. - - - -
Invoking Methods in C++ In order to easily invoke a task's methods from a C++ program, - the ORO_Execution::MethodC class was designed to store - and invoke methods and collect the return values. ORO_Execution::MethodC - objects are created by a task's method factory. For example: + only only needs a pointer to a TaskContext object, for example + using the 'getPeer()' class function. // create a method: - MethodC reset_meth = a_task.methods()->create("this", "reset"); + TaskContext* a_task_ptr; + Method<void(void)> my_reset_meth + = a_task_ptr->methods()->getMethod<void(void)>("reset"); // Call 'reset' of a_task: - bool valid = reset_meth.execute(); + reset_meth(); Methods can also be given arguments and collect return values. Both constant - arguments and variable arguments are supported. However, the return value + arguments and variable arguments are supported. + + // used to hold the return value: + string name; + Method<string(void)> name_meth = + a_task_ptr->methods()->getMethod<string(void)>("name"); + + // Call 'name' of a_task: + name = name_meth(); + + cout << "Name was: " << name << endl; + + // hold return value. + double oldvalue; + Method<double(double)> mychange_1 = + a_task.methods()->create("changeP"); + + // Call 'changeParameter' of a_task with argument '1.0' + oldvalue = mychange_1( 1.0 ); + // oldvalue now contains previous value. + + Up to 4 arguments can be given. If the signature was + not correct, the method invocation will be ignored. + One can check validity of a method object with the + 'ready()' function: + + Method<double(double)> mychange_1 = ...; + assert( mychange_1.ready() ); +
Invoking Methods in Scripts @@ -1203,24 +1187,6 @@ cd quit do ATask.changeP( 0.1 ) // or : set result = ATask.changeP( 0.1 ) // store return value - - If the method should - belong to the task's interface, the - "this" object is assumed. - If another "objname" is given instead - of "this", this would result in : - - - do ATask.objname.changeP( 0.1 ) - - Any number of methods and objects can be added to a - TaskContext. Also the methods of the TaskContext - itself (or its derived classes) may be added. The - added methods keep their polymorphism, meaning that - - you may add pure virtual methods to the factory. - -
@@ -1392,7 +1358,7 @@ cd quit PurposeA task's commands are intended to be called 'asynchronously', thus sent by the caller to the receiver. Use it to 'reach a goal' in the receiver, typically - this takes time to accomplish. Commands are, in contrast with methods, + this takes time to accomplish. Command functions are, in contrast with methods, executed by the receiver. @@ -1400,20 +1366,17 @@ cd quit - The next factory we discuss is the Command Factory, - which produces C++ ORO_Execution::CommandC - objects which encapsulate a command call to a TaskContext's - interface. + The command interface is very similar to the Method interface above.
Adding Commands to a TaskContext - To add a command to the Command Interface, one can use - the TemplateCommandFactory, - to easily create command factories : + To add a command to the Command Interface, one + must create ORO_Execution::Command, + objects : - #include <execution/TemplateFactories.hpp> + #include <execution/Command.hpp> class MyTask : public ORO_Execution::GenericTaskContext @@ -1425,57 +1388,53 @@ cd quit bool startCycle() { ... } bool cycleDone() const { ... } + Command<bool(void)> cycleCommand; + /** * Another command cleans stuff up. */ bool cleanupMess(double f) { ... } bool isMessCleaned() const { ... } + Command<bool(double)> messCommand; + public: MyTask(std::string name) - : ORO_Execution::GenericTaskContext(name) + : ORO_Execution::GenericTaskContext(name), + cycleCommand("startCycle", + &MyTask::startCycle, + &MyTask::cycleDone, this), + messCommand( "cleanup", + &MyTask::cleanupMess, + &MyTask::isMessCleaned, this) { // ... other startup code here - TemplateCommandFactory<MyTask>* cfact = - newCommandFactory( this ); - cfact->add( "startCycle", - command( &MyTask::startCycle, - &MyTask::cycleDone, - "Start a new cycle." ) ); - cfact->add( "cleanup", - command( &MyTask::cleanupMess, - &MyTask::isMessCleaned, - "Start cleanup operation.", - "cfactor", "A cfactor denoting the thoroughness." ) ); - - this->commands()->registerObject("this", cfact); + this->commands()->addCommand( &cycleCommand, + "Start a new cycle."); + this->commands()->addCommand( &messCommand, + "Start cleanup operation.", + "cfactor", "A cfactor denoting the thoroughness."); } }; Commands differ from Methods in that they take - an extra function which is called the Completion - Condition. It is a function which returns true + an extra function which is called the Completion + Condition. It is a function which returns true when the command is done. The command itself also returns a boolean which indicates if it was accepted or not. Reasons to be rejected can be faulty arguments or that the system is not ready to accept a new command. - - cfact->add( "startCycle", - command( &MyTask::startCycle, - &MyTask::cycleDone, - "Start a new cycle." ) ); - - Thus the command() function - requires two member pointers instead of - one. The first one is a function that does the actual work - that the command will invoke, and the second is a bool - const function having : + + The Command object requires two member + pointers instead of one, which must both return a 'bool'. The + first one is the command function that does the actual work, + and the completion condition is a function having : - the same arguments as the command, + exactly the same arguments as the command, OR only the first argument of the command, @@ -1485,24 +1444,58 @@ cd quit - The second function (the completion condition) - will be called to see whether the - associated command is finished. The rest of the arguments to - the command function remain the same. It also requires a - constant C string describing the function, and two constant C - strings giving a description and name for every argument. + Analogous to addMethod(), + addCommand adds the Command objects to + the TaskContext interface and also requires a string + describing the command, and two strings giving a name and + description for every argument. - - The command factory, and all other factories of a TaskContext - take ownership of the registered or added objects. You are not - allowed to delete them. -
Invoking Commands in C++ - Once a command is added to a task's factory, other tasks - can make use of that command. The ORO_Execution::CommandC + Once a command is added to a TaskContext's interface, other tasks + can make use of that command. + + + The ORO_Execution::Command + class can be used to invoke commands as well. + You can get such object from a task's interface: + + Command<bool(void)> mycom + = a_task.commands()->getCommand<bool(void)>("startCycle"); + // check if the command is ok: + assert( mycom.ready() ); + + // Send 'startCycle' to a_task (asynchronous). + bool result = mycom(); + // next, check its status: + bool accepted = mycom.accepted(); // accepted by execution engine? + bool valid = mycom.valid(); // command was valid (well-formed)? + bool done = mycom.evaluate(); // command was done? + + + Such commands can also be given arguments. Both constant + arguments and variable arguments are supported: + + // get a command: + Command<bool(double)> mycleanup_1 = + a_task.commands()->getCommand<bool(double)>("cleanup"); + + // Send 'cleanup' to a_task with argument '1.0' + bool result_1 = mycleanup_1( 1.0 ); + + bool d_arg = 5.0; + // Send 'cleanup' to a_task, reads contents of d_arg. + bool result_2 = mycleanup_1(d_arg); + + The current implementation supports up to 4 arguments. + Since the use of 'structs' is allowed, this is enough + for most applications. + +
Invoking Commands from Scripts @@ -1544,8 +1538,8 @@ cd quit The above lets you write in a program script : - do this.startCycle() - do this.cleanup( 0.1 ) + do startCycle() + do cleanup( 0.1 ) when the program is loaded in a_task. @@ -1577,16 +1571,16 @@ cd quit A task may register its events in its interface in order to be - used by its state machines and other tasks as well. The events - used by the task context are defined and explained by the Orocos - CoreLib. The ORO_Execution::EventService is the - main access point to register and locate a task's events. + used by its state machines and other tasks as well. Events + are defined and explained in the Orocos + CoreLib Manual.
Adding Events Events can be easily added to a task's interface, - much like properties are: + much like methods are: + #include <corelib/Event.hpp> class MyTask @@ -1598,24 +1592,31 @@ cd quit ORO_CoreLib::Event< bool(double, double, double) > moveAxis; public: MyTask(std::string name) - : ORO_Execution::GenericTaskContext(name) + : ORO_Execution::GenericTaskContext(name), + turnSwitch( "turnSwitch" ), + moveAxis( "move" ) { // ... other startup code here // add it to the task's interface: - this->events()->addEvent( "turnSwitch", &turnSwitch ); - this->events()->addEvent( "move", &moveAxis ); + this->events()->addEvent( &turnSwitch ); + this->events()->addEvent( &moveAxis ); } }; - and so on. + + An ORO_CoreLib::Event object has the signature + ('void(bool)') of the 'callback function' it will call when + the event is 'emitted' (or 'fired'). The object is initialised + with a name ("turnSwitch") and added to the interface ('addEvent').
Emitting Events in C++ Once events are added, they can be emitted using the - ORO_Execution::EventC object. Analogous to - commands and methods, arguments can be provided: + ORO_Execution::EventC object. + 'argC' is used to add 'Constant' arguments, 'arg' is used to add + variable arguments. ORO_Execution::EventC move_event = a_task.events()->setupEmit( "move" ).argC(1.0).argC(2.0).argC(3.0); // emit the event 'move' with given args: diff --git a/packages/execution/task_context/current/include/BindStorage.hpp b/packages/execution/task_context/current/include/BindStorage.hpp index e3ed5e5e7..d534cc6db 100644 --- a/packages/execution/task_context/current/include/BindStorage.hpp +++ b/packages/execution/task_context/current/include/BindStorage.hpp @@ -260,7 +260,6 @@ namespace ORO_Execution } }; - /** * A class which binds a Type F to object O. If it is invoked * with more arguments than F, the extra arguments are discarded. diff --git a/packages/execution/task_context/current/include/BufferPort.hpp b/packages/execution/task_context/current/include/BufferPort.hpp index 830a5e9f2..72cc3f6ba 100644 --- a/packages/execution/task_context/current/include/BufferPort.hpp +++ b/packages/execution/task_context/current/include/BufferPort.hpp @@ -32,8 +32,8 @@ #include #include "PortInterface.hpp" #include "BufferConnectionInterface.hpp" -#include "TemplateDataSourceFactory.hpp" -#include "MemberFactoryComposite.hpp" +#include "OperationInterface.hpp" +#include "Method.hpp" namespace ORO_Execution { @@ -83,6 +83,16 @@ namespace ORO_Execution return false; } + /** + * Get the next value to be Pop()'ed, or + * the default value if empty. + */ + T front() const { + if (mconn) + return mconn->read()->front(); + return T(); + } + bool connected() const { return mconn; }; /** @@ -103,6 +113,56 @@ namespace ORO_Execution return other->addReader( this ); } + /** + * Clears all contents of this buffer. + */ + void clear() { + if (mconn) + return mconn->read()->clear(); + } + + /** + * Returns the actual number of items that are stored in the + * buffer. + * @return number of items. + */ + BufferBase::size_type size() const { + if (mconn) + return mconn->read()->size(); + return 0; + } + + /** + * Returns the maximum number of items that can be stored in the + * buffer. + * @return maximum number of items. + */ + BufferBase::size_type capacity() const { + if (mconn) + return mconn->read()->capacity(); + return 0; + } + + /** + * Check if this buffer is empty. + * @return true if size() == 0 + */ + bool empty() const { + if (mconn) + return mconn->read()->empty(); + return 0; + } + + /** + * Check if this buffer is full. + * @return true if size() == capacity() + */ + bool full() const { + if (mconn) + return mconn->read()->full(); + return 0; + } + virtual PortInterface* clone() const { return new ReadBufferPort( this->getName() ); } @@ -113,23 +173,25 @@ namespace ORO_Execution */ virtual PortInterface* antiClone() const; - virtual DataSourceFactoryInterface* createDataSources() { + virtual OperationInterface* createPortObject() { #ifndef ORO_EMBEDDED - if ( !mconn ) - return 0; - TemplateDataSourceFactory >* datas = newDataSourceFactory( mconn->read() ); - bool (ORO_CoreLib::ReadInterface::*PopPtr)(typename ORO_CoreLib::ReadInterface::reference_t) = &ORO_CoreLib::ReadInterface::Pop; - datas->add( "Pop", data( PopPtr, "Pop a single value from the Buffer. Returns false if empty.", - "Val", "The value returned by argument.") ); - datas->add( "front", data( &ORO_CoreLib::ReadInterface::front, "Get the next to be popped value from the buffer. Returns default value if buffer is empty.")); - - TemplateDataSourceFactory* datab = newDataSourceFactory( mconn->read() ); - datab->add("size", data( &ORO_CoreLib::BufferBase::size, "Get the used size of the buffer.")); - datab->add("capacity", data( &ORO_CoreLib::BufferBase::capacity, "Get the capacity of the buffer.")); - datab->add("empty", data( &ORO_CoreLib::BufferBase::empty, "Inspect if the buffer is empty.")); - datab->add("full", data( &ORO_CoreLib::BufferBase::full, "Inspect if the buffer is full.")); - - return new MemberFactoryComposite( datas, datab ); + TaskObject* to = new TaskObject( this->getName() ); + to->methods()->addMethod(method("Pop", &ReadBufferPort::Pop, this), + "Pop a single value from the Buffer. Returns false if empty.", + "Val", "The value returned by argument."); + to->methods()->addMethod(method("front", &ReadBufferPort::front, this), + "Get the next to be popped value from the buffer. Returns default value if buffer is empty."); + to->methods()->addMethod(method("size", &ReadBufferPort::size, this), + "Get the used size of the buffer."); + to->methods()->addMethod(method("capacity", &ReadBufferPort::capacity, this), + "Get the capacity of the buffer."); + to->methods()->addMethod(method("empty", &ReadBufferPort::empty, this), + "Inspect if the buffer is empty."); + to->methods()->addMethod(method("full", &ReadBufferPort::full, this), + "Inspect if the buffer is full."); + to->methods()->addMethod(method("clear", &ReadBufferPort::clear, this), + "Clear the contents of the buffer."); + return to; #else return 0; #endif @@ -232,6 +294,57 @@ namespace ORO_Execution mconn = 0; } + + /** + * Clears all contents of this buffer. + */ + void clear() { + if (mconn) + return mconn->write()->clear(); + } + + /** + * Returns the actual number of items that are stored in the + * buffer. + * @return number of items. + */ + BufferBase::size_type size() const { + if (mconn) + return mconn->write()->size(); + return 0; + } + + /** + * Returns the maximum number of items that can be stored in the + * buffer. + * @return maximum number of items. + */ + BufferBase::size_type capacity() const { + if (mconn) + return mconn->write()->capacity(); + return 0; + } + + /** + * Check if this buffer is empty. + * @return true if size() == 0 + */ + bool empty() const { + if (mconn) + return mconn->write()->empty(); + return 0; + } + + /** + * Check if this buffer is full. + * @return true if size() == capacity() + */ + bool full() const { + if (mconn) + return mconn->write()->full(); + return 0; + } + virtual PortInterface* clone() const { return new WriteBufferPort( this->getName(), buf_size, minitial_value ); } @@ -240,21 +353,23 @@ namespace ORO_Execution return new ReadBufferPort( this->getName() ); } - virtual DataSourceFactoryInterface* createDataSources() { + virtual OperationInterface* createPortObject() { #ifndef ORO_EMBEDDED - if ( !mconn ) - return 0; - TemplateDataSourceFactory >* datas = newDataSourceFactory( mconn->write() ); - bool (ORO_CoreLib::WriteInterface::*PushPtr)(typename ORO_CoreLib::WriteInterface::param_t) = &ORO_CoreLib::WriteInterface::Push; - datas->add("Push", data( PushPtr, "Push a single value in the Buffer. Returns false if full.", - "Val", "The value.") ); - - TemplateDataSourceFactory* datab = newDataSourceFactory( mconn->write() ); - datab->add("size", data( &ORO_CoreLib::BufferBase::size, "Get the used size of the buffer.")); - datab->add("capacity", data( &ORO_CoreLib::BufferBase::capacity, "Get the capacity of the buffer.")); - datab->add("empty", data( &ORO_CoreLib::BufferBase::empty, "Inspect if the buffer is empty.")); - datab->add("full", data( &ORO_CoreLib::BufferBase::full, "Inspect if the buffer is full.")); - return new MemberFactoryComposite( datas, datab ); + TaskObject* to = new TaskObject( this->getName() ); + to->methods()->addMethod(method("Push", &WriteBufferPort::Push, this), + "Push a single value in the Buffer. Returns false if full().", + "Val", "The value."); + to->methods()->addMethod(method("size", &WriteBufferPort::size, this), + "Get the used size of the buffer."); + to->methods()->addMethod(method("capacity", &WriteBufferPort::capacity, this), + "Get the capacity of the buffer."); + to->methods()->addMethod(method("empty", &WriteBufferPort::empty, this), + "Inspect if the buffer is empty."); + to->methods()->addMethod(method("full", &WriteBufferPort::full, this), + "Inspect if the buffer is full."); + to->methods()->addMethod(method("clear", &WriteBufferPort::clear, this), + "Clear the contents of the buffer."); + return to; #else return 0; #endif @@ -342,6 +457,56 @@ namespace ORO_Execution ReadBufferPort::disconnect(); } + /** + * Clears all contents of this buffer. + */ + void clear() { + if (mconn) + return mconn->buffer()->clear(); + } + + /** + * Returns the actual number of items that are stored in the + * buffer. + * @return number of items. + */ + BufferBase::size_type size() const { + if (mconn) + return mconn->buffer()->size(); + return 0; + } + + /** + * Returns the maximum number of items that can be stored in the + * buffer. + * @return maximum number of items. + */ + BufferBase::size_type capacity() const { + if (mconn) + return mconn->buffer()->capacity(); + return 0; + } + + /** + * Check if this buffer is empty. + * @return true if size() == 0 + */ + bool empty() const { + if (mconn) + return mconn->buffer()->empty(); + return 0; + } + + /** + * Check if this buffer is full. + * @return true if size() == capacity() + */ + bool full() const { + if (mconn) + return mconn->buffer()->full(); + return 0; + } + virtual PortInterface* clone() const { return new BufferPort( this->getName(), this->buf_size, this->minitial_value ); } @@ -350,26 +515,28 @@ namespace ORO_Execution return new BufferPort( this->getName(), this->buf_size, this->minitial_value ); } - virtual DataSourceFactoryInterface* createDataSources() { + virtual OperationInterface* createPortObject() { #ifndef ORO_EMBEDDED - if ( !mconn ) - return 0; - TemplateDataSourceFactory >* datas = newDataSourceFactory( mconn->buffer() ); - bool (ORO_CoreLib::BufferInterface::*PushPtr)(typename ORO_CoreLib::BufferInterface::param_t) = &ORO_CoreLib::BufferInterface::Push; - bool (ORO_CoreLib::BufferInterface::*PopPtr)(typename ORO_CoreLib::BufferInterface::reference_t) = &ORO_CoreLib::BufferInterface::Pop; - typename ORO_CoreLib::BufferInterface::value_t (ORO_CoreLib::BufferInterface::*FrontPtr)() const = &ORO_CoreLib::BufferInterface::front; - datas->add("Push", data( PushPtr, "Push a single value in the Buffer. Returns false if full.", - "Val", "The value.") ); - datas->add("Pop", data( PopPtr, "Pop a single value from the Buffer. Returns false if empty.", - "Val", "The value returned by argument.") ); - datas->add("front", data( FrontPtr, "Get the next to be popped value from the buffer. Returns default value if buffer is empty.")); - - TemplateDataSourceFactory* datab = newDataSourceFactory( mconn->buffer() ); - datab->add("size", data( &ORO_CoreLib::BufferBase::size, "Get the used size of the buffer.")); - datab->add("capacity", data( &ORO_CoreLib::BufferBase::capacity, "Get the capacity of the buffer.")); - datab->add("empty", data( &ORO_CoreLib::BufferBase::empty, "Inspect if the buffer is empty.")); - datab->add("full", data( &ORO_CoreLib::BufferBase::full, "Inspect if the buffer is full.")); - return new MemberFactoryComposite( datas, datab ); + TaskObject* to = new TaskObject( this->getName() ); + to->methods()->addMethod(method("Push", &WriteBufferPort::Push, this), + "Push a single value in the Buffer. Returns false if full().", + "Val", "The value."); + to->methods()->addMethod(method("Pop", &ReadBufferPort::Pop, this), + "Pop a single value from the Buffer. Returns false if empty.", + "Val", "The value returned by argument."); + to->methods()->addMethod(method("front", &ReadBufferPort::front, this), + "Get the next to be popped value from the buffer. Returns default value if buffer is empty."); + to->methods()->addMethod(method("size", &BufferPort::size, this), + "Get the used size of the buffer."); + to->methods()->addMethod(method("capacity", &BufferPort::capacity, this), + "Get the capacity of the buffer."); + to->methods()->addMethod(method("empty", &BufferPort::empty, this), + "Inspect if the buffer is empty."); + to->methods()->addMethod(method("full", &BufferPort::full, this), + "Inspect if the buffer is full."); + to->methods()->addMethod(method("clear", &BufferPort::clear, this), + "Clear the contents of the buffer."); + return to; #else return 0; #endif diff --git a/packages/execution/task_context/current/include/Command.hpp b/packages/execution/task_context/current/include/Command.hpp index e029ed7c0..5084175de 100644 --- a/packages/execution/task_context/current/include/Command.hpp +++ b/packages/execution/task_context/current/include/Command.hpp @@ -9,8 +9,11 @@ namespace ORO_Execution { /** - * A Command is a function which can be executed (sent) to another - * task and queried for its execution status. Normally, it is the + * A Command is a function which can be sent to a + * task for execution and be queried for its execution status. + * The sending is also called the 'invocation' of the Command object. + * + * It is good practice that the * receiving task which defines the commands it can execute, but * this class allows otherwise as well. * @@ -32,8 +35,9 @@ namespace ORO_Execution X x; Command mycom("Command1",&X::command_1,&X::condition_1, &x); + // Invoke the command: Frame f = //... - mycom(3, f, 9.0); // executes the command. + mycom(3, f, 9.0); @endcode * */ @@ -181,45 +185,65 @@ namespace ORO_Execution return *this; } + /** + * Returns true if the command is ready for invocation. + * If ready() returns true, this command may be invoked, + * otherwise, invocation will fail. + */ bool ready() const { return this->impl && this->impl->ready(); } - bool dispatch() { - if (!this->impl) return false; - return this->impl->dispatch(); - } - - bool execute() { - if (!this->impl) return false; - return this->impl->execute(); - } - + /** + * Returns true if the command is executed and the completion + * condition returns true as well. + */ bool evaluate() const { if (!this->impl) return false; return this->impl->evaluate(); } + /** + * After reset(), another attempt to dispatch + * the command will be done when invoked. + */ void reset() { if (!this->impl) return; return this->impl->reset(); } + /** + * Returns true if the command was sent to the CommandProcessor. + * You can use this flag to check whether this command was invoked. + */ bool sent() const { if (!this->impl) return false; return this->impl->sent(); } + /** + * Returns true if the command was accepted when sent to the CommandProcessor. + * A Command is accepted when the CommandProcessor was running and its queue + * was not full. + */ bool accepted() const { if (!this->impl) return false; return this->impl->accepted(); } + /** + * Returns true if the command function was executed by the CommandProcessor. + * When executed() is true, you can check if it was found valid(). + */ bool executed() const { if (!this->impl) return false; return this->impl->executed(); } + /** + * Returns true if the command was valid, i.e. the command function itself + * was executed and returned true. + */ bool valid() const { if (!this->impl) return false; return this->impl->valid(); @@ -234,10 +258,22 @@ namespace ORO_Execution return mname; } + /** + * The Command class is just a wrapper around an implementation, + * this function returns the implementation. Make a clone() if you + * want to keep the pointer. + * + * @return The implementation + */ detail::CommandBase* getCommandImpl() const { return this->impl; } + /** + * Change the implementation of this Command, delete the old one. + * + * @param new_impl The new implementation. + */ void setCommandImpl(detail::CommandBase* new_impl) const { delete this->impl; return this->impl = new_impl; diff --git a/packages/execution/task_context/current/include/CommandC.hpp b/packages/execution/task_context/current/include/CommandC.hpp index 6fb78802a..40fb42a19 100644 --- a/packages/execution/task_context/current/include/CommandC.hpp +++ b/packages/execution/task_context/current/include/CommandC.hpp @@ -34,6 +34,7 @@ #include "corelib/DataSourceBase.hpp" #include "CommandFactoryInterface.hpp" +#include "OperationFactory.hpp" namespace ORO_CoreLib { @@ -74,7 +75,7 @@ namespace ORO_Execution * The constructor. * @see CommandRepository */ - CommandC( const CommandRepository* gcf, const std::string& name); + CommandC( const CommandFactory* gcf, const std::string& name); /** * A CommandC is copyable by value. @@ -169,7 +170,7 @@ namespace ORO_Execution * completion condition was true as well. * @retval false otherwise. */ - bool evaluate(); + bool evaluate() const; /** * Reset the command. diff --git a/packages/execution/task_context/current/include/CommandDS.hpp b/packages/execution/task_context/current/include/CommandDS.hpp index 8842cd5b5..547c581b3 100644 --- a/packages/execution/task_context/current/include/CommandDS.hpp +++ b/packages/execution/task_context/current/include/CommandDS.hpp @@ -5,6 +5,7 @@ #include #include "CommandProcessor.hpp" #include "BindStorage.hpp" +#include "UnMember.hpp" namespace ORO_Execution { @@ -80,5 +81,11 @@ namespace ORO_Execution }; + template + CommandDS::type > command_ds(std::string name, ComF command, ConF condition, CommandProcessor* cp, bool invert = false) { + return CommandDS::type >(name, command, condition, cp, invert); + } + + } #endif diff --git a/packages/execution/task_context/current/include/CommandDSFunctors.hpp b/packages/execution/task_context/current/include/CommandDSFunctors.hpp index a7e2963fb..5980eb02d 100644 --- a/packages/execution/task_context/current/include/CommandDSFunctors.hpp +++ b/packages/execution/task_context/current/include/CommandDSFunctors.hpp @@ -13,14 +13,15 @@ namespace ORO_Execution class FunctorDS0 { public: + typedef boost::function FunctionImpl; typedef FunctionT Function; - typedef typename boost::remove_pointer::type CompT; - FunctionT fun; + typedef typename boost::remove_pointer::type CompT; + FunctionImpl fun; typename DataSource >::shared_ptr ds; typedef boost::weak_ptr CompW; typedef boost::shared_ptr CompS; - FunctorDS0( DataSource* c, FunctionT f ) + FunctorDS0( DataSource* c, FunctionImpl f ) : fun( f ), ds(c) {} @@ -65,14 +66,15 @@ namespace ORO_Execution { public: typedef FunctionT Function; + typedef boost::function FunctionImpl; // arg1_type is the component type. - typedef typename boost::remove_pointer::type CompT; - typedef typename FunctionT::arg2_type Arg2T; - FunctionT fun; + typedef typename boost::remove_pointer::type CompT; + typedef typename FunctionImpl::arg2_type Arg2T; + FunctionImpl fun; typename DataSource::shared_ptr aa; typename DataSource >::shared_ptr ds; - FunctorDS1( DataSource >* c, FunctionT f, DataSource* a = 0) + FunctorDS1( DataSource >* c, FunctionImpl f, DataSource* a = 0) : fun( f ), aa( a ), ds(c) { } diff --git a/packages/execution/task_context/current/include/CommandFunctors.hpp b/packages/execution/task_context/current/include/CommandFunctors.hpp index efcafb211..649488f3a 100644 --- a/packages/execution/task_context/current/include/CommandFunctors.hpp +++ b/packages/execution/task_context/current/include/CommandFunctors.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -288,17 +289,18 @@ namespace ORO_Execution */ template< class FunctionT> struct Functor - : public FunctorImpl + : public FunctorImpl::arity,boost::function > { typedef FunctionT Function; + typedef boost::function FunctionImpl; - Functor(FunctionT impl) - : FunctorImpl(impl) + Functor(FunctionImpl impl) + : FunctorImpl::arity,FunctionImpl>(impl) {} // Allow construction from base class. - Functor(FunctorImpl impl) - : FunctorImpl(impl) + Functor(FunctorImpl::arity,FunctionImpl> impl) + : FunctorImpl::arity,FunctionImpl>(impl) {} }; @@ -308,12 +310,12 @@ namespace ORO_Execution * @param Signature The function signature of this command. * @param FunctorT The function that stores the command. */ - template > > + template > class CommandFunctor :public CommandInterface { public: - typedef typename FunctorT::Function Function; + typedef typename FunctorT::FunctionImpl Function; typedef SignatureT Signature; typedef FunctorT Functor; @@ -383,12 +385,12 @@ namespace ORO_Execution * @param Signature The function signature of this condition * @param FunctorT The function that stores the command. */ - template > > + template > class ConditionFunctor :public ConditionInterface { public: - typedef typename FunctorT::Function Function; + typedef typename FunctorT::FunctionImpl Function; typedef SignatureT Signature; typedef FunctorT Functor; diff --git a/packages/execution/task_context/current/include/CommandRepository.hpp b/packages/execution/task_context/current/include/CommandRepository.hpp new file mode 100644 index 000000000..96094194c --- /dev/null +++ b/packages/execution/task_context/current/include/CommandRepository.hpp @@ -0,0 +1,324 @@ +#ifndef ORO_COMMAND_REPOSITORY_HPP +#define ORO_COMMAND_REPOSITORY_HPP + +#include "DataSourceArgsCommand.hpp" +#include "OperationFactory.hpp" +#include "CommandC.hpp" +#include "LocalCommand.hpp" +#define ORO_REMOTING +#ifdef ORO_REMOTING +#include "RemoteCommand.hpp" +#endif + +namespace ORO_Execution +{ + /** + * A command repository stores a number of commands from a Task which + * can be used by other tasks or from scripts. + */ + class CommandRepository + : public OperationFactory + { + template + inline T* getpointer(T& t) { + return &t; + } + template + inline T* getpointer(T* t) { + return t; + } + + std::map simplecommands; + public: + typedef CommandFactory Factory; + + ~CommandRepository() + { + clear(); + } + + /** + * Retrieve a previously added Command. + * + * @param name The name of the Command + * @param args A vector of command arguments. + * + * @return A dispatchable object which is a new Command object. + */ + DispatchInterface* getCommand( std::string name, + const std::vector& args) const + { + return this->produce(name, args); + } + + /** + * Return the pointer to an added simple Command. + * + * @param name The name of the command to retrieve. + * @param Signature The function signature of the command, for + * example: getCommand("name"); + * + * @return A new pointer to a simple Command, or null if it does not exist. + */ + template + DispatchInterface* getCommand( std::string name ) + { + if ( simplecommands.count(name) ) + return simplecommands[name]->clone(); +#ifdef ORO_REMOTING + if ( this->hasMember(name ) ) { + return new detail::RemoteCommand(this, name); + } +#endif + return 0; + } + /** + * Retrieve the completion condition of a previously added Command. + * + * @param name The name of the Command + * @param args A vector of command arguments + * + * @return A condition which evaluates the command's completion. + */ + ConditionInterface* getCondition( std::string name, + const std::vector& args) const + { + DispatchInterface* di = this->produce(name, args); + ConditionInterface* ret = di->createCondition(); + delete di; + return ret; + } + + void clear() { + while ( !simplecommands.empty() ) { + delete simplecommands.begin()->second; + simplecommands.erase( simplecommands.begin() ); + } + OperationFactory::clear(); + } + + + /** + * Create a CommandC container object, which can be used + * to access an added Command. + * + * @param name The name of the Command + * + * @return A new CommandC object. + */ + CommandC create(std::string name) { + return CommandC( this, name ); + } + + /** + * Add a Command to the interface. You can retrieve it with getCommand. + * + * @param com A pointer to a Command object. + * + * @return true if the command could be added. + */ + template + bool addCommand( CommandT* com ) + { + if ( simplecommands.count( com->getName() ) ) + return false; + simplecommands[com->getName()] = com->getCommandImpl()->clone(); + return true; + } + + + /** + * Add an existing Command, which takes no arguments, to the Operations interface. + * + * @param c A pointer to the existing command. + * @param description A user readable description of what this command does. + * + * @return true if the command could be added. + */ + template + bool addCommand( CommandT com, const char* description) + { + typedef typename boost::remove_pointer::type CommandVT; + typedef typename boost::add_pointer::type CommandPT; + typedef typename CommandVT::Signature ComSig; + CommandPT c = this->getpointer(com); + detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); + // We can only add local commands. + if ( !lc ) + return false; + // First add the command to the normal interface. + if ( this->addCommand( c ) == false ) + return false; + // Next, add it to the Command from 'DataSource' interface. + this->add( c->getName(), new detail::OperationFactoryPart0 >( + detail::DataSourceArgsCommand(lc->getCommandFunction(), + lc->getConditionFunction(), + lc->getCommandProcessor(), lc->isInverted() ), description) ); + return true; + } + + /** + * Add an existing Command, which takes one argument, to the + * Operations Interface. + * + * @param c A pointer to the existing command. + * @param description A user readable description of what this command does. + * @param arg1 A single word name of the argument. + * @param arg1_description A user readable description of the argument. + * + * @return true if the command could be added. + */ + template + bool addCommand( CommandT com, const char* description, + const char* arg1, const char* arg1_description) + { + typedef typename boost::remove_pointer::type CommandVT; + typedef typename boost::add_pointer::type CommandPT; + typedef typename CommandVT::Signature ComSig; + CommandPT c = this->getpointer(com); + detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); + if ( !lc ) + return false; + if ( this->addCommand( c ) == false ) + return false; + this->add( c->getName(), new detail::OperationFactoryPart1 >( + detail::DataSourceArgsCommand(lc->getCommandFunction(), + lc->getConditionFunction(), + lc->getCommandProcessor(), lc->isInverted() ), + description, arg1, arg1_description) ); + return true; + } + + /** + * Add an existing Command, which takes two arguments, to the + * Operations Interface. + * + * @param c A pointer to the existing command. + * @param description A user readable description of what this command does. + * @param arg1 A single word name of the first argument. + * @param arg1_description A user readable description of the first argument. + * @param arg2 A single word name of the second argument. + * @param arg2_description A user readable description of the second argument. + * + * @return true if the command could be added. + */ + template + bool addCommand( CommandT com, const char* description, + const char* arg1, const char* arg1_description, + const char* arg2, const char* arg2_description) + { + typedef typename boost::remove_pointer::type CommandVT; + typedef typename boost::add_pointer::type CommandPT; + typedef typename CommandVT::Signature ComSig; + CommandPT c = this->getpointer(com); + detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); + if ( !lc ) + return false; + if ( this->addCommand( c ) == false ) + return false; + this->add( c->getName(), new detail::OperationFactoryPart2 >( + detail::DataSourceArgsCommand(lc->getCommandFunction(), + lc->getConditionFunction(), + lc->getCommandProcessor(), lc->isInverted() ), + description, arg1, arg1_description, + arg2, arg2_description) ); + return true; + } + + + template + bool addCommand( CommandT com, const char* description, + const char* arg1, const char* arg1_description, + const char* arg2, const char* arg2_description, + const char* arg3, const char* arg3_description) + { + typedef typename boost::remove_pointer::type CommandVT; + typedef typename boost::add_pointer::type CommandPT; + typedef typename CommandVT::Signature ComSig; + CommandPT c = this->getpointer(com); + detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); + if ( !lc ) + return false; + if ( this->addCommand( c ) == false ) + return false; + this->add( c->getName(), new detail::OperationFactoryPart3 >( + detail::DataSourceArgsCommand(lc->getCommandFunction(), + lc->getConditionFunction(), + lc->getCommandProcessor(), lc->isInverted() ), + description, arg1, arg1_description, + arg2, arg2_description, + arg3, arg3_description) ); + return true; + } + + template + bool addCommand( CommandT com, const char* description, + const char* arg1, const char* arg1_description, + const char* arg2, const char* arg2_description, + const char* arg3, const char* arg3_description, + const char* arg4, const char* arg4_description) + { + typedef typename boost::remove_pointer::type CommandVT; + typedef typename boost::add_pointer::type CommandPT; + typedef typename CommandVT::Signature ComSig; + CommandPT c = this->getpointer(com); + detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); + if ( !lc ) + return false; + if ( this->addCommand( c ) == false ) + return false; + this->add( c->getName(), new detail::OperationFactoryPart4 >( + detail::DataSourceArgsCommand(lc->getCommandFunction(), + lc->getConditionFunction(), + lc->getCommandProcessor(), lc->isInverted() ), + description, arg1, arg1_description, + arg2, arg2_description, + arg3, arg3_description, + arg4, arg4_description) ); + return true; + } + + template + bool addCommandDS( DataSource< boost::weak_ptr >* wp, CommandT c, const char* description) + { + using namespace detail; + typedef typename CommandT::Signature ComSig; + if ( this->hasMember(c.getName() ) ) + return false; + typedef FunctorDS0 CommandF; + typedef detail::DataSourceArgsCommand DSComm; + this->add( c.getName(), new detail::OperationFactoryPart0( + DSComm( CommandF(wp, c.getCommandFunction()), + CommandF(wp, c.getConditionFunction()), + c.getCommandProcessor(), c.isInverted() ), + description) ); + return true; + } + + template + bool addCommandDS( DataSource >* wp, CommandT c, const char* description, + const char* arg1, const char* arg1_description) + { + using namespace detail; + typedef typename CommandT::Signature ComSig; + typedef FunctorDS1 CommandF; + typedef detail::DataSourceArgsCommand DSComm; + if ( this->hasMember(c.getName() ) ) + return false; + this->add( c.getName(), new detail::OperationFactoryPart1( + DSComm( CommandF(wp, c.getCommandFunction()), + CommandF(wp, c.getConditionFunction()), + c.getCommandProcessor(), c.isInverted() ), + description, arg1, arg1_description) ); + return true; + } + + + }; + +} + + +#endif diff --git a/packages/execution/task_context/current/include/DataPort.hpp b/packages/execution/task_context/current/include/DataPort.hpp index 2a322d6c3..ebecd6f93 100644 --- a/packages/execution/task_context/current/include/DataPort.hpp +++ b/packages/execution/task_context/current/include/DataPort.hpp @@ -32,7 +32,8 @@ #include #include "PortInterface.hpp" #include "DataConnectionInterface.hpp" -#include "TemplateDataSourceFactory.hpp" +#include "OperationInterface.hpp" +#include "Method.hpp" #include "ConnectionTypes.hpp" namespace ORO_Execution @@ -113,13 +114,12 @@ namespace ORO_Execution virtual PortInterface* antiClone() const; - virtual DataSourceFactoryInterface* createDataSources() { + virtual OperationInterface* createPortObject() { #ifndef ORO_EMBEDDED - if ( !mconn ) - return 0; - TemplateDataSourceFactory >* datas = newDataSourceFactory( mconn->data() ); - datas->add("Get", ORO_Execution::data( &ORO_CoreLib::DataObjectInterface::Get, "Get the current value of this Data Object")); - return datas; + TaskObject* to = new TaskObject( this->getName() ); + to->methods()->addMethod( method("Get",&ReadDataPort::Get, this), + "Get the current value of this Data Port"); + return to; #else return 0; #endif @@ -236,15 +236,15 @@ namespace ORO_Execution return new ReadDataPort( this->getName() ); } - virtual DataSourceFactoryInterface* createDataSources() { + virtual OperationInterface* createPortObject() { #ifndef ORO_EMBEDDED - if ( !mconn ) - return 0; - TemplateDataSourceFactory >* datas = newDataSourceFactory( mconn->data() ); - datas->add("Get", ORO_Execution::data( &ORO_CoreLib::DataObjectInterface::Get, "Get the current value of this Data Object")); - datas->add("Set", ORO_Execution::data( &ORO_CoreLib::DataObjectInterface::Set, "Set the current value of this Data Object", - "Value", "The new value.") ); - return datas; + TaskObject* to = new TaskObject( this->getName() ); + to->methods()->addMethod( method("Get",&WriteDataPort::Get, this), + "Get the current value of this Data Port"); + to->methods()->addMethod( method("Set",&WriteDataPort::Set, this), + "Set the current value of this Data Port", + "Value", "The new value."); + return to; #else return 0; #endif diff --git a/packages/execution/task_context/current/include/DataSourceArgsCommand.hpp b/packages/execution/task_context/current/include/DataSourceArgsCommand.hpp new file mode 100644 index 000000000..86cc1f31b --- /dev/null +++ b/packages/execution/task_context/current/include/DataSourceArgsCommand.hpp @@ -0,0 +1,161 @@ +#ifndef ORO_DATASOURCE_ARGS_COMMAND_HPP +#define ORO_DATASOURCE_ARGS_COMMAND_HPP + +#include "CommandFunctors.hpp" +#include "CommandProcessor.hpp" +#include "CommandDSFunctors.hpp" +#include "DispatchInterface.hpp" + +namespace ORO_Execution +{ + namespace detail + { + /** + * A Command which dispatches locally. + * The arguments are fetched from DataSources. + */ + template > + class DataSourceArgsCommand + : public DispatchInterface + { + CommandF mcom; + mutable CommandF mcon; + CommandProcessor* mcp; + bool minvoked, maccept, mvalid, mexec, minvert; + public: + typedef boost::function_traits traits; + typedef CommandT Signature; + typedef bool result_type; + + DataSourceArgsCommand(boost::function com, boost::function con, CommandProcessor* cp, bool inverted) + : mcom( com ), mcon( con ), + mcp( cp ), + minvoked(false), maccept(false), + mvalid(false), mexec(false), minvert(inverted) + { + } + + DataSourceArgsCommand(CommandF com, CommandF con, CommandProcessor* cp, bool inverted) + : mcom( com ), mcon( con ), + mcp( cp ), + minvoked(false), maccept(false), + mvalid(false), mexec(false), minvert(inverted) + { + } + + DataSourceArgsCommand* create() const + { + return clone(); + } + + template + DataSourceArgsCommand* create(DataSource* a1) const + { + DataSourceArgsCommand* r = this->clone(); + r->mcom.setArguments(a1); + r->mcon.setArguments(a1); + return r; + } + + template + DataSourceArgsCommand* create(DataSource* a1, DataSource* a2) const + { + DataSourceArgsCommand* r = this->clone(); + r->mcom.setArguments(a1, a2); + r->mcon.setArguments(a1, a2); + return r; + } + + template + DataSourceArgsCommand* create(DataSource* a1, DataSource* a2, DataSource* a3) const + { + DataSourceArgsCommand* r = this->clone(); + r->mcom.setArguments(a1, a2, a3); + r->mcon.setArguments(a1, a2, a3); + return r; + } + + template + DataSourceArgsCommand* create(DataSource* a1, DataSource* a2, DataSource* a3, DataSource* a4) const + { + DataSourceArgsCommand* r = this->clone(); + r->mcom.setArguments(a1, a2, a3, a4); + r->mcon.setArguments(a1, a2, a3, a4); + return r; + } + + bool ready() const { + return !minvoked; + } + + bool operator()() { + if (minvoked) + return false; + minvoked = true; + return maccept = mcp->process( this ); + } + + virtual bool dispatch() { + if (minvoked) + return false; + minvoked = true; + return maccept = mcp->process( this ); + } + + virtual void readArguments() { mcom.readArguments(); } + + virtual bool execute() { + mvalid = mcom.execute(); + mexec = true; + return mvalid; + } + + virtual bool evaluate() const { + if (mexec && mvalid ) + return mcon.evaluate() != minvert; + return false; + } + + virtual void reset() { + minvoked = (false); + maccept = (false); + mvalid = (false); + mexec = (false); + } + + virtual bool sent() const { + return minvoked; + } + + virtual bool accepted() const { + return maccept; + } + + virtual bool executed() const { + return mexec; + } + + virtual bool valid() const { + return mvalid; + } + + virtual ORO_CoreLib::ConditionInterface* createCondition() const + { + return new detail::ConditionFunctor(mcon, minvert); + } + + virtual DataSourceArgsCommand* clone() const { + return new DataSourceArgsCommand(*this); + } + + virtual DataSourceArgsCommand* copy( std::map& alreadyCloned ) const { + return new DataSourceArgsCommand(CommandF(mcom.copy(alreadyCloned)), + CommandF(mcon.copy(alreadyCloned)),mcp, minvert); + } + + }; + } +} + +#endif diff --git a/packages/execution/task_context/current/include/DataSourceArgsMethod.hpp b/packages/execution/task_context/current/include/DataSourceArgsMethod.hpp new file mode 100644 index 000000000..df5b21ae9 --- /dev/null +++ b/packages/execution/task_context/current/include/DataSourceArgsMethod.hpp @@ -0,0 +1,104 @@ +#ifndef ORO_DATASOURCE_ARGS_METHOD_HPP +#define ORO_DATASOURCE_ARGS_METHOD_HPP + +#include "DataSource.hpp" +#include "LocalMethod.hpp" +#include "TemplateMemberFactory.hpp" + +namespace ORO_Execution +{ + namespace detail + { + /** + * A method which gets its arguments from a data source and + * is a datasource itself. + */ + template > > + class DataSourceArgsMethod + : public DataSource< typename boost::function_traits::result_type > + { + typename FunctorT::shared_ptr mmeth; + public: + typedef boost::function_traits traits; + typedef SignatureT Signature; + + typedef typename boost::function_traits::result_type result_type; + typedef DataSource Base; + + DataSourceArgsMethod(boost::function meth) + : mmeth( new FunctorT(meth) ) + { + } + + DataSourceArgsMethod( typename FunctorT::shared_ptr ds) + : mmeth( ds ) + { + } + + DataSourceArgsMethod* create() const + { + return clone(); + } + + template + DataSourceArgsMethod* create(DataSource* a1) const + { + DataSourceArgsMethod* r = this->clone(); + r->mmeth->setArguments(a1); + return r; + } + + template + DataSourceArgsMethod* create(DataSource* a1, DataSource* a2) const + { + DataSourceArgsMethod* r = this->clone(); + r->mmeth->setArguments(a1, a2); + return r; + } + + template + DataSourceArgsMethod* create(DataSource* a1, DataSource* a2, DataSource* a3) const + { + DataSourceArgsMethod* r = this->clone(); + r->mmeth->setArguments(a1, a2, a3); + return r; + } + + template + DataSourceArgsMethod* create(DataSource* a1, DataSource* a2, DataSource* a3, DataSource* a4) const + { + DataSourceArgsMethod* r = this->clone(); + r->mmeth->setArguments(a1, a2, a3, a4); + return r; + } + + result_type operator()() { + return mmeth->get(); + } + + virtual result_type get() const { + return mmeth->get(); + } + + virtual result_type value() const { + return mmeth->value(); + } + + virtual DataSourceArgsMethod* clone() const { + return new DataSourceArgsMethod( typename FunctorT::shared_ptr(mmeth->clone()) ); + } + + virtual DataSource* copy( std::map& alreadyCloned ) const + { + return new DataSourceArgsMethod( typename FunctorT::shared_ptr(mmeth->copy(alreadyCloned)) ); + } + + boost::function getMethodFunction() const { + return mmeth.ff.gen; + } + }; + } +} + + +#endif diff --git a/packages/execution/task_context/current/include/DataSourceStorage.hpp b/packages/execution/task_context/current/include/DataSourceStorage.hpp new file mode 100644 index 000000000..95f2f9e43 --- /dev/null +++ b/packages/execution/task_context/current/include/DataSourceStorage.hpp @@ -0,0 +1,165 @@ +#ifndef ORO_TASK_DATASOURCE_STORAGE_HPP +#define ORO_TASK_DATASOURCE_STORAGE_HPP + +#include +#include +#include +#include +#include +#include "CommandC.hpp" + +namespace ORO_Execution +{ + namespace detail + { + // Partial specialisations for storing a void or not a void. + template + struct DataSourceResultStorage + { + typename ORO_CoreLib::ValueDataSource::shared_ptr value; + DataSourceResultStorage() + : value(new ORO_CoreLib::ValueDataSource() ) + {} + }; + + template<> + struct DataSourceResultStorage + { + }; + + // Partial specialisations for storing a reference or not reference + template + struct DataSourceArgStorage + { + typename ORO_CoreLib::ValueDataSource::shared_ptr value; + DataSourceArgStorage() + : value(new ORO_CoreLib::ValueDataSource() ) + {} + }; + +#if 0 + // references not used for now: + // the result will not be communicated back to user code. + template + struct DataSourceArgStorage + { + ORO_CoreLib::ReferenceDataSource::shared_ptr value; + DataSourceArgStorage(A& a) + : value(new ORO_CoreLib::ReferenceDataSource(a) ) + {} + }; +#endif + + + template + struct DataSourceStorageImpl; + + /** + * When no arguments are to be stored. + */ + template + struct DataSourceStorageImpl<0, DataType> + : public DataSourceResultStorage::result_type> + { + void initArgs(CommandC& ) {} + }; + + /** + * Stores one data source. + */ + template + struct DataSourceStorageImpl<1, DataType> + { + typedef typename boost::function_traits::arg1_type arg1_type; + DataSourceArgStorage ma1; + + void initArgs(CommandC& cc) { + cc.arg( ma1.value ); + } + + void store(arg1_type a1) { + ma1.value->set(a1); + } + }; + + template + struct DataSourceStorageImpl<2, DataType> + { + typedef typename boost::function_traits::arg1_type arg1_type; + typedef typename boost::function_traits::arg2_type arg2_type; + DataSourceArgStorage ma1; + DataSourceArgStorage ma2; + + void initArgs(CommandC& cc) { + cc.arg( ma1.value ); + cc.arg( ma2.value ); + } + void store(arg1_type a1, arg2_type a2) { + ma1.value->set(a1); + ma2.value->set(a2); + } + }; + + template + struct DataSourceStorageImpl<3, DataType> + { + typedef typename boost::function_traits::arg1_type arg1_type; + typedef typename boost::function_traits::arg2_type arg2_type; + typedef typename boost::function_traits::arg3_type arg3_type; + DataSourceArgStorage ma1; + DataSourceArgStorage ma2; + DataSourceArgStorage ma3; + + void initArgs(CommandC& cc) { + cc.arg( ma1.value ); + cc.arg( ma2.value ); + cc.arg( ma3.value ); + } + void store(arg1_type a1, arg2_type a2, arg3_type a3) { + ma1.value->set(a1); + ma2.value->set(a2); + ma3.value->set(a3); + } + }; + + template + struct DataSourceStorageImpl<4, DataType> + { + typedef typename boost::function_traits::arg1_type arg1_type; + typedef typename boost::function_traits::arg2_type arg2_type; + typedef typename boost::function_traits::arg3_type arg3_type; + typedef typename boost::function_traits::arg4_type arg4_type; + DataSourceArgStorage ma1; + DataSourceArgStorage ma2; + DataSourceArgStorage ma3; + DataSourceArgStorage ma4; + + void initArgs(CommandC& cc) { + cc.arg( ma1.value ); + cc.arg( ma2.value ); + cc.arg( ma3.value ); + cc.arg( ma4.value ); + } + void store(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) { + ma1.value->set(a1); + ma2.value->set(a2); + ma3.value->set(a3); + ma3.value->set(a4); + } + }; + + + /** + * A helper-class for the Command implementation which stores the + * command and condition function objects. It can store both + * pointers to member functions (with their object pointer) and + * plain C functions. + */ + template + struct DataSourceStorage + : public DataSourceStorageImpl::arity, DataType> + { + }; + } +} +#endif diff --git a/packages/execution/task_context/current/include/EventService.hpp b/packages/execution/task_context/current/include/EventService.hpp index 077d62e08..c7fc9f072 100644 --- a/packages/execution/task_context/current/include/EventService.hpp +++ b/packages/execution/task_context/current/include/EventService.hpp @@ -29,6 +29,7 @@ #ifndef EVENT_SERVICE_HPP #define EVENT_SERVICE_HPP +#include #include "TemplateEventFactory.hpp" #include "EventC.hpp" #include "ConnectionC.hpp" @@ -115,6 +116,7 @@ namespace ORO_Execution /** * Add an arbitrary Event to this Service. + * @deprecated by the addEvent function below. */ template< class EventT> bool addEvent( const std::string& ename, EventT* e ) { @@ -126,6 +128,32 @@ namespace ORO_Execution return true; } + /** + * Add an Event with a unique name within the Event Service. + * + * @param e The event to add + * + * @return True if the event's name was unique + * and could be added. + */ + template< class EventT> + bool addEvent( EventT* e ) { + using namespace ORO_CoreLib; + std::string ename = e->getName(); + if ( ename.empty() ) { + Logger::In in("EventService"); + log(Error) << "Can not use addEvent with nameless Even: give your event a name upon construction." << endlog(); + return false; + } + + if ( fact.count(ename) != 0 ) + return false; + fact[ename] = new detail::EventStub( e, + detail::EventHookFactoryGenerator().receptor(), + detail::EventHookFactoryGenerator().emittor() ); + return true; + } + /** * Query for the existence of an Event in this Service. */ @@ -267,10 +295,6 @@ namespace ORO_Execution */ ORO_CoreLib::DataSourceBase::shared_ptr setupEmit(const std::string& ename,const std::vector& args) const; - /* - * The Global EventService, in which global Events are stored. - */ - //static EventService Global; }; diff --git a/packages/execution/task_context/current/include/Invoker.hpp b/packages/execution/task_context/current/include/Invoker.hpp index 2c9a1ca85..fb7d18360 100644 --- a/packages/execution/task_context/current/include/Invoker.hpp +++ b/packages/execution/task_context/current/include/Invoker.hpp @@ -21,6 +21,7 @@ namespace ORO_Execution template struct InvokerBaseImpl<0,F,R> { + virtual ~InvokerBaseImpl() {} virtual R operator()() = 0; }; @@ -28,6 +29,7 @@ namespace ORO_Execution struct InvokerBaseImpl<1,F,R> { typedef typename boost::function::arg1_type arg1_type; + virtual ~InvokerBaseImpl() {} virtual R operator()(arg1_type a1) = 0; }; @@ -36,6 +38,7 @@ namespace ORO_Execution { typedef typename boost::function::arg1_type arg1_type; typedef typename boost::function::arg2_type arg2_type; + virtual ~InvokerBaseImpl() {} virtual R operator()(arg1_type a1, arg2_type a2) = 0; }; @@ -45,6 +48,7 @@ namespace ORO_Execution typedef typename boost::function::arg1_type arg1_type; typedef typename boost::function::arg2_type arg2_type; typedef typename boost::function::arg3_type arg3_type; + virtual ~InvokerBaseImpl() {} virtual R operator()(arg1_type a1, arg2_type a2, arg3_type a3) = 0; }; @@ -55,6 +59,7 @@ namespace ORO_Execution typedef typename boost::function::arg2_type arg2_type; typedef typename boost::function::arg3_type arg3_type; typedef typename boost::function::arg4_type arg4_type; + virtual ~InvokerBaseImpl() {} virtual R operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) = 0; }; @@ -223,7 +228,7 @@ namespace ORO_Execution { if (impl) return (*impl)(); - return NA::na; + return NA::na(); } protected: ToInvoke* impl; @@ -254,7 +259,7 @@ namespace ORO_Execution { if (impl) return (*impl)( a1 ); - return NA::na; + return NA::na(); } protected: ToInvoke* impl; @@ -285,7 +290,7 @@ namespace ORO_Execution { if (impl) return (*impl)(t1, t2); - return NA::na; + return NA::na(); } protected: @@ -318,7 +323,7 @@ namespace ORO_Execution { if (impl) return (*impl)(t1, t2, t3); - return NA::na; + return NA::na(); } protected: @@ -352,7 +357,7 @@ namespace ORO_Execution { if (impl) return (*impl)(t1, t2, t3, t4); - return NA::na; + return NA::na(); } protected: diff --git a/packages/execution/task_context/current/include/LocalCommand.hpp b/packages/execution/task_context/current/include/LocalCommand.hpp index dd4deda00..40dd4680d 100644 --- a/packages/execution/task_context/current/include/LocalCommand.hpp +++ b/packages/execution/task_context/current/include/LocalCommand.hpp @@ -181,13 +181,15 @@ namespace ORO_Execution if (this->minvoked && !this->evaluate() ) // if invoked and not ready. return false; this->reset(); + this->maccept = this->mcp->process( this ); this->minvoked = true; - return this->maccept = this->mcp->process( this ); + return this->maccept; } virtual bool execute() { + this->mvalid = this->invoke(); this->mexec = true; - return this->mvalid = this->invoke(); + return this->mvalid; } virtual bool evaluate() const { @@ -221,7 +223,9 @@ namespace ORO_Execution virtual ORO_CoreLib::ConditionInterface* createCondition() const { - return new detail::ConditionFunctor( boost::bind( boost::mem_fn(&LocalCommand::evaluate), this), this->minvert ); + // LocalCommands are not used by the Parser, so this method is actually + // not used within Orocos. + return new detail::ConditionFunctor( boost::bind( boost::mem_fn(&LocalCommand::evaluate), this) ); } /** diff --git a/packages/execution/task_context/current/include/LocalMethod.hpp b/packages/execution/task_context/current/include/LocalMethod.hpp index c8d2fa185..e7713d0ba 100644 --- a/packages/execution/task_context/current/include/LocalMethod.hpp +++ b/packages/execution/task_context/current/include/LocalMethod.hpp @@ -26,6 +26,8 @@ namespace ORO_Execution bool execute() { return false; } + + using MethodBase::operator(); /** * Invoke this operator if the method has no arguments. diff --git a/packages/execution/task_context/current/include/Method.hpp b/packages/execution/task_context/current/include/Method.hpp index bf967face..feab3e82f 100644 --- a/packages/execution/task_context/current/include/Method.hpp +++ b/packages/execution/task_context/current/include/Method.hpp @@ -10,6 +10,7 @@ namespace ORO_Execution { + using namespace ORO_CoreLib; /** * A method which executes a function. * @@ -183,6 +184,27 @@ namespace ORO_Execution Method< typename detail::UnMember::type > method(std::string name, F method, O object) { return Method< typename detail::UnMember::type >(name, method, object); } + + /** + * Create a Method which executes a function locally. + * + * @param name The name of the resulting Method object + * @param method A pointer to a function to be executed. + */ + template + Method method(std::string name, F method) { + return Method(name, method); + } + /** + * Create a Method which executes a function locally. + * + * @param name The name of the resulting Method object + * @param method A pointer to a function to be executed. + */ + template + Method< typename detail::ArgMember::type > method_ds(std::string name, F method) { + return Method< typename detail::ArgMember::type >(name, method); + } } #endif diff --git a/packages/execution/task_context/current/include/MethodC.hpp b/packages/execution/task_context/current/include/MethodC.hpp index 5640b891c..a431d32f2 100644 --- a/packages/execution/task_context/current/include/MethodC.hpp +++ b/packages/execution/task_context/current/include/MethodC.hpp @@ -32,11 +32,11 @@ #include #include #include +#include "OperationFactory.hpp" namespace ORO_Execution { class GlobalMemberFactory; - class MethodRepository; /** * A user friendly method to a TaskContext. @@ -67,7 +67,7 @@ namespace ORO_Execution * The constructor. * @see MethodRepository */ - MethodC( const MethodRepository* mr, const std::string& name); + MethodC( const MethodFactory* mr, const std::string& name); /** * A MethodC is copyable by value. diff --git a/packages/execution/task_context/current/include/MethodRepository.hpp b/packages/execution/task_context/current/include/MethodRepository.hpp new file mode 100644 index 000000000..39df4c390 --- /dev/null +++ b/packages/execution/task_context/current/include/MethodRepository.hpp @@ -0,0 +1,258 @@ +#ifndef ORO_METHOD_REPOSITORY_HPP +#define ORO_METHOD_REPOSITORY_HPP + +#include "OperationFactory.hpp" +#include "LocalMethod.hpp" +#include "DataSourceArgsMethod.hpp" +#include "MethodC.hpp" + +namespace ORO_Execution +{ + /** + * This class allows storage and retrieval of Method objects. + * + */ + class MethodRepository + : public OperationFactory + { + template + inline T* getpointer(T& t) { + return &t; + } + template + inline T* getpointer(T* t) { + return t; + } + + protected: + std::map simplemethods; + public: + typedef MethodFactory Factory; + + ~MethodRepository() + { + clear(); + } + + /** + * Clear all added methods from the repository, saving memory space. + */ + void clear() { + while ( !simplemethods.empty() ) { + delete simplemethods.begin()->second; + simplemethods.erase( simplemethods.begin() ); + } + OperationFactory::clear(); + } + + /** + * Add a Method object to the method interface. + * + * @param meth The Method object to add + * + * @return true if it could be added, false otherwise. + */ + template + bool addMethod( MethodT* meth ) + { + if ( simplemethods.count( meth->getName() ) ) + return false; + simplemethods[meth->getName()] = meth->getMethodImpl()->clone(); + return true; + } + + /** + * Get a new Method object from the method interface. + * + * @param name The name of the method to retrieve. + * @param Signature The function signature of the command, for + * example: getMethod("name"); + * + * @return true if it could be found, false otherwise. + */ + template + ORO_CoreLib::ActionInterface* getMethod( std::string name ) + { + if ( simplemethods.count(name) ) + return simplemethods[name]->clone(); + return 0; + } + + + template + bool addMethod( MethodT meth, const char* description) + { + typedef typename boost::remove_pointer::type MethodVT; + typedef typename boost::add_pointer::type MethodPT; + MethodPT c = this->getpointer(meth); + typedef typename MethodVT::Signature Sig; + if ( this->hasMember(c->getName() ) ) + return false; + const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); + if ( !lm ) + return false; + this->add( c->getName(), new detail::OperationFactoryPart0 >( + detail::DataSourceArgsMethod( lm->getMethodFunction()), description) ); + return true; + } + + template + bool addMethod( MethodT meth, const char* description, + const char* arg1, const char* arg1_description) + { + typedef typename boost::remove_pointer::type MethodVT; + typedef typename boost::add_pointer::type MethodPT; + MethodPT c = this->getpointer(meth); + typedef typename MethodVT::Signature Sig; + if ( this->hasMember(c->getName() ) ) + return false; + const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); + if ( !lm ) + return false; + this->add( c->getName(), new detail::OperationFactoryPart1 >( + detail::DataSourceArgsMethod(lm->getMethodFunction()), + description, arg1, arg1_description) ); + return true; + } + + template + bool addMethod( MethodT meth, const char* description, + const char* arg1, const char* arg1_description, + const char* arg2, const char* arg2_description) + { + typedef typename boost::remove_pointer::type MethodVT; + typedef typename boost::add_pointer::type MethodPT; + MethodPT c = this->getpointer(meth); + typedef typename MethodVT::Signature Sig; + if ( this->hasMember(c->getName() ) ) + return false; + const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); + if ( !lm ) + return false; + this->add( c->getName(), new detail::OperationFactoryPart2 >( + detail::DataSourceArgsMethod(lm->getMethodFunction()), + description, + arg1, arg1_description, + arg2, arg2_description) ); + return true; + } + template + bool addMethod( MethodT meth, const char* description, + const char* arg1, const char* arg1_description, + const char* arg2, const char* arg2_description, + const char* arg3, const char* arg3_description) + { + typedef typename boost::remove_pointer::type MethodVT; + typedef typename boost::add_pointer::type MethodPT; + MethodPT c = this->getpointer(meth); + typedef typename MethodVT::Signature Sig; + if ( this->hasMember(c->getName() ) ) + return false; + const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); + if ( !lm ) + return false; + this->add( c->getName(), new detail::OperationFactoryPart3 >( + detail::DataSourceArgsMethod(lm->getMethodFunction()), + description, + arg1, arg1_description, + arg2, arg2_description, + arg3, arg3_description) ); + return true; + } + + template + bool addMethod( MethodT meth, const char* description, + const char* arg1, const char* arg1_description, + const char* arg2, const char* arg2_description, + const char* arg3, const char* arg3_description, + const char* arg4, const char* arg4_description) + { + typedef typename boost::remove_pointer::type MethodVT; + typedef typename boost::add_pointer::type MethodPT; + MethodPT c = this->getpointer(meth); + typedef typename MethodVT::Signature Sig; + if ( this->hasMember(c->getName() ) ) + return false; + const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); + if ( !lm ) + return false; + this->add( c->getName(), new detail::OperationFactoryPart4 >( + detail::DataSourceArgsMethod(lm->getMethodFunction()), + description, + arg1, arg1_description, + arg2, arg2_description, + arg3, arg3_description, + arg4, arg4_description) ); + return true; + } + + template + bool addMethodDS( DataSource< boost::weak_ptr >* wp, MethodT c, const char* description) + { + using namespace detail; + typedef typename MethodT::Signature Sig; + if ( this->hasMember(c.getName() ) ) + return false; + const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c.getMethodImpl() ); + if ( !lm ) + return false; + typedef FunctorDataSourceDS0 > FunctorT; + typedef detail::DataSourceArgsMethod DSMeth; + + this->add( c.getName(), new detail::OperationFactoryPart0( + DSMeth( typename FunctorT::shared_ptr(new FunctorT(wp, lm->getMethodFunction()))), + description)); + return true; + } + + template + bool addMethodDS( DataSource< boost::weak_ptr >* wp, MethodT c, const char* description, + const char* a1, const char* d1) + { + using namespace detail; + typedef typename MethodT::Signature Sig; + if ( this->hasMember(c.getName() ) ) + return false; + const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c.getMethodImpl() ); + if ( !lm ) + return false; + typedef typename MethodT::traits::arg2_type arg1_type; // second arg is 1st data arg. + typedef FunctorDataSourceDS1, arg1_type > FunctorT; + typedef detail::DataSourceArgsMethod DSMeth; + this->add( c.getName(), new detail::OperationFactoryPart1( + DSMeth( typename FunctorT::shared_ptr(new FunctorT(wp, lm->getMethodFunction()))), + description, a1, d1)); + return true; + } + + /** + * Get a previously added method as a DataSource. + * This function is inferior to getMethod(std::string name) + * + * @param name The name of the method + * @param args The arguments of the method as Data Sources. + * + * @return A DataSource which, when evaluated, invokes the method. + */ + DataSourceBase* getMethod( std::string name, + const std::vector& args) const + { + return this->produce(name, args); + } + + /** + * Create a MethodC object, a template-less method invocation + * object. This function is inferior to getMethod(std::string name). + * + * @param name The name of the method + * + * @return An object which can invoke a method. + */ + MethodC create(std::string name) { + return MethodC( this, name ); + } + }; +} + + +#endif diff --git a/packages/execution/task_context/current/include/NA.hpp b/packages/execution/task_context/current/include/NA.hpp index 5a9ed778b..bf0afb617 100644 --- a/packages/execution/task_context/current/include/NA.hpp +++ b/packages/execution/task_context/current/include/NA.hpp @@ -14,12 +14,25 @@ namespace ORO_Execution template struct NA { + public: typedef typename boost::remove_const::type>::type value_type; - static value_type na; + static T na() { return Gna; } + private: + static value_type Gna; + }; + + /** + * Specialisation to return a void. + */ + template<> + struct NA + { + typedef void value_type; + static void na() {}; }; template - typename NA::value_type NA::na; + typename NA::value_type NA::Gna; } } #endif diff --git a/packages/execution/task_context/current/include/OperationFactory.hpp b/packages/execution/task_context/current/include/OperationFactory.hpp index bee17fae6..b0c752aed 100644 --- a/packages/execution/task_context/current/include/OperationFactory.hpp +++ b/packages/execution/task_context/current/include/OperationFactory.hpp @@ -21,6 +21,7 @@ #include "DataSource.hpp" #include "FactoryExceptions.hpp" #include "ArgumentDescription.hpp" +#include "DispatchInterface.hpp" /** * @file OperationFactory.hpp This file contains some code that is common @@ -35,502 +36,481 @@ namespace ORO_Execution using ORO_CoreLib::PropertyBag; /** - * @defgroup CMDFactories Command, Method and DataSource Factories. - * This module groups all factores for commands, methods and - * datasources used in the ORO_Execution namespace. For each command, - * method or datasource you wish to add to a factory, you need to generate - * a \ref partFunctions. + * @internal + * @defgroup OperationFactoryPart Base Classes for parts. + * @brief Class keeping the information on how to generate one thing that + * the factory can generate. * - * Thus : - * -each \a command,\a datasource,\a method of your TaskContext requires one \a part. - * -each \a part is inserted in exactly one \a factory. - */ - - /** - * @defgroup partFunctions Functions to generate a 'Part Factory Object' - * @ingroup CMDFactories - * This module contains all 'C' functions you can use to generate 'part' object - * factories. A part matches exactly one method, command or datasource. + * Each name in the OperationFactory will + * be linked with one OperationFactoryPart that knows how to produce + * the thing that the name is used for.. Below are standard + * implementations for functors of various signatures. + * @{ */ - + template + class OperationFactoryPart + { + const char* mdesc; + public: + OperationFactoryPart( const char* desc ) + : mdesc( desc ) + { + } + + virtual ~OperationFactoryPart() {}; + std::string description() const + { + return mdesc; + } + /** + * Return the result (return) type of this part. + */ + virtual std::string resultType() const = 0; + + /** + * Get a description of the desired arguments in + * the property format. + */ + virtual PropertyBag getArgumentSpec() const = 0; + /** + * Get a description of the desired arguments in + * the ArgumentDescription format. + */ + virtual std::vector getArgumentList() const = 0; + + /** + * Returns the arity (number of arguments) of this part. + */ + virtual int arity() const = 0; + + /** + * Create one part (function object) for a given component. + * @param args The arguments for the target object's function. + */ + virtual ResultT produce( const std::vector& args ) const = 0; + }; + + template + class OperationFactoryPart0 + : public OperationFactoryPart + { + typedef FunctorT fun_t; + fun_t fun; + public: + OperationFactoryPart0( fun_t f, const char* desc ) + : OperationFactoryPart( desc ), fun( f ) + { + } + + PropertyBag getArgumentSpec() const + { + return PropertyBag(); + } + + std::string resultType() const + { + return DataSource::GetType(); + } + + std::vector getArgumentList() const + { + return std::vector(); + } + + int arity() const { return 0; } + + ResultT produce( + const std::vector& args) const + { + if ( ! args.empty() ) + ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 0, args.size() ), ResultT()); + return fun.create(); + } + }; + + template + class OperationFactoryPart1 + : public OperationFactoryPart + { + typedef FunctorT fun_t; + fun_t fun; + const char* arg1name; + const char* arg1desc; + public: + OperationFactoryPart1( fun_t f, const char* desc, + const char* a1n, const char* a1d ) + : OperationFactoryPart( desc ), + fun( f ), arg1name( a1n ), arg1desc( a1d ) + { + } + + std::string resultType() const + { + return DataSource::GetType(); + } + + std::vector< ArgumentDescription > getArgumentList( ) const + { + std::vector< ArgumentDescription > mlist; + mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource::GetType() ) ); + return mlist; + } + + PropertyBag getArgumentSpec() const + { + PropertyBag ret; + ret.add( new Property( arg1name, arg1desc ) ); + return ret; + } + + int arity() const { return 1; } + + ResultT produce( + const std::vector& args) const + { + if ( args.size() != 1 ) + ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 1, args.size() ), ResultT()); + typename DataSource::shared_ptr a = + ORO_CoreLib::AdaptDataSource()( args[0] ); + if ( ! a ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource::GetType(), args[0]->getType() ), ResultT()); + return fun.create( a.get() ); + } + }; + + template + class OperationFactoryPart2 + : public OperationFactoryPart + { + typedef FunctorT fun_t; + typedef typename FunctorT::traits::arg1_type arg1_type; + typedef typename FunctorT::traits::arg2_type arg2_type; + fun_t fun; + const char* arg1name; + const char* arg1desc; + const char* arg2name; + const char* arg2desc; + public: + OperationFactoryPart2( fun_t f, const char* desc, const char* a1n, + const char* a1d, const char* a2n, + const char* a2d) + : OperationFactoryPart( desc ), fun( f ), + arg1name( a1n ), arg1desc( a1d ), arg2name( a2n ), + arg2desc( a2d ) + { + } + + std::string resultType() const + { + return DataSource::GetType(); + } + + std::vector< ArgumentDescription > getArgumentList( ) const + { + std::vector< ArgumentDescription > mlist; + mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource::GetType() ) ); + mlist.push_back( ArgumentDescription( arg2name, arg2desc, DataSource::GetType() ) ); + return mlist; + } + + PropertyBag getArgumentSpec() const + { + PropertyBag ret; + ret.add( new Property( arg1name, arg1desc ) ); + ret.add( new Property( arg2name, arg2desc ) ); + return ret; + } + + int arity() const { return 2; } + + ResultT produce(const std::vector& args) const + { + if ( args.size() != 2 ) + ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 2, args.size() ), ResultT()); + + typename DataSource::shared_ptr a = + ORO_CoreLib::AdaptDataSource()( args[0] ); + if ( !a ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource::GetType(), args[0]->getType() ), ResultT()); + typename DataSource::shared_ptr b = + ORO_CoreLib::AdaptDataSource()( args[1] ); + if ( !b ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 2, DataSource::GetType(), args[1]->getType() ), ResultT()); + + return fun.create(a.get(), b.get() ); + } + }; + + template + class OperationFactoryPart3 + : public OperationFactoryPart + { + typedef FunctorT fun_t; + typedef typename FunctorT::traits::arg1_type arg1_type; + typedef typename FunctorT::traits::arg2_type arg2_type; + typedef typename FunctorT::traits::arg3_type arg3_type; + + fun_t fun; + const char* arg1name; + const char* arg1desc; + const char* arg2name; + const char* arg2desc; + const char* arg3name; + const char* arg3desc; + public: + OperationFactoryPart3( fun_t f, const char* desc, const char* a1n, + const char* a1d, const char* a2n, + const char* a2d, const char* a3n, + const char* a3d ) + : OperationFactoryPart( desc ), fun( f ), + arg1name( a1n ), arg1desc( a1d ), + arg2name( a2n ), arg2desc( a2d ), + arg3name( a3n ), arg3desc( a3d ) + { + } + + std::string resultType() const + { + return DataSource::GetType(); + } + + PropertyBag getArgumentSpec() const + { + PropertyBag ret; + ret.add( new Property( arg1name, arg1desc ) ); + ret.add( new Property( arg2name, arg2desc ) ); + ret.add( new Property( arg3name, arg3desc ) ); + return ret; + } + + std::vector< ArgumentDescription > getArgumentList( ) const + { + std::vector< ArgumentDescription > mlist; + mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource::GetType() ) ); + mlist.push_back( ArgumentDescription( arg2name, arg2desc, DataSource::GetType() ) ); + mlist.push_back( ArgumentDescription( arg3name, arg3desc, DataSource::GetType() ) ); + return mlist; + } + + int arity() const { return 3; } + + ResultT produce(const std::vector& args) const + { + if ( args.size() != 3 ) + ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 3, args.size() ), ResultT()); + + typename DataSource::shared_ptr a = + ORO_CoreLib::AdaptDataSource()( args[0] ); + if ( !a ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource::GetType(), args[0]->getType() ), ResultT()); + typename DataSource::shared_ptr b = + ORO_CoreLib::AdaptDataSource()( args[1] ); + if ( !b ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 2, DataSource::GetType(), args[1]->getType() ), ResultT()); + typename DataSource::shared_ptr c = + ORO_CoreLib::AdaptDataSource()( args[2] ); + if ( !c ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 3, DataSource::GetType(), args[2]->getType() ), ResultT()); + + return fun.create(a.get(), b.get(), c.get() ); + } + }; + + template + class OperationFactoryPart4 + : public OperationFactoryPart + { + typedef FunctorT fun_t; + typedef typename FunctorT::traits::arg1_type arg1_type; + typedef typename FunctorT::traits::arg2_type arg2_type; + typedef typename FunctorT::traits::arg3_type arg3_type; + typedef typename FunctorT::traits::arg4_type arg4_type; + + fun_t fun; + const char* arg1name; + const char* arg1desc; + const char* arg2name; + const char* arg2desc; + const char* arg3name; + const char* arg3desc; + const char* arg4name; + const char* arg4desc; + public: + OperationFactoryPart4( fun_t f, const char* desc, const char* a1n, + const char* a1d, const char* a2n, + const char* a2d, const char* a3n, + const char* a3d, const char* a4n, + const char* a4d ) + : OperationFactoryPart( desc ), fun( f ), + arg1name( a1n ), arg1desc( a1d ), + arg2name( a2n ), arg2desc( a2d ), + arg3name( a3n ), arg3desc( a3d ), + arg4name( a4n ), arg4desc( a4d ) + { + } + + std::string resultType() const + { + return DataSource::GetType(); + } + + PropertyBag getArgumentSpec() const + { + PropertyBag ret; + ret.add( new Property( arg1name, arg1desc ) ); + ret.add( new Property( arg2name, arg2desc ) ); + ret.add( new Property( arg3name, arg3desc ) ); + ret.add( new Property( arg4name, arg4desc ) ); + return ret; + } + + std::vector< ArgumentDescription > getArgumentList( ) const + { + std::vector< ArgumentDescription > mlist; + mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource::GetType() ) ); + mlist.push_back( ArgumentDescription( arg2name, arg2desc, DataSource::GetType() ) ); + mlist.push_back( ArgumentDescription( arg3name, arg3desc, DataSource::GetType() ) ); + mlist.push_back( ArgumentDescription( arg4name, arg4desc, DataSource::GetType() ) ); + return mlist; + } + + int arity() const { return 4; } + + ResultT produce(const std::vector& args) const + { + if ( args.size() != 4 ) + ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 4, args.size() ), ResultT()); + + typename DataSource::shared_ptr a = + ORO_CoreLib::AdaptDataSource()( args[0] ); + if ( !a ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource::GetType(), args[0]->getType() ), ResultT()); + typename DataSource::shared_ptr b = + ORO_CoreLib::AdaptDataSource()( args[1] ); + if ( !b ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 2, DataSource::GetType(), args[1]->getType() ), ResultT()); + typename DataSource::shared_ptr c = + ORO_CoreLib::AdaptDataSource()( args[2] ); + if ( !c ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 3, DataSource::GetType(), args[2]->getType() ), ResultT()); + typename DataSource::shared_ptr d = + ORO_CoreLib::AdaptDataSource()( args[3] ); + if ( !d ) + ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 4, DataSource::GetType(), args[3]->getType() ), ResultT()); + + return fun.create(a.get(), b.get(), c.get(), d.get() ); + } + }; /** - * @defgroup objectFactory TaskContext Object Factories - * @ingroup CMDFactories - * An object factory delivers DataSources for the method - * or datasource interface of a TaskContext or Command objects for the command - * interface of a TaskContext. An object groups multiple 'parts'. - */ - - - /** - * @internal - * @defgroup OperationFactoryPart Base Classes for parts. - * @brief Class keeping the information on how to generate one thing that - * the factory can generate. - * - * Each name in the OperationFactory will - * be linked with one OperationFactoryPart that knows how to produce - * the thing that the name is used for.. Below are standard - * implementations for functors of various signatures. - * @{ - */ - template - class OperationFactoryPart - { - const char* mdesc; - public: - OperationFactoryPart( const char* desc ) - : mdesc( desc ) - { - } - - virtual ~OperationFactoryPart() {}; - std::string description() const - { - return mdesc; - } - /** - * Return the result (return) type of this part. - */ - virtual std::string resultType() const = 0; - - /** - * Get a description of the desired arguments in - * the property format. - */ - virtual PropertyBag getArgumentSpec() const = 0; - /** - * Get a description of the desired arguments in - * the ArgumentDescription format. - */ - virtual std::vector getArgumentList() const = 0; - - /** - * Returns the arity (number of arguments) of this part. - */ - virtual int arity() const = 0; - - /** - * Create one part (function object) for a given component. - * @param args The arguments for the target object's function. - */ - virtual ResultT produce( const std::vector& args ) const = 0; - }; - - template - class OperationFactoryPart0 - : public OperationFactoryPart - { - typedef FunctorT fun_t; - fun_t fun; - public: - OperationFactoryPart0( fun_t f, const char* desc ) - : OperationFactoryPart( desc ), fun( f ) - { - } - - PropertyBag getArgumentSpec() const - { - return PropertyBag(); - } - - std::string resultType() const - { - return DataSource::GetType(); - } - - std::vector getArgumentList() const - { - return std::vector(); - } - - int arity() const { return 0; } - - ResultT produce( - const std::vector& args) const - { - if ( ! args.empty() ) - ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 0, args.size() ), ResultT()); - return fun.create(); - } - }; - - template - class OperationFactoryPart1 - : public OperationFactoryPart - { - typedef FunctorT fun_t; - fun_t fun; - const char* arg1name; - const char* arg1desc; - public: - OperationFactoryPart1( fun_t f, const char* desc, - const char* a1n, const char* a1d ) - : OperationFactoryPart( desc ), - fun( f ), arg1name( a1n ), arg1desc( a1d ) - { - } - - std::string resultType() const - { - return DataSource::GetType(); - } - - std::vector< ArgumentDescription > getArgumentList( ) const - { - std::vector< ArgumentDescription > mlist; - mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource::GetType() ) ); - return mlist; - } - - PropertyBag getArgumentSpec() const - { - PropertyBag ret; - ret.add( new Property( arg1name, arg1desc ) ); - return ret; - } - - int arity() const { return 1; } - - ResultT produce( - const std::vector& args) const - { - if ( args.size() != 1 ) - ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 1, args.size() ), ResultT()); - typename DataSource::shared_ptr a = - ORO_CoreLib::AdaptDataSource()( args[0] ); - if ( ! a ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource::GetType(), args[0]->getType() ), ResultT()); - return fun.create( a.get() ); - } - }; - - template - class OperationFactoryPart2 - : public OperationFactoryPart - { - typedef FunctorT fun_t; - typedef typename FunctorT::traits::arg1_type arg1_type; - typedef typename FunctorT::traits::arg2_type arg2_type; - fun_t fun; - const char* arg1name; - const char* arg1desc; - const char* arg2name; - const char* arg2desc; - public: - OperationFactoryPart2( fun_t f, const char* desc, const char* a1n, - const char* a1d, const char* a2n, - const char* a2d) - : OperationFactoryPart( desc ), fun( f ), - arg1name( a1n ), arg1desc( a1d ), arg2name( a2n ), - arg2desc( a2d ) - { - } - - std::string resultType() const - { - return DataSource::GetType(); - } - - std::vector< ArgumentDescription > getArgumentList( ) const - { - std::vector< ArgumentDescription > mlist; - mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource::GetType() ) ); - mlist.push_back( ArgumentDescription( arg2name, arg2desc, DataSource::GetType() ) ); - return mlist; - } - - PropertyBag getArgumentSpec() const - { - PropertyBag ret; - ret.add( new Property( arg1name, arg1desc ) ); - ret.add( new Property( arg2name, arg2desc ) ); - return ret; - } - - int arity() const { return 2; } - - ResultT produce(const std::vector& args) const - { - if ( args.size() != 2 ) - ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 2, args.size() ), ResultT()); - - typename DataSource::shared_ptr a = - ORO_CoreLib::AdaptDataSource()( args[0] ); - if ( !a ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource::GetType(), args[0]->getType() ), ResultT()); - typename DataSource::shared_ptr b = - ORO_CoreLib::AdaptDataSource()( args[1] ); - if ( !b ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 2, DataSource::GetType(), args[1]->getType() ), ResultT()); - - return fun.create(a.get(), b.get() ); - } - }; - - template - class OperationFactoryPart3 - : public OperationFactoryPart - { - typedef FunctorT fun_t; - typedef typename FunctorT::traits::arg1_type arg1_type; - typedef typename FunctorT::traits::arg2_type arg2_type; - typedef typename FunctorT::traits::arg3_type arg3_type; - - fun_t fun; - const char* arg1name; - const char* arg1desc; - const char* arg2name; - const char* arg2desc; - const char* arg3name; - const char* arg3desc; - public: - OperationFactoryPart3( fun_t f, const char* desc, const char* a1n, - const char* a1d, const char* a2n, - const char* a2d, const char* a3n, - const char* a3d ) - : OperationFactoryPart( desc ), fun( f ), - arg1name( a1n ), arg1desc( a1d ), - arg2name( a2n ), arg2desc( a2d ), - arg3name( a3n ), arg3desc( a3d ) - { - } - - std::string resultType() const - { - return DataSource::GetType(); - } - - PropertyBag getArgumentSpec() const - { - PropertyBag ret; - ret.add( new Property( arg1name, arg1desc ) ); - ret.add( new Property( arg2name, arg2desc ) ); - ret.add( new Property( arg3name, arg3desc ) ); - return ret; - } - - std::vector< ArgumentDescription > getArgumentList( ) const - { - std::vector< ArgumentDescription > mlist; - mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource::GetType() ) ); - mlist.push_back( ArgumentDescription( arg2name, arg2desc, DataSource::GetType() ) ); - mlist.push_back( ArgumentDescription( arg3name, arg3desc, DataSource::GetType() ) ); - return mlist; - } - - int arity() const { return 3; } - - ResultT produce(const std::vector& args) const - { - if ( args.size() != 3 ) - ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 3, args.size() ), ResultT()); - - typename DataSource::shared_ptr a = - ORO_CoreLib::AdaptDataSource()( args[0] ); - if ( !a ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource::GetType(), args[0]->getType() ), ResultT()); - typename DataSource::shared_ptr b = - ORO_CoreLib::AdaptDataSource()( args[1] ); - if ( !b ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 2, DataSource::GetType(), args[1]->getType() ), ResultT()); - typename DataSource::shared_ptr c = - ORO_CoreLib::AdaptDataSource()( args[2] ); - if ( !c ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 3, DataSource::GetType(), args[2]->getType() ), ResultT()); - - return fun.create(a.get(), b.get(), c.get() ); - } - }; - - template - class OperationFactoryPart4 - : public OperationFactoryPart - { - typedef FunctorT fun_t; - typedef typename FunctorT::traits::arg1_type arg1_type; - typedef typename FunctorT::traits::arg2_type arg2_type; - typedef typename FunctorT::traits::arg3_type arg3_type; - typedef typename FunctorT::traits::arg4_type arg4_type; - - fun_t fun; - const char* arg1name; - const char* arg1desc; - const char* arg2name; - const char* arg2desc; - const char* arg3name; - const char* arg3desc; - const char* arg4name; - const char* arg4desc; - public: - OperationFactoryPart4( fun_t f, const char* desc, const char* a1n, - const char* a1d, const char* a2n, - const char* a2d, const char* a3n, - const char* a3d, const char* a4n, - const char* a4d ) - : OperationFactoryPart( desc ), fun( f ), - arg1name( a1n ), arg1desc( a1d ), - arg2name( a2n ), arg2desc( a2d ), - arg3name( a3n ), arg3desc( a3d ), - arg4name( a4n ), arg4desc( a4d ) - { - } - - std::string resultType() const - { - return DataSource::GetType(); - } - - PropertyBag getArgumentSpec() const - { - PropertyBag ret; - ret.add( new Property( arg1name, arg1desc ) ); - ret.add( new Property( arg2name, arg2desc ) ); - ret.add( new Property( arg3name, arg3desc ) ); - ret.add( new Property( arg4name, arg4desc ) ); - return ret; - } - - std::vector< ArgumentDescription > getArgumentList( ) const - { - std::vector< ArgumentDescription > mlist; - mlist.push_back( ArgumentDescription( arg1name, arg1desc, DataSource::GetType() ) ); - mlist.push_back( ArgumentDescription( arg2name, arg2desc, DataSource::GetType() ) ); - mlist.push_back( ArgumentDescription( arg3name, arg3desc, DataSource::GetType() ) ); - mlist.push_back( ArgumentDescription( arg4name, arg4desc, DataSource::GetType() ) ); - return mlist; - } - - int arity() const { return 4; } - - ResultT produce(const std::vector& args) const - { - if ( args.size() != 4 ) - ORO_THROW_OR_RETURN(wrong_number_of_args_exception( 4, args.size() ), ResultT()); - - typename DataSource::shared_ptr a = - ORO_CoreLib::AdaptDataSource()( args[0] ); - if ( !a ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 1, DataSource::GetType(), args[0]->getType() ), ResultT()); - typename DataSource::shared_ptr b = - ORO_CoreLib::AdaptDataSource()( args[1] ); - if ( !b ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 2, DataSource::GetType(), args[1]->getType() ), ResultT()); - typename DataSource::shared_ptr c = - ORO_CoreLib::AdaptDataSource()( args[2] ); - if ( !c ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 3, DataSource::GetType(), args[2]->getType() ), ResultT()); - typename DataSource::shared_ptr d = - ORO_CoreLib::AdaptDataSource()( args[3] ); - if ( !d ) - ORO_THROW_OR_RETURN(wrong_types_of_args_exception( 4, DataSource::GetType(), args[3]->getType() ), ResultT()); - - return fun.create(a.get(), b.get(), c.get(), d.get() ); - } - }; - /** - * @} - */ + * @} + */ } /** * @brief This factory is a template for creating parts. */ - template - class OperationFactory - { - protected: - typedef std::map* > map_t; - map_t data; - public: - OperationFactory() - { - } - - ~OperationFactory() - { - for ( typename map_t::iterator i = data.begin(); i != data.end(); ++i ) - delete i->second; - } - - std::vector getNames() const - { - std::vector ret; - std::transform( data.begin(), data.end(), - std::back_inserter( ret ), - ORO_std::select1st() ); - return ret; - } - - bool hasMember( const std::string& name ) const - { - return data.find( name ) != data.end(); - } - - int getArity( const std::string& name ) const - { - typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) return -1; - return i->second->arity(); - } - - ResultT produce( const std::string& name, const ORO_CoreLib::PropertyBag& args ) const - { - typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT()); - std::vector dsVect; - std::transform( args.begin(), args.end(), - std::back_inserter( dsVect ), - boost::bind( &ORO_CoreLib::PropertyBase::getDataSource, _1)); - return i->second->produce(dsVect); - } - - ResultT produce( const std::string& name, - const std::vector& args ) const - { - typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT()); - return i->second->produce( args ); - } - - ORO_CoreLib::PropertyBag getArgumentSpec( const std::string& name ) const - { - typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), ORO_CoreLib::PropertyBag()); - return i->second->getArgumentSpec(); - } - - std::vector getArgumentList( const std::string& name ) const - { - typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), std::vector()); - return i->second->getArgumentList(); - } - - std::string getResultType( const std::string& name ) const - { - typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string()); - return i->second->resultType(); - } - - std::string getDescription( const std::string& name ) const - { - typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string()); - return i->second->description(); - } - - void add( const std::string& name, - detail::OperationFactoryPart* part ) - { - typename map_t::iterator i = data.find( name ); - // XXX, wouldn't it be better to throw ? - if ( i != data.end() ) - delete i->second; - data[name] = part; - } - }; + template + class OperationFactory + { + protected: + typedef std::map* > map_t; + map_t data; + public: + OperationFactory() + { + } + + ~OperationFactory() + { + } + + void clear() { + for ( typename map_t::iterator i = data.begin(); i != data.end(); ++i ) + delete i->second; + data.clear(); + } + + std::vector getNames() const + { + std::vector ret; + std::transform( data.begin(), data.end(), + std::back_inserter( ret ), + ORO_std::select1st() ); + return ret; + } + + bool hasMember( const std::string& name ) const + { + return data.find( name ) != data.end(); + } + + int getArity( const std::string& name ) const + { + typename map_t::const_iterator i = data.find( name ); + if ( i == data.end() ) return -1; + return i->second->arity(); + } + + ResultT produce( const std::string& name, const ORO_CoreLib::PropertyBag& args ) const + { + typename map_t::const_iterator i = data.find( name ); + if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT()); + std::vector dsVect; + std::transform( args.begin(), args.end(), + std::back_inserter( dsVect ), + boost::bind( &ORO_CoreLib::PropertyBase::getDataSource, _1)); + return i->second->produce(dsVect); + } + + ResultT produce( const std::string& name, + const std::vector& args ) const + { + typename map_t::const_iterator i = data.find( name ); + if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT()); + return i->second->produce( args ); + } + + ORO_CoreLib::PropertyBag getArgumentSpec( const std::string& name ) const + { + typename map_t::const_iterator i = data.find( name ); + if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), ORO_CoreLib::PropertyBag()); + return i->second->getArgumentSpec(); + } + + std::vector getArgumentList( const std::string& name ) const + { + typename map_t::const_iterator i = data.find( name ); + if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), std::vector()); + return i->second->getArgumentList(); + } + + std::string getResultType( const std::string& name ) const + { + typename map_t::const_iterator i = data.find( name ); + if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string()); + return i->second->resultType(); + } + + std::string getDescription( const std::string& name ) const + { + typename map_t::const_iterator i = data.find( name ); + if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string()); + return i->second->description(); + } + + void add( const std::string& name, + detail::OperationFactoryPart* part ) + { + typename map_t::iterator i = data.find( name ); + // XXX, wouldn't it be better to throw ? + if ( i != data.end() ) + delete i->second; + data[name] = part; + } + }; + + typedef OperationFactory CommandFactory; + typedef OperationFactory MethodFactory; } #endif diff --git a/packages/execution/task_context/current/include/OperationInterface.hpp b/packages/execution/task_context/current/include/OperationInterface.hpp index 2c3913394..1e4c22326 100644 --- a/packages/execution/task_context/current/include/OperationInterface.hpp +++ b/packages/execution/task_context/current/include/OperationInterface.hpp @@ -1,734 +1,12 @@ #ifndef ORO_OPERATION_INTERFACE_HPP #define ORO_OPERATION_INTERFACE_HPP -#include "CommandFunctors.hpp" -#include "CommandProcessor.hpp" -#include "CommandDSFunctors.hpp" -#include "DispatchInterface.hpp" -#include "OperationFactory.hpp" -#include "TemplateMemberFactory.hpp" -#include "CommandC.hpp" -#include "LocalCommand.hpp" -#include "LocalMethod.hpp" -#include "MethodC.hpp" +#include +#include "CommandRepository.hpp" +#include "MethodRepository.hpp" namespace ORO_Execution { - - /** - * A Command which dispatches locally. - * The arguments are fetched from DataSources. - */ - template, - class ConF=detail::ConditionFunctor > - class CommandFromDS - : public DispatchInterface - { - ComF mcom; - mutable ConF mcon; - CommandProcessor* mcp; - bool minvoked, maccept, mvalid, mexec; - public: - typedef boost::function_traits traits; - typedef CommandT Signature; - typedef bool result_type; - - CommandFromDS(boost::function com, boost::function con, CommandProcessor* cp, bool inverted) - : mcom( com ), mcon( con, inverted ), - mcp( cp ), - minvoked(false), maccept(false), - mvalid(false), mexec(false) - { - } - - CommandFromDS(ComF com, ConF con, CommandProcessor* cp) - : mcom( com ), mcon( con ), - mcp( cp ), - minvoked(false), maccept(false), - mvalid(false), mexec(false) - { - } - - CommandFromDS* create() const - { - return clone(); - } - - template - CommandFromDS* create(DataSource* a1) const - { - CommandFromDS* r = this->clone(); - r->mcom.com.setArguments(a1); - r->mcon.con.setArguments(a1); - return r; - } - - template - CommandFromDS* create(DataSource* a1, DataSource* a2) const - { - CommandFromDS* r = this->clone(); - r->mcom.com.setArguments(a1, a2); - r->mcon.con.setArguments(a1, a2); - return r; - } - - template - CommandFromDS* create(DataSource* a1, DataSource* a2, DataSource* a3) const - { - CommandFromDS* r = this->clone(); - r->mcom.com.setArguments(a1, a2, a3); - r->mcon.con.setArguments(a1, a2, a3); - return r; - } - - template - CommandFromDS* create(DataSource* a1, DataSource* a2, DataSource* a3, DataSource* a4) const - { - CommandFromDS* r = this->clone(); - r->mcom.com.setArguments(a1, a2, a3, a4); - r->mcon.con.setArguments(a1, a2, a3, a4); - return r; - } - - bool ready() const { - return !minvoked; - } - - bool operator()() { - if (minvoked) - return false; - minvoked = true; - return maccept = mcp->process( this ); - } - - virtual bool dispatch() { - if (minvoked) - return false; - minvoked = true; - return maccept = mcp->process( this ); - } - - virtual void readArguments() {} - - virtual bool execute() { - mexec = true; - return mvalid = mcom.execute(); - } - - virtual bool evaluate() const { - if (mexec && mvalid ) - return mcon.evaluate(); - return false; - } - - virtual void reset() { - minvoked = (false); - maccept = (false); - mvalid = (false); - mexec = (false); - } - - virtual bool sent() const { - return minvoked; - } - - virtual bool accepted() const { - return maccept; - } - - virtual bool executed() const { - return mexec; - } - - virtual bool valid() const { - return mvalid; - } - - virtual ORO_CoreLib::ConditionInterface* createCondition() const - { - return mcon.clone(); - } - - virtual CommandFromDS* clone() const { - return new CommandFromDS(*this); - } - - }; - - /** - * A command repository stores a number of commands from a Task which - * can be used by other tasks or from scripts. - */ - class CommandRepository - : public OperationFactory - { - template - inline T* getpointer(T t) { - return &t; - } - template - inline T* getpointer(T* t) { - return t; - } - - std::map simplecommands; - public: - ~CommandRepository() - { - while ( !simplecommands.empty() ) { - delete simplecommands.begin()->second; - simplecommands.erase( simplecommands.begin() ); - } - } - - /** - * Retrieve a previously added Command. - * - * @param name The name of the Command - * @param args A vector of command arguments. - * - * @return A dispatchable object which is a new Command object. - */ - DispatchInterface* getCommand( std::string name, - const std::vector& args) const - { - return this->produce(name, args); - } - - /** - * Return the pointer to an added simple Command. - * - * @param name The name of the command to retrieve. - * - * @return A new pointer to a simple Command, or null if it does not exist. - */ - DispatchInterface* getCommand( std::string name ) - { - if ( simplecommands.count(name) ) - return simplecommands[name]->clone(); - return 0; - } - /** - * Retrieve the completion condition of a previously added Command. - * - * @param name The name of the Command - * @param args A vector of command arguments - * - * @return A condition which evaluates the command's completion. - */ - ConditionInterface* getCondition( std::string name, - const std::vector& args) const - { - DispatchInterface* di = this->produce(name, args); - ConditionInterface* ret = di->createCondition(); - delete di; - return ret; - } - - /** - * Create a CommandC container object, which can be used - * to access an added Command. - * - * @param name The name of the Command - * - * @return A new CommandC object. - */ - CommandC create(std::string name) { - return CommandC( this, name ); - } - - /** - * Add a Command to the interface. You can retrieve it with getCommand. - * - * @param com A pointer to a Command object. - * - * @return true if the command could be added. - */ - template - bool addCommand( CommandT* com ) - { - if ( simplecommands.count( com->getName() ) ) - return false; - simplecommands[com->getName()] = com->getCommandImpl()->clone(); - return true; - } - - - /** - * Add an existing Command, which takes no arguments, to the Operations interface. - * - * @param c A pointer to the existing command. - * @param description A user readable description of what this command does. - * - * @return true if the command could be added. - */ - template - bool addCommand( CommandT com, const char* description) - { - typedef typename boost::remove_pointer::type CommandVT; - typedef typename boost::add_pointer::type CommandPT; - typedef typename CommandVT::Signature ComSig; - CommandPT c = this->getpointer(com); - detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); - // We can only add local commands. - if ( !lc ) - return false; - // First add the command to the normal interface. - if ( this->addCommand( c ) == false ) - return false; - // Next, add it to the Command from 'DataSource' interface. - this->add( c->getName(), new detail::OperationFactoryPart0 >( - CommandFromDS(lc->getCommandFunction(), - lc->getConditionFunction(), - lc->getCommandProcessor(), lc->isInverted() ), description) ); - return true; - } - - /** - * Add an existing Command, which takes one argument, to the - * Operations Interface. - * - * @param c A pointer to the existing command. - * @param description A user readable description of what this command does. - * @param arg1 A single word name of the argument. - * @param arg1_description A user readable description of the argument. - * - * @return true if the command could be added. - */ - template - bool addCommand( CommandT com, const char* description, - const char* arg1, const char* arg1_description) - { - typedef typename boost::remove_pointer::type CommandVT; - typedef typename boost::add_pointer::type CommandPT; - typedef typename CommandVT::Signature ComSig; - CommandPT c = this->getpointer(com); - detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); - if ( !lc ) - return false; - if ( this->addCommand( c ) == false ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart1 >( - CommandFromDS(lc->getCommandFunction(), - lc->getConditionFunction(), - lc->getCommandProcessor(), lc->isInverted() ), - description, arg1, arg1_description) ); - return true; - } - - /** - * Add an existing Command, which takes two arguments, to the - * Operations Interface. - * - * @param c A pointer to the existing command. - * @param description A user readable description of what this command does. - * @param arg1 A single word name of the first argument. - * @param arg1_description A user readable description of the first argument. - * @param arg2 A single word name of the second argument. - * @param arg2_description A user readable description of the second argument. - * - * @return true if the command could be added. - */ - template - bool addCommand( CommandT com, const char* description, - const char* arg1, const char* arg1_description, - const char* arg2, const char* arg2_description) - { - typedef typename boost::remove_pointer::type CommandVT; - typedef typename boost::add_pointer::type CommandPT; - typedef typename CommandVT::Signature ComSig; - CommandPT c = this->getpointer(com); - detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); - if ( !lc ) - return false; - if ( this->addCommand( c ) == false ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart2 >( - CommandFromDS(lc->getCommandFunction(), - lc->getConditionFunction(), - lc->getCommandProcessor(), lc->isInverted() ), - description, arg1, arg1_description, - arg2, arg2_description) ); - return true; - } - - - template - bool addCommand( CommandT com, const char* description, - const char* arg1, const char* arg1_description, - const char* arg2, const char* arg2_description, - const char* arg3, const char* arg3_description) - { - typedef typename boost::remove_pointer::type CommandVT; - typedef typename boost::add_pointer::type CommandPT; - typedef typename CommandVT::Signature ComSig; - CommandPT c = this->getpointer(com); - detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); - if ( !lc ) - return false; - if ( this->addCommand( c ) == false ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart3 >( - CommandFromDS(lc->getCommandFunction(), - lc->getConditionFunction(), - lc->getCommandProcessor(), lc->isInverted() ), - description, arg1, arg1_description, - arg2, arg2_description, - arg3, arg3_description) ); - return true; - } - - template - bool addCommand( CommandT com, const char* description, - const char* arg1, const char* arg1_description, - const char* arg2, const char* arg2_description, - const char* arg3, const char* arg3_description, - const char* arg4, const char* arg4_description) - { - typedef typename boost::remove_pointer::type CommandVT; - typedef typename boost::add_pointer::type CommandPT; - typedef typename CommandVT::Signature ComSig; - CommandPT c = this->getpointer(com); - detail::LocalCommand* lc = dynamic_cast*>( c->getCommandImpl() ); - if ( !lc ) - return false; - if ( this->addCommand( c ) == false ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart4 >( - CommandFromDS(lc->getCommandFunction(), - lc->getConditionFunction(), - lc->getCommandProcessor(), lc->isInverted() ), - description, arg1, arg1_description, - arg2, arg2_description, - arg3, arg3_description, - arg4, arg4_description) ); - return true; - } - - template - bool addCommandDS( DataSource< boost::weak_ptr >* wp, CommandT* c, const char* description) - { - using namespace detail; - typedef typename CommandT::Signature ComSig; - if ( this->hasMember(c->getName() ) ) - return false; - typedef CommandFunctor > > ComF; - typedef ConditionFunctor > > ConF; - typedef CommandFromDS DSComm; - this->add( c->getName(), new detail::OperationFactoryPart0( - DSComm( ComF( FunctorDS0 >(wp, c->getCommandFunction())), - ConF( FunctorDS0 >(wp, c->getConditionFunction()), c->isInverted()), - c->getCommandProcessor() ), - description) ); - return true; - } - - template - bool addCommandDS( DataSource >* wp, CommandT* c, const char* description, - const char* arg1, const char* arg1_description) - { - using namespace detail; - typedef typename CommandT::Signature ComSig; - typedef CommandFunctor > > ComF; - typedef ConditionFunctor > > ConF; - typedef CommandFromDS DSComm; - if ( this->hasMember(c->getName() ) ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart1( - DSComm( ComF( FunctorDS1 >(wp, c->getCommandFunction())), - ConF( FunctorDS1 >(wp, c->getConditionFunction()), c->isInverted()), - c->getCommandProcessor() ), - description, arg1, arg1_description) ); - return true; - } - - - }; - - /** - * A method which gets its arguments from a data source and - * is a datasource itself. - */ - template > > - class MethodFromDS - : public DataSource< typename boost::function_traits::result_type > - { - typename FunctorT::shared_ptr mmeth; - public: - typedef boost::function_traits traits; - typedef SignatureT Signature; - - typedef typename boost::function_traits::result_type result_type; - typedef DataSource Base; - - MethodFromDS(boost::function meth) - : mmeth( new FunctorT(meth) ) - { - } - - MethodFromDS( typename FunctorT::shared_ptr ds) - : mmeth( ds ) - { - } - - MethodFromDS* create() const - { - return clone(); - } - - template - MethodFromDS* create(DataSource* a1) const - { - MethodFromDS* r = this->clone(); - r->mmeth->setArguments(a1); - return r; - } - - template - MethodFromDS* create(DataSource* a1, DataSource* a2) const - { - MethodFromDS* r = this->clone(); - r->mmeth->setArguments(a1, a2); - return r; - } - - template - MethodFromDS* create(DataSource* a1, DataSource* a2, DataSource* a3) const - { - MethodFromDS* r = this->clone(); - r->mmeth->setArguments(a1, a2, a3); - return r; - } - - template - MethodFromDS* create(DataSource* a1, DataSource* a2, DataSource* a3, DataSource* a4) const - { - MethodFromDS* r = this->clone(); - r->mmeth->setArguments(a1, a2, a3, a4); - return r; - } - - result_type operator()() { - return mmeth->get(); - } - - virtual result_type get() const { - return mmeth->get(); - } - - virtual result_type value() const { - return mmeth->value(); - } - - virtual MethodFromDS* clone() const { - return new MethodFromDS( typename FunctorT::shared_ptr(mmeth->clone()) ); - } - - virtual DataSource* copy( std::map& alreadyCloned ) const - { - return new MethodFromDS( typename FunctorT::shared_ptr(mmeth->copy(alreadyCloned)) ); - } - - boost::function getMethodFunction() const { - return mmeth.ff.gen; - } - }; - - - /** - * This class allows storage and retrieval of Method objects. - * - */ - class MethodRepository - : public OperationFactory - { - protected: - std::map simplemethods; - public: - ~MethodRepository() - { - while ( !simplemethods.empty() ) { - delete simplemethods.begin()->second; - simplemethods.erase( simplemethods.begin() ); - } - } - DataSourceBase* getMethod( std::string name, - const std::vector& args) const - { - return this->produce(name, args); - } - - MethodC create(std::string name) { - return MethodC( this, name ); - } - - /** - * Add a Method object to the method interface. - * - * @param meth The Method object to add - * - * @return true if it could be added, false otherwise. - */ - template - bool addMethod( MethodT* meth ) - { - if ( simplemethods.count( meth->getName() ) ) - return false; - simplemethods[meth->getName()] = meth->getMethodImpl()->clone(); - return true; - } - - /** - * Get a new Method object from the method interface. - * - * @param name The name of the method to retrieve. - * - * @return true if it could be found, false otherwise. - */ - ORO_CoreLib::ActionInterface* getMethod( std::string name ) - { - if ( simplemethods.count(name) ) - return simplemethods[name]->clone(); - return 0; - } - - - template - bool addMethod( MethodT* c, const char* description) - { - typedef typename MethodT::Signature Sig; - if ( this->hasMember(c->getName() ) ) - return false; - const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); - if ( !lm ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart0 >( - MethodFromDS( lm->getMethodFunction()), description) ); - return true; - } - - template - bool addMethod( MethodT* c, const char* description, - const char* arg1, const char* arg1_description) - { - typedef typename MethodT::Signature Sig; - if ( this->hasMember(c->getName() ) ) - return false; - const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); - if ( !lm ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart1 >( - MethodFromDS(lm->getMethodFunction()), - description, arg1, arg1_description) ); - return true; - } - - template - bool addMethod( MethodT* c, const char* description, - const char* arg1, const char* arg1_description, - const char* arg2, const char* arg2_description) - { - typedef typename MethodT::Signature Sig; - if ( this->hasMember(c->getName() ) ) - return false; - const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); - if ( !lm ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart2 >( - MethodFromDS(lm->getMethodFunction()), - description, - arg1, arg1_description, - arg2, arg2_description) ); - return true; - } - template - bool addMethod( MethodT* c, const char* description, - const char* arg1, const char* arg1_description, - const char* arg2, const char* arg2_description, - const char* arg3, const char* arg3_description) - { - typedef typename MethodT::Signature Sig; - if ( this->hasMember(c->getName() ) ) - return false; - const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); - if ( !lm ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart3 >( - MethodFromDS(lm->getMethodFunction()), - description, - arg1, arg1_description, - arg2, arg2_description, - arg3, arg3_description) ); - return true; - } - - template - bool addMethod( MethodT* c, const char* description, - const char* arg1, const char* arg1_description, - const char* arg2, const char* arg2_description, - const char* arg3, const char* arg3_description, - const char* arg4, const char* arg4_description) - { - typedef typename MethodT::Signature Sig; - if ( this->hasMember(c->getName() ) ) - return false; - const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); - if ( !lm ) - return false; - this->add( c->getName(), new detail::OperationFactoryPart4 >( - MethodFromDS(lm->getMethodFunction()), - description, - arg1, arg1_description, - arg2, arg2_description, - arg3, arg3_description, - arg4, arg4_description) ); - return true; - } - - template - bool addMethodDS( DataSource< boost::weak_ptr >* wp, MethodT* c, const char* description) - { - using namespace detail; - typedef typename MethodT::Signature Sig; - if ( this->hasMember(c->getName() ) ) - return false; - const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); - if ( !lm ) - return false; - typedef FunctorDataSourceDS0 > FunctorT; - typedef MethodFromDS DSMeth; - - this->add( c->getName(), new detail::OperationFactoryPart0( - DSMeth( typename FunctorT::shared_ptr(new FunctorT(wp, lm->getMethodFunction()))), - description)); - return true; - } - - template - bool addMethodDS( DataSource< boost::weak_ptr >* wp, MethodT* c, const char* description, - const char* a1, const char* d1) - { - using namespace detail; - typedef typename MethodT::Signature Sig; - if ( this->hasMember(c->getName() ) ) - return false; - const detail::LocalMethod* lm = dynamic_cast< const detail::LocalMethod* >( c->getMethodImpl() ); - if ( !lm ) - return false; - typedef typename MethodT::traits::arg2_type arg1_type; // second arg is 1st data arg. - typedef FunctorDataSourceDS1, arg1_type > FunctorT; - typedef MethodFromDS DSMeth; - this->add( c->getName(), new detail::OperationFactoryPart1( - DSMeth( typename FunctorT::shared_ptr(new FunctorT(wp, lm->getMethodFunction()))), - description, a1, d1)); - return true; - } - - }; - /** * The interface for accessing and executing 'operations', being commands * and methods. @@ -737,6 +15,7 @@ namespace ORO_Execution { public: virtual ~OperationInterface() {} + virtual const std::string& getName() const = 0; virtual CommandRepository* commands() = 0; virtual MethodRepository* methods() = 0; @@ -760,7 +39,7 @@ namespace ORO_Execution : mname(name) {} - const std::string& getName() { return mname; } + const std::string& getName() const { return mname; } virtual CommandRepository* commands() { return &mcommands; } diff --git a/packages/execution/task_context/current/include/PortInterface.hpp b/packages/execution/task_context/current/include/PortInterface.hpp index 42434bc7d..277541074 100644 --- a/packages/execution/task_context/current/include/PortInterface.hpp +++ b/packages/execution/task_context/current/include/PortInterface.hpp @@ -32,7 +32,7 @@ #include #include "ConnectionTypes.hpp" #include "ConnectionInterface.hpp" -#include "DataSourceFactoryInterface.hpp" +#include "OperationInterface.hpp" namespace ORO_Execution { @@ -112,10 +112,10 @@ namespace ORO_Execution virtual ConnectionInterface::shared_ptr createConnection(PortInterface* other, ConnectionTypes::ConnectionType con_type = ConnectionTypes::lockfree); /** - * Create accessor DataSources for this Port, for addition to a - * DataSource interface. + * Create accessor Object for this Port, for addition to a + * TaskContext Object interface. */ - virtual DataSourceFactoryInterface* createDataSources(); + virtual OperationInterface* createPortObject(); }; } diff --git a/packages/execution/task_context/current/include/RemoteCommand.hpp b/packages/execution/task_context/current/include/RemoteCommand.hpp new file mode 100644 index 000000000..27bd6df2d --- /dev/null +++ b/packages/execution/task_context/current/include/RemoteCommand.hpp @@ -0,0 +1,155 @@ +#ifndef ORO_REMOTE_COMMAND_HPP +#define ORO_REMOTE_COMMAND_HPP + +#include +#include +#include "DispatchInterface.hpp" +#include "CommandProcessor.hpp" +#include "CommandFunctors.hpp" +#include "DataSourceStorage.hpp" +#include "Invoker.hpp" + +namespace ORO_Execution +{ + namespace detail + { + /** + * A Command which is dispatched remotely to a CommandProcessor. + * @param CommandT The function signature of the command. For example, + * bool( int, Frame, double) + * + */ + template + class RemoteCommandImpl + : public CommandBase, + protected detail::DataSourceStorage + { + protected: + CommandC mcom; + public: + /** + * The defaults are reset by the constructor. + */ + RemoteCommandImpl() + : mcom() + {} + + /** + * Call this operator if the RemoteCommand takes no arguments. + * + * @return true if ready and succesfully sent. + */ + bool operator()() { + return mcom.execute(); + } + + template + bool operator()( T1 a1 ) { + this->store( a1 ); + return mcom.execute(); + } + + template + bool operator()( T1 a1, T2 a2 ) { + this->store( a1, a2 ); + return mcom.execute(); + } + + template + bool operator()( T1 a1, T2 a2, T3 a3 ) { + this->store( a1, a2, a3 ); + return mcom.execute(); + } + + template + bool operator()( T1 a1, T2 a2, T3 a3, T4 a4 ) { + this->store( a1, a2, a3, a4 ); + return mcom.execute(); + } + }; + + + /** + * A Command which is dispatched remotely to a CommandProcessor. + * @param CommandT The function signature of the command. For example, + * bool( int, Frame, double) + * + */ + template + class RemoteCommand + : public Invoker > + { + public: + typedef CommandT Signature; + + /** + * Create a RemoteCommand object which executes a remote command + * + * @param name The name of this command. + * @param com The OperationFactory for commands. + */ + RemoteCommand(CommandFactory* of, std::string name) + { + // create the command. + this->mcom = CommandC(of, name); + // add the arguments to the command. + this->initArgs( this->mcom ); + } + + virtual void readArguments() {} + + virtual bool ready() const { + return this->mcom.ready(); + } + + virtual bool dispatch() { + return this->mcom.execute(); + } + + virtual bool execute() { + return this->mcom.execute(); + } + + virtual bool evaluate() const { + return this->mcom.evaluate(); + } + + virtual void reset() { + return this->mcom.reset(); + } + + virtual bool sent() const { + return this->mcom.sent(); + } + + virtual bool accepted() const { + return this->mcom.accepted(); + } + + virtual bool executed() const { + return this->mcom.executed(); + } + + virtual bool valid() const { + return this->mcom.valid(); + } + + virtual ORO_CoreLib::ConditionInterface* createCondition() const + { + return new detail::ConditionFunctor( boost::bind( boost::mem_fn(&RemoteCommand::evaluate), this) ); + } + + /** + * Creates a clone of this RemoteCommand object. + * Use this method to get a new command object + * which has its own state information. + * + * @return + */ + virtual RemoteCommand* clone() const { + return new RemoteCommand(*this); + } + }; + } +} +#endif diff --git a/packages/execution/task_context/current/include/TaskContext.hpp b/packages/execution/task_context/current/include/TaskContext.hpp index 2d2287a2a..227662765 100644 --- a/packages/execution/task_context/current/include/TaskContext.hpp +++ b/packages/execution/task_context/current/include/TaskContext.hpp @@ -51,11 +51,13 @@ namespace ORO_Execution * A TaskContext exports the commands, methods, events, properties and ports * a task has. Furthermore, it allows to visit its peer tasks. * + * @section exec TaskContext interface * When a command is exported, one can access it using commands(). A similar * mechanism is available for properties(), methods(), events() and ports(). * The commands of this TaskContext are executed by its * ExecutionEngine. * + * @section exec Executing a TaskContext * In order to run the ExecutionEngine, the ExecutionEngine must * be invoked from an ActivityInterface implementation. As long as * there is no activity or the activity is not started, this @@ -64,6 +66,10 @@ namespace ORO_Execution * of this class can determine himself at which point and at which * moment commands and programs can be executed. * + * @section exec Connecting TaskContexts + * TaskContexts are connected using the unidirectional addPeer() or bidirectional + * connectPeers() methods. These methods setup data connections and allow + * 'peer' TaskContexts to use each other's interface. * In order to disconnect this task from its peers, use disconnect(), which * will disconnect all the Data Flow Ports and remove this object from its * Peers. @@ -77,13 +83,18 @@ namespace ORO_Execution typedef std::map< std::string, TaskContext* > PeerMap; typedef std::vector< TaskContext* > Users; - // map of the tasks we are using + typedef std::vector< OperationInterface* > Objects; + /// map of the tasks we are using PeerMap _task_map; - // map of the tasks that are using us. + /// map of the tasks that are using us. Users musers; + /// the TaskObjects. + Objects mobjects; ScriptingAccess* mscriptAcc; + + void connectDataFlow( TaskContext* peer ); void exportPorts(); @@ -100,6 +111,7 @@ namespace ORO_Execution void removeUser(TaskContext* user); public: typedef std::vector< std::string > PeerList; + typedef std::vector< std::string > ObjectList; /** * Create a TaskContext visible with \a name. @@ -200,7 +212,7 @@ namespace ORO_Execution * @return true if it cuold be added, false if such * object already exists. */ - bool addObject( TaskObject *obj ); + bool addObject( OperationInterface *obj ); /** * Get a pointer to a previously added TaskObject @@ -209,7 +221,14 @@ namespace ORO_Execution * * @return the pointer */ - TaskObject* getObject(const std::string& obj_name ) const; + OperationInterface* getObject(const std::string& obj_name ); + + /** + * Get a list of all the object names of this TaskContext. + * + * @return a list of string names. + */ + ObjectList getObjectList() const; /** * Remove and delete a previously added TaskObject. @@ -266,7 +285,7 @@ namespace ORO_Execution { return ⅇ } - +#if 0 /** * The Commands of this TaskContext. */ @@ -294,7 +313,7 @@ namespace ORO_Execution const GlobalMethodFactory* methods() const{ return &methodFactory; } - +#endif /** * The DataSources of this TaskContext. */ @@ -365,6 +384,7 @@ namespace ORO_Execution return &dataPorts; } + private: /** * The Command Factory of this TaskContext. * @deprecated by commands() diff --git a/packages/execution/task_context/current/include/TaskCore.hpp b/packages/execution/task_context/current/include/TaskCore.hpp index 7105fbc34..ff2505f5f 100644 --- a/packages/execution/task_context/current/include/TaskCore.hpp +++ b/packages/execution/task_context/current/include/TaskCore.hpp @@ -2,6 +2,7 @@ #define ORO_TASK_CORE_HPP #include "ExecutionEngine.hpp" +#include "OperationInterface.hpp" #include @@ -15,6 +16,7 @@ namespace ORO_Execution * task browsing is required (for every task). */ class TaskCore + : public OperationInterface { // non copyable TaskCore( TaskCore& ); @@ -22,6 +24,8 @@ namespace ORO_Execution std::string _task_name; ExecutionEngine ee; + CommandRepository comms; + MethodRepository meths; public: /** * Create a TaskCore visible with \a name. @@ -74,7 +78,7 @@ namespace ORO_Execution /** * Get the name of this TaskCore. */ - const std::string& getName() + const std::string& getName() const { return _task_name; } @@ -104,6 +108,27 @@ namespace ORO_Execution { return ⅇ } +#if 1 + CommandRepository* commands() + { + return &comms; + } + + const CommandRepository* commands() const + { + return &comms; + } + + MethodRepository* methods() + { + return &meths; + } + + const MethodRepository* methods() const + { + return &meths; + } +#endif }; } diff --git a/packages/execution/task_context/current/include/UnMember.hpp b/packages/execution/task_context/current/include/UnMember.hpp index b9a83b32e..b0acbeb0e 100644 --- a/packages/execution/task_context/current/include/UnMember.hpp +++ b/packages/execution/task_context/current/include/UnMember.hpp @@ -2,8 +2,12 @@ #define ORO_UN_MEMBER_HPP #include +#include #include #include +#include +#include +#include #include #include @@ -22,6 +26,35 @@ namespace ORO_Execution typedef typename boost::function_type::type type; //typedef typename non_member_signature::representee type; }; + + template + class ArgMember + { + typedef boost::function_type_signature member_signature; + // remove the class from the arg list: + typedef typename boost::mpl::erase::type>::type>::type non_member_signature; + // insert it as first argument. + typedef typename boost::mpl::insert::type>::type, + typename boost::add_pointer >::type>::type + >::type arg_signature; + //typedef typename arg_signature::blah ok; + //typedef typename member_signature::types::blah ok2; + public: + typedef typename boost::function_type::type type; + //typedef typename boost::function_type::type::fail type2; + //typedef typename non_member_signature::representee type; + }; + + template + class UnPointer + { + typedef boost::function_type_signature signature; + public: + typedef typename boost::function_type::type type; + //typedef typename non_member_signature::representee type; + }; } } diff --git a/packages/execution/task_context/current/src/CommandC.cxx b/packages/execution/task_context/current/src/CommandC.cxx index b2cbd6bda..65264ed8a 100644 --- a/packages/execution/task_context/current/src/CommandC.cxx +++ b/packages/execution/task_context/current/src/CommandC.cxx @@ -46,7 +46,7 @@ namespace ORO_Execution { public: const GlobalCommandFactory* mgcf; - const CommandRepository* mcr; + const CommandRepository::Factory* mcr; std::string mobject, mname; std::pair comcon; std::vector args; @@ -61,7 +61,7 @@ namespace ORO_Execution size_t sz = mcr->getArity(mname); if ( sz == args.size() ) { // may throw or return '0,0' if no exceptions. - comcon.first = mcr->getCommand(mname, args); // the dispatch flag is no longer relevant here. + comcon.first = mcr->produce(mname, args); // the dispatch flag is no longer relevant here. args.clear(); if (comcon.first == 0) return; @@ -108,7 +108,7 @@ namespace ORO_Execution this->checkAndCreate(); } - D( const CommandRepository* cr, const std::string& name) + D( const CommandRepository::Factory* cr, const std::string& name) : mgcf(0), mcr(cr), mname(name) { comcon.first = 0; @@ -153,7 +153,7 @@ namespace ORO_Execution } } - CommandC::CommandC(const CommandRepository* cr, const std::string& name) + CommandC::CommandC(const CommandRepository::Factory* cr, const std::string& name) : d( cr ? new D( cr, name) : 0 ), cc() { if ( d->comcon.first ) { @@ -260,7 +260,7 @@ namespace ORO_Execution return false; } - bool CommandC::evaluate() { + bool CommandC::evaluate() const { // check if done if (cc ) return cc->evaluate(); diff --git a/packages/execution/task_context/current/src/MethodC.cxx b/packages/execution/task_context/current/src/MethodC.cxx index 1a682a0d2..aeaba654a 100644 --- a/packages/execution/task_context/current/src/MethodC.cxx +++ b/packages/execution/task_context/current/src/MethodC.cxx @@ -43,7 +43,7 @@ namespace ORO_Execution { public: const GlobalMethodFactory* mgcf; - const MethodRepository* mmr; + const MethodRepository::Factory* mmr; std::string mobject, mname; std::vector args; AttributeBase* rta; @@ -59,7 +59,7 @@ namespace ORO_Execution size_t sz = mmr->getArity(mname); if ( sz == args.size() ) { // may throw or return nill - m = mmr->getMethod(mname, args ); + m = mmr->produce(mname, args ); args.clear(); if ( !m ) return; @@ -109,7 +109,7 @@ namespace ORO_Execution this->checkAndCreate(); } - D( const MethodRepository* mr, const std::string& name) + D( const MethodRepository::Factory* mr, const std::string& name) : mgcf(0), mmr(mr), mname(name), rta(0), m() { this->checkAndCreate(); @@ -143,7 +143,7 @@ namespace ORO_Execution } } - MethodC::MethodC(const MethodRepository* mr, const std::string& name) + MethodC::MethodC(const MethodRepository::Factory* mr, const std::string& name) : d( mr ? new D( mr, name) : 0 ), m() { if ( d->m ) { diff --git a/packages/execution/task_context/current/src/PortInterface.cxx b/packages/execution/task_context/current/src/PortInterface.cxx index 86a49157c..c7da48d8d 100644 --- a/packages/execution/task_context/current/src/PortInterface.cxx +++ b/packages/execution/task_context/current/src/PortInterface.cxx @@ -57,7 +57,7 @@ namespace ORO_Execution return ConnectionInterface::shared_ptr(); } - DataSourceFactoryInterface* PortInterface::createDataSources() { + OperationInterface* PortInterface::createPortObject() { return 0; } diff --git a/packages/execution/task_context/current/src/TaskContext.cxx b/packages/execution/task_context/current/src/TaskContext.cxx index 93b389793..baed0a587 100644 --- a/packages/execution/task_context/current/src/TaskContext.cxx +++ b/packages/execution/task_context/current/src/TaskContext.cxx @@ -100,6 +100,12 @@ namespace ORO_Execution } // Do not call this->disconnect() !!! // Ports are probably already destructed by user code. + + Objects::const_iterator it = mobjects.begin(); + while ( it != mobjects.end() ) { + delete *it; + ++it; + } } void TaskContext::exportPorts() @@ -108,11 +114,11 @@ namespace ORO_Execution for (DataFlowInterface::Ports::iterator it = myports.begin(); it != myports.end(); ++it) { - if ( this->datasources()->getObjectFactory( (*it)->getName() ) == 0 ) { + if ( this->getObject( (*it)->getName() ) == 0 ) { // Add the port to the method interface. - DataSourceFactoryInterface* ms = (*it)->createDataSources(); + OperationInterface* ms = (*it)->createPortObject(); if ( ms ) - this->datasources()->registerObject( (*it)->getName(), ms ); + this->addObject( ms ); } } } @@ -313,17 +319,43 @@ namespace ORO_Execution return 0; } - bool TaskContext::addObject( TaskObject *obj ) { - return false; + bool TaskContext::addObject( OperationInterface *obj ) { + if ( getObject( obj->getName() ) ) + return false; + mobjects.push_back(obj); + return true; } - TaskObject* TaskContext::getObject(const std::string& obj_name ) const + OperationInterface* TaskContext::getObject(const std::string& obj_name ) { + if (obj_name == "this") + return this; + Objects::const_iterator it = mobjects.begin(); + while ( it != mobjects.end() ) + if ( (*it)->getName() == obj_name ) + return *it; + else + ++it; return 0; } + std::vector TaskContext::getObjectList() const + { + std::vector res; + std::transform(mobjects.begin(), mobjects.end(), + std::back_inserter( res ), boost::bind(&OperationInterface::getName,_1)); + return res; + } + + bool TaskContext::removeObject(const std::string& obj_name ) { - return false; + OperationInterface* tgt = getObject(obj_name); + if (tgt) { + mobjects.erase( find(mobjects.begin(), mobjects.end(), tgt) ); + delete tgt; + return true; + } + return false; } } diff --git a/packages/templates/allpackages/current.ect b/packages/templates/allpackages/current.ect index 0b4ae40cc..0645b777e 100644 --- a/packages/templates/allpackages/current.ect +++ b/packages/templates/allpackages/current.ect @@ -38,17 +38,6 @@ cdl_configuration template_allpackages { package OROPKG_DEVICE_DRIVERS_CANOPEN current; package OROPKG_DEVICE_DRIVERS_PORTS current; package OROPKG_DEVICE_DRIVERS_K600 current; - package OROPKG_CONTROL_FRAMEWORK current; - package OROPKG_CONTROL_KERNEL current; - package OROPKG_CONTROL_KERNEL_COMPONENTS current ; - package OROPKG_CONTROL_KERNEL_COMPONENTS_MOTION_CONTROL current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_MOTION_CONTROL_AXIS current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_MOTION_CONTROL_N_AXIS current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_MOTION_CONTROL_CARTESIAN current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_HARDWARE current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_PROCESS_CONTROL current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_KINEMATICS current; - package OROPKG_CONTROL_KERNEL_SERVER current ; package OROPKG_EXECUTION current; package OROPKG_EXECUTION_PROGRAM_PARSER current; package OROPKG_EXECUTION_PROGRAM_PROCESSOR current; diff --git a/packages/templates/dist-packages/current.ect b/packages/templates/dist-packages/current.ect index dea8408b8..241ad7f55 100644 --- a/packages/templates/dist-packages/current.ect +++ b/packages/templates/dist-packages/current.ect @@ -33,16 +33,6 @@ cdl_configuration template_dist_packages { package OROPKG_DEVICE_DRIVERS current; package OROPKG_DEVICE_DRIVERS_LOGICAL current; package OROPKG_DEVICE_DRIVERS_PORTS current; - package OROPKG_CONTROL_FRAMEWORK current; - package OROPKG_CONTROL_KERNEL current; - package OROPKG_CONTROL_KERNEL_COMPONENTS current ; - package OROPKG_CONTROL_KERNEL_COMPONENTS_MOTION_CONTROL current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_MOTION_CONTROL_AXIS current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_MOTION_CONTROL_N_AXIS current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_MOTION_CONTROL_CARTESIAN current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_HARDWARE current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_PROCESS_CONTROL current; - package OROPKG_CONTROL_KERNEL_COMPONENTS_KINEMATICS current; package OROPKG_EXECUTION current; package OROPKG_EXECUTION_PROGRAM_PARSER current; package OROPKG_EXECUTION_PROGRAM_PROCESSOR current; diff --git a/tests/dispatch_test.cpp b/tests/dispatch_test.cpp index 8a7675298..b04d8f53b 100644 --- a/tests/dispatch_test.cpp +++ b/tests/dispatch_test.cpp @@ -25,6 +25,8 @@ #include #include #include +#include +#include using namespace std; @@ -45,11 +47,10 @@ void DispatchTest::setUp() { // ltc has a test object - ltc.methodFactory.registerObject("test", this->createMethodFactory() ); - ltc.commandFactory.registerObject("test", this->createCommandFactory() ); + ltc.addObject( this->createObject("test", ltc.engine()->commands()) ); // mtc has two methods. - mtc.methodFactory.registerObject("this", this->createMethodFactory() ); - mtc.dataFactory.registerObject("test", this->createDataSourceFactory() ); + mtc.addObject( this->createObject("this", mtc.engine()->commands()) ); + mtc.addObject( this->createObject("test", mtc.engine()->commands()) ); gtc.addPeer( &mtc ); mtc.connectPeers( <c ); @@ -75,51 +76,27 @@ bool DispatchTest::assertMsg( bool b, const std::string& msg) { } -MethodFactoryInterface* DispatchTest::createMethodFactory() +TaskObject* DispatchTest::createObject(string a, CommandProcessor* cp) { - // Add the data of the EE: - TemplateMethodFactory< DispatchTest >* dat = - newMethodFactory( this ); - - dat->add( "assert", method( &DispatchTest::assertBool, - "Assert", "bool", "") ); - dat->add( "assertMsg", method( &DispatchTest::assertMsg, - "Assert message", "bool", "", "text", "text" ) ); - return dat; -} - -DataSourceFactoryInterface* DispatchTest::createDataSourceFactory() -{ - // Add the data of the EE: - TemplateDataSourceFactory< DispatchTest >* dat = - newDataSourceFactory( this ); - - dat->add( "isTrue", data( &DispatchTest::assertBool, - "Identity function", "bool", "") ); - return dat; -} - -CommandFactoryInterface* DispatchTest::createCommandFactory() -{ - // Add the data of the EE: - TemplateCommandFactory< DispatchTest >* dat = - newCommandFactory( this ); - - dat->add( "instantDone", command( &DispatchTest::true_genCom, - &DispatchTest::true_gen, - "returns immediately") ); - dat->add( "neverDone", command( &DispatchTest::true_genCom, - &DispatchTest::false_gen, - "returns never") ); - dat->add( "instantNotDone", command( &DispatchTest::true_genCom, - &DispatchTest::true_gen, - "returns never", false ) ); - dat->add( "instantFail", command( &DispatchTest::false_genCom, - &DispatchTest::true_gen, - "fails immediately") ); - dat->add( "totalFail", command( &DispatchTest::false_genCom, - &DispatchTest::false_gen, - "fails in command and condition") ); + TaskObject* dat = new TaskObject(a); + dat->methods()->addMethod( method( "assert", &DispatchTest::assertBool, this), "Assert", "bool", "" ); + dat->methods()->addMethod( method( "assertMsg", &DispatchTest::assertMsg, this), "Assert message", "bool", "", "text", "text" ); + dat->methods()->addMethod( method( "isTrue", &DispatchTest::assertBool, this), "Identity function", "bool", "" ); + dat->commands()->addCommand( command( "instantDone", &DispatchTest::true_genCom, + &DispatchTest::true_gen, this, cp), + "returns immediately" ); + dat->commands()->addCommand( command( "neverDone", &DispatchTest::true_genCom, + &DispatchTest::false_gen, this, cp), + "returns never" ); + dat->commands()->addCommand( command( "instantNotDone", &DispatchTest::true_genCom, + &DispatchTest::true_gen, this, cp, false), + "returns never"); + dat->commands()->addCommand( command( "instantFail", &DispatchTest::false_genCom, + &DispatchTest::true_gen, this, cp), + "fails immediately" ); + dat->commands()->addCommand( command( "totalFail", &DispatchTest::false_genCom, + &DispatchTest::false_gen, this, cp), + "fails in command and condition" ); return dat; } diff --git a/tests/dispatch_test.hpp b/tests/dispatch_test.hpp index 456076a93..767d3ebd7 100644 --- a/tests/dispatch_test.hpp +++ b/tests/dispatch_test.hpp @@ -53,9 +53,7 @@ class DispatchTest : public CppUnit::TestFixture SimulationActivity gtask; SimulationActivity mtask; SimulationActivity ltask; - MethodFactoryInterface* createMethodFactory(); - CommandFactoryInterface* createCommandFactory(); - DataSourceFactoryInterface* createDataSourceFactory(); + TaskObject* createObject(std::string a, CommandProcessor* cp); bool true_genCom() { return true; } bool false_genCom() { return false; } diff --git a/tests/function_test.cpp b/tests/function_test.cpp index 562c59670..4cd1a1543 100644 --- a/tests/function_test.cpp +++ b/tests/function_test.cpp @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include using namespace std; @@ -42,9 +43,7 @@ void FunctionTest::setUp() { // ltc has a test object - gtc.methodFactory.registerObject("test", this->createMethodFactory() ); - gtc.commandFactory.registerObject("test", this->createCommandFactory() ); - gtc.dataFactory.registerObject("test", this->createDataSourceFactory() ); + gtc.addObject(this->createObject("test", gtc.engine()->commands() ) ); i = 0; } @@ -53,9 +52,6 @@ FunctionTest::setUp() void FunctionTest::tearDown() { - gtc.methodFactory.unregisterObject( "test" ); - gtc.commandFactory.unregisterObject( "test" ); - gtc.dataFactory.unregisterObject( "test" ); } @@ -77,57 +73,38 @@ void FunctionTest::reset() { } -MethodFactoryInterface* FunctionTest::createMethodFactory() +OperationInterface* FunctionTest::createObject(string a, CommandProcessor* cp) { - // Add the data of the EE: - TemplateMethodFactory< FunctionTest >* dat = - newMethodFactory( this ); - - dat->add( "assert", method( &FunctionTest::assertBool, - "Assert", "bool", "") ); - dat->add( "increase", method( &FunctionTest::increase, - "Return increasing i" ) ); - dat->add( "reset", method( &FunctionTest::reset, - "Reset i") ); - dat->add( "assertMsg", method( &FunctionTest::assertMsg, - "Assert message", "bool", "", "text", "text" ) ); - return dat; -} - -DataSourceFactoryInterface* FunctionTest::createDataSourceFactory() -{ - // Add the data of the EE: - TemplateDataSourceFactory< FunctionTest >* dat = - newDataSourceFactory( this ); - - dat->add( "isTrue", data( &FunctionTest::assertBool, - "Identity function", "bool", "") ); - dat->add( "i", data( &FunctionTest::i, - "Return the current number" ) ); - return dat; -} - -CommandFactoryInterface* FunctionTest::createCommandFactory() -{ - // Add the data of the EE: - TemplateCommandFactory< FunctionTest >* dat = - newCommandFactory( this ); - - dat->add( "instantDone", command( &FunctionTest::true_genCom, - &FunctionTest::true_gen, - "returns immediately") ); - dat->add( "neverDone", command( &FunctionTest::true_genCom, - &FunctionTest::false_gen, - "returns never") ); - dat->add( "instantNotDone", command( &FunctionTest::true_genCom, - &FunctionTest::true_gen, - "returns never", false ) ); - dat->add( "instantFail", command( &FunctionTest::false_genCom, - &FunctionTest::true_gen, - "fails immediately") ); - dat->add( "totalFail", command( &FunctionTest::false_genCom, - &FunctionTest::false_gen, - "fails in command and condition") ); + TaskObject* dat = new TaskObject(a); + dat->methods()->addMethod( method( "assert", &FunctionTest::assertBool, this), + "Assert", "bool", "" ); + dat->methods()->addMethod( method( "increase", &FunctionTest::increase, this), + "Return increasing i" ); + dat->methods()->addMethod( method( "reset", &FunctionTest::reset, this), + "Reset i" ); + dat->methods()->addMethod( method( "assertMsg", &FunctionTest::assertMsg, this), + "Assert message", "bool", "", "text", "text" ); + + dat->methods()->addMethod( method( "isTrue", &FunctionTest::assertBool, this), + "Identity function", "bool", "" ); + dat->methods()->addMethod( method( "i", &FunctionTest::getI, this), + "Return the current number" ); + + dat->commands()->addCommand( command( "instantDone", &FunctionTest::true_genCom, + &FunctionTest::true_gen, this, cp), + "returns immediately" ); + dat->commands()->addCommand( command( "neverDone", &FunctionTest::true_genCom, + &FunctionTest::false_gen, this, cp), + "returns never" ); + dat->commands()->addCommand( command( "instantNotDone", &FunctionTest::true_genCom, + &FunctionTest::true_gen, this, cp, false), + "returns never"); + dat->commands()->addCommand( command( "instantFail", &FunctionTest::false_genCom, + &FunctionTest::true_gen, this, cp), + "fails immediately" ); + dat->commands()->addCommand( command( "totalFail", &FunctionTest::false_genCom, + &FunctionTest::false_gen, this, cp), + "fails in command and condition" ); return dat; } diff --git a/tests/function_test.hpp b/tests/function_test.hpp index cb7df59e5..7fc27318f 100644 --- a/tests/function_test.hpp +++ b/tests/function_test.hpp @@ -48,9 +48,7 @@ class FunctionTest : public CppUnit::TestFixture Parser parser; TaskContext gtc; SimulationActivity gtask; - MethodFactoryInterface* createMethodFactory(); - CommandFactoryInterface* createCommandFactory(); - DataSourceFactoryInterface* createDataSourceFactory(); + OperationInterface* createObject(std::string name, CommandProcessor* cp); bool assertBool( bool ); bool assertMsg( bool, const std::string& msg); int increase(); @@ -64,6 +62,7 @@ class FunctionTest : public CppUnit::TestFixture bool false_gen() const { return false; } bool bool_gen( bool b ) const { return b; } + int getI() const { return i; } int i; public: FunctionTest(); diff --git a/tests/generictask_test.cpp b/tests/generictask_test.cpp index c2130a3ea..827ce9a58 100644 --- a/tests/generictask_test.cpp +++ b/tests/generictask_test.cpp @@ -50,9 +50,8 @@ void Generic_TaskTest::setUp() { tc = new TaskContext( "root" ); - tc->methodFactory.registerObject("methods", this->createMethodFactory() ); - tc->commandFactory.registerObject("commands", this->createCommandFactory() ); - tc->dataFactory.registerObject("data", this->createDataSourceFactory() ); + tc->addObject( this->createMethodFactory() ); + tc->addObject( this->createCommandFactory() ); tsim = new SimulationActivity(0.001, tc->engine() ); } @@ -72,68 +71,52 @@ bool Generic_TaskTest::assertBool( bool b) { return b; } -MethodFactoryInterface* Generic_TaskTest::createMethodFactory() +TaskObject* Generic_TaskTest::createMethodFactory() { - TemplateMethodFactory< Generic_TaskTest >* dat = - newMethodFactory( this ); + TaskObject* to = new TaskObject("methods"); - dat->add( "assert", method( &Generic_TaskTest::assertBool, "assert","b","bd") ); + to->methods()->addMethod( method("assert", &Generic_TaskTest::assertBool, this), "assert","b","bd"); - dat->add( "m0", method( &Generic_TaskTest::m0, "M0") ); - dat->add( "m1", method( &Generic_TaskTest::m1, "M1","a","ad") ); - dat->add( "m2", method( &Generic_TaskTest::m2, "M2","a","ad","a","ad") ); - dat->add( "m3", method( &Generic_TaskTest::m3, "M3","a","ad","a","ad","a","ad") ); - dat->add( "m4", method( &Generic_TaskTest::m4, "M4","a","ad","a","ad","a","ad","a","ad") ); - return dat; + to->methods()->addMethod( method("m0", &Generic_TaskTest::m0, this), "M0"); + to->methods()->addMethod( method("m1", &Generic_TaskTest::m1, this), "M1","a","ad"); + to->methods()->addMethod( method("m2", &Generic_TaskTest::m2, this), "M2","a","ad","a","ad"); + to->methods()->addMethod( method("m3", &Generic_TaskTest::m3, this), "M3","a","ad","a","ad","a","ad"); + to->methods()->addMethod( method("m4", &Generic_TaskTest::m4, this), "M4","a","ad","a","ad","a","ad","a","ad"); + return to; } -DataSourceFactoryInterface* Generic_TaskTest::createDataSourceFactory() +TaskObject* Generic_TaskTest::createCommandFactory() { - TemplateDataSourceFactory< Generic_TaskTest >* dat = - newDataSourceFactory( this ); - - dat->add( "d0", data( &Generic_TaskTest::d0, "d0") ); - dat->add( "d1", data( &Generic_TaskTest::d1, "d1","a","ad") ); - dat->add( "d2", data( &Generic_TaskTest::d2, "d2","a","ad","a","ad") ); - dat->add( "d3", data( &Generic_TaskTest::d3, "d3","a","ad","a","ad","a","ad") ); - dat->add( "d4", data( &Generic_TaskTest::d4, "d4","a","ad","a","ad","a","ad","a","ad") ); - - return dat; -} - -CommandFactoryInterface* Generic_TaskTest::createCommandFactory() -{ - TemplateCommandFactory< Generic_TaskTest >* dat = - newCommandFactory( this ); - - dat->add( "c00", command( &Generic_TaskTest::cd0, &Generic_TaskTest::cn0, "c0d") ); - dat->add( "c10", command( &Generic_TaskTest::cd1, &Generic_TaskTest::cn0, "c1d","a","ad") ); - dat->add( "c11", command( &Generic_TaskTest::cd1, &Generic_TaskTest::cn1, "c1d","a","ad") ); - dat->add( "c20", command( &Generic_TaskTest::cd2, &Generic_TaskTest::cn0, "c2d","a","ad","a","ad") ); - dat->add( "c21", command( &Generic_TaskTest::cd2, &Generic_TaskTest::cn1, "c2d","a","ad","a","ad") ); - dat->add( "c22", command( &Generic_TaskTest::cd2, &Generic_TaskTest::cn2, "c2d","a","ad","a","ad") ); - dat->add( "c30", command( &Generic_TaskTest::cd3, &Generic_TaskTest::cn0, "c3d","a","ad","a","ad","a","ad") ); - dat->add( "c31", command( &Generic_TaskTest::cd3, &Generic_TaskTest::cn1, "c3d","a","ad","a","ad","a","ad") ); - dat->add( "c33", command( &Generic_TaskTest::cd3, &Generic_TaskTest::cn3, "c3d","a","ad","a","ad","a","ad") ); - dat->add( "c40", command( &Generic_TaskTest::cd4, &Generic_TaskTest::cn0, "c4d","a","ad","a","ad","a","ad","a","ad") ); - dat->add( "c41", command( &Generic_TaskTest::cd4, &Generic_TaskTest::cn1, "c4d","a","ad","a","ad","a","ad","a","ad") ); - dat->add( "c44", command( &Generic_TaskTest::cd4, &Generic_TaskTest::cn4, "c4d","a","ad","a","ad","a","ad","a","ad") ); - return dat; + TaskObject* to = new TaskObject("commands"); + + to->commands()->addCommand( command("c00", &Generic_TaskTest::cd0, &Generic_TaskTest::cn0, this, tc->engine()->commands()), "c0d"); + to->commands()->addCommand( command("c10", &Generic_TaskTest::cd1, &Generic_TaskTest::cn0, this, tc->engine()->commands()), "c1d","a","ad"); + to->commands()->addCommand( command("c11", &Generic_TaskTest::cd1, &Generic_TaskTest::cn1, this, tc->engine()->commands()), "c1d","a","ad"); + to->commands()->addCommand( command("c20", &Generic_TaskTest::cd2, &Generic_TaskTest::cn0, this, tc->engine()->commands()), "c2d","a","ad","a","ad"); + to->commands()->addCommand( command("c21", &Generic_TaskTest::cd2, &Generic_TaskTest::cn1, this, tc->engine()->commands()), "c2d","a","ad","a","ad"); + to->commands()->addCommand( command("c22", &Generic_TaskTest::cd2, &Generic_TaskTest::cn2, this, tc->engine()->commands()), "c2d","a","ad","a","ad"); + to->commands()->addCommand( command("c30", &Generic_TaskTest::cd3, &Generic_TaskTest::cn0, this, tc->engine()->commands()), "c3d","a","ad","a","ad","a","ad"); + to->commands()->addCommand( command("c31", &Generic_TaskTest::cd3, &Generic_TaskTest::cn1, this, tc->engine()->commands()), "c3d","a","ad","a","ad","a","ad"); + to->commands()->addCommand( command("c33", &Generic_TaskTest::cd3, &Generic_TaskTest::cn3, this, tc->engine()->commands()), "c3d","a","ad","a","ad","a","ad"); + to->commands()->addCommand( command("c40", &Generic_TaskTest::cd4, &Generic_TaskTest::cn0, this, tc->engine()->commands()), "c4d","a","ad","a","ad","a","ad","a","ad"); + to->commands()->addCommand( command("c41", &Generic_TaskTest::cd4, &Generic_TaskTest::cn1, this, tc->engine()->commands()), "c4d","a","ad","a","ad","a","ad","a","ad"); + to->commands()->addCommand( command("c44", &Generic_TaskTest::cd4, &Generic_TaskTest::cn4, this, tc->engine()->commands()), "c4d","a","ad","a","ad","a","ad","a","ad"); + return to; } void Generic_TaskTest::testMethodsC() { MethodC mc; double r = 0.0; - mc = tc->methods()->create("methods", "m0").ret( r ); + mc = tc->getObject("methods")->methods()->create("m0").ret( r ); CPPUNIT_ASSERT( mc.execute() ); CPPUNIT_ASSERT( r == -1.0 ); - mc = tc->methods()->create("methods", "m2").argC(1).argC(1.0).ret( r ); + mc = tc->getObject("methods")->methods()->create("m2").argC(1).argC(1.0).ret( r ); CPPUNIT_ASSERT( mc.execute() ); CPPUNIT_ASSERT( r == -3.0 ); - mc = tc->methods()->create("methods", "m3").ret( r ).argC(1).argC(1.0).argC(true); + mc = tc->getObject("methods")->methods()->create("m3").ret( r ).argC(1).argC(1.0).argC(true); CPPUNIT_ASSERT( mc.execute() ); CPPUNIT_ASSERT( r == -4.0 ); @@ -153,11 +136,11 @@ void Generic_TaskTest::testMethodsC() void Generic_TaskTest::testCommandsC() { - CommandC cc = tc->commands()->create("commands","c00"); - CommandC c20 = tc->commands()->create("commands","c20").argC(1).argC(1.0); - CommandC c32 = tc->commands()->create("commands","c31").argC(1).argC(1.0).argC('a'); - CommandC c33 = tc->commands()->create("commands","c33").argC(1).argC(1.0).argC('a'); - CommandC c44 = tc->commands()->create("commands","c44").argC(1).argC(1.0).argC('a').argC(true); + CommandC cc = tc->getObject("commands")->commands()->create("c00"); + CommandC c20 = tc->getObject("commands")->commands()->create("c20").argC(1).argC(1.0); + CommandC c32 = tc->getObject("commands")->commands()->create("c31").argC(1).argC(1.0).argC('a'); + CommandC c33 = tc->getObject("commands")->commands()->create("c33").argC(1).argC(1.0).argC('a'); + CommandC c44 = tc->getObject("commands")->commands()->create("c44").argC(1).argC(1.0).argC('a').argC(true); SimulationThread::Instance()->stop(); tsim->stop(); @@ -531,17 +514,17 @@ void Generic_TaskTest::testCommandFactory() CPPUNIT_ASSERT( to.commands()->addCommand(&com10) ); // test constructor - Command rc0 = to.commands()->getCommand("c0"); + Command rc0 = to.commands()->getCommand("c0"); CPPUNIT_ASSERT( rc0.getCommandImpl() ); CPPUNIT_ASSERT( rc0.ready() ); // test operator=() Command rc11; - rc11 = to.commands()->getCommand("c11"); + rc11 = to.commands()->getCommand("c11"); CPPUNIT_ASSERT( rc11.getCommandImpl() ); CPPUNIT_ASSERT( rc11.ready() ); - Command rc10 = to.commands()->getCommand("c10"); + Command rc10 = to.commands()->getCommand("c10"); CPPUNIT_ASSERT( rc10.getCommandImpl() ); CPPUNIT_ASSERT( rc10.ready() ); @@ -651,14 +634,20 @@ void Generic_TaskTest::testDSCommand() &Generic_TaskTest::cd0, &Generic_TaskTest::cn0, tc->engine()->commands() ); + command_ds("c0", &Generic_TaskTest::cd0, &Generic_TaskTest::cn0, tc->engine()->commands() ); + CommandDS com1("c1", &Generic_TaskTest::cd1, &Generic_TaskTest::cn1, tc->engine()->commands() ); + command_ds("c1",&Generic_TaskTest::cd1, &Generic_TaskTest::cn1, tc->engine()->commands() ); + + command_ds("cs",&Generic_TaskTest::comstr, &Generic_TaskTest::comstr, tc->engine()->commands() ); + boost::shared_ptr ptr( new Generic_TaskTest() ); ValueDataSource >::shared_ptr wp = new ValueDataSource >( ptr ); - CPPUNIT_ASSERT( to.commands()->addCommandDS( wp.get(), &com0, "desc" ) ); - CPPUNIT_ASSERT( to.commands()->addCommandDS( wp.get(), &com1, "desc", "a1", "d1" ) ); + CPPUNIT_ASSERT( to.commands()->addCommandDS( wp.get(), com0, "desc" ) ); + CPPUNIT_ASSERT( to.commands()->addCommandDS( wp.get(), com1, "desc", "a1", "d1" ) ); // this actually works ! the command will detect the deleted pointer. //ptr.reset(); @@ -706,17 +695,17 @@ void Generic_TaskTest::testMethodFactory() CPPUNIT_ASSERT( to.methods()->addMethod(&m2) ); // test constructor - Method mm0 = to.methods()->getMethod("m0"); + Method mm0 = to.methods()->getMethod("m0"); CPPUNIT_ASSERT( mm0.getMethodImpl() ); CPPUNIT_ASSERT( mm0.ready() ); // test operator=() Method mm1; - mm1 = to.methods()->getMethod("m1"); + mm1 = to.methods()->getMethod("m1"); CPPUNIT_ASSERT( mm1.getMethodImpl() ); CPPUNIT_ASSERT( mm1.ready() ); - Method mm2 = to.methods()->getMethod("m2"); + Method mm2 = to.methods()->getMethod("m2"); CPPUNIT_ASSERT( mm2.getMethodImpl() ); CPPUNIT_ASSERT( mm2.ready() ); @@ -821,13 +810,18 @@ void Generic_TaskTest::testDSMethod() Method meth0("m0", &Generic_TaskTest::m0); + method_ds("m0", &Generic_TaskTest::m0); + Method meth1("m1", &Generic_TaskTest::m1); + method_ds("m1", &Generic_TaskTest::m1); + method_ds("ms",&Generic_TaskTest::comstr ); + boost::shared_ptr ptr( new Generic_TaskTest() ); ValueDataSource >::shared_ptr wp = new ValueDataSource >( ptr ); - CPPUNIT_ASSERT( to.methods()->addMethodDS( wp.get(), &meth0, "desc" ) ); - CPPUNIT_ASSERT( to.methods()->addMethodDS( wp.get(), &meth1, "desc", "a1", "d1" ) ); + CPPUNIT_ASSERT( to.methods()->addMethodDS( wp.get(), meth0, "desc" ) ); + CPPUNIT_ASSERT( to.methods()->addMethodDS( wp.get(), meth1, "desc", "a1", "d1" ) ); // this actually works ! the method will detect the deleted pointer. //ptr.reset(); diff --git a/tests/generictask_test.hpp b/tests/generictask_test.hpp index 8da3aed66..087ca6d45 100644 --- a/tests/generictask_test.hpp +++ b/tests/generictask_test.hpp @@ -53,9 +53,8 @@ class Generic_TaskTest : public CppUnit::TestFixture TaskContext* tc; ActivityInterface* tsim; - MethodFactoryInterface* createMethodFactory(); - DataSourceFactoryInterface* createDataSourceFactory(); - CommandFactoryInterface* createCommandFactory(); + TaskObject* createMethodFactory(); + TaskObject* createCommandFactory(); // ref/const-ref tests: double ret; @@ -83,6 +82,9 @@ class Generic_TaskTest : public CppUnit::TestFixture double d3(int i, double d, bool c) const { return 4.0; } double d4(int i, double d, bool c, std::string s) const { return 5.0; } + // test const std::string& argument for command_ds + bool comstr(const std::string&) { return true; } + bool cd0() { return true; } bool cd1(int i) { return true; } bool cd2(int i, double d) { return true; } diff --git a/tests/logger_test.cpp b/tests/logger_test.cpp index 9155065c7..099e62f6d 100644 --- a/tests/logger_test.cpp +++ b/tests/logger_test.cpp @@ -63,3 +63,17 @@ void LoggerTest::testLogEnv() Logger::log() << "Test Log Environment variable : flush" << flush; Logger::log() << " and std::endl." << std::endl; } + +void LoggerTest::testNewLog() +{ + log( Debug ) << "Debug Level set + text"<< endlog(); + log() << "Test Log Environment variable : Single line" << endlog(Debug); + log() << "Test Log Environment variable : Two "; + log() << "lines on one line." << endlog(); + log() << "Test Log Environment variable : Two" << nlog(); + log() << "lines on two lines." << endlog(); + + log() << "Test Log Environment variable : nl" << nlog(); + log() << "Test Log Environment variable : flush" << flushlog(); + log() << " and std::endl." << std::endl; +} diff --git a/tests/logger_test.hpp b/tests/logger_test.hpp index cd2c4547a..297f5b176 100644 --- a/tests/logger_test.hpp +++ b/tests/logger_test.hpp @@ -32,6 +32,7 @@ class LoggerTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE( LoggerTest ); CPPUNIT_TEST( testStartStop ); CPPUNIT_TEST( testLogEnv ); + CPPUNIT_TEST( testNewLog ); CPPUNIT_TEST_SUITE_END(); public: @@ -41,6 +42,7 @@ class LoggerTest : public CppUnit::TestFixture void testStartStop(); void testLogEnv(); + void testNewLog(); }; #endif diff --git a/tests/program_test.cpp b/tests/program_test.cpp index d708ca05b..af64d5bda 100644 --- a/tests/program_test.cpp +++ b/tests/program_test.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include using namespace std; @@ -44,17 +46,13 @@ ProgramTest::setUp() { const_i = new Constant(-1); // ltc has a test object - gtc.methodFactory.registerObject("test", this->createMethodFactory() ); - gtc.commandFactory.registerObject("test", this->createCommandFactory() ); - gtc.dataFactory.registerObject("test", this->createDataSourceFactory() ); + gtc.addObject( this->createObject(new TaskObject("test"), gtc.engine()->commands()) ); // also this functions - gtc.methodFactory.registerObject("this", this->createMethodFactory() ); - gtc.commandFactory.registerObject("this", this->createCommandFactory() ); - gtc.dataFactory.registerObject("this", this->createDataSourceFactory() ); + this->createObject( >c, gtc.engine()->commands()); - gtc.attributeRepository.addAttribute("tvar_i", &var_i); - gtc.attributeRepository.addConstant("tconst_i", const_i); + gtc.attributes()->addAttribute("tvar_i", &var_i); + gtc.attributes()->addConstant("tconst_i", const_i); var_i.set(-1); i = 0; } @@ -66,9 +64,6 @@ ProgramTest::tearDown() delete const_i; SimulationThread::Instance()->stop(); gtask.stop(); - gtc.methodFactory.unregisterObject( "test" ); - gtc.commandFactory.unregisterObject( "test" ); - gtc.dataFactory.unregisterObject( "test" ); } @@ -90,57 +85,36 @@ void ProgramTest::reset() { } -MethodFactoryInterface* ProgramTest::createMethodFactory() +OperationInterface* ProgramTest::createObject(OperationInterface* dat, CommandProcessor* cp) { // Add the data of the EE: - TemplateMethodFactory< ProgramTest >* dat = - newMethodFactory( this ); - - dat->add( "assert", method( &ProgramTest::assertBool, - "Assert", "bool", "") ); - dat->add( "increase", method( &ProgramTest::increase, - "Return increasing i" ) ); - dat->add( "reset", method( &ProgramTest::reset, - "Reset i") ); - dat->add( "assertMsg", method( &ProgramTest::assertMsg, - "Assert message", "bool", "", "text", "text" ) ); - return dat; -} - -DataSourceFactoryInterface* ProgramTest::createDataSourceFactory() -{ - // Add the data of the EE: - TemplateDataSourceFactory< ProgramTest >* dat = - newDataSourceFactory( this ); - - dat->add( "isTrue", data( &ProgramTest::assertBool, - "Identity function", "bool", "") ); - dat->add( "i", data( &ProgramTest::i, - "Return the current number" ) ); - return dat; -} - -CommandFactoryInterface* ProgramTest::createCommandFactory() -{ - // Add the data of the EE: - TemplateCommandFactory< ProgramTest >* dat = - newCommandFactory( this ); - - dat->add( "instantDone", command( &ProgramTest::true_genCom, - &ProgramTest::true_gen, - "returns immediately") ); - dat->add( "neverDone", command( &ProgramTest::true_genCom, - &ProgramTest::false_gen, - "returns never") ); - dat->add( "instantNotDone", command( &ProgramTest::true_genCom, - &ProgramTest::true_gen, - "returns never", false ) ); - dat->add( "instantFail", command( &ProgramTest::false_genCom, - &ProgramTest::true_gen, - "fails immediately") ); - dat->add( "totalFail", command( &ProgramTest::false_genCom, - &ProgramTest::false_gen, - "fails in command and condition") ); + dat->methods()->addMethod( method( "assert", &ProgramTest::assertBool, this), + "Assert", "bool", "" ); + dat->methods()->addMethod( method( "increase", &ProgramTest::increase, this), + "Return increasing i" ); + dat->methods()->addMethod( method( "reset", &ProgramTest::reset, this), + "Reset i" ); + dat->methods()->addMethod( method( "assertMsg", &ProgramTest::assertMsg, this), + "Assert message", "bool", "", "text", "text" ); + dat->methods()->addMethod( method( "isTrue", &ProgramTest::assertBool, this), + "Identity function", "bool", "" ); + dat->methods()->addMethod( method( "i", &ProgramTest::getI, this), + "Return the current number" ); + dat->commands()->addCommand( command( "instantDone", &ProgramTest::true_genCom, + &ProgramTest::true_gen, this, cp), + "returns immediately" ); + dat->commands()->addCommand( command( "neverDone", &ProgramTest::true_genCom, + &ProgramTest::false_gen, this, cp), + "returns never" ); + dat->commands()->addCommand( command( "instantNotDone", &ProgramTest::true_genCom, + &ProgramTest::true_gen, this, cp, false), + "returns never" ); + dat->commands()->addCommand( command( "instantFail", &ProgramTest::false_genCom, + &ProgramTest::true_gen, this, cp), + "fails immediately" ); + dat->commands()->addCommand( command( "totalFail", &ProgramTest::false_genCom, + &ProgramTest::false_gen, this, cp), + "fails in command and condition" ); return dat; } diff --git a/tests/program_test.hpp b/tests/program_test.hpp index 3e32194e1..bf3db4773 100644 --- a/tests/program_test.hpp +++ b/tests/program_test.hpp @@ -48,9 +48,7 @@ class ProgramTest : public CppUnit::TestFixture Parser parser; TaskContext gtc; SimulationActivity gtask; - MethodFactoryInterface* createMethodFactory(); - CommandFactoryInterface* createCommandFactory(); - DataSourceFactoryInterface* createDataSourceFactory(); + OperationInterface* createObject( OperationInterface*, CommandProcessor* cp ); Attribute var_i; Constant* const_i; bool assertBool( bool ); @@ -67,6 +65,8 @@ class ProgramTest : public CppUnit::TestFixture bool false_gen() const { return false; } bool bool_gen( bool b ) const { return b; } + int getI() const { return i; } + int i; public: ProgramTest(); diff --git a/tests/state_test.cpp b/tests/state_test.cpp index effeca176..dc4502c08 100644 --- a/tests/state_test.cpp +++ b/tests/state_test.cpp @@ -28,7 +28,8 @@ #endif #include #include -#include +#include +#include #include #ifdef OROPKG_GEOMETRY @@ -50,12 +51,10 @@ void StateTest::setUp() { // ltc has a test object - gtc.methodFactory.registerObject("test", this->createMethodFactory() ); - gtc.commandFactory.registerObject("test", this->createCommandFactory() ); - gtc.dataFactory.registerObject("test", this->createDataSourceFactory() ); + gtc.addObject(this->createObject("test") ); - gtc.eventService.addEvent( "d_event", &d_event ); - gtc.eventService.addEvent( "b_event", &b_event ); + gtc.events()->addEvent( "d_event", &d_event ); + gtc.events()->addEvent( "b_event", &b_event ); i = 0; #ifdef OROPKG_GEOMETRY @@ -70,9 +69,6 @@ StateTest::tearDown() // if a test failed, we must still stop : SimulationThread::Instance()->stop(); gtask.stop(); - gtc.methodFactory.unregisterObject( "test" ); - gtc.commandFactory.unregisterObject( "test" ); - gtc.dataFactory.unregisterObject( "test" ); } @@ -94,57 +90,37 @@ void StateTest::reset() { } -MethodFactoryInterface* StateTest::createMethodFactory() +TaskObject* StateTest::createObject(string a) { - // Add the data of the EE: - TemplateMethodFactory< StateTest >* dat = - newMethodFactory( this ); - - dat->add( "assert", method( &StateTest::assertBool, - "Assert", "bool", "") ); - dat->add( "increase", method( &StateTest::increase, - "Return increasing i" ) ); - dat->add( "reset", method( &StateTest::reset, - "Reset i") ); - dat->add( "assertMsg", method( &StateTest::assertMsg, - "Assert message", "bool", "", "text", "text" ) ); - return dat; -} - -DataSourceFactoryInterface* StateTest::createDataSourceFactory() -{ - // Add the data of the EE: - TemplateDataSourceFactory< StateTest >* dat = - newDataSourceFactory( this ); - - dat->add( "isTrue", data( &StateTest::assertBool, - "Identity function", "bool", "") ); - dat->add( "i", data( &StateTest::i, - "Return the current number" ) ); - return dat; -} - -CommandFactoryInterface* StateTest::createCommandFactory() -{ - // Add the data of the EE: - TemplateCommandFactory< StateTest >* dat = - newCommandFactory( this ); - - dat->add( "instantDone", command( &StateTest::true_genCom, - &StateTest::true_gen, - "returns immediately") ); - dat->add( "neverDone", command( &StateTest::true_genCom, - &StateTest::false_gen, - "returns never") ); - dat->add( "instantNotDone", command( &StateTest::true_genCom, - &StateTest::true_gen, - "returns never", false ) ); - dat->add( "instantFail", command( &StateTest::false_genCom, - &StateTest::true_gen, - "fails immediately") ); - dat->add( "totalFail", command( &StateTest::false_genCom, - &StateTest::false_gen, - "fails in command and condition") ); + TaskObject* dat = new TaskObject(a); + + dat->methods()->addMethod( method( "assert", &StateTest::assertBool, this), + "Assert", "bool", "" ); + dat->methods()->addMethod( method( "increase", &StateTest::increase, this), + "Return increasing i" ); + dat->methods()->addMethod( method( "reset", &StateTest::reset, this), + "Reset i" ); + dat->methods()->addMethod( method( "assertMsg", &StateTest::assertMsg, this), + "Assert message", "bool", "", "text", "text" ); + dat->methods()->addMethod( method( "isTrue", &StateTest::assertBool, this), + "Identity function", "bool", "" ); + dat->methods()->addMethod( method( "i", &StateTest::getI, this), + "Return the current number" ); + dat->commands()->addCommand( command( "instantDone", &StateTest::true_genCom, + &StateTest::true_gen, this, gtc.engine()->commands()), + "returns immediately" ); + dat->commands()->addCommand( command( "neverDone", &StateTest::true_genCom, + &StateTest::false_gen, this, gtc.engine()->commands()), + "returns never" ); + dat->commands()->addCommand( command( "instantNotDone", &StateTest::true_genCom, + &StateTest::true_gen, this, gtc.engine()->commands(), false), + "returns never"); + dat->commands()->addCommand( command( "instantFail", &StateTest::false_genCom, + &StateTest::true_gen, this, gtc.engine()->commands()), + "fails immediately" ); + dat->commands()->addCommand( command( "totalFail", &StateTest::false_genCom, + &StateTest::false_gen, this, gtc.engine()->commands()), + "fails in command and condition" ); return dat; } @@ -790,9 +766,9 @@ void StateTest::doState( const std::string& prog, TaskContext* tc, bool test ) CPPUNIT_ASSERT_MESSAGE( "Error : State Context '"+sm->getName()+"' did not get activated.", sm->isActive() ); stringstream errormsg; int line = sm->getLineNumber(); - errormsg <<" in StateContext "+sm->getName() + errormsg <<" in StateMachine "+sm->getName() <<" in state "<< sm->currentState()->getName() - <<" on line " << line <<" of that StateContext:"<getText() ); int cnt = 1; while ( cnt++ " << sline << endl; - CPPUNIT_ASSERT_MESSAGE( "Runtime error encountered" + errormsg.str(), sm->inError() == false ); + CPPUNIT_ASSERT_MESSAGE( "Runtime error (inError() == true) encountered" + errormsg.str(), sm->inError() == false ); // check error status of all children: StateMachine::ChildList cl = sm->getChildren(); StateMachine::ChildList::iterator clit = cl.begin(); while( clit != cl.end() ) { stringstream cerrormsg; if ( (*clit)->currentState() ) - cerrormsg <<" in state "<<(*clit)->currentState()->getName()<< " on line " << (*clit)->getLineNumber() <<" of that StateContext."< " << sline << endl; + cerrormsg <<" in state "<<(*clit)->currentState()->getName()<< " on line " << (*clit)->getLineNumber() <<" of that StateMachine."< " << sline << endl; else - cerrormsg <<" (deactivated) on line " << (*clit)->getLineNumber() <<" of that StateContext."< " << sline << endl; - CPPUNIT_ASSERT_MESSAGE( "Runtime error encountered in child "+(*clit)->getName() + cerrormsg.str(), (*clit)->inError() == false ); + cerrormsg <<" (deactivated) on line " << (*clit)->getLineNumber() <<" of that StateMachine."< " << sline << endl; + CPPUNIT_ASSERT_MESSAGE( "Runtime error (inError() == true) encountered in child "+(*clit)->getName() + cerrormsg.str(), (*clit)->inError() == false ); ++clit; } } diff --git a/tests/state_test.hpp b/tests/state_test.hpp index 2d830593b..c0f1fcb89 100644 --- a/tests/state_test.hpp +++ b/tests/state_test.hpp @@ -55,7 +55,7 @@ class StateTest : public CppUnit::TestFixture SimulationActivity gtask; Event d_event; Event b_event; - MethodFactoryInterface* createMethodFactory(); + TaskObject* createObject(std::string); CommandFactoryInterface* createCommandFactory(); DataSourceFactoryInterface* createDataSourceFactory(); bool assertBool( bool ); @@ -71,6 +71,7 @@ class StateTest : public CppUnit::TestFixture bool false_gen() const { return false; } bool bool_gen( bool b ) const { return b; } + int getI() const {return i;} int i; public: StateTest(); diff --git a/tests/template_factory_test.cpp b/tests/template_factory_test.cpp index abc802c9b..bac5e3c06 100644 --- a/tests/template_factory_test.cpp +++ b/tests/template_factory_test.cpp @@ -22,7 +22,8 @@ #include #include #include -#include +#include +#include #include #include @@ -45,10 +46,9 @@ void Template_FactoryTest::setUp() { tc = new TaskContext( "root" ); - tc->methods()->registerObject("methods", this->createMethodFactory() ); - tc->methods()->registerObject("umethods", this->createUserMethodFactory() ); - tc->commands()->registerObject("commands", this->createCommandFactory() ); - tc->datasources()->registerObject("data", this->createDataSourceFactory() ); + tc->addObject( this->createMethodFactory() ); + tc->addObject( this->createUserMethodFactory() ); + tc->addObject( this->createCommandFactory() ); tc->events()->addEvent("FloatEvent", &t_event_float); tsim = new SimulationActivity(0.001, tc->engine() ); event_proc = new EventProcessor(); @@ -71,62 +71,44 @@ bool Template_FactoryTest::assertBool( bool b) { return b; } -MethodFactoryInterface* Template_FactoryTest::createMethodFactory() +TaskObject* Template_FactoryTest::createMethodFactory() { - TemplateMethodFactory< Template_FactoryTest >* dat = - newMethodFactory( this ); - - dat->add( "assert", method( &Template_FactoryTest::assertBool, "assert","b","bd") ); - - dat->add( "m0", method( &Template_FactoryTest::m0, "M0") ); - dat->add( "m1", method( &Template_FactoryTest::m1, "M1","a","ad") ); - dat->add( "m2", method( &Template_FactoryTest::m2, "M2","a","ad","a","ad") ); - dat->add( "m3", method( &Template_FactoryTest::m3, "M3","a","ad","a","ad","a","ad") ); - dat->add( "m4", method( &Template_FactoryTest::m4, "M4","a","ad","a","ad","a","ad","a","ad") ); + TaskObject* dat = new TaskObject("methods"); + + dat->methods()->addMethod( method("assert", &Template_FactoryTest::assertBool, this), "assert","b","bd"); + dat->methods()->addMethod( method("m0", &Template_FactoryTest::m0, this), "M0"); + dat->methods()->addMethod( method("m1", &Template_FactoryTest::m1, this), "M1","a","ad"); + dat->methods()->addMethod( method("m2", &Template_FactoryTest::m2, this), "M2","a","ad","a","ad"); + dat->methods()->addMethod( method("m3", &Template_FactoryTest::m3, this), "M3","a","ad","a","ad","a","ad"); + dat->methods()->addMethod( method("m4", &Template_FactoryTest::m4, this), "M4","a","ad","a","ad","a","ad","a","ad"); return dat; } -MethodFactoryInterface* Template_FactoryTest::createUserMethodFactory() +TaskObject* Template_FactoryTest::createUserMethodFactory() { - TemplateMethodFactory< Template_FactoryTest >* dat = - newMethodFactory( this ); - - dat->add( "umd", method( &Template_FactoryTest::umd, "umd", "D0", "D0") ); - dat->add( "umv", method( &Template_FactoryTest::umv, "umv", "V0", "V0") ); - dat->add( "umcv", method( &Template_FactoryTest::umcv, "umv", "V0", "V0") ); - dat->add( "umcrv", method( &Template_FactoryTest::umcrv, "umv", "V0", "V0") ); - dat->add( "umrv", method( &Template_FactoryTest::umrv, "umv", "V0", "V0") ); - return dat; -} - -DataSourceFactoryInterface* Template_FactoryTest::createDataSourceFactory() -{ - TemplateDataSourceFactory< Template_FactoryTest >* dat = - newDataSourceFactory( this ); - - dat->add( "d0", data( &Template_FactoryTest::d0, "d0") ); - dat->add( "d1", data( &Template_FactoryTest::d1, "d1","a","ad") ); - dat->add( "d2", data( &Template_FactoryTest::d2, "d2","a","ad","a","ad") ); - dat->add( "d3", data( &Template_FactoryTest::d3, "d3","a","ad","a","ad","a","ad") ); - dat->add( "d4", data( &Template_FactoryTest::d4, "d4","a","ad","a","ad","a","ad","a","ad") ); + TaskObject* dat = new TaskObject("umethods"); + dat->methods()->addMethod( method("umd", &Template_FactoryTest::umd, this), "umd", "D0", "D0"); + dat->methods()->addMethod( method("umv", &Template_FactoryTest::umv, this), "umv", "V0", "V0"); + dat->methods()->addMethod( method("umcv", &Template_FactoryTest::umcv, this), "umv", "V0", "V0"); + dat->methods()->addMethod( method("umcrv", &Template_FactoryTest::umcrv, this), "umv", "V0", "V0"); + dat->methods()->addMethod( method("umrv", &Template_FactoryTest::umrv, this), "umv", "V0", "V0"); return dat; } -CommandFactoryInterface* Template_FactoryTest::createCommandFactory() +TaskObject* Template_FactoryTest::createCommandFactory() { - TemplateCommandFactory< Template_FactoryTest >* dat = - newCommandFactory( this ); - - dat->add( "c00", command( &Template_FactoryTest::cd0, &Template_FactoryTest::cn0, "c0d") ); - dat->add( "c10", command( &Template_FactoryTest::cd1, &Template_FactoryTest::cn0, "c1d","a","ad") ); - dat->add( "c11", command( &Template_FactoryTest::cd1, &Template_FactoryTest::cn1, "c1d","a","ad") ); - dat->add( "c20", command( &Template_FactoryTest::cd2, &Template_FactoryTest::cn0, "c2d","a","ad","a","ad") ); - dat->add( "c21", command( &Template_FactoryTest::cd2, &Template_FactoryTest::cn1, "c2d","a","ad","a","ad") ); - dat->add( "c22", command( &Template_FactoryTest::cd2, &Template_FactoryTest::cn2, "c2d","a","ad","a","ad") ); - dat->add( "c30", command( &Template_FactoryTest::cd3, &Template_FactoryTest::cn0, "c3d","a","ad","a","ad","a","ad") ); - dat->add( "c31", command( &Template_FactoryTest::cd3, &Template_FactoryTest::cn1, "c3d","a","ad","a","ad","a","ad") ); - dat->add( "c33", command( &Template_FactoryTest::cd3, &Template_FactoryTest::cn3, "c3d","a","ad","a","ad","a","ad") ); + TaskObject* dat = new TaskObject("commands"); + + dat->commands()->addCommand( command("c00", &Template_FactoryTest::cd0, &Template_FactoryTest::cn0, this, tc->engine()->commands() ), "c0d"); + dat->commands()->addCommand( command("c10", &Template_FactoryTest::cd1, &Template_FactoryTest::cn0, this, tc->engine()->commands() ), "c1d","a","ad"); + dat->commands()->addCommand( command("c11", &Template_FactoryTest::cd1, &Template_FactoryTest::cn1, this, tc->engine()->commands() ), "c1d","a","ad"); + dat->commands()->addCommand( command("c20", &Template_FactoryTest::cd2, &Template_FactoryTest::cn0, this, tc->engine()->commands() ), "c2d","a","ad","a","ad"); + dat->commands()->addCommand( command("c21", &Template_FactoryTest::cd2, &Template_FactoryTest::cn1, this, tc->engine()->commands() ), "c2d","a","ad","a","ad"); + dat->commands()->addCommand( command("c22", &Template_FactoryTest::cd2, &Template_FactoryTest::cn2, this, tc->engine()->commands() ), "c2d","a","ad","a","ad"); + dat->commands()->addCommand( command("c30", &Template_FactoryTest::cd3, &Template_FactoryTest::cn0, this, tc->engine()->commands() ), "c3d","a","ad","a","ad","a","ad"); + dat->commands()->addCommand( command("c31", &Template_FactoryTest::cd3, &Template_FactoryTest::cn1, this, tc->engine()->commands() ), "c3d","a","ad","a","ad","a","ad"); + dat->commands()->addCommand( command("c33", &Template_FactoryTest::cd3, &Template_FactoryTest::cn3, this, tc->engine()->commands() ), "c3d","a","ad","a","ad","a","ad"); return dat; } @@ -219,38 +201,6 @@ void Template_FactoryTest::testUserMethods() executePrograms( pg_list ); } -void Template_FactoryTest::testData() -{ - string prog = string("program x { ") - +" var double r = 0.0\n" - +" set r = data.d0\n" - +" set r = data.d0()\n" - +" do methods.assert( r == 1.0 )\n" - +" set r = data.d1(1)\n" - +" do methods.assert( r == 2.0 )\n" - +" set r = data.d2(1, 1.0)\n" - +" do methods.assert( r == 3.0 )\n" - +" set r = data.d3(1, 1.0, true)\n" - +" do methods.assert( r == 4.0 )\n" - +" set r = data.d4(1, 1.0, true, \"hello\")\n" - +" do methods.assert( r == 5.0 )\n" - +"}"; - Parser::ParsedPrograms pg_list; - try { - pg_list = parser.parseProgram( prog, tc); - } - catch( const file_parse_exception& exc ) - { - CPPUNIT_ASSERT_MESSAGE(exc.what(), false ); - } - if ( pg_list.empty() ) - { - CPPUNIT_ASSERT( false ); - } - // execute - executePrograms( pg_list ); -} - void Template_FactoryTest::testCommands() { string prog = string("program x { ") diff --git a/tests/template_factory_test.hpp b/tests/template_factory_test.hpp index 8903565ec..f1bef4dfc 100644 --- a/tests/template_factory_test.hpp +++ b/tests/template_factory_test.hpp @@ -37,7 +37,6 @@ class Template_FactoryTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE( Template_FactoryTest ); CPPUNIT_TEST( testMethods ); CPPUNIT_TEST( testUserMethods ); - CPPUNIT_TEST( testData ); CPPUNIT_TEST( testCommands ); CPPUNIT_TEST( testManual ); CPPUNIT_TEST( testEventC ); @@ -47,10 +46,9 @@ class Template_FactoryTest : public CppUnit::TestFixture TaskContext* tc; ActivityInterface* tsim; CommandProcessor processor; - MethodFactoryInterface* createMethodFactory(); - MethodFactoryInterface* createUserMethodFactory(); - DataSourceFactoryInterface* createDataSourceFactory(); - CommandFactoryInterface* createCommandFactory(); + TaskObject* createMethodFactory(); + TaskObject* createUserMethodFactory(); + TaskObject* createCommandFactory(); ORO_CoreLib::Event t_event_float; int float_listener(float a, float b); diff --git a/tests/types_test.cpp b/tests/types_test.cpp index 7a0fad7f7..c5a08e6e2 100644 --- a/tests/types_test.cpp +++ b/tests/types_test.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #ifdef OROPKG_GEOMETRY @@ -39,7 +39,7 @@ void TypesTest::setUp() { tc = new TaskContext( "root" ); - tc->methodFactory.registerObject("test", this->createMethodFactory() ); + tc->addObject( this->createMethodFactory() ); tsim = new SimulationActivity( 0.001, tc->engine() ); #ifdef OROPKG_GEOMETRY @@ -66,23 +66,20 @@ bool TypesTest::assertMsg( bool b, const std::string& msg) { } - MethodFactoryInterface* TypesTest::createMethodFactory() + TaskObject* TypesTest::createMethodFactory() { - // Add the data of the EE: - TemplateMethodFactory< TypesTest >* dat = - newMethodFactory( this ); - - dat->add( "assert", method( &TypesTest::assertBool, - "Assert", "bool", "") ); - dat->add( "assertMsg", method( &TypesTest::assertMsg, - "Assert message", "bool", "", "text", "text" ) ); + TaskObject* to = new TaskObject("test"); + to->methods()->addMethod( method("assert", &TypesTest::assertBool, this), + "Assert", "bool", ""); + to->methods()->addMethod( method("assertMsg", &TypesTest::assertMsg, this), + "Assert message", "bool", "", "text", "text" ); #ifdef OROPKG_GEOMETRY - dat->add( "equalFrames", method( &TypesTest::equalFrames, - "Assert equal frames", "f1", "", "f2", "" ) ); - dat->add( "equalVectors", method( &TypesTest::equalVectors, - "Assert equal vectors", "v1", "", "v2", "" ) ); + to->methods()->addMethod( method("equalFrames", &TypesTest::equalFrames, this), + "Assert equal frames", "f1", "", "f2", "" ); + to->methods()->addMethod( method("equalVectors", &TypesTest::equalVectors, this), + "Assert equal vectors", "v1", "", "v2", "" ); #endif - return dat; + return to; } #ifdef OROPKG_GEOMETRY @@ -343,8 +340,8 @@ void TypesTest::testProperties() #ifdef OROPKG_GEOMETRY Property pf("Frame","", Frame::Identity() ); Property pr("Rotation","", Rotation::RPY(0.0, 45.0, 60.0) ); - tc->attributeRepository.addProperty( &pf ); - tc->attributeRepository.addProperty( &pr ); + tc->properties()->addProperty( &pf ); + tc->properties()->addProperty( &pr ); pb.value().add( &pf ); pb.value().add( &pr ); #endif @@ -353,10 +350,10 @@ void TypesTest::testProperties() pb.value().add( &pd3 ); pb.value().add( &pb ); // yep, recursive ! - tc->attributeRepository.addProperty( &pd1 ); - tc->attributeRepository.addProperty( &pd2 ); - tc->attributeRepository.addProperty( &pd3 ); - tc->attributeRepository.addProperty( &pb ); + tc->properties()->addProperty( &pd1 ); + tc->properties()->addProperty( &pd2 ); + tc->properties()->addProperty( &pd3 ); + tc->properties()->addProperty( &pb ); Parser::ParsedPrograms pg_list; try { diff --git a/tests/types_test.hpp b/tests/types_test.hpp index 8d49425cc..f71405a80 100644 --- a/tests/types_test.hpp +++ b/tests/types_test.hpp @@ -49,7 +49,7 @@ class TypesTest : public CppUnit::TestFixture Parser parser; TaskContext* tc; ActivityInterface* tsim; - MethodFactoryInterface* createMethodFactory(); + TaskObject* createMethodFactory(); bool assertBool( bool ); #ifdef OROPKG_GEOMETRY bool equalFrames(const Frame& f1, Frame& f2);