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 "GlobalEngine.hpp"
00055 #include <boost/fusion/include/vector_tie.hpp>
00056 #include "../os/oro_allocator.hpp"
00057
00058 #include <iostream>
00059
00060 #include <boost/fusion/sequence/io.hpp>
00061 using namespace std;
00062
00063 namespace RTT
00064 {
00065 namespace internal
00066 {
00078 template<class FunctionT>
00079 class LocalOperationCallerImpl
00080 : public base::OperationCallerBase<FunctionT>,
00081 public internal::CollectBase<FunctionT>,
00082 protected BindStorage<FunctionT>
00083 {
00084 public:
00085 LocalOperationCallerImpl() : myengine(GlobalEngine::Instance()), caller(GlobalEngine::Instance()) {}
00086 typedef FunctionT Signature;
00087 typedef typename boost::function_traits<Signature>::result_type result_type;
00088 typedef typename boost::function_traits<Signature>::result_type result_reference;
00089 typedef boost::function_traits<Signature> traits;
00090
00091 typedef boost::shared_ptr<LocalOperationCallerImpl> shared_ptr;
00092
00093 virtual bool ready() const {
00094 return true;
00095 }
00096
00097 virtual void setExecutor(ExecutionEngine* ee) {
00098 if (met == OwnThread)
00099 myengine = ee;
00100 else
00101 myengine = GlobalEngine::Instance();
00102 }
00103
00104 virtual void setCaller(ExecutionEngine* ee) {
00105 if (ee)
00106 caller = ee;
00107 else
00108 caller = GlobalEngine::Instance();
00109 }
00110
00111 virtual bool setThread(ExecutionThread et, ExecutionEngine* executor) {
00112 met = et;
00113 setExecutor(executor);
00114 return true;
00115 }
00116
00117 void executeAndDispose() {
00118 using namespace std;
00119 if (!this->retv.isExecuted()) {
00120 this->exec();
00121
00122 bool result = false;
00123 if (caller){
00124 result = caller->process(this);
00125 }
00126 if (!result)
00127 dispose();
00128 } else {
00129
00130
00131
00132
00133
00134 dispose();
00135 }
00136 return;
00137 }
00138
00143 void dispose() {
00144
00145
00146 self.reset();
00147 }
00148
00149 ExecutionEngine* getMessageProcessor() const { return myengine; }
00150
00151 SendHandle<Signature> do_send(shared_ptr cl) {
00152 assert(myengine);
00153
00154 if ( myengine->process( cl.get() ) ) {
00155 cl->self = cl;
00156 return SendHandle<Signature>( cl );
00157 } else {
00158
00159
00160
00161 return SendHandle<Signature>();
00162 }
00163 }
00164
00165 SendHandle<Signature> send_impl() {
00166 return do_send( this->cloneRT() );
00167 }
00168
00169 template<class T1>
00170 SendHandle<Signature> send_impl( T1 a1 ) {
00171
00172 shared_ptr cl = this->cloneRT();
00173 cl->store( a1 );
00174 return do_send(cl);
00175 }
00176
00177 template<class T1, class T2>
00178 SendHandle<Signature> send_impl( T1 a1, T2 a2 ) {
00179
00180 shared_ptr cl = this->cloneRT();
00181 cl->store( a1,a2 );
00182 return do_send(cl);
00183 }
00184
00185 template<class T1, class T2, class T3>
00186 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3 ) {
00187
00188 shared_ptr cl = this->cloneRT();
00189 cl->store( a1,a2,a3 );
00190 return do_send(cl);
00191 }
00192
00193 template<class T1, class T2, class T3, class T4>
00194 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4 ) {
00195
00196 shared_ptr cl = this->cloneRT();
00197 cl->store( a1,a2,a3,a4 );
00198 return do_send(cl);
00199 }
00200
00201 template<class T1, class T2, class T3, class T4, class T5>
00202 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5 ) {
00203
00204 shared_ptr cl = this->cloneRT();
00205 cl->store( a1,a2,a3,a4,a5 );
00206 return do_send(cl);
00207 }
00208
00209 template<class T1, class T2, class T3, class T4, class T5, class T6>
00210 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6 ) {
00211
00212 shared_ptr cl = this->cloneRT();
00213 cl->store( a1,a2,a3,a4,a5,a6 );
00214 return do_send(cl);
00215 }
00216
00217 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00218 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7 ) {
00219
00220 shared_ptr cl = this->cloneRT();
00221 cl->store( a1,a2,a3,a4,a5,a6,a7 );
00222 return do_send(cl);
00223 }
00224
00225
00226 SendStatus collectIfDone_impl() {
00227 if ( this->retv.isExecuted()) {
00228 return SendSuccess;
00229 } else
00230 return SendNotReady;
00231 }
00232
00233
00234
00235 template<class T1>
00236 SendStatus collectIfDone_impl( T1& a1 ) {
00237 if ( this->retv.isExecuted()) {
00238 bf::vector_tie(a1) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00239 return SendSuccess;
00240 } else
00241 return SendNotReady;
00242 }
00243
00244 template<class T1, class T2>
00245 SendStatus collectIfDone_impl( T1& a1, T2& a2 ) {
00246 if ( this->retv.isExecuted()) {
00247 bf::vector_tie(a1,a2) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00248 return SendSuccess;
00249 }
00250 return SendNotReady;
00251 }
00252
00253 template<class T1, class T2, class T3>
00254 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3 ) {
00255 if ( this->retv.isExecuted()) {
00256 bf::vector_tie(a1,a2,a3) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00257 return SendSuccess;
00258 } else
00259 return SendNotReady;
00260 }
00261
00262 template<class T1, class T2, class T3, class T4>
00263 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4 ) {
00264 if ( this->retv.isExecuted()) {
00265 bf::vector_tie(a1,a2,a3,a4) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00266 return SendSuccess;
00267 } else
00268 return SendNotReady;
00269 }
00270
00271 template<class T1, class T2, class T3, class T4, class T5>
00272 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5 ) {
00273 if ( this->retv.isExecuted()) {
00274 bf::vector_tie(a1,a2,a3,a4,a5) = 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>
00281 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6 ) {
00282 if ( this->retv.isExecuted()) {
00283 bf::vector_tie(a1,a2,a3,a4,a5,a6) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00284 return SendSuccess;
00285 } else
00286 return SendNotReady;
00287 }
00288
00289 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00290 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7 ) {
00291 if ( this->retv.isExecuted()) {
00292 bf::vector_tie(a1,a2,a3,a4,a5,a6,a7) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00293 return SendSuccess;
00294 } else
00295 return SendNotReady;
00296 }
00297
00298 SendStatus collect_impl() {
00299 caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00300 return this->collectIfDone_impl();
00301 }
00302 template<class T1>
00303 SendStatus collect_impl( T1& a1 ) {
00304 caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00305 return this->collectIfDone_impl(a1);
00306 }
00307
00308 template<class T1, class T2>
00309 SendStatus collect_impl( T1& a1, T2& a2 ) {
00310 caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00311 return this->collectIfDone_impl(a1,a2);
00312 }
00313
00314 template<class T1, class T2, class T3>
00315 SendStatus collect_impl( T1& a1, T2& a2, T3& a3 ) {
00316 caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00317 return this->collectIfDone_impl(a1,a2,a3);
00318 }
00319
00323 result_type call_impl()
00324 {
00325
00326 if (met == OwnThread && myengine != caller) {
00327 SendHandle<Signature> h = send_impl();
00328 if ( h.collect() == SendSuccess )
00329 return h.ret();
00330 else
00331 throw SendFailure;
00332 } else {
00333 if (this->msig) this->msig->emit();
00334 if ( this->mmeth )
00335 return this->mmeth();
00336 else
00337 return NA<result_type>::na();
00338 }
00339 }
00340
00341
00345 template<class T1>
00346 result_type call_impl(T1 a1)
00347 {
00348 SendHandle<Signature> h;
00349 if (met == OwnThread && myengine != caller) {
00350 h = send_impl<T1>(a1);
00351
00352
00353 if ( h.collect() == SendSuccess )
00354 return h.ret(a1);
00355 else
00356 throw SendFailure;
00357 } else{
00358 if (this->msig) this->msig->emit(a1);
00359 if ( this->mmeth )
00360 return this->mmeth(a1);
00361 else
00362 return NA<result_type>::na();
00363 }
00364 return NA<result_type>::na();
00365 }
00366
00367 template<class T1, class T2>
00368 result_type call_impl(T1 a1, T2 a2)
00369 {
00370 SendHandle<Signature> h;
00371 if (met == OwnThread && myengine != caller) {
00372 h = send_impl<T1,T2>(a1,a2);
00373 if ( h.collect() == SendSuccess )
00374 return h.ret(a1,a2);
00375 else
00376 throw SendFailure;
00377 } else {
00378 if (this->msig) this->msig->emit(a1,a2);
00379 if ( this->mmeth )
00380 return this->mmeth(a1,a2);
00381 else
00382 return NA<result_type>::na();
00383 }
00384 return NA<result_type>::na();
00385 }
00386
00387 template<class T1, class T2, class T3>
00388 result_type call_impl(T1 a1, T2 a2, T3 a3)
00389 {
00390 SendHandle<Signature> h;
00391 if (met == OwnThread && myengine != caller) {
00392 h = send_impl<T1,T2,T3>(a1,a2,a3);
00393 if ( h.collect() == SendSuccess )
00394 return h.ret(a1,a2,a3);
00395 else
00396 throw SendFailure;
00397 } else {
00398 if (this->msig) this->msig->emit(a1,a2,a3);
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 (met == OwnThread && myengine != caller) {
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 if (this->msig) this->msig->emit(a1,a2,a3,a4);
00419 if ( this->mmeth )
00420 return this->mmeth(a1,a2,a3,a4);
00421 else
00422 return NA<result_type>::na();
00423 }
00424 return NA<result_type>::na();
00425 }
00426
00427 template<class T1, class T2, class T3, class T4, class T5>
00428 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00429 {
00430 SendHandle<Signature> h;
00431 if (met == OwnThread && myengine != caller) {
00432 h = send_impl<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
00433 if ( h.collect() == SendSuccess )
00434 return h.ret(a1,a2,a3,a4,a5);
00435 else
00436 throw SendFailure;
00437 } else {
00438 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5);
00439 if ( this->mmeth )
00440 return this->mmeth(a1,a2,a3,a4,a5);
00441 else
00442 return NA<result_type>::na();
00443 }
00444 return NA<result_type>::na();
00445 }
00446
00447 template<class T1, class T2, class T3, class T4, class T5, class T6>
00448 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00449 {
00450 SendHandle<Signature> h;
00451 if (met == OwnThread && myengine != caller) {
00452 h = send_impl<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6);
00453 if ( h.collect() == SendSuccess )
00454 return h.ret(a1,a2,a3,a4,a5,a6);
00455 else
00456 throw SendFailure;
00457 } else {
00458 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6);
00459 if ( this->mmeth )
00460 return this->mmeth(a1,a2,a3,a4,a5,a6);
00461 else
00462 return NA<result_type>::na();
00463 }
00464 return NA<result_type>::na();
00465 }
00466
00467 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00468 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00469 {
00470 SendHandle<Signature> h;
00471 if (met == OwnThread && myengine != caller) {
00472 h = send_impl<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7);
00473 if ( h.collect() == SendSuccess )
00474 return h.ret(a1,a2,a3,a4,a5,a6,a7);
00475 else
00476 throw SendFailure;
00477 } else {
00478 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6,a7);
00479 if ( this->mmeth )
00480 return this->mmeth(a1,a2,a3,a4,a5,a6,a7);
00481 else
00482 return NA<result_type>::na();
00483 }
00484 return NA<result_type>::na();
00485 }
00486
00487 result_type ret_impl()
00488 {
00489 return this->retv.result();
00490 }
00491
00497 template<class T1>
00498 result_type ret_impl(T1 a1)
00499 {
00500 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00501 bf::vector<T1> vArgs( boost::ref(a1) );
00502 if ( this->retv.isExecuted())
00503 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00504 return this->retv.result();
00505 }
00506
00507 template<class T1,class T2>
00508 result_type ret_impl(T1 a1, T2 a2)
00509 {
00510 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00511 bf::vector<T1,T2> vArgs( boost::ref(a1), boost::ref(a2) );
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, class T3>
00518 result_type ret_impl(T1 a1, T2 a2, T3 a3)
00519 {
00520 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00521 bf::vector<T1,T2,T3> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3) );
00522 if ( this->retv.isExecuted())
00523 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00524 return this->retv.result();
00525 }
00526
00527 template<class T1,class T2, class T3, class T4>
00528 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00529 {
00530 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00531 bf::vector<T1,T2,T3,T4> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4) );
00532 if ( this->retv.isExecuted())
00533 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00534 return this->retv.result();
00535 }
00536
00537 template<class T1,class T2, class T3, class T4, class T5>
00538 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00539 {
00540 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00541 bf::vector<T1,T2,T3,T4,T5> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5) );
00542 if ( this->retv.isExecuted())
00543 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00544 return this->retv.result();
00545 }
00546
00547 template<class T1,class T2, class T3, class T4, class T5, class T6>
00548 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00549 {
00550 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00551 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) );
00552 if ( this->retv.isExecuted())
00553 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00554 return this->retv.result();
00555 }
00556
00557 template<class T1,class T2, class T3, class T4, class T5, class T6, class T7>
00558 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00559 {
00560 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00561 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) );
00562 if ( this->retv.isExecuted())
00563 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00564 return this->retv.result();
00565 }
00566
00567 virtual shared_ptr cloneRT() const = 0;
00568
00569 protected:
00570 ExecutionEngine* myengine;
00571 ExecutionEngine* caller;
00572 typedef BindStorage<FunctionT> Store;
00573 ExecutionThread met;
00579 typename base::OperationCallerBase<FunctionT>::shared_ptr self;
00580 };
00581
00591 template<class FunctionT>
00592 struct LocalOperationCaller
00593 : public Invoker<FunctionT,LocalOperationCallerImpl<FunctionT> >
00594 {
00595 typedef FunctionT Signature;
00596 typedef typename boost::function_traits<Signature>::result_type result_type;
00597 typedef boost::function_traits<Signature> traits;
00598
00599 typedef boost::shared_ptr<LocalOperationCaller> shared_ptr;
00600
00606 LocalOperationCaller()
00607 {}
00608
00617 template<class M, class ObjectType>
00618 LocalOperationCaller(M meth, ObjectType object, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread )
00619 {
00620 if (!ee)
00621 ee = GlobalEngine::Instance();
00622 this->mmeth = OperationCallerBinder<Signature>()(meth, object);
00623 this->myengine = ee;
00624 this->caller = caller;
00625 this->met = et;
00626 }
00627
00634 template<class M>
00635 LocalOperationCaller(M meth, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread )
00636 {
00637 if (!ee)
00638 ee = GlobalEngine::Instance();
00639 this->mmeth = meth;
00640 this->myengine = ee;
00641 this->caller = caller;
00642 this->met = et;
00643 }
00644
00645 boost::function<Signature> getOperationCallerFunction() const
00646 {
00647 return this->mmeth;
00648 }
00649
00650 void setSignal(typename Signal<Signature>::shared_ptr sig) {
00651 this->msig = sig;
00652 }
00653
00654 base::OperationCallerBase<Signature>* cloneI(ExecutionEngine* caller) const
00655 {
00656 LocalOperationCaller<Signature>* ret = new LocalOperationCaller<Signature>(*this);
00657 ret->setCaller( caller );
00658 ret->setSignal( this->msig );
00659 return ret;
00660 }
00661
00662 typename LocalOperationCallerImpl<Signature>::shared_ptr cloneRT() const
00663 {
00664
00665
00666 return boost::allocate_shared<LocalOperationCaller<Signature> >(os::rt_allocator<LocalOperationCaller<Signature> >(), *this);
00667 }
00668 };
00669 }
00670 }
00671
00672 #endif