Orocos Real-Time Toolkit  2.9.0
LocalOperationCaller.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: FMTC do nov 2 13:06:05 CET 2006 LocalOperationCaller.hpp
3 
4  LocalOperationCaller.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_LOCAL_METHOD_HPP
40 #define ORO_LOCAL_METHOD_HPP
41 
42 #include <boost/function.hpp>
43 #include <boost/shared_ptr.hpp>
44 #include <boost/make_shared.hpp>
45 #include <string>
46 #include "Invoker.hpp"
47 #include "../base/OperationCallerBase.hpp"
48 #include "../base/OperationBase.hpp"
49 #include "BindStorage.hpp"
50 #include "../SendStatus.hpp"
51 #include "../SendHandle.hpp"
52 #include "../ExecutionEngine.hpp"
54 #include <boost/fusion/include/vector_tie.hpp>
55 #include "../os/oro_allocator.hpp"
56 
57 #include <iostream>
58 // For doing I/O
59 #include <boost/fusion/sequence/io.hpp>
60 
61 namespace RTT
62 {
63  namespace internal
64  {
76  template<class FunctionT>
78  : public base::OperationCallerBase<FunctionT>,
79  public internal::CollectBase<FunctionT>,
80  protected BindStorage<FunctionT>
81  {
82  public:
84  typedef FunctionT Signature;
85  typedef typename boost::function_traits<Signature>::result_type result_type;
86  typedef typename boost::function_traits<Signature>::result_type result_reference;
87  typedef boost::function_traits<Signature> traits;
88 
89  typedef boost::shared_ptr<LocalOperationCallerImpl> shared_ptr;
90 
91  virtual bool ready() const {
92  return true;
93  }
94 
95  virtual bool isError() const {
96  return this->retv.isError();
97  }
98 
100  if (!this->retv.isExecuted()) {
101  this->exec(); // calls BindStorage.
102  //cout << "executed method"<<endl;
103  if(this->retv.isError())
104  this->reportError();
105  bool result = false;
106  if ( this->caller){
107  result = this->caller->process(this);
108  }
109  if (!result)
110  dispose();
111  } else {
112  //cout << "received method done msg."<<endl;
113  // Already executed, are in caller.
114  // nop, we will check ret in collect()
115  // This is the place to call call-back functions,
116  // since we're in the caller's (or proxy's) EE.
117  dispose();
118  }
119  return;
120  }
121 
126  void dispose() {
127  self.reset();
128  }
129 
131  //std::cout << "Sending clone..."<<std::endl;
132  ExecutionEngine* receiver = this->getMessageProcessor();
133  cl->self = cl;
134  if ( receiver && receiver->process( cl.get() ) ) {
135  return SendHandle<Signature>( cl );
136  } else {
137  cl->dispose();
138  // cleanup. Done by shared_ptr.
139  return SendHandle<Signature>();
140  }
141  }
142  // We need a handle object !
144  return do_send( this->cloneRT() );
145  }
146 
147  template<class T1>
149  // bind types from Storage<Function>
150  shared_ptr cl = this->cloneRT();
151  cl->store( a1 );
152  return do_send(cl);
153  }
154 
155  template<class T1, class T2>
157  // bind types from Storage<Function>
158  shared_ptr cl = this->cloneRT();
159  cl->store( a1,a2 );
160  return do_send(cl);
161  }
162 
163  template<class T1, class T2, class T3>
164  SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3 ) {
165  // bind types from Storage<Function>
166  shared_ptr cl = this->cloneRT();
167  cl->store( a1,a2,a3 );
168  return do_send(cl);
169  }
170 
171  template<class T1, class T2, class T3, class T4>
172  SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4 ) {
173  // bind types from Storage<Function>
174  shared_ptr cl = this->cloneRT();
175  cl->store( a1,a2,a3,a4 );
176  return do_send(cl);
177  }
178 
179  template<class T1, class T2, class T3, class T4, class T5>
180  SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5 ) {
181  // bind types from Storage<Function>
182  shared_ptr cl = this->cloneRT();
183  cl->store( a1,a2,a3,a4,a5 );
184  return do_send(cl);
185  }
186 
187  template<class T1, class T2, class T3, class T4, class T5, class T6>
188  SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6 ) {
189  // bind types from Storage<Function>
190  shared_ptr cl = this->cloneRT();
191  cl->store( a1,a2,a3,a4,a5,a6 );
192  return do_send(cl);
193  }
194 
195  template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
196  SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7 ) {
197  // bind types from Storage<Function>
198  shared_ptr cl = this->cloneRT();
199  cl->store( a1,a2,a3,a4,a5,a6,a7 );
200  return do_send(cl);
201  }
202 
203 
205  if ( this->retv.isExecuted()) {
206  this->retv.checkError();
207  return SendSuccess;
208  } else
209  return SendNotReady;
210  }
211 
212  // collect_impl belongs in LocalOperationCallerImpl because it would need
213  // to be repeated in each BindStorage spec.
214  template<class T1>
215  SendStatus collectIfDone_impl( T1& a1 ) const {
216  if ( this->retv.isExecuted()) {
217  this->retv.checkError();
218  bf::vector_tie(a1) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
219  return SendSuccess;
220  } else
221  return SendNotReady;
222  }
223 
224  template<class T1, class T2>
225  SendStatus collectIfDone_impl( T1& a1, T2& a2 ) const {
226  if ( this->retv.isExecuted()) {
227  this->retv.checkError();
228  bf::vector_tie(a1,a2) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
229  return SendSuccess;
230  }
231  return SendNotReady;
232  }
233 
234  template<class T1, class T2, class T3>
235  SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3 ) const {
236  if ( this->retv.isExecuted()) {
237  this->retv.checkError();
238  bf::vector_tie(a1,a2,a3) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
239  return SendSuccess;
240  } else
241  return SendNotReady;
242  }
243 
244  template<class T1, class T2, class T3, class T4>
245  SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4 ) const {
246  if ( this->retv.isExecuted()) {
247  this->retv.checkError();
248  bf::vector_tie(a1,a2,a3,a4) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
249  return SendSuccess;
250  } else
251  return SendNotReady;
252  }
253 
254  template<class T1, class T2, class T3, class T4, class T5>
255  SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5 ) const {
256  if ( this->retv.isExecuted()) {
257  this->retv.checkError();
258  bf::vector_tie(a1,a2,a3,a4,a5) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
259  return SendSuccess;
260  } else
261  return SendNotReady;
262  }
263 
264  template<class T1, class T2, class T3, class T4, class T5, class T6>
265  SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6 ) const {
266  if ( this->retv.isExecuted()) {
267  this->retv.checkError();
268  bf::vector_tie(a1,a2,a3,a4,a5,a6) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
269  return SendSuccess;
270  } else
271  return SendNotReady;
272  }
273 
274  template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
275  SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7 ) const {
276  if ( this->retv.isExecuted()) {
277  this->retv.checkError();
278  bf::vector_tie(a1,a2,a3,a4,a5,a6,a7) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
279  return SendSuccess;
280  } else
281  return SendNotReady;
282  }
283 
284  bool checkCaller() const {
285  if (!this->caller) {
286  log(Error) << "You're using call() an OwnThread operation or collect() on a sent operation without setting a caller in the OperationCaller. This often causes deadlocks." <<endlog();
287  log(Error) << "Use this->engine() in a component or GlobalEngine::Instance() in a non-component function. Returning a CollectFailure." <<endlog();
288  assert( false && "You forgot to use setCaller(). See Orocos LOG messages for explanation.");
289  return false;
290  }
291  return true;
292  }
293 
295  if (!checkCaller()) return CollectFailure;
296  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
297  return this->collectIfDone_impl();
298  }
299  template<class T1>
300  SendStatus collect_impl( T1& a1 ) const {
301  if (!checkCaller()) return CollectFailure;
302  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
303  return this->collectIfDone_impl(a1);
304  }
305 
306  template<class T1, class T2>
307  SendStatus collect_impl( T1& a1, T2& a2 ) const {
308  if (!checkCaller()) return CollectFailure;
309  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
310  return this->collectIfDone_impl(a1,a2);
311  }
312 
313  template<class T1, class T2, class T3>
314  SendStatus collect_impl( T1& a1, T2& a2, T3& a3 ) const {
315  if (!checkCaller()) return CollectFailure;
316  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
317  return this->collectIfDone_impl(a1,a2,a3);
318  }
319 
320  template<class T1, class T2, class T3, class T4>
321  SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4) const {
322  if (!checkCaller()) return CollectFailure;
323  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
324  return this->collectIfDone_impl(a1,a2,a3,a4);
325  }
326 
327  template<class T1, class T2, class T3, class T4, class T5>
328  SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5) const {
329  if (!checkCaller()) return CollectFailure;
330  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
331  return this->collectIfDone_impl(a1,a2,a3,a4, a5);
332  }
333 
334  template<class T1, class T2, class T3, class T4, class T5, class T6>
335  SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6) const {
336  if (!checkCaller()) return CollectFailure;
337  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
338  return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6);
339  }
340 
341  template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
342  SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7) const {
343  if (!checkCaller()) return CollectFailure;
344  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
345  return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6,a7);
346  }
347 
351  template<class Xignored>
352  result_type call_impl()
353  {
354  if ( this->isSend() ) {
356  if ( h.collect() == SendSuccess )
357  return h.ret();
358  else
359  throw SendFailure;
360  } else {
361 #ifdef ORO_SIGNALLING_OPERATIONS
362  if (this->msig) this->msig->emit();
363 #endif
364  if ( this->mmeth )
365  return this->mmeth(); // ClientThread
366  else
367  return NA<result_type>::na();
368  }
369  }
370 
371 
375  template<class T1>
376  result_type call_impl(T1 a1)
377  {
379  if ( this->isSend() ) {
380  h = send_impl<T1>(a1);
381  // collect_impl may take diff number of arguments than
382  // call_impl/ret_impl(), so we use generic collect() + ret_impl()
383  if ( h.collect() == SendSuccess )
384  return h.ret(a1);
385  else
386  throw SendFailure;
387  } else{
388 #ifdef ORO_SIGNALLING_OPERATIONS
389  if (this->msig) this->msig->emit(a1);
390 #endif
391  if ( this->mmeth )
392  return this->mmeth(a1);
393  else
394  return NA<result_type>::na();
395  }
396  return NA<result_type>::na();
397  }
398 
399  template<class T1, class T2>
400  result_type call_impl(T1 a1, T2 a2)
401  {
403  if ( this->isSend() ) {
404  h = send_impl<T1,T2>(a1,a2);
405  if ( h.collect() == SendSuccess )
406  return h.ret(a1,a2);
407  else
408  throw SendFailure;
409  } else {
410 #ifdef ORO_SIGNALLING_OPERATIONS
411  if (this->msig) this->msig->emit(a1,a2);
412 #endif
413  if ( this->mmeth )
414  return this->mmeth(a1,a2);
415  else
416  return NA<result_type>::na();
417  }
418  return NA<result_type>::na();
419  }
420 
421  template<class T1, class T2, class T3>
422  result_type call_impl(T1 a1, T2 a2, T3 a3)
423  {
425  if ( this->isSend() ) {
426  h = send_impl<T1,T2,T3>(a1,a2,a3);
427  if ( h.collect() == SendSuccess )
428  return h.ret(a1,a2,a3);
429  else
430  throw SendFailure;
431  } else {
432 #ifdef ORO_SIGNALLING_OPERATIONS
433  if (this->msig) this->msig->emit(a1,a2,a3);
434 #endif
435  if ( this->mmeth )
436  return this->mmeth(a1,a2,a3);
437  else
438  return NA<result_type>::na();
439  }
440  return NA<result_type>::na();
441  }
442 
443  template<class T1, class T2, class T3, class T4>
444  result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4)
445  {
447  if ( this->isSend() ) {
448  h = send_impl<T1,T2,T3,T4>(a1,a2,a3,a4);
449  if ( h.collect() == SendSuccess )
450  return h.ret(a1,a2,a3,a4);
451  else
452  throw SendFailure;
453  } else {
454 #ifdef ORO_SIGNALLING_OPERATIONS
455  if (this->msig) this->msig->emit(a1,a2,a3,a4);
456 #endif
457  if ( this->mmeth )
458  return this->mmeth(a1,a2,a3,a4);
459  else
460  return NA<result_type>::na();
461  }
462  return NA<result_type>::na();
463  }
464 
465  template<class T1, class T2, class T3, class T4, class T5>
466  result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
467  {
469  if (this->isSend()) {
470  h = send_impl<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
471  if ( h.collect() == SendSuccess )
472  return h.ret(a1,a2,a3,a4,a5);
473  else
474  throw SendFailure;
475  } else {
476 #ifdef ORO_SIGNALLING_OPERATIONS
477  if (this->msig) this->msig->emit(a1,a2,a3,a4,a5);
478 #endif
479  if ( this->mmeth )
480  return this->mmeth(a1,a2,a3,a4,a5);
481  else
482  return NA<result_type>::na();
483  }
484  return NA<result_type>::na();
485  }
486 
487  template<class T1, class T2, class T3, class T4, class T5, class T6>
488  result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
489  {
491  if (this->isSend()) {
492  h = send_impl<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6);
493  if ( h.collect() == SendSuccess )
494  return h.ret(a1,a2,a3,a4,a5,a6);
495  else
496  throw SendFailure;
497  } else {
498 #ifdef ORO_SIGNALLING_OPERATIONS
499  if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6);
500 #endif
501  if ( this->mmeth )
502  return this->mmeth(a1,a2,a3,a4,a5,a6);
503  else
504  return NA<result_type>::na();
505  }
506  return NA<result_type>::na();
507  }
508 
509  template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
510  result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
511  {
513  if (this->isSend()) {
514  h = send_impl<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7);
515  if ( h.collect() == SendSuccess )
516  return h.ret(a1,a2,a3,a4,a5,a6,a7);
517  else
518  throw SendFailure;
519  } else {
520 #ifdef ORO_SIGNALLING_OPERATIONS
521  if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6,a7);
522 #endif
523  if ( this->mmeth )
524  return this->mmeth(a1,a2,a3,a4,a5,a6,a7);
525  else
526  return NA<result_type>::na();
527  }
528  return NA<result_type>::na();
529  }
530 
531  result_type ret_impl() const
532  {
533  this->retv.checkError();
534  return this->retv.result(); // may return void.
535  }
536 
542  template<class T1>
543  result_type ret_impl(T1 a1) const
544  {
545  this->retv.checkError();
546  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
547  bf::vector<T1> vArgs( boost::ref(a1) );
548  if ( this->retv.isExecuted())
549  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
550  return this->retv.result(); // may return void.
551  }
552 
553  template<class T1,class T2>
554  result_type ret_impl(T1 a1, T2 a2) const
555  {
556  this->retv.checkError();
557  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
558  bf::vector<T1,T2> vArgs( boost::ref(a1), boost::ref(a2) );
559  if ( this->retv.isExecuted())
560  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg< boost::remove_reference<mpl::_> > >(this->vStore);
561  return this->retv.result(); // may return void.
562  }
563 
564  template<class T1,class T2, class T3>
565  result_type ret_impl(T1 a1, T2 a2, T3 a3) const
566  {
567  this->retv.checkError();
568  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
569  bf::vector<T1,T2,T3> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3) );
570  if ( this->retv.isExecuted())
571  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
572  return this->retv.result(); // may return void.
573  }
574 
575  template<class T1,class T2, class T3, class T4>
576  result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4) const
577  {
578  this->retv.checkError();
579  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
580  bf::vector<T1,T2,T3,T4> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4) );
581  if ( this->retv.isExecuted())
582  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
583  return this->retv.result(); // may return void.
584  }
585 
586  template<class T1,class T2, class T3, class T4, class T5>
587  result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) const
588  {
589  this->retv.checkError();
590  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
591  bf::vector<T1,T2,T3,T4,T5> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5) );
592  if ( this->retv.isExecuted())
593  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
594  return this->retv.result(); // may return void.
595  }
596 
597  template<class T1,class T2, class T3, class T4, class T5, class T6>
598  result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) const
599  {
600  this->retv.checkError();
601  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
602  bf::vector<T1,T2,T3,T4,T5,T6> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5), boost::ref(a6) );
603  if ( this->retv.isExecuted())
604  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
605  return this->retv.result(); // may return void.
606  }
607 
608  template<class T1,class T2, class T3, class T4, class T5, class T6, class T7>
609  result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) const
610  {
611  this->retv.checkError();
612  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
613  bf::vector<T1,T2,T3,T4,T5,T6,T7> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5), boost::ref(a6), boost::ref(a7) );
614  if ( this->retv.isExecuted())
615  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
616  return this->retv.result(); // may return void.
617  }
618 
619  virtual shared_ptr cloneRT() const = 0;
620  protected:
628  };
629 
639  template<class FunctionT>
641  : public Invoker<FunctionT,LocalOperationCallerImpl<FunctionT> >
642  {
643  typedef FunctionT Signature;
644  typedef typename boost::function_traits<Signature>::result_type result_type;
645  typedef boost::function_traits<Signature> traits;
646 
647  typedef boost::shared_ptr<LocalOperationCaller> shared_ptr;
648 
655  {}
656 
666  template<class M, class ObjectType>
668  {
669  this->setCaller( caller );
670  this->setOwner(ee );
671  this->setThread( et, ee );
672  this->mmeth = OperationCallerBinder<Signature>()(meth, object);
673  }
674 
680  template<class M>
682  {
683  this->setCaller( caller );
684  this->setOwner( ee );
685  this->setThread( et, ee );
686  this->mmeth = meth;
687  }
688 
689  boost::function<Signature> getOperationCallerFunction() const
690  {
691  return this->mmeth;
692  }
693 
694 #ifdef ORO_SIGNALLING_OPERATIONS
695  void setSignal(typename Signal<Signature>::shared_ptr sig) {
696  this->msig = sig;
697  }
698 #endif
700  {
702  ret->setCaller( caller ); // mandatory !
703  return ret;
704  }
705 
707  {
708  // returns identical copy of this;
709  return boost::allocate_shared<LocalOperationCaller<Signature> >(os::rt_allocator<LocalOperationCaller<Signature> >(), *this);
710  }
711  };
712  }
713 }
714 
715 #endif
result_type call_impl(T1 a1, T2 a2, T3 a3)
result_type call_impl()
Invoke this operator if the method has no arguments.
SendStatus collectIfDone_impl(T1 &a1, T2 &a2) const
LocalOperationCallerImpl< Signature >::shared_ptr cloneRT() const
SendHandle< Signature > send_impl(T1 a1, T2 a2, T3 a3)
boost::function_traits< Signature > traits
result_type ret_impl(T1 a1, T2 a2) const
SendHandle< Signature > send_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
SendStatus collectIfDone_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4) const
static T na()
Definition: NA.hpp:57
void executeAndDispose()
Execute functionality and free this object.
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5, T6 &a6, T7 &a7) const
SendHandle< Signature > send_impl(T1 a1, T2 a2)
result_type ret_impl(T1 a1) const
This function has the same signature of call() and returns the stored return value, and tries to return all arguments.
bool setThread(ExecutionThread et, ExecutionEngine *executor)
Sets the Thread execution policy of this object.
result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4) const
boost::function< Signature > getOperationCallerFunction() const
virtual void setCaller(ExecutionEngine *ee)
Sets the caller&#39;s engine of this operation.
Creates an invocation object with a function signature to invoke and an implementation in which an op...
Definition: Invoker.hpp:61
result_type call_impl(T1 a1)
Invoke this operator if the method has one argument.
void waitForMessages(const boost::function< bool(void)> &pred)
Call this if you wish to block on a message arriving in the Execution Engine.
SendStatus collectIfDone_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5) const
SendStatus collectIfDone_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5, T6 &a6) const
result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) const
boost::function_traits< Signature >::result_type result_type
A real-time malloc allocator which allocates every block with oro_rt_malloc() and deallocates with or...
base::OperationCallerBase< Signature > * cloneI(ExecutionEngine *caller) const
bool isSend()
Helpful function to tell us if this operations is to be sent or not.
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4) const
void reportError()
Executed when the operation execution resulted in a C++ exception.
The base class for all method implementations.
An execution engine serialises (executes one after the other) the execution of all commands...
SendStatus
Returns the status of a send() or collect() invocation.
Definition: SendStatus.hpp:53
SendHandle< Signature > do_send(shared_ptr cl)
boost::shared_ptr< LocalOperationCallerImpl > shared_ptr
LocalOperationCaller(M meth, ExecutionEngine *ee, ExecutionEngine *caller, ExecutionThread et=ClientThread)
Construct a LocalOperationCaller from a function pointer or function object.
A helper-class for the Command implementation which stores the command and collition function objects...
result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
boost::function_traits< Signature >::result_type result_reference
boost::shared_ptr< Signal< Signature, TSlotFunction > > shared_ptr
Definition: Signal.hpp:215
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5, T6 &a6) const
boost::shared_ptr< OperationCallerBase< F > > shared_ptr
A method which executes a local function.
result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
The SendHandle is used to collect the result values of an asynchronous invocation.
Definition: rtt-fwd.hpp:79
virtual void setOwner(ExecutionEngine *ee)
Set the ExecutionEngine of the task which owns this method.
SendStatus collect_impl(T1 &a1, T2 &a2) const
SendHandle< Signature > send_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
Returned when the result of the send() could not be collected.
Definition: SendStatus.hpp:55
SendHandle< Signature > send_impl(T1 a1, T2 a2, T3 a3, T4 a4)
void dispose()
As long as dispose (or executeAndDispose() ) is not called, this object will not be destroyed...
SendHandle< Signature > send_impl(T1 a1)
Outargs are of type AStore and contain a pure reference.
result_type ret_impl(T1 a1, T2 a2, T3 a3) const
Implements call, send, collect, collectIfDone for all function arities.
LocalOperationCaller(M meth, ObjectType object, ExecutionEngine *ee, ExecutionEngine *caller, ExecutionThread et=ClientThread)
Construct a LocalOperationCaller from a class member pointer and an object of that class...
boost::function_traits< Signature > traits
LocalOperationCaller()
Create an empty LocalOperationCaller object.
SendStatus collectIfDone_impl(T1 &a1, T2 &a2, T3 &a3) const
result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) const
ExecutionEngine * getMessageProcessor() const
Returned when the send() succeeded, but the operation has not yet been executed by the receiving comp...
Definition: SendStatus.hpp:57
virtual shared_ptr cloneRT() const =0
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5) const
Returned when the send() failed to deliver the operation call to the receiving component.
Definition: SendStatus.hpp:56
This struct takes the user&#39;s Function signature F and transforms it to the form required in the Colle...
Definition: CollectBase.hpp:69
boost::function_traits< Signature >::result_type result_type
result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) const
SendStatus collect() const
Collect this operator if the method has no arguments.
Definition: SendHandle.hpp:124
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
SendStatus collectIfDone_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5, T6 &a6, T7 &a7) const
Very simple factory class to bind a member function to an object pointer and leave the arguments open...
result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4)
virtual bool process(base::DisposableInterface *c)
Queue and execute (process) a given message.
result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
boost::shared_ptr< LocalOperationCaller > shared_ptr
SendHandle< Signature > send_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3) const
ExecutionThread
Users can choose if an operation&#39;s function is executed in the component&#39;s thread (OwnThread) or in t...
virtual bool ready() const
Available such that implementations have a way to expose their ready-ness, ie being able to do the ca...