Orocos Real-Time Toolkit  2.8.3
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>
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 ) {
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 ) {
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 ) {
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 ) {
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 ) {
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 ) {
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() {
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  return false;
289  }
290  return true;
291  }
292 
294  if (!checkCaller()) return CollectFailure;
295  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
296  return this->collectIfDone_impl();
297  }
298  template<class T1>
300  if (!checkCaller()) return CollectFailure;
301  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
302  return this->collectIfDone_impl(a1);
303  }
304 
305  template<class T1, class T2>
306  SendStatus collect_impl( T1& a1, T2& a2 ) {
307  if (!checkCaller()) return CollectFailure;
308  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
309  return this->collectIfDone_impl(a1,a2);
310  }
311 
312  template<class T1, class T2, class T3>
313  SendStatus collect_impl( T1& a1, T2& a2, T3& a3 ) {
314  if (!checkCaller()) return CollectFailure;
315  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
316  return this->collectIfDone_impl(a1,a2,a3);
317  }
318 
319  template<class T1, class T2, class T3, class T4>
320  SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4) {
321  if (!checkCaller()) return CollectFailure;
322  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
323  return this->collectIfDone_impl(a1,a2,a3,a4);
324  }
325 
326  template<class T1, class T2, class T3, class T4, class T5>
327  SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5) {
328  if (!checkCaller()) return CollectFailure;
329  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
330  return this->collectIfDone_impl(a1,a2,a3,a4, a5);
331  }
332 
333  template<class T1, class T2, class T3, class T4, class T5, class T6>
334  SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6) {
335  if (!checkCaller()) return CollectFailure;
336  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
337  return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6);
338  }
339 
340  template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
341  SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7) {
342  if (!checkCaller()) return CollectFailure;
343  this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
344  return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6,a7);
345  }
346 
350  template<class Xignored>
351  result_type call_impl()
352  {
353  if ( this->isSend() ) {
355  if ( h.collect() == SendSuccess )
356  return h.ret();
357  else
358  throw SendFailure;
359  } else {
360 #ifdef ORO_SIGNALLING_OPERATIONS
361  if (this->msig) this->msig->emit();
362 #endif
363  if ( this->mmeth )
364  return this->mmeth(); // ClientThread
365  else
366  return NA<result_type>::na();
367  }
368  }
369 
370 
374  template<class T1>
375  result_type call_impl(T1 a1)
376  {
378  if ( this->isSend() ) {
379  h = send_impl<T1>(a1);
380  // collect_impl may take diff number of arguments than
381  // call_impl/ret_impl(), so we use generic collect() + ret_impl()
382  if ( h.collect() == SendSuccess )
383  return h.ret(a1);
384  else
385  throw SendFailure;
386  } else{
387 #ifdef ORO_SIGNALLING_OPERATIONS
388  if (this->msig) this->msig->emit(a1);
389 #endif
390  if ( this->mmeth )
391  return this->mmeth(a1);
392  else
393  return NA<result_type>::na();
394  }
395  return NA<result_type>::na();
396  }
397 
398  template<class T1, class T2>
399  result_type call_impl(T1 a1, T2 a2)
400  {
402  if ( this->isSend() ) {
403  h = send_impl<T1,T2>(a1,a2);
404  if ( h.collect() == SendSuccess )
405  return h.ret(a1,a2);
406  else
407  throw SendFailure;
408  } else {
409 #ifdef ORO_SIGNALLING_OPERATIONS
410  if (this->msig) this->msig->emit(a1,a2);
411 #endif
412  if ( this->mmeth )
413  return this->mmeth(a1,a2);
414  else
415  return NA<result_type>::na();
416  }
417  return NA<result_type>::na();
418  }
419 
420  template<class T1, class T2, class T3>
421  result_type call_impl(T1 a1, T2 a2, T3 a3)
422  {
424  if ( this->isSend() ) {
425  h = send_impl<T1,T2,T3>(a1,a2,a3);
426  if ( h.collect() == SendSuccess )
427  return h.ret(a1,a2,a3);
428  else
429  throw SendFailure;
430  } else {
431 #ifdef ORO_SIGNALLING_OPERATIONS
432  if (this->msig) this->msig->emit(a1,a2,a3);
433 #endif
434  if ( this->mmeth )
435  return this->mmeth(a1,a2,a3);
436  else
437  return NA<result_type>::na();
438  }
439  return NA<result_type>::na();
440  }
441 
442  template<class T1, class T2, class T3, class T4>
443  result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4)
444  {
446  if ( this->isSend() ) {
447  h = send_impl<T1,T2,T3,T4>(a1,a2,a3,a4);
448  if ( h.collect() == SendSuccess )
449  return h.ret(a1,a2,a3,a4);
450  else
451  throw SendFailure;
452  } else {
453 #ifdef ORO_SIGNALLING_OPERATIONS
454  if (this->msig) this->msig->emit(a1,a2,a3,a4);
455 #endif
456  if ( this->mmeth )
457  return this->mmeth(a1,a2,a3,a4);
458  else
459  return NA<result_type>::na();
460  }
461  return NA<result_type>::na();
462  }
463 
464  template<class T1, class T2, class T3, class T4, class T5>
465  result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
466  {
468  if (this->isSend()) {
469  h = send_impl<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
470  if ( h.collect() == SendSuccess )
471  return h.ret(a1,a2,a3,a4,a5);
472  else
473  throw SendFailure;
474  } else {
475 #ifdef ORO_SIGNALLING_OPERATIONS
476  if (this->msig) this->msig->emit(a1,a2,a3,a4,a5);
477 #endif
478  if ( this->mmeth )
479  return this->mmeth(a1,a2,a3,a4,a5);
480  else
481  return NA<result_type>::na();
482  }
483  return NA<result_type>::na();
484  }
485 
486  template<class T1, class T2, class T3, class T4, class T5, class T6>
487  result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
488  {
490  if (this->isSend()) {
491  h = send_impl<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6);
492  if ( h.collect() == SendSuccess )
493  return h.ret(a1,a2,a3,a4,a5,a6);
494  else
495  throw SendFailure;
496  } else {
497 #ifdef ORO_SIGNALLING_OPERATIONS
498  if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6);
499 #endif
500  if ( this->mmeth )
501  return this->mmeth(a1,a2,a3,a4,a5,a6);
502  else
503  return NA<result_type>::na();
504  }
505  return NA<result_type>::na();
506  }
507 
508  template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
509  result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
510  {
512  if (this->isSend()) {
513  h = send_impl<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7);
514  if ( h.collect() == SendSuccess )
515  return h.ret(a1,a2,a3,a4,a5,a6,a7);
516  else
517  throw SendFailure;
518  } else {
519 #ifdef ORO_SIGNALLING_OPERATIONS
520  if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6,a7);
521 #endif
522  if ( this->mmeth )
523  return this->mmeth(a1,a2,a3,a4,a5,a6,a7);
524  else
525  return NA<result_type>::na();
526  }
527  return NA<result_type>::na();
528  }
529 
530  result_type ret_impl()
531  {
532  this->retv.checkError();
533  return this->retv.result(); // may return void.
534  }
535 
541  template<class T1>
542  result_type ret_impl(T1 a1)
543  {
544  this->retv.checkError();
545  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
546  bf::vector<T1> vArgs( boost::ref(a1) );
547  if ( this->retv.isExecuted())
548  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
549  return this->retv.result(); // may return void.
550  }
551 
552  template<class T1,class T2>
553  result_type ret_impl(T1 a1, T2 a2)
554  {
555  this->retv.checkError();
556  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
557  bf::vector<T1,T2> vArgs( boost::ref(a1), boost::ref(a2) );
558  if ( this->retv.isExecuted())
559  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg< boost::remove_reference<mpl::_> > >(this->vStore);
560  return this->retv.result(); // may return void.
561  }
562 
563  template<class T1,class T2, class T3>
564  result_type ret_impl(T1 a1, T2 a2, T3 a3)
565  {
566  this->retv.checkError();
567  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
568  bf::vector<T1,T2,T3> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3) );
569  if ( this->retv.isExecuted())
570  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
571  return this->retv.result(); // may return void.
572  }
573 
574  template<class T1,class T2, class T3, class T4>
575  result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
576  {
577  this->retv.checkError();
578  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
579  bf::vector<T1,T2,T3,T4> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4) );
580  if ( this->retv.isExecuted())
581  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
582  return this->retv.result(); // may return void.
583  }
584 
585  template<class T1,class T2, class T3, class T4, class T5>
586  result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
587  {
588  this->retv.checkError();
589  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
590  bf::vector<T1,T2,T3,T4,T5> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5) );
591  if ( this->retv.isExecuted())
592  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
593  return this->retv.result(); // may return void.
594  }
595 
596  template<class T1,class T2, class T3, class T4, class T5, class T6>
597  result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
598  {
599  this->retv.checkError();
600  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
601  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) );
602  if ( this->retv.isExecuted())
603  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
604  return this->retv.result(); // may return void.
605  }
606 
607  template<class T1,class T2, class T3, class T4, class T5, class T6, class T7>
608  result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
609  {
610  this->retv.checkError();
611  typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
612  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) );
613  if ( this->retv.isExecuted())
614  as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
615  return this->retv.result(); // may return void.
616  }
617 
618  virtual shared_ptr cloneRT() const = 0;
619  protected:
627  };
628 
638  template<class FunctionT>
640  : public Invoker<FunctionT,LocalOperationCallerImpl<FunctionT> >
641  {
642  typedef FunctionT Signature;
643  typedef typename boost::function_traits<Signature>::result_type result_type;
644  typedef boost::function_traits<Signature> traits;
645 
646  typedef boost::shared_ptr<LocalOperationCaller> shared_ptr;
647 
654  {}
655 
665  template<class M, class ObjectType>
667  {
668  this->setCaller( caller );
669  this->setOwner(ee );
670  this->setThread( et, ee );
671  this->mmeth = OperationCallerBinder<Signature>()(meth, object);
672  }
673 
679  template<class M>
681  {
682  this->setCaller( caller );
683  this->setOwner( ee );
684  this->setThread( et, ee );
685  this->mmeth = meth;
686  }
687 
688  boost::function<Signature> getOperationCallerFunction() const
689  {
690  return this->mmeth;
691  }
692 
693 #ifdef ORO_SIGNALLING_OPERATIONS
694  void setSignal(typename Signal<Signature>::shared_ptr sig) {
695  this->msig = sig;
696  }
697 #endif
699  {
701  ret->setCaller( caller ); // mandatory !
702  return ret;
703  }
704 
706  {
707  // returns identical copy of this;
708  return boost::allocate_shared<LocalOperationCaller<Signature> >(os::rt_allocator<LocalOperationCaller<Signature> >(), *this);
709  }
710  };
711  }
712 }
713 
714 #endif
result_type call_impl(T1 a1, T2 a2, T3 a3)
SendStatus collectIfDone_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5)
result_type call_impl()
Invoke this operator if the method has no arguments.
SendStatus collect()
Collect this operator if the method has no arguments.
Definition: SendHandle.hpp:124
SendStatus collectIfDone_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4)
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5, T6 &a6)
LocalOperationCallerImpl< Signature >::shared_ptr cloneRT() const
bool isSend()
Helpful function to tell us if this operations is to be sent or not.
SendHandle< Signature > send_impl(T1 a1, T2 a2, T3 a3)
boost::function_traits< Signature > traits
SendHandle< Signature > send_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
static T na()
Definition: NA.hpp:57
void executeAndDispose()
Execute functionality and free this object.
SendHandle< Signature > send_impl(T1 a1, T2 a2)
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, T5 a5, T6 a6, T7 a7)
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4)
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.
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...
result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
base::OperationCallerBase< Signature > * cloneI(ExecutionEngine *caller) const
void reportError()
Executed when the operation execution resulted in a C++ exception.
The base class for all method implementations.
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3)
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
result_type ret_impl(T1 a1)
This function has the same signature of call() and returns the stored return value, and tries to return all arguments.
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 ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
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
boost::shared_ptr< OperationCallerBase< F > > shared_ptr
A method which executes a local function.
SendStatus collect_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, T5 &a5, T6 &a6)
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.
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.
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.
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
result_type ret_impl(T1 a1, T2 a2, T3 a3)
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
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:51
Very simple factory class to bind a member function to an object pointer and leave the arguments open...
SendStatus collectIfDone_impl(T1 &a1, T2 &a2, T3 &a3)
SendStatus collectIfDone_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5, T6 &a6, T7 &a7)
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
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5)
SendHandle< Signature > send_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
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...