Orocos Real-Time Toolkit  2.8.3
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 "ConditionComposite.hpp"
47 #include "TryCommand.hpp"
48 #include <sstream>
49 #include <map>
50 #include <string>
51 #include "../internal/mystd.hpp"
52 #include <PropertyBag.hpp>
53 #include <Property.hpp>
54 #include "../Attribute.hpp"
55 #include "parse_exception.hpp"
56 #include "../internal/DataSourceCommand.hpp"
57 #include "../FactoryExceptions.hpp"
58 #include "../../Handle.hpp"
59 
60 
61 namespace RTT {
62  using namespace detail;
63 
64 
66  : func(pi), proc(procs) {}
67 
68  std::string FunctionFactory::resultType() const {
69  return func->getResult() ? func->getResult()->getDataSource()->getTypeName() : "void";
70  }
71 
72  std::string FunctionFactory::getName() const {
73  return func->getName();
74  }
75 
76  std::string FunctionFactory::description() const {
77  return "Orocos Program Script Function.";
78  }
79 
80  std::vector< ArgumentDescription > FunctionFactory::getArgumentList() const
81  {
82  std::vector<AttributeBase*> origlist = func->getArguments();
83  std::vector< ArgumentDescription > mlist;
84  for ( std::vector<AttributeBase*>::const_iterator it = origlist.begin();
85  it != origlist.end(); ++it)
86  mlist.push_back( ArgumentDescription( "arg", "Function Argument", (*it)->getDataSource()->getType() ) );
87  return mlist;
88  }
89 
90  unsigned int FunctionFactory::arity( ) const
91  {
92  return func->getArguments().size();
93  }
94 
95  unsigned int FunctionFactory::collectArity( ) const
96  {
97  return func->getResult() ? 1 : 0;
98  }
99 
100  const types::TypeInfo* FunctionFactory::getArgumentType(unsigned int arg) const
101  {
102  if (arg == 0 ) {
103  if ( func->getResult() )
104  return func->getResult()->getDataSource()->getTypeInfo();
105  else
107  }
108  std::vector<AttributeBase*> origlist = func->getArguments();
109  if ( arg > origlist.size() )
110  return 0;
111  return origlist[arg - 1]->getDataSource()->getTypeInfo();
112  }
113 
114  const types::TypeInfo* FunctionFactory::getCollectType(unsigned int arg) const {
115  if (arg == 1 && collectArity() )
116  return func->getResult()->getDataSource()->getTypeInfo();
117  return 0;
118  }
119 
121  const std::vector<DataSourceBase::shared_ptr>& args
122  , ExecutionEngine* caller
123  ) const {
124 
125  // check if correct number of args :
126  boost::shared_ptr<ProgramInterface> orig = func;
127  std::vector<AttributeBase*> origlist = orig->getArguments();
128  if ( args.size() != origlist.size() )
129  throw wrong_number_of_args_exception( origlist.size(), args.size() );
130 
131  // make a semi-deep copy of the function :
132  // copy the local variables, but clone() the remote datasources.
133  std::map<const DataSourceBase*, DataSourceBase*> replacementdss;
134  assert( orig );
135  boost::shared_ptr<ProgramInterface> fcopy( orig->copy( replacementdss ) );
136  assert( fcopy );
137  // create commands that init all the args :
138  CommandComposite* icom= new CommandComposite();
139 
140  // get the correct pointers.
141  origlist = fcopy->getArguments();
142  std::vector<DataSourceBase::shared_ptr>::const_iterator dit = args.begin();
143  std::vector<AttributeBase*>::const_iterator tit = origlist.begin();
144 #ifndef ORO_EMBEDDED
145  try {
146  for (; dit != args.end(); ++dit, ++tit)
147  icom->add( (*tit)->getDataSource()->updateAction( dit->get() ) );
148  }
149  catch( const bad_assignment& ) {
150  delete icom;
151  int parnb = (dit - args.begin()) + 1;
152  throw wrong_types_of_args_exception(parnb, (*tit)->getDataSource()->getType() ,(*dit)->getType() );
153  }
154 #else
155  for (; dit != args.end(); ++dit, ++tit) {
156  ActionInterface* ret = (*tit)->getDataSource()->updateAction( dit->get() );
157  if (ret)
158  icom->add( ret );
159  else {
160  delete icom;
161  return 0;
162  }
163  }
164 #endif
165 
166  // the args of the copy can now safely be removed (saves memory):
167  //fcopy->clearArguments();
168 
169  // the command gets ownership of the new function :
170  // this command is a DataSourceBase...
171  AttributeBase* ar= fcopy->getResult();
172  if (!caller)
173  caller = GlobalEngine::Instance();
174  if (ar)
175  return ar->getDataSource()->getTypeInfo()->buildActionAlias( new CallFunction( icom, fcopy, proc, caller ), ar->getDataSource()).get();
176  else // void case, returns result of runFunction (backwards compatibility).
177  return new DataSourceCommand( new CallFunction( icom, fcopy, proc, caller ) );
178  }
179 
181  throw no_asynchronous_operation_exception("Send not yet implemented for scripting functions.");
182  return 0;
183  }
184  base::DataSourceBase::shared_ptr FunctionFactory::produceSend(const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* caller
185  ) const {
186  throw no_asynchronous_operation_exception("Send not yet implemented for scripting functions.");
187  return 0;
188  }
189  base::DataSourceBase::shared_ptr FunctionFactory::produceCollect(const std::vector<base::DataSourceBase::shared_ptr>& args, DataSource<bool>::shared_ptr blocking
190  ) const {
191  if (args.size() != 2) {
192  log(Error) <<"Invalid number of arguments. Script functions can only collect the return value." <<endlog();
193  }
194  throw no_asynchronous_operation_exception("Send not yet implemented for scripting functions.");
195  return 0;
196  }
197 #ifdef ORO_SIGNALLING_OPERATIONS
198  Handle FunctionFactory::produceSignal(base::ActionInterface* func, const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* subscriber
199  ) const {
200  throw no_asynchronous_operation_exception("Signal not yet implemented for scripting functions.");
201  return Handle();
202  }
203 #endif
204 }
205 
206 
DataSource is a base class representing a generic way to read data of type T.
Definition: DataSource.hpp:94
std::string resultType() const
Return the result (return) type of this operation.
const types::TypeInfo * getCollectType(unsigned int arg) const
Returns the type information of the n&#39;th collectable argument.
std::string getName() const
Returns the name of this operation.
unsigned int collectArity() const
Returns the number of collectable arguments of this operation&#39;s function.
base::DataSourceBase::shared_ptr produceCollect(const std::vector< base::DataSourceBase::shared_ptr > &args, internal::DataSource< bool >::shared_ptr blocking) const
Create a DataSource for collecting the results of a Send.
virtual DataSourceBase::shared_ptr getDataSource() const =0
Return a internal::DataSource which contains the same contents.
boost::shared_ptr< ProgramInterface > ProgramInterfacePtr
This exception is thrown if the target and source type of an assignment of a DataSource with a base::...
Definition: DataSource.hpp:62
An execution engine serialises (executes one after the other) the execution of all commands...
const types::TypeInfo * getArgumentType(unsigned int arg) const
Returns the type information of the n&#39;th argument, with argument zero being the return value...
An attribute is a minimalistic, named placeholder for data.
static const types::TypeInfo * getTypeInfo()
Return the typeinfo object.
static RTT_API ExecutionEngine * Instance()
This is an overloaded member function, provided for convenience. It differs from the above function o...
Description of one Argument of a Command.
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
Create a DataSource for a given callable operation.
std::string description() const
Returns the description of this operation.
A class for representing a user type, and which can build instances of that type. ...
Definition: TypeInfo.hpp:66
std::vector< ArgumentDescription > getArgumentList() const
Get a description of the desired arguments in the ArgumentDescription format.
unsigned int arity() const
Returns the arity (number of arguments) of this operation.
base::DataSourceBase::shared_ptr produceSend(const std::vector< base::DataSourceBase::shared_ptr > &args, ExecutionEngine *caller) const
Create a DataSource for a given send operation.
base::DataSourceBase::shared_ptr produceHandle() const
Create an empty SendHandle object for this operation.
A class that wraps a Command in a internal::DataSource<bool> interface.
virtual void add(base::ActionInterface *com)
add a command to the vect
Exception thrown when a factory is requested to create an object, but a wrong argument type was given...
Exception thrown when a factory is requested to create an object but the wrong number of arguments wa...
boost::intrusive_ptr< DataSourceBase > shared_ptr
Use this type to store a pointer to a DataSourceBase.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:51
An action which calls a FunctionFraph for execution in a ExecutionEngine.
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...
Exception thrown when a factory is requested to produce an asynchronous object while it is not availa...
FunctionFactory(ProgramInterfacePtr func, ExecutionEngine *procs)