Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "FunctionFactory.hpp"
00040
00041 #include "../ExecutionEngine.hpp"
00042 #include "../internal/GlobalEngine.hpp"
00043 #include "CommandComposite.hpp"
00044 #include "CommandBinary.hpp"
00045 #include "CallFunction.hpp"
00046 #include "ConditionComposite.hpp"
00047 #include "TryCommand.hpp"
00048 #include <sstream>
00049 #include <map>
00050 #include <string>
00051 #include "../internal/mystd.hpp"
00052 #include <PropertyBag.hpp>
00053 #include <Property.hpp>
00054 #include "../Attribute.hpp"
00055 #include "parse_exception.hpp"
00056 #include "../internal/DataSourceCommand.hpp"
00057 #include "../FactoryExceptions.hpp"
00058 #include "../../Handle.hpp"
00059
00060
00061 namespace RTT {
00062 using namespace detail;
00063
00064
00065 FunctionFactory::FunctionFactory(ProgramInterfacePtr pi, ExecutionEngine* procs)
00066 : func(pi), proc(procs) {}
00067
00068 std::string FunctionFactory::resultType() const {
00069 return func->getResult() ? func->getResult()->getDataSource()->getTypeName() : "void";
00070 }
00071
00072 std::string FunctionFactory::getName() const {
00073 return func->getName();
00074 }
00075
00076 std::string FunctionFactory::description() const {
00077 return "Orocos Program Script Function.";
00078 }
00079
00080 std::vector< ArgumentDescription > FunctionFactory::getArgumentList() const
00081 {
00082 std::vector<AttributeBase*> origlist = func->getArguments();
00083 std::vector< ArgumentDescription > mlist;
00084 for ( std::vector<AttributeBase*>::const_iterator it = origlist.begin();
00085 it != origlist.end(); ++it)
00086 mlist.push_back( ArgumentDescription( "arg", "Function Argument", (*it)->getDataSource()->getType() ) );
00087 return mlist;
00088 }
00089
00090 unsigned int FunctionFactory::arity( ) const
00091 {
00092 return func->getArguments().size();
00093 }
00094
00095 unsigned int FunctionFactory::collectArity( ) const
00096 {
00097 return func->getResult() ? 1 : 0;
00098 }
00099
00100 const types::TypeInfo* FunctionFactory::getArgumentType(unsigned int arg) const
00101 {
00102 if (arg == 0 ) {
00103 if ( func->getResult() )
00104 return func->getResult()->getDataSource()->getTypeInfo();
00105 else
00106 return DataSourceTypeInfo<void>::getTypeInfo();
00107 }
00108 std::vector<AttributeBase*> origlist = func->getArguments();
00109 if ( arg > origlist.size() )
00110 return 0;
00111 return origlist[arg - 1]->getDataSource()->getTypeInfo();
00112 }
00113
00114 const types::TypeInfo* FunctionFactory::getCollectType(unsigned int arg) const {
00115 if (arg == 1 && collectArity() )
00116 return func->getResult()->getDataSource()->getTypeInfo();
00117 return 0;
00118 }
00119
00120 DataSourceBase::shared_ptr FunctionFactory::produce(
00121 const std::vector<DataSourceBase::shared_ptr>& args
00122 , ExecutionEngine* caller
00123 ) const {
00124
00125
00126 boost::shared_ptr<ProgramInterface> orig = func;
00127 std::vector<AttributeBase*> origlist = orig->getArguments();
00128 if ( args.size() != origlist.size() )
00129 throw wrong_number_of_args_exception( origlist.size(), args.size() );
00130
00131
00132
00133 std::map<const DataSourceBase*, DataSourceBase*> replacementdss;
00134 assert( orig );
00135 boost::shared_ptr<ProgramInterface> fcopy( orig->copy( replacementdss ) );
00136 assert( fcopy );
00137
00138 CommandComposite* icom= new CommandComposite();
00139
00140
00141 origlist = fcopy->getArguments();
00142 std::vector<DataSourceBase::shared_ptr>::const_iterator dit = args.begin();
00143 std::vector<AttributeBase*>::const_iterator tit = origlist.begin();
00144 #ifndef ORO_EMBEDDED
00145 try {
00146 for (; dit != args.end(); ++dit, ++tit)
00147 icom->add( (*tit)->getDataSource()->updateAction( dit->get() ) );
00148 }
00149 catch( const bad_assignment& ) {
00150 delete icom;
00151 int parnb = (dit - args.begin()) + 1;
00152 throw wrong_types_of_args_exception(parnb, (*tit)->getDataSource()->getType() ,(*dit)->getType() );
00153 }
00154 #else
00155 for (; dit != args.end(); ++dit, ++tit) {
00156 ActionInterface* ret = (*tit)->getDataSource()->updateAction( dit->get() );
00157 if (ret)
00158 icom->add( ret );
00159 else {
00160 delete icom;
00161 return 0;
00162 }
00163 }
00164 #endif
00165
00166
00167
00168
00169
00170
00171 AttributeBase* ar= fcopy->getResult();
00172 if (!caller)
00173 caller = GlobalEngine::Instance();
00174 if (ar)
00175 return ar->getDataSource()->getTypeInfo()->buildActionAlias( new CallFunction( icom, fcopy, proc, caller ), ar->getDataSource()).get();
00176 else
00177 return new DataSourceCommand( new CallFunction( icom, fcopy, proc, caller ) );
00178 }
00179
00180 base::DataSourceBase::shared_ptr FunctionFactory::produceHandle() const {
00181 throw no_asynchronous_operation_exception("Send not yet implemented for scripting functions.");
00182 return 0;
00183 }
00184 base::DataSourceBase::shared_ptr FunctionFactory::produceSend(const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* caller
00185 ) const {
00186 throw no_asynchronous_operation_exception("Send not yet implemented for scripting functions.");
00187 return 0;
00188 }
00189 base::DataSourceBase::shared_ptr FunctionFactory::produceCollect(const std::vector<base::DataSourceBase::shared_ptr>& args, DataSource<bool>::shared_ptr blocking
00190 ) const {
00191 if (args.size() != 2) {
00192 log(Error) <<"Invalid number of arguments. Script functions can only collect the return value." <<endlog();
00193 }
00194 throw no_asynchronous_operation_exception("Send not yet implemented for scripting functions.");
00195 return 0;
00196 }
00197 #ifdef ORO_SIGNALLING_OPERATIONS
00198 Handle FunctionFactory::produceSignal(base::ActionInterface* func, const std::vector<base::DataSourceBase::shared_ptr>& args
00199 ) const {
00200 throw no_asynchronous_operation_exception("Send not yet implemented for scripting functions.");
00201 return Handle();
00202 }
00203 #endif
00204 }
00205
00206