FunctionFactory.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Tue Dec 21 22:43:08 CET 2004 FunctionFactory.cxx
3 
4  FunctionFactory.cxx - description
5  -------------------
6  begin : Tue December 21 2004
7  copyright : (C) 2004 Peter Soetens
8  email : peter.soetens@mech.kuleuven.ac.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 #include "FunctionFactory.hpp"
40 
41 #include "../ExecutionEngine.hpp"
42 #include "../internal/GlobalEngine.hpp"
43 #include "CommandComposite.hpp"
44 #include "CommandBinary.hpp"
45 #include "CallFunction.hpp"
46 #include "CmdFunction.hpp"
47 #include "ConditionComposite.hpp"
48 #include "TryCommand.hpp"
49 #include <sstream>
50 #include <map>
51 #include <string>
52 #include "../internal/mystd.hpp"
53 #include <PropertyBag.hpp>
54 #include <Property.hpp>
55 #include "../Attribute.hpp"
56 #include "parse_exception.hpp"
57 #include "../internal/DataSourceCommand.hpp"
58 #include "../FactoryExceptions.hpp"
59 #include "../../Handle.hpp"
60 
61 
62 namespace RTT {
63  using namespace detail;
64 
66  : public DataSource<SendStatus>
67  {
69  public:
70  typedef boost::intrusive_ptr<CmdFunctionWrapper> shared_ptr;
71 
73  : alias(ds)
74  {}
75 
77 
78  bool evaluate() const {
79  return alias->evaluate();
80  }
81 
83  {
84  return alias->get();
85  }
86 
88  {
89  return alias->value();
90  }
91 
93  {
94  return alias->rvalue();
95  }
96 
97  virtual void reset() { /* nop, don't reset ! */ }
98 
99  virtual CmdFunctionWrapper* clone() const {
100  return new CmdFunctionWrapper(alias.get());
101  }
102  virtual CmdFunctionWrapper* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const {
103  return new CmdFunctionWrapper(alias->copy(alreadyCloned) );
104  }
105  };
106 
107 
109  : func(pi), proc(procs) {}
110 
111  std::string FunctionFactory::resultType() const {
112  return func->getResult() ? func->getResult()->getDataSource()->getTypeName() : "void";
113  }
114 
115  std::string FunctionFactory::getName() const {
116  return func->getName();
117  }
118 
119  std::string FunctionFactory::description() const {
120  return "Orocos Program Script Function.";
121  }
122 
123  std::vector< ArgumentDescription > FunctionFactory::getArgumentList() const
124  {
125  std::vector<AttributeBase*> origlist = func->getArguments();
126  std::vector< ArgumentDescription > mlist;
127  for ( std::vector<AttributeBase*>::const_iterator it = origlist.begin();
128  it != origlist.end(); ++it)
129  mlist.push_back( ArgumentDescription( "arg", "Function Argument", (*it)->getDataSource()->getType() ) );
130  return mlist;
131  }
132 
133  unsigned int FunctionFactory::arity( ) const
134  {
135  return func->getArguments().size();
136  }
137 
138  unsigned int FunctionFactory::collectArity( ) const
139  {
140  return func->getResult() ? 1 : 0;
141  }
142 
143  const types::TypeInfo* FunctionFactory::getArgumentType(unsigned int arg) const
144  {
145  if (arg == 0 ) {
146  if ( func->getResult() )
147  return func->getResult()->getDataSource()->getTypeInfo();
148  else
150  }
151  std::vector<AttributeBase*> origlist = func->getArguments();
152  if ( arg > origlist.size() )
153  return 0;
154  return origlist[arg - 1]->getDataSource()->getTypeInfo();
155  }
156 
157  const types::TypeInfo* FunctionFactory::getCollectType(unsigned int arg) const {
158  if (arg == 1 && collectArity() )
159  return func->getResult()->getDataSource()->getTypeInfo();
160  return 0;
161  }
162 
164  const std::vector<DataSourceBase::shared_ptr>& args
165  , ExecutionEngine* caller
166  ) const {
167  bool issend = false;
168  return produceHelper(args, caller, issend);
169  }
170 
172  const std::vector<DataSourceBase::shared_ptr>& args
173  , ExecutionEngine* caller, bool issend
174  ) const {
175  // check if correct number of args :
176  boost::shared_ptr<ProgramInterface> orig = func;
177  std::vector<AttributeBase*> origlist = orig->getArguments();
178  if ( args.size() != origlist.size() )
179  throw wrong_number_of_args_exception( origlist.size(), args.size() );
180 
181  // make a semi-deep copy of the function :
182  // copy the local variables, but clone() the remote datasources.
183  std::map<const DataSourceBase*, DataSourceBase*> replacementdss;
184  assert( orig );
185  boost::shared_ptr<ProgramInterface> fcopy( orig->copy( replacementdss ) );
186  assert( fcopy );
187  // create commands that init all the args :
188  CommandComposite* icom= new CommandComposite();
189 
190  // get the correct pointers.
191  origlist = fcopy->getArguments();
192  std::vector<DataSourceBase::shared_ptr>::const_iterator dit = args.begin();
193  std::vector<AttributeBase*>::const_iterator tit = origlist.begin();
194 #ifndef ORO_EMBEDDED
195  try {
196  for (; dit != args.end(); ++dit, ++tit)
197  icom->add( (*tit)->getDataSource()->updateAction( dit->get() ) );
198  }
199  catch( const bad_assignment& ) {
200  delete icom;
201  int parnb = (dit - args.begin()) + 1;
202  throw wrong_types_of_args_exception(parnb, (*tit)->getDataSource()->getType() ,(*dit)->getType() );
203  }
204 #else
205  for (; dit != args.end(); ++dit, ++tit) {
206  ActionInterface* ret = (*tit)->getDataSource()->updateAction( dit->get() );
207  if (ret)
208  icom->add( ret );
209  else {
210  delete icom;
211  return 0;
212  }
213  }
214 #endif
215 
216  // the args of the copy can now safely be removed (saves memory):
217  //fcopy->clearArguments();
218 
219  if (!caller)
220  caller = GlobalEngine::Instance();
221  if (issend == false) {
222  // the command gets ownership of the new function :
223  // this command is a DataSourceBase...
224  AttributeBase* ar= fcopy->getResult();
225  if (ar)
226  return ar->getDataSource()->getTypeInfo()->buildActionAlias( new CallFunction( icom, fcopy, proc, caller ), ar->getDataSource()).get();
227  else // void case, returns result of runFunction (backwards compatibility).
228  return new DataSourceCommand( new CallFunction( icom, fcopy, proc, caller ) );
229  } else {
230  return new CmdFunction( icom, fcopy, proc, caller );
231  }
232  }
233 
236  }
237  base::DataSourceBase::shared_ptr FunctionFactory::produceSend(const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* caller
238  ) const {
239  return produceHelper(args, caller, true);
240  }
241  base::DataSourceBase::shared_ptr FunctionFactory::produceCollect(const std::vector<base::DataSourceBase::shared_ptr>& args, DataSource<bool>::shared_ptr blocking
242  ) const {
243  if (blocking->get() == true )
244  throw no_asynchronous_operation_exception("Blocking call to collect() not yet implemented for scripting functions. Use collectIfDone().");
245 
246  if (args.size() >= 1) {
247  if ( dynamic_cast<CmdFunction* > (args[0].get()) != 0 ) {
248  // The CmdFunction : wrap it and return it
249  // wrapping is necessary because we don't want to propagate reset()
250  return new CmdFunctionWrapper( dynamic_cast<CmdFunction*>(args[0].get()) );
251  } else if ( dynamic_cast<CmdFunctionWrapper* > (args[0].get()) != 0 ) {
252  // Return argument.
253  return args[0];
254  } else {
255  log(Error) <<"FunctionFactory: Please define your SendHandle with 'var SendHandle' for script functions." <<endlog();
256  return 0;
257  }
258 
259  }
260  log(Error) <<"FunctionFactory: Must provide an argument in produceCollect." <<endlog();
261  return 0;
262  }
263 #ifdef ORO_SIGNALLING_OPERATIONS
264  Handle FunctionFactory::produceSignal(base::ActionInterface* func, const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* subscriber
265  ) const {
266  throw no_asynchronous_operation_exception("Signal not yet implemented for scripting functions.");
267  return Handle();
268  }
269 #endif
270 }
271 
272 
const types::TypeInfo * getCollectType(unsigned int arg) const
virtual result_t get() const =0
unsigned int collectArity() const
virtual CmdFunctionWrapper * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned) const
base::DataSourceBase::shared_ptr produceCollect(const std::vector< base::DataSourceBase::shared_ptr > &args, internal::DataSource< bool >::shared_ptr blocking) const
base::DataSourceBase::shared_ptr produceHelper(const std::vector< base::DataSourceBase::shared_ptr > &args, ExecutionEngine *caller, bool issend) const
virtual CmdFunctionWrapper * clone() const
virtual DataSourceBase::shared_ptr getDataSource() const =0
boost::shared_ptr< ProgramInterface > ProgramInterfacePtr
DataSource< SendStatus >::result_t value() const
virtual DataSource< T > * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned) const =0
const types::TypeInfo * getArgumentType(unsigned int arg) const
static RTT_API ExecutionEngine * Instance()
Description of one Argument of a Command.
virtual const_reference_t rvalue() const =0
Based on the software pattern &#39;command&#39;, this interface allows execution of action objects...
base::DataSourceBase::shared_ptr produce(const std::vector< base::DataSourceBase::shared_ptr > &args, ExecutionEngine *caller) const
std::vector< ArgumentDescription > getArgumentList() const
boost::intrusive_ptr< CmdFunctionWrapper > shared_ptr
DataSource< SendStatus >::shared_ptr alias
static const types::TypeInfo * getTypeInfo()
base::DataSourceBase::shared_ptr produceSend(const std::vector< base::DataSourceBase::shared_ptr > &args, ExecutionEngine *caller) const
base::DataSourceBase::shared_ptr produceHandle() const
virtual void add(base::ActionInterface *com)
virtual result_t value() const =0
boost::intrusive_ptr< DataSourceBase > shared_ptr
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
DataSource< SendStatus >::const_reference_t rvalue() const
CmdFunctionWrapper(DataSource< SendStatus > *ds)
static Logger & log()
Definition: Logger.hpp:350
The Handle holds the information, and allows manipulation, of a connection between a internal::Signal...
Definition: Handle.hpp:66
Based on the software pattern &#39;composite&#39;, this class RTT_SCRIPTING_API allows composing command obje...
static Logger::LogFunction endlog()
Definition: Logger.hpp:362
FunctionFactory(ProgramInterfacePtr func, ExecutionEngine *procs)
virtual bool evaluate() const


rtt
Author(s): RTT Developers
autogenerated on Tue Jun 25 2019 19:33:24