00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef ORO_LOCAL_METHOD_HPP
00040 #define ORO_LOCAL_METHOD_HPP
00041
00042 #include <boost/function.hpp>
00043 #include <boost/shared_ptr.hpp>
00044 #include <boost/make_shared.hpp>
00045 #include <string>
00046 #include "Invoker.hpp"
00047 #include "../base/OperationCallerBase.hpp"
00048 #include "../base/OperationBase.hpp"
00049 #include "BindStorage.hpp"
00050 #include "../SendStatus.hpp"
00051 #include "../SendHandle.hpp"
00052 #include "../ExecutionEngine.hpp"
00053 #include "OperationCallerBinder.hpp"
00054 #include <boost/fusion/include/vector_tie.hpp>
00055 #include "../os/oro_allocator.hpp"
00056
00057 #include <iostream>
00058
00059 #include <boost/fusion/sequence/io.hpp>
00060
00061 namespace RTT
00062 {
00063 namespace internal
00064 {
00076 template<class FunctionT>
00077 class LocalOperationCallerImpl
00078 : public base::OperationCallerBase<FunctionT>,
00079 public internal::CollectBase<FunctionT>,
00080 protected BindStorage<FunctionT>
00081 {
00082 public:
00083 LocalOperationCallerImpl() {}
00084 typedef FunctionT Signature;
00085 typedef typename boost::function_traits<Signature>::result_type result_type;
00086 typedef typename boost::function_traits<Signature>::result_type result_reference;
00087 typedef boost::function_traits<Signature> traits;
00088
00089 typedef boost::shared_ptr<LocalOperationCallerImpl> shared_ptr;
00090
00091 virtual bool ready() const {
00092 return true;
00093 }
00094
00095 virtual bool isError() const {
00096 return this->retv.isError();
00097 }
00098
00099 void executeAndDispose() {
00100 if (!this->retv.isExecuted()) {
00101 this->exec();
00102
00103 if(this->retv.isError())
00104 this->reportError();
00105 bool result = false;
00106 if ( this->caller){
00107 result = this->caller->process(this);
00108 }
00109 if (!result)
00110 dispose();
00111 } else {
00112
00113
00114
00115
00116
00117 dispose();
00118 }
00119 return;
00120 }
00121
00126 void dispose() {
00127
00128
00129 self.reset();
00130 }
00131
00132
00133 ExecutionEngine* getMessageProcessor() const { return this->myengine; }
00134
00135 SendHandle<Signature> do_send(shared_ptr cl) {
00136 assert(this->myengine);
00137
00138 if ( this->myengine->process( cl.get() ) ) {
00139 cl->self = cl;
00140 return SendHandle<Signature>( cl );
00141 } else {
00142
00143
00144
00145 return SendHandle<Signature>();
00146 }
00147 }
00148
00149 SendHandle<Signature> send_impl() {
00150 return do_send( this->cloneRT() );
00151 }
00152
00153 template<class T1>
00154 SendHandle<Signature> send_impl( T1 a1 ) {
00155
00156 shared_ptr cl = this->cloneRT();
00157 cl->store( a1 );
00158 return do_send(cl);
00159 }
00160
00161 template<class T1, class T2>
00162 SendHandle<Signature> send_impl( T1 a1, T2 a2 ) {
00163
00164 shared_ptr cl = this->cloneRT();
00165 cl->store( a1,a2 );
00166 return do_send(cl);
00167 }
00168
00169 template<class T1, class T2, class T3>
00170 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3 ) {
00171
00172 shared_ptr cl = this->cloneRT();
00173 cl->store( a1,a2,a3 );
00174 return do_send(cl);
00175 }
00176
00177 template<class T1, class T2, class T3, class T4>
00178 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4 ) {
00179
00180 shared_ptr cl = this->cloneRT();
00181 cl->store( a1,a2,a3,a4 );
00182 return do_send(cl);
00183 }
00184
00185 template<class T1, class T2, class T3, class T4, class T5>
00186 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5 ) {
00187
00188 shared_ptr cl = this->cloneRT();
00189 cl->store( a1,a2,a3,a4,a5 );
00190 return do_send(cl);
00191 }
00192
00193 template<class T1, class T2, class T3, class T4, class T5, class T6>
00194 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6 ) {
00195
00196 shared_ptr cl = this->cloneRT();
00197 cl->store( a1,a2,a3,a4,a5,a6 );
00198 return do_send(cl);
00199 }
00200
00201 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00202 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7 ) {
00203
00204 shared_ptr cl = this->cloneRT();
00205 cl->store( a1,a2,a3,a4,a5,a6,a7 );
00206 return do_send(cl);
00207 }
00208
00209
00210 SendStatus collectIfDone_impl() {
00211 if ( this->retv.isExecuted()) {
00212 this->retv.checkError();
00213 return SendSuccess;
00214 } else
00215 return SendNotReady;
00216 }
00217
00218
00219
00220 template<class T1>
00221 SendStatus collectIfDone_impl( T1& a1 ) {
00222 if ( this->retv.isExecuted()) {
00223 this->retv.checkError();
00224 bf::vector_tie(a1) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00225 return SendSuccess;
00226 } else
00227 return SendNotReady;
00228 }
00229
00230 template<class T1, class T2>
00231 SendStatus collectIfDone_impl( T1& a1, T2& a2 ) {
00232 if ( this->retv.isExecuted()) {
00233 this->retv.checkError();
00234 bf::vector_tie(a1,a2) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00235 return SendSuccess;
00236 }
00237 return SendNotReady;
00238 }
00239
00240 template<class T1, class T2, class T3>
00241 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3 ) {
00242 if ( this->retv.isExecuted()) {
00243 this->retv.checkError();
00244 bf::vector_tie(a1,a2,a3) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00245 return SendSuccess;
00246 } else
00247 return SendNotReady;
00248 }
00249
00250 template<class T1, class T2, class T3, class T4>
00251 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4 ) {
00252 if ( this->retv.isExecuted()) {
00253 this->retv.checkError();
00254 bf::vector_tie(a1,a2,a3,a4) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00255 return SendSuccess;
00256 } else
00257 return SendNotReady;
00258 }
00259
00260 template<class T1, class T2, class T3, class T4, class T5>
00261 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5 ) {
00262 if ( this->retv.isExecuted()) {
00263 this->retv.checkError();
00264 bf::vector_tie(a1,a2,a3,a4,a5) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00265 return SendSuccess;
00266 } else
00267 return SendNotReady;
00268 }
00269
00270 template<class T1, class T2, class T3, class T4, class T5, class T6>
00271 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6 ) {
00272 if ( this->retv.isExecuted()) {
00273 this->retv.checkError();
00274 bf::vector_tie(a1,a2,a3,a4,a5,a6) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00275 return SendSuccess;
00276 } else
00277 return SendNotReady;
00278 }
00279
00280 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00281 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7 ) {
00282 if ( this->retv.isExecuted()) {
00283 this->retv.checkError();
00284 bf::vector_tie(a1,a2,a3,a4,a5,a6,a7) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00285 return SendSuccess;
00286 } else
00287 return SendNotReady;
00288 }
00289
00290 SendStatus collect_impl() {
00291 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00292 return this->collectIfDone_impl();
00293 }
00294 template<class T1>
00295 SendStatus collect_impl( T1& a1 ) {
00296 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00297 return this->collectIfDone_impl(a1);
00298 }
00299
00300 template<class T1, class T2>
00301 SendStatus collect_impl( T1& a1, T2& a2 ) {
00302 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00303 return this->collectIfDone_impl(a1,a2);
00304 }
00305
00306 template<class T1, class T2, class T3>
00307 SendStatus collect_impl( T1& a1, T2& a2, T3& a3 ) {
00308 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00309 return this->collectIfDone_impl(a1,a2,a3);
00310 }
00311
00315 result_type call_impl()
00316 {
00317
00318 if ( this->isSend() ) {
00319 SendHandle<Signature> h = send_impl();
00320 if ( h.collect() == SendSuccess )
00321 return h.ret();
00322 else
00323 throw SendFailure;
00324 } else {
00325 #ifdef ORO_SIGNALLING_OPERATIONS
00326 if (this->msig) this->msig->emit();
00327 #endif
00328 if ( this->mmeth )
00329 return this->mmeth();
00330 else
00331 return NA<result_type>::na();
00332 }
00333 }
00334
00335
00339 template<class T1>
00340 result_type call_impl(T1 a1)
00341 {
00342 SendHandle<Signature> h;
00343 if ( this->isSend() ) {
00344 h = send_impl<T1>(a1);
00345
00346
00347 if ( h.collect() == SendSuccess )
00348 return h.ret(a1);
00349 else
00350 throw SendFailure;
00351 } else{
00352 #ifdef ORO_SIGNALLING_OPERATIONS
00353 if (this->msig) this->msig->emit(a1);
00354 #endif
00355 if ( this->mmeth )
00356 return this->mmeth(a1);
00357 else
00358 return NA<result_type>::na();
00359 }
00360 return NA<result_type>::na();
00361 }
00362
00363 template<class T1, class T2>
00364 result_type call_impl(T1 a1, T2 a2)
00365 {
00366 SendHandle<Signature> h;
00367 if ( this->isSend() ) {
00368 h = send_impl<T1,T2>(a1,a2);
00369 if ( h.collect() == SendSuccess )
00370 return h.ret(a1,a2);
00371 else
00372 throw SendFailure;
00373 } else {
00374 #ifdef ORO_SIGNALLING_OPERATIONS
00375 if (this->msig) this->msig->emit(a1,a2);
00376 #endif
00377 if ( this->mmeth )
00378 return this->mmeth(a1,a2);
00379 else
00380 return NA<result_type>::na();
00381 }
00382 return NA<result_type>::na();
00383 }
00384
00385 template<class T1, class T2, class T3>
00386 result_type call_impl(T1 a1, T2 a2, T3 a3)
00387 {
00388 SendHandle<Signature> h;
00389 if ( this->isSend() ) {
00390 h = send_impl<T1,T2,T3>(a1,a2,a3);
00391 if ( h.collect() == SendSuccess )
00392 return h.ret(a1,a2,a3);
00393 else
00394 throw SendFailure;
00395 } else {
00396 #ifdef ORO_SIGNALLING_OPERATIONS
00397 if (this->msig) this->msig->emit(a1,a2,a3);
00398 #endif
00399 if ( this->mmeth )
00400 return this->mmeth(a1,a2,a3);
00401 else
00402 return NA<result_type>::na();
00403 }
00404 return NA<result_type>::na();
00405 }
00406
00407 template<class T1, class T2, class T3, class T4>
00408 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00409 {
00410 SendHandle<Signature> h;
00411 if ( this->isSend() ) {
00412 h = send_impl<T1,T2,T3,T4>(a1,a2,a3,a4);
00413 if ( h.collect() == SendSuccess )
00414 return h.ret(a1,a2,a3,a4);
00415 else
00416 throw SendFailure;
00417 } else {
00418 #ifdef ORO_SIGNALLING_OPERATIONS
00419 if (this->msig) this->msig->emit(a1,a2,a3,a4);
00420 #endif
00421 if ( this->mmeth )
00422 return this->mmeth(a1,a2,a3,a4);
00423 else
00424 return NA<result_type>::na();
00425 }
00426 return NA<result_type>::na();
00427 }
00428
00429 template<class T1, class T2, class T3, class T4, class T5>
00430 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00431 {
00432 SendHandle<Signature> h;
00433 if (this->isSend()) {
00434 h = send_impl<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
00435 if ( h.collect() == SendSuccess )
00436 return h.ret(a1,a2,a3,a4,a5);
00437 else
00438 throw SendFailure;
00439 } else {
00440 #ifdef ORO_SIGNALLING_OPERATIONS
00441 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5);
00442 #endif
00443 if ( this->mmeth )
00444 return this->mmeth(a1,a2,a3,a4,a5);
00445 else
00446 return NA<result_type>::na();
00447 }
00448 return NA<result_type>::na();
00449 }
00450
00451 template<class T1, class T2, class T3, class T4, class T5, class T6>
00452 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00453 {
00454 SendHandle<Signature> h;
00455 if (this->isSend()) {
00456 h = send_impl<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6);
00457 if ( h.collect() == SendSuccess )
00458 return h.ret(a1,a2,a3,a4,a5,a6);
00459 else
00460 throw SendFailure;
00461 } else {
00462 #ifdef ORO_SIGNALLING_OPERATIONS
00463 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6);
00464 #endif
00465 if ( this->mmeth )
00466 return this->mmeth(a1,a2,a3,a4,a5,a6);
00467 else
00468 return NA<result_type>::na();
00469 }
00470 return NA<result_type>::na();
00471 }
00472
00473 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00474 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00475 {
00476 SendHandle<Signature> h;
00477 if (this->isSend()) {
00478 h = send_impl<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7);
00479 if ( h.collect() == SendSuccess )
00480 return h.ret(a1,a2,a3,a4,a5,a6,a7);
00481 else
00482 throw SendFailure;
00483 } else {
00484 #ifdef ORO_SIGNALLING_OPERATIONS
00485 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6,a7);
00486 #endif
00487 if ( this->mmeth )
00488 return this->mmeth(a1,a2,a3,a4,a5,a6,a7);
00489 else
00490 return NA<result_type>::na();
00491 }
00492 return NA<result_type>::na();
00493 }
00494
00495 result_type ret_impl()
00496 {
00497 this->retv.checkError();
00498 return this->retv.result();
00499 }
00500
00506 template<class T1>
00507 result_type ret_impl(T1 a1)
00508 {
00509 this->retv.checkError();
00510 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00511 bf::vector<T1> vArgs( boost::ref(a1) );
00512 if ( this->retv.isExecuted())
00513 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00514 return this->retv.result();
00515 }
00516
00517 template<class T1,class T2>
00518 result_type ret_impl(T1 a1, T2 a2)
00519 {
00520 this->retv.checkError();
00521 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00522 bf::vector<T1,T2> vArgs( boost::ref(a1), boost::ref(a2) );
00523 if ( this->retv.isExecuted())
00524 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg< boost::remove_reference<mpl::_> > >(this->vStore);
00525 return this->retv.result();
00526 }
00527
00528 template<class T1,class T2, class T3>
00529 result_type ret_impl(T1 a1, T2 a2, T3 a3)
00530 {
00531 this->retv.checkError();
00532 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00533 bf::vector<T1,T2,T3> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3) );
00534 if ( this->retv.isExecuted())
00535 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00536 return this->retv.result();
00537 }
00538
00539 template<class T1,class T2, class T3, class T4>
00540 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00541 {
00542 this->retv.checkError();
00543 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00544 bf::vector<T1,T2,T3,T4> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4) );
00545 if ( this->retv.isExecuted())
00546 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00547 return this->retv.result();
00548 }
00549
00550 template<class T1,class T2, class T3, class T4, class T5>
00551 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00552 {
00553 this->retv.checkError();
00554 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00555 bf::vector<T1,T2,T3,T4,T5> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5) );
00556 if ( this->retv.isExecuted())
00557 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00558 return this->retv.result();
00559 }
00560
00561 template<class T1,class T2, class T3, class T4, class T5, class T6>
00562 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00563 {
00564 this->retv.checkError();
00565 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00566 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) );
00567 if ( this->retv.isExecuted())
00568 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00569 return this->retv.result();
00570 }
00571
00572 template<class T1,class T2, class T3, class T4, class T5, class T6, class T7>
00573 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00574 {
00575 this->retv.checkError();
00576 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00577 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) );
00578 if ( this->retv.isExecuted())
00579 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00580 return this->retv.result();
00581 }
00582
00583 virtual shared_ptr cloneRT() const = 0;
00584 protected:
00585 typedef BindStorage<FunctionT> Store;
00591 typename base::OperationCallerBase<FunctionT>::shared_ptr self;
00592 };
00593
00603 template<class FunctionT>
00604 struct LocalOperationCaller
00605 : public Invoker<FunctionT,LocalOperationCallerImpl<FunctionT> >
00606 {
00607 typedef FunctionT Signature;
00608 typedef typename boost::function_traits<Signature>::result_type result_type;
00609 typedef boost::function_traits<Signature> traits;
00610
00611 typedef boost::shared_ptr<LocalOperationCaller> shared_ptr;
00612
00618 LocalOperationCaller()
00619 {}
00620
00631 template<class M, class ObjectType>
00632 LocalOperationCaller(M meth, ObjectType object, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread, ExecutionEngine* oe = NULL )
00633 {
00634 this->setExecutor( ee );
00635 this->setCaller( caller );
00636 this->setOwner(oe);
00637 this->setThread( et, ee );
00638 this->mmeth = OperationCallerBinder<Signature>()(meth, object);
00639 }
00640
00646 template<class M>
00647 LocalOperationCaller(M meth, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread, ExecutionEngine* oe = NULL )
00648 {
00649 this->setExecutor( ee );
00650 this->setCaller( caller );
00651 this->setOwner(oe);
00652 this->setThread( et, ee );
00653 this->mmeth = meth;
00654 }
00655
00656 boost::function<Signature> getOperationCallerFunction() const
00657 {
00658 return this->mmeth;
00659 }
00660
00661 #ifdef ORO_SIGNALLING_OPERATIONS
00662 void setSignal(typename Signal<Signature>::shared_ptr sig) {
00663 this->msig = sig;
00664 }
00665 #endif
00666 base::OperationCallerBase<Signature>* cloneI(ExecutionEngine* caller) const
00667 {
00668 LocalOperationCaller<Signature>* ret = new LocalOperationCaller<Signature>(*this);
00669 ret->setCaller( caller );
00670 #ifdef ORO_SIGNALLING_OPERATIONS
00671 ret->setSignal( this->msig );
00672 #endif
00673 return ret;
00674 }
00675
00676 typename LocalOperationCallerImpl<Signature>::shared_ptr cloneRT() const
00677 {
00678
00679
00680 return boost::allocate_shared<LocalOperationCaller<Signature> >(os::rt_allocator<LocalOperationCaller<Signature> >(), *this);
00681 }
00682 };
00683 }
00684 }
00685
00686 #endif