39 #ifndef ORO_LOCAL_METHOD_HPP 40 #define ORO_LOCAL_METHOD_HPP 42 #include <boost/function.hpp> 43 #include <boost/shared_ptr.hpp> 44 #include <boost/make_shared.hpp> 47 #include "../base/OperationCallerBase.hpp" 48 #include "../base/OperationBase.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" 59 #include <boost/fusion/sequence/io.hpp> 76 template<
class FunctionT>
85 typedef typename boost::function_traits<Signature>::result_type
result_type;
87 typedef boost::function_traits<Signature>
traits;
89 typedef boost::shared_ptr<LocalOperationCallerImpl>
shared_ptr;
96 return this->retv.isError();
100 if (!this->retv.isExecuted()) {
103 if(this->retv.isError())
134 if ( receiver && receiver->
process( cl.get() ) ) {
150 shared_ptr cl = this->
cloneRT();
155 template<
class T1,
class T2>
158 shared_ptr cl = this->
cloneRT();
163 template<
class T1,
class T2,
class T3>
166 shared_ptr cl = this->
cloneRT();
167 cl->store( a1,a2,a3 );
171 template<
class T1,
class T2,
class T3,
class T4>
174 shared_ptr cl = this->
cloneRT();
175 cl->store( a1,a2,a3,a4 );
179 template<
class T1,
class T2,
class T3,
class T4,
class T5>
182 shared_ptr cl = this->
cloneRT();
183 cl->store( a1,a2,a3,a4,a5 );
187 template<
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
190 shared_ptr cl = this->
cloneRT();
191 cl->store( a1,a2,a3,a4,a5,a6 );
195 template<
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
198 shared_ptr cl = this->
cloneRT();
199 cl->store( a1,a2,a3,a4,a5,a6,a7 );
205 if ( this->retv.isExecuted()) {
206 this->retv.checkError();
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);
224 template<
class T1,
class T2>
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);
234 template<
class T1,
class T2,
class T3>
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);
244 template<
class T1,
class T2,
class T3,
class T4>
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);
254 template<
class T1,
class T2,
class T3,
class T4,
class T5>
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);
264 template<
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
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);
274 template<
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
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);
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.");
306 template<
class T1,
class T2>
313 template<
class T1,
class T2,
class T3>
320 template<
class T1,
class T2,
class T3,
class T4>
327 template<
class T1,
class T2,
class T3,
class T4,
class T5>
334 template<
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
341 template<
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
351 template<
class Xignored>
361 #ifdef ORO_SIGNALLING_OPERATIONS 362 if (this->msig) this->msig->emit();
365 return this->mmeth();
380 h = send_impl<T1>(a1);
388 #ifdef ORO_SIGNALLING_OPERATIONS 389 if (this->msig) this->msig->emit(a1);
392 return this->mmeth(a1);
399 template<
class T1,
class T2>
404 h = send_impl<T1,T2>(a1,a2);
410 #ifdef ORO_SIGNALLING_OPERATIONS 411 if (this->msig) this->msig->emit(a1,a2);
414 return this->mmeth(a1,a2);
421 template<
class T1,
class T2,
class T3>
426 h = send_impl<T1,T2,T3>(a1,a2,a3);
428 return h.ret(a1,a2,a3);
432 #ifdef ORO_SIGNALLING_OPERATIONS 433 if (this->msig) this->msig->emit(a1,a2,a3);
436 return this->mmeth(a1,a2,a3);
443 template<
class T1,
class T2,
class T3,
class T4>
448 h = send_impl<T1,T2,T3,T4>(a1,a2,a3,a4);
450 return h.ret(a1,a2,a3,a4);
454 #ifdef ORO_SIGNALLING_OPERATIONS 455 if (this->msig) this->msig->emit(a1,a2,a3,a4);
458 return this->mmeth(a1,a2,a3,a4);
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)
470 h = send_impl<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
472 return h.ret(a1,a2,a3,a4,a5);
476 #ifdef ORO_SIGNALLING_OPERATIONS 477 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5);
480 return this->mmeth(a1,a2,a3,a4,a5);
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)
492 h = send_impl<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6);
494 return h.ret(a1,a2,a3,a4,a5,a6);
498 #ifdef ORO_SIGNALLING_OPERATIONS 499 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6);
502 return this->mmeth(a1,a2,a3,a4,a5,a6);
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)
514 h = send_impl<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7);
516 return h.ret(a1,a2,a3,a4,a5,a6,a7);
520 #ifdef ORO_SIGNALLING_OPERATIONS 521 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6,a7);
524 return this->mmeth(a1,a2,a3,a4,a5,a6,a7);
533 this->retv.checkError();
534 return this->retv.result();
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();
553 template<
class T1,
class T2>
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();
564 template<
class T1,
class T2,
class T3>
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();
575 template<
class T1,
class T2,
class T3,
class T4>
576 result_type
ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
const 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();
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 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();
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 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();
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 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();
619 virtual shared_ptr
cloneRT()
const = 0;
639 template<
class FunctionT>
641 :
public Invoker<FunctionT,LocalOperationCallerImpl<FunctionT> >
644 typedef typename boost::function_traits<Signature>::result_type
result_type;
645 typedef boost::function_traits<Signature>
traits;
666 template<
class M,
class ObjectType>
694 #ifdef ORO_SIGNALLING_OPERATIONS 702 ret->setCaller( caller );
result_type call_impl(T1 a1, T2 a2, T3 a3)
SendStatus collectIfDone_impl() const
result_type call_impl()
Invoke this operator if the method has no arguments.
SendStatus collectIfDone_impl(T1 &a1, T2 &a2) const
SendStatus collect_impl(T1 &a1) const
LocalOperationCallerImpl< Signature >::shared_ptr cloneRT() const
SendStatus collectIfDone_impl(T1 &a1) 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
virtual bool isError() const
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.
BindStorage< FunctionT > Store
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's engine of this operation.
Creates an invocation object with a function signature to invoke and an implementation in which an op...
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 collect_impl() 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.
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
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.
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.
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...
virtual shared_ptr cloneRT() const =0
SendStatus collect_impl(T1 &a1, T2 &a2, T3 &a3, T4 &a4, T5 &a5) const
result_type ret_impl() const
Returned when the send() failed to deliver the operation call to the receiving component.
This struct takes the user's Function signature F and transforms it to the form required in the Colle...
boost::function_traits< Signature >::result_type result_type
SendHandle< Signature > send_impl()
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.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
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
LocalOperationCallerImpl()
result_type call_impl(T1 a1, T2 a2)
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's function is executed in the component'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...