Orocos Real-Time Toolkit
2.5.0
|
00001 /*************************************************************************** 00002 tag: FMTC do nov 2 13:06:05 CET 2006 LocalOperationCaller.hpp 00003 00004 LocalOperationCaller.hpp - description 00005 ------------------- 00006 begin : do november 02 2006 00007 copyright : (C) 2006 FMTC 00008 email : peter.soetens@fmtc.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 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 // For doing I/O 00060 #include <boost/fusion/sequence/io.hpp> 00061 00062 namespace RTT 00063 { 00064 namespace internal 00065 { 00077 template<class FunctionT> 00078 class LocalOperationCallerImpl 00079 : public base::OperationCallerBase<FunctionT>, 00080 public internal::CollectBase<FunctionT>, 00081 protected BindStorage<FunctionT> 00082 { 00083 public: 00084 LocalOperationCallerImpl() : myengine(GlobalEngine::Instance()), caller(GlobalEngine::Instance()) {} 00085 typedef FunctionT Signature; 00086 typedef typename boost::function_traits<Signature>::result_type result_type; 00087 typedef typename boost::function_traits<Signature>::result_type result_reference; 00088 typedef boost::function_traits<Signature> traits; 00089 00090 typedef boost::shared_ptr<LocalOperationCallerImpl> shared_ptr; 00091 00092 virtual bool ready() const { 00093 return true; 00094 } 00095 00096 virtual void setExecutor(ExecutionEngine* ee) { 00097 if (met == OwnThread) 00098 myengine = ee; 00099 else 00100 myengine = GlobalEngine::Instance(); 00101 } 00102 00103 virtual void setCaller(ExecutionEngine* ee) { 00104 if (ee) 00105 caller = ee; 00106 else 00107 caller = GlobalEngine::Instance(); 00108 } 00109 00110 virtual bool setThread(ExecutionThread et, ExecutionEngine* executor) { 00111 met = et; 00112 setExecutor(executor); 00113 return true; 00114 } 00115 00116 void executeAndDispose() { 00117 if (!this->retv.isExecuted()) { 00118 this->exec(); // calls BindStorage. 00119 //cout << "executed method"<<endl; 00120 bool result = false; 00121 if (caller){ 00122 result = caller->process(this); 00123 } 00124 if (!result) 00125 dispose(); 00126 } else { 00127 //cout << "received method done msg."<<endl; 00128 // Already executed, are in caller. 00129 // nop, we will check ret in collect() 00130 // This is the place to call call-back functions, 00131 // since we're in the caller's (or proxy's) EE. 00132 dispose(); 00133 } 00134 return; 00135 } 00136 00141 void dispose() { 00142 //this->~LocalOperationCallerImpl(); 00143 //oro_rt_free(this); 00144 self.reset(); 00145 } 00146 00147 ExecutionEngine* getMessageProcessor() const { return myengine; } 00148 00149 SendHandle<Signature> do_send(shared_ptr cl) { 00150 assert(myengine); // myengine must be either the caller's engine or GlobalEngine::Instance(). 00151 //std::cout << "Sending clone..."<<std::endl; 00152 if ( myengine->process( cl.get() ) ) { 00153 cl->self = cl; 00154 return SendHandle<Signature>( cl ); 00155 } else { 00156 // cleanup. Done by shared_ptr. 00157 //cl->~OperationCallerBase(); 00158 //oro_rt_free(cl); 00159 return SendHandle<Signature>(); 00160 } 00161 } 00162 // We need a handle object ! 00163 SendHandle<Signature> send_impl() { 00164 return do_send( this->cloneRT() ); 00165 } 00166 00167 template<class T1> 00168 SendHandle<Signature> send_impl( T1 a1 ) { 00169 // bind types from Storage<Function> 00170 shared_ptr cl = this->cloneRT(); 00171 cl->store( a1 ); 00172 return do_send(cl); 00173 } 00174 00175 template<class T1, class T2> 00176 SendHandle<Signature> send_impl( T1 a1, T2 a2 ) { 00177 // bind types from Storage<Function> 00178 shared_ptr cl = this->cloneRT(); 00179 cl->store( a1,a2 ); 00180 return do_send(cl); 00181 } 00182 00183 template<class T1, class T2, class T3> 00184 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3 ) { 00185 // bind types from Storage<Function> 00186 shared_ptr cl = this->cloneRT(); 00187 cl->store( a1,a2,a3 ); 00188 return do_send(cl); 00189 } 00190 00191 template<class T1, class T2, class T3, class T4> 00192 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4 ) { 00193 // bind types from Storage<Function> 00194 shared_ptr cl = this->cloneRT(); 00195 cl->store( a1,a2,a3,a4 ); 00196 return do_send(cl); 00197 } 00198 00199 template<class T1, class T2, class T3, class T4, class T5> 00200 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5 ) { 00201 // bind types from Storage<Function> 00202 shared_ptr cl = this->cloneRT(); 00203 cl->store( a1,a2,a3,a4,a5 ); 00204 return do_send(cl); 00205 } 00206 00207 template<class T1, class T2, class T3, class T4, class T5, class T6> 00208 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6 ) { 00209 // bind types from Storage<Function> 00210 shared_ptr cl = this->cloneRT(); 00211 cl->store( a1,a2,a3,a4,a5,a6 ); 00212 return do_send(cl); 00213 } 00214 00215 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7> 00216 SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7 ) { 00217 // bind types from Storage<Function> 00218 shared_ptr cl = this->cloneRT(); 00219 cl->store( a1,a2,a3,a4,a5,a6,a7 ); 00220 return do_send(cl); 00221 } 00222 00223 00224 SendStatus collectIfDone_impl() { 00225 if ( this->retv.isExecuted()) { 00226 return SendSuccess; 00227 } else 00228 return SendNotReady; 00229 } 00230 00231 // collect_impl belongs in LocalOperationCallerImpl because it would need 00232 // to be repeated in each BindStorage spec. 00233 template<class T1> 00234 SendStatus collectIfDone_impl( T1& a1 ) { 00235 if ( this->retv.isExecuted()) { 00236 bf::vector_tie(a1) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore); 00237 return SendSuccess; 00238 } else 00239 return SendNotReady; 00240 } 00241 00242 template<class T1, class T2> 00243 SendStatus collectIfDone_impl( T1& a1, T2& a2 ) { 00244 if ( this->retv.isExecuted()) { 00245 bf::vector_tie(a1,a2) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore); 00246 return SendSuccess; 00247 } 00248 return SendNotReady; 00249 } 00250 00251 template<class T1, class T2, class T3> 00252 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3 ) { 00253 if ( this->retv.isExecuted()) { 00254 bf::vector_tie(a1,a2,a3) = 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> 00261 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4 ) { 00262 if ( this->retv.isExecuted()) { 00263 bf::vector_tie(a1,a2,a3,a4) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore); 00264 return SendSuccess; 00265 } else 00266 return SendNotReady; 00267 } 00268 00269 template<class T1, class T2, class T3, class T4, class T5> 00270 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5 ) { 00271 if ( this->retv.isExecuted()) { 00272 bf::vector_tie(a1,a2,a3,a4,a5) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore); 00273 return SendSuccess; 00274 } else 00275 return SendNotReady; 00276 } 00277 00278 template<class T1, class T2, class T3, class T4, class T5, class T6> 00279 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6 ) { 00280 if ( this->retv.isExecuted()) { 00281 bf::vector_tie(a1,a2,a3,a4,a5,a6) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore); 00282 return SendSuccess; 00283 } else 00284 return SendNotReady; 00285 } 00286 00287 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7> 00288 SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7 ) { 00289 if ( this->retv.isExecuted()) { 00290 bf::vector_tie(a1,a2,a3,a4,a5,a6,a7) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore); 00291 return SendSuccess; 00292 } else 00293 return SendNotReady; 00294 } 00295 00296 SendStatus collect_impl() { 00297 caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) ); 00298 return this->collectIfDone_impl(); 00299 } 00300 template<class T1> 00301 SendStatus collect_impl( T1& a1 ) { 00302 caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) ); 00303 return this->collectIfDone_impl(a1); 00304 } 00305 00306 template<class T1, class T2> 00307 SendStatus collect_impl( T1& a1, T2& a2 ) { 00308 caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) ); 00309 return this->collectIfDone_impl(a1,a2); 00310 } 00311 00312 template<class T1, class T2, class T3> 00313 SendStatus collect_impl( T1& a1, T2& a2, T3& a3 ) { 00314 caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) ); 00315 return this->collectIfDone_impl(a1,a2,a3); 00316 } 00317 00321 result_type call_impl() 00322 { 00323 00324 if (met == OwnThread && myengine != caller) { 00325 SendHandle<Signature> h = send_impl(); 00326 if ( h.collect() == SendSuccess ) 00327 return h.ret(); 00328 else 00329 throw SendFailure; 00330 } else { 00331 #ifdef ORO_SIGNALLING_OPERATIONS 00332 if (this->msig) this->msig->emit(); 00333 #endif 00334 if ( this->mmeth ) 00335 return this->mmeth(); // ClientThread 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 // collect_impl may take diff number of arguments than 00352 // call_impl/ret_impl(), so we use generic collect() + ret_impl() 00353 if ( h.collect() == SendSuccess ) 00354 return h.ret(a1); 00355 else 00356 throw SendFailure; 00357 } else{ 00358 #ifdef ORO_SIGNALLING_OPERATIONS 00359 if (this->msig) this->msig->emit(a1); 00360 #endif 00361 if ( this->mmeth ) 00362 return this->mmeth(a1); 00363 else 00364 return NA<result_type>::na(); 00365 } 00366 return NA<result_type>::na(); 00367 } 00368 00369 template<class T1, class T2> 00370 result_type call_impl(T1 a1, T2 a2) 00371 { 00372 SendHandle<Signature> h; 00373 if (met == OwnThread && myengine != caller) { 00374 h = send_impl<T1,T2>(a1,a2); 00375 if ( h.collect() == SendSuccess ) 00376 return h.ret(a1,a2); 00377 else 00378 throw SendFailure; 00379 } else { 00380 #ifdef ORO_SIGNALLING_OPERATIONS 00381 if (this->msig) this->msig->emit(a1,a2); 00382 #endif 00383 if ( this->mmeth ) 00384 return this->mmeth(a1,a2); 00385 else 00386 return NA<result_type>::na(); 00387 } 00388 return NA<result_type>::na(); 00389 } 00390 00391 template<class T1, class T2, class T3> 00392 result_type call_impl(T1 a1, T2 a2, T3 a3) 00393 { 00394 SendHandle<Signature> h; 00395 if (met == OwnThread && myengine != caller) { 00396 h = send_impl<T1,T2,T3>(a1,a2,a3); 00397 if ( h.collect() == SendSuccess ) 00398 return h.ret(a1,a2,a3); 00399 else 00400 throw SendFailure; 00401 } else { 00402 #ifdef ORO_SIGNALLING_OPERATIONS 00403 if (this->msig) this->msig->emit(a1,a2,a3); 00404 #endif 00405 if ( this->mmeth ) 00406 return this->mmeth(a1,a2,a3); 00407 else 00408 return NA<result_type>::na(); 00409 } 00410 return NA<result_type>::na(); 00411 } 00412 00413 template<class T1, class T2, class T3, class T4> 00414 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4) 00415 { 00416 SendHandle<Signature> h; 00417 if (met == OwnThread && myengine != caller) { 00418 h = send_impl<T1,T2,T3,T4>(a1,a2,a3,a4); 00419 if ( h.collect() == SendSuccess ) 00420 return h.ret(a1,a2,a3,a4); 00421 else 00422 throw SendFailure; 00423 } else { 00424 #ifdef ORO_SIGNALLING_OPERATIONS 00425 if (this->msig) this->msig->emit(a1,a2,a3,a4); 00426 #endif 00427 if ( this->mmeth ) 00428 return this->mmeth(a1,a2,a3,a4); 00429 else 00430 return NA<result_type>::na(); 00431 } 00432 return NA<result_type>::na(); 00433 } 00434 00435 template<class T1, class T2, class T3, class T4, class T5> 00436 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 00437 { 00438 SendHandle<Signature> h; 00439 if (met == OwnThread && myengine != caller) { 00440 h = send_impl<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5); 00441 if ( h.collect() == SendSuccess ) 00442 return h.ret(a1,a2,a3,a4,a5); 00443 else 00444 throw SendFailure; 00445 } else { 00446 #ifdef ORO_SIGNALLING_OPERATIONS 00447 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5); 00448 #endif 00449 if ( this->mmeth ) 00450 return this->mmeth(a1,a2,a3,a4,a5); 00451 else 00452 return NA<result_type>::na(); 00453 } 00454 return NA<result_type>::na(); 00455 } 00456 00457 template<class T1, class T2, class T3, class T4, class T5, class T6> 00458 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) 00459 { 00460 SendHandle<Signature> h; 00461 if (met == OwnThread && myengine != caller) { 00462 h = send_impl<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6); 00463 if ( h.collect() == SendSuccess ) 00464 return h.ret(a1,a2,a3,a4,a5,a6); 00465 else 00466 throw SendFailure; 00467 } else { 00468 #ifdef ORO_SIGNALLING_OPERATIONS 00469 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6); 00470 #endif 00471 if ( this->mmeth ) 00472 return this->mmeth(a1,a2,a3,a4,a5,a6); 00473 else 00474 return NA<result_type>::na(); 00475 } 00476 return NA<result_type>::na(); 00477 } 00478 00479 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7> 00480 result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) 00481 { 00482 SendHandle<Signature> h; 00483 if (met == OwnThread && myengine != caller) { 00484 h = send_impl<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7); 00485 if ( h.collect() == SendSuccess ) 00486 return h.ret(a1,a2,a3,a4,a5,a6,a7); 00487 else 00488 throw SendFailure; 00489 } else { 00490 #ifdef ORO_SIGNALLING_OPERATIONS 00491 if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6,a7); 00492 #endif 00493 if ( this->mmeth ) 00494 return this->mmeth(a1,a2,a3,a4,a5,a6,a7); 00495 else 00496 return NA<result_type>::na(); 00497 } 00498 return NA<result_type>::na(); 00499 } 00500 00501 result_type ret_impl() 00502 { 00503 return this->retv.result(); // may return void. 00504 } 00505 00511 template<class T1> 00512 result_type ret_impl(T1 a1) 00513 { 00514 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred; 00515 bf::vector<T1> vArgs( boost::ref(a1) ); 00516 if ( this->retv.isExecuted()) 00517 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore); 00518 return this->retv.result(); // may return void. 00519 } 00520 00521 template<class T1,class T2> 00522 result_type ret_impl(T1 a1, T2 a2) 00523 { 00524 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred; 00525 bf::vector<T1,T2> vArgs( boost::ref(a1), boost::ref(a2) ); 00526 if ( this->retv.isExecuted()) 00527 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg< boost::remove_reference<mpl::_> > >(this->vStore); 00528 return this->retv.result(); // may return void. 00529 } 00530 00531 template<class T1,class T2, class T3> 00532 result_type ret_impl(T1 a1, T2 a2, T3 a3) 00533 { 00534 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred; 00535 bf::vector<T1,T2,T3> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3) ); 00536 if ( this->retv.isExecuted()) 00537 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore); 00538 return this->retv.result(); // may return void. 00539 } 00540 00541 template<class T1,class T2, class T3, class T4> 00542 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4) 00543 { 00544 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred; 00545 bf::vector<T1,T2,T3,T4> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4) ); 00546 if ( this->retv.isExecuted()) 00547 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore); 00548 return this->retv.result(); // may return void. 00549 } 00550 00551 template<class T1,class T2, class T3, class T4, class T5> 00552 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 00553 { 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(); // may return void. 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 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred; 00565 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) ); 00566 if ( this->retv.isExecuted()) 00567 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore); 00568 return this->retv.result(); // may return void. 00569 } 00570 00571 template<class T1,class T2, class T3, class T4, class T5, class T6, class T7> 00572 result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) 00573 { 00574 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred; 00575 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) ); 00576 if ( this->retv.isExecuted()) 00577 as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore); 00578 return this->retv.result(); // may return void. 00579 } 00580 00581 virtual shared_ptr cloneRT() const = 0; 00582 00583 protected: 00584 ExecutionEngine* myengine; 00585 ExecutionEngine* caller; 00586 typedef BindStorage<FunctionT> Store; 00587 ExecutionThread met; 00593 typename base::OperationCallerBase<FunctionT>::shared_ptr self; 00594 }; 00595 00605 template<class FunctionT> 00606 struct LocalOperationCaller 00607 : public Invoker<FunctionT,LocalOperationCallerImpl<FunctionT> > 00608 { 00609 typedef FunctionT Signature; 00610 typedef typename boost::function_traits<Signature>::result_type result_type; 00611 typedef boost::function_traits<Signature> traits; 00612 00613 typedef boost::shared_ptr<LocalOperationCaller> shared_ptr; 00614 00620 LocalOperationCaller() 00621 {} 00622 00631 template<class M, class ObjectType> 00632 LocalOperationCaller(M meth, ObjectType object, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread ) 00633 { 00634 if (!ee) 00635 ee = GlobalEngine::Instance(); 00636 this->mmeth = OperationCallerBinder<Signature>()(meth, object); 00637 this->myengine = ee; 00638 this->caller = caller; 00639 this->met = et; 00640 } 00641 00648 template<class M> 00649 LocalOperationCaller(M meth, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread ) 00650 { 00651 if (!ee) 00652 ee = GlobalEngine::Instance(); 00653 this->mmeth = meth; 00654 this->myengine = ee; 00655 this->caller = caller; 00656 this->met = et; 00657 } 00658 00659 boost::function<Signature> getOperationCallerFunction() const 00660 { 00661 return this->mmeth; 00662 } 00663 00664 #ifdef ORO_SIGNALLING_OPERATIONS 00665 void setSignal(typename Signal<Signature>::shared_ptr sig) { 00666 this->msig = sig; 00667 } 00668 #endif 00669 base::OperationCallerBase<Signature>* cloneI(ExecutionEngine* caller) const 00670 { 00671 LocalOperationCaller<Signature>* ret = new LocalOperationCaller<Signature>(*this); 00672 ret->setCaller( caller ); 00673 #ifdef ORO_SIGNALLING_OPERATIONS 00674 ret->setSignal( this->msig ); 00675 #endif 00676 return ret; 00677 } 00678 00679 typename LocalOperationCallerImpl<Signature>::shared_ptr cloneRT() const 00680 { 00681 //void* obj = oro_rt_malloc(sizeof(LocalOperationCallerImpl<Signature>)); 00682 //return new(obj) LocalOperationCaller<Signature>(*this); 00683 return boost::allocate_shared<LocalOperationCaller<Signature> >(os::rt_allocator<LocalOperationCaller<Signature> >(), *this); 00684 } 00685 }; 00686 } 00687 } 00688 00689 #endif