Orocos Real-Time Toolkit  2.9.0
OperationCaller.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: FMTC do nov 2 13:06:07 CET 2006 OperationCaller.hpp
3 
4  OperationCaller.hpp - description
5  -------------------
6  begin : do november 02 2006
7  copyright : (C) 2006 FMTC
8  email : peter.soetens@fmtc.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 #ifndef ORO_TASK_OPERATION_CALLER_HPP
40 #define ORO_TASK_OPERATION_CALLER_HPP
41 
42 #include <string>
43 #include <boost/function.hpp>
45 #ifdef ORO_TEST_OPERATION_CALLER
46 #include "internal/UnMember.hpp"
48 #endif
51 #include "Logger.hpp"
52 #include "Service.hpp"
53 #ifdef ORO_REMOTING
54 #include "OperationInterface.hpp"
56 #endif
57 
58 namespace RTT
59 {
81  template<class SignatureT>
83  : public internal::InvokerSignature<boost::function_traits<SignatureT>::arity,
84  SignatureT,
85  boost::shared_ptr< base::OperationCallerBase<SignatureT> > >,
87  {
88  std::string mname;
89  ExecutionEngine* mcaller;
90  public:
91  typedef SignatureT Signature;
93  Signature,
94  boost::shared_ptr< base::OperationCallerBase<Signature> > > Base;
95  typedef typename boost::function_traits<Signature>::result_type result_type;
96  typedef boost::function_traits<Signature> traits;
97  typedef boost::shared_ptr< base::OperationCallerBase<Signature> > OperationCallerBasePtr;
98 
104  : Base(), mname(), mcaller(0)
105  {}
106 
112  OperationCaller(std::string name, ExecutionEngine* caller = 0)
113  : Base(), mname(name), mcaller(caller)
114  {}
115 
124  : Base(m.impl ? boost::shared_ptr< base::OperationCallerBase<Signature> >(m.impl->cloneI(m.mcaller)) : m.impl ),
125  mname(m.mname), mcaller(m.mcaller)
126  {}
127 
138  {
139  if ( this == &m )
140  return *this;
141  mname = m.mname;
142  mcaller = m.mcaller;
143  if (m.impl)
144  this->impl.reset( m.impl->cloneI(mcaller) );
145  else
146  this->impl.reset();
147  return *this;
148  }
149 
159  OperationCaller(boost::shared_ptr<base::DisposableInterface> implementation, ExecutionEngine* caller = 0)
160  : Base( boost::dynamic_pointer_cast< base::OperationCallerBase<Signature> >(implementation) ),
161  mname(), mcaller(caller)
162  {
163  if ( !this->impl && implementation ) {
164  log(Error) << "Tried to construct OperationCaller from incompatible local operation."<< endlog();
165  } else {
166  if (this->impl) {
167  this->impl.reset( this->impl->cloneI(mcaller) );
168  }
169  }
170  }
171 
181  : Base(),
182  mname(), mcaller(caller)
183  {
184  if (part) {
185  mname = part->getName();
186  this->impl = boost::dynamic_pointer_cast< base::OperationCallerBase<Signature> >( part->getLocalOperation() );
187  setupOperationCaller( part );
188  }
189  }
190 
199  OperationCaller(const std::string& name, ServicePtr service, ExecutionEngine* caller = 0)
200  : Base(),
201  mname(name), mcaller(caller)
202  {
203  if (service) {
204  this->impl = boost::dynamic_pointer_cast< base::OperationCallerBase<Signature> >( service->getLocalOperation(name) );
205  if (service->hasMember(name))
206  setupOperationCaller( service->getOperation(name) );
207  }
208  }
209 
218  OperationCaller& operator=(boost::shared_ptr<base::DisposableInterface> implementation)
219  {
220  if (this->impl && this->impl == implementation)
221  return *this;
222  OperationCaller<Signature> tmp(implementation, mcaller);
223  *this = tmp;
224  return *this;
225  }
226 
237  {
238  if (part == 0) {
239  log(Warning) << "Assigning OperationCaller from null part."<<endlog();
240  this->impl.reset();
241  }
242  if (this->impl && this->impl == part->getLocalOperation() )
243  return *this;
244  OperationCaller<Signature> tmp(part, mcaller);
245  *this = tmp;
246  return *this;
247  }
248 
257  {
258  if ( !service ) {
259  log(Warning) << "Assigning OperationCaller from null service."<<endlog();
260  this->impl.reset();
261  }
262  if (this->mname.empty()) {
263  log(Error) << "Can't initialise unnamed OperationCaller from service '"<<service->getName() <<"'."<<endlog();
264  return *this;
265  }
266  OperationCaller<Signature> tmp(mname, service, mcaller);
267  *this = tmp;
268  return *this;
269  }
270 
271 #ifdef ORO_TEST_OPERATION_CALLER
272 
281  template<class M, class ObjectType>
282  OperationCaller(std::string name, M meth, ObjectType object, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0, ExecutionThread et = ClientThread)
283  : Base( OperationCallerBasePtr(new internal::LocalOperationCaller<Signature>(meth, object, ee, caller, et) ) ),
284  mname(name), mcaller(caller)
285  {}
286 
294  template<class M>
295  OperationCaller(std::string name, M meth, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0, ExecutionThread et = ClientThread)
297  mname(name), mcaller(caller)
298  {}
299 #endif
300 #ifdef ORO_REMOTING
301 
307  template<class M>
308  OperationCaller(std::string name, OperationInterfacePart* orp, ExecutionEngine* caller = 0)
310  mname(name)
311  {}
312 #endif
313 
318  {
319  }
320 
326  bool ready() const {
327  return this->impl && this->impl->ready();
328  }
329 
333  std::string const& getName() const {return mname;}
334 
335  bool setImplementation(boost::shared_ptr<base::DisposableInterface> implementation, ExecutionEngine* caller = 0) {
336  *this = implementation;
337  if ( this->impl ) {
338  this->mcaller = caller;
339  this->impl->setCaller(caller);
340  }
341  return ready();
342  }
343 
345  OperationCaller<Signature> tmp(orp, caller);
346  if (tmp.ready()) {
347  *this = tmp;
348  return true;
349  }
350  return false;
351  }
352 
356  const OperationCallerBasePtr getOperationCallerImpl() const {
357  return this->impl;
358  }
359 
363  void setOperationCallerImpl( OperationCallerBasePtr new_impl) {
364  this->impl = new_impl;
365  }
366 
367  void setCaller(ExecutionEngine* caller) {
368  this->mcaller = caller;
369  if (this->impl)
370  this->impl->setCaller(caller);
371  }
372 
373  void disconnect()
374  {
375  this->impl.reset();
376  }
377  protected:
384  if ( !this->impl ) {
385 #ifdef ORO_REMOTING
386  // try differently
387  try {
388  this->impl.reset( new internal::RemoteOperationCaller<Signature>( part, mname, mcaller ));
389  } catch( std::exception& e ) {
390  log(Error) << "Constructing RemoteOperationCaller for "<< mname <<" was not possible."<<endlog();
391  log(Error) << "Probable cause: " << e.what() <<endlog();
392  return;
393  }
394  if (this->impl->ready()) {
395  log(Debug) << "Constructed OperationCaller from remote implementation '"<< mname<<"'."<< endlog();
396  } else {
397  this->impl.reset(); // clean up.
398  log(Error) << "Tried to construct OperationCaller from incompatible operation '"<< mname<<"'."<< endlog();
399  }
400 #else
401  log(Error) << "Tried to construct remote OperationCaller but ORO_REMOTING was disabled."<< endlog();
402 #endif
403  } else {
404  // finally clone and set caller on clone.
405  this->impl.reset( this->impl->cloneI(mcaller) );
406  }
407  }
408 
409  };
410 
411 #ifdef ORO_TEST_OPERATION_CALLER
412 
420  template<class F, class O>
421  OperationCaller< typename internal::UnMember<F>::type > method(std::string name, F method, O object, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0) {
422  return OperationCaller< typename internal::UnMember<F>::type >(name, method, object, ee, caller);
423  }
424 
432  template<class F>
433  OperationCaller<F> method(std::string name, F method, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0) {
434  return OperationCaller<F>(name, method, ee, caller);
435  }
443  template<class F>
444  OperationCaller< typename internal::ArgMember<F>::type > method_ds(std::string name, F method, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0) {
445  return OperationCaller< typename internal::ArgMember<F>::type >(name, method, ee, caller);
446  }
447 #endif
448 }
449 
450 #endif
OperationCaller(std::string name, ExecutionEngine *caller=0)
Create an OperationCaller object with a name and optional caller.
std::string const & getName() const
Get the name of this OperationCaller.
An invoker can be given an implementation and is identified by a name.
OperationCaller & operator=(OperationInterfacePart *part)
OperationCaller objects may be assigned to a part responsible for production of an implementation...
OperationCaller & operator=(ServicePtr service)
Named OperationCaller objects may be looked up in a Service.
OperationCaller & operator=(const OperationCaller &m)
OperationCaller objects may be assigned.
const OperationCallerBasePtr getOperationCallerImpl() const
Returns the internal implementation of the OperationCaller object.
bool ready() const
Check if this OperationCaller is ready for execution.
internal::InvokerSignature< boost::function_traits< Signature >::arity, Signature, boost::shared_ptr< base::OperationCallerBase< Signature > > > Base
void setCaller(ExecutionEngine *caller)
Sets the caller of this method after the implementation was set.
virtual std::string getName() const =0
Returns the name of this operation.
boost::shared_ptr< base::OperationCallerBase< Signature > > OperationCallerBasePtr
boost::function_traits< Signature >::result_type result_type
OperationCaller & operator=(boost::shared_ptr< base::DisposableInterface > implementation)
OperationCaller objects may be assigned to an implementation.
The base class for all method implementations.
An execution engine serialises (executes one after the other) the execution of all commands...
OperationCaller(OperationInterfacePart *part, ExecutionEngine *caller=0)
Initialise a nameless OperationCaller object from an operation factory.
A OperationCaller serves as a placeholder (aka &#39;proxy&#39;) for a remote Operation.
A OperationCaller implementation which delegates C++ to datasource conversions when C++ code tries to...
boost::shared_ptr< Service > ServicePtr
Definition: rtt-fwd.hpp:86
Used by various classes to define operator(), given a Signature.
bool setImplementationPart(OperationInterfacePart *orp, ExecutionEngine *caller=0)
Sets a new implementation for this method by using a service part.
void setOperationCallerImpl(OperationCallerBasePtr new_impl)
Sets the internal implementation of the OperationCaller object.
OperationCaller(const std::string &name, ServicePtr service, ExecutionEngine *caller=0)
Initialise a named OperationCaller object from a Service.
This class defines the interface for creating operation objects without using C++ templates...
bool setImplementation(boost::shared_ptr< base::DisposableInterface > implementation, ExecutionEngine *caller=0)
Sets a new implementation for this method.
boost::function_traits< Signature > traits
virtual RTT_API boost::shared_ptr< base::DisposableInterface > getLocalOperation() const
Returns any local operation associated with this operation.
OperationCaller(const OperationCaller &m)
OperationCaller objects may be copied.
~OperationCaller()
Clean up the OperationCaller object.
void disconnect()
Disconnects this caller from the operation it was connected to.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
OperationCaller(boost::shared_ptr< base::DisposableInterface > implementation, ExecutionEngine *caller=0)
Initialise a nameless OperationCaller object from a local Operation.
void setupOperationCaller(OperationInterfacePart *part)
If no local implementation of an operation could be found, this method tries it using the operationre...
ExecutionThread
Users can choose if an operation&#39;s function is executed in the component&#39;s thread (OwnThread) or in t...
OperationCaller()
Create an empty OperationCaller object.