Orocos Real-Time Toolkit
2.6.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 <boost/fusion/include/vector_tie.hpp> 00055 #include "../os/oro_allocator.hpp" 00056 00057 #include <iostream> 00058 // For doing I/O 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(); // calls BindStorage. 00102 //cout << "executed method"<<endl; 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 //cout << "received method done msg."<<endl; 00113 // Already executed, are in caller. 00114 // nop, we will check ret in collect() 00115 // This is the place to call call-back functions, 00116 // since we're in the caller's (or proxy's) EE. 00117 dispose(); 00118 } 00119 return; 00120 } 00121 00126 void dispose() { 00127 //this->~LocalOperationCallerImpl(); 00128 //oro_rt_free(this); 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); // myengine must be either the caller's engine or GlobalEngine::Instance(). 00137 //std::cout << "Sending clone..."<<std::endl; 00138 if ( this->myengine->process( cl.get() ) ) { 00139 cl->self = cl; 00140 return SendHandle<Signature>( cl ); 00141 } else { 00142 // cleanup. Done by shared_ptr. 00143 //cl->~OperationCallerBase(); 00144 //oro_rt_free(cl); 00145 return SendHandle<Signature>(); 00146 } 00147 } 00148 // We need a handle object ! 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 // bind types from Storage<Function> 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 // bind types from Storage<Function> 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 // bind types from Storage<Function> 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 // bind types from Storage<Function> 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 // bind types from Storage<Function> 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 // bind types from Storage<Function> 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 // bind types from Storage<Function> 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 // collect_impl belongs in LocalOperationCallerImpl because it would need 00219 // to be repeated in each BindStorage spec. 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(); // ClientThread 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 // collect_impl may take diff number of arguments than 00346 // call_impl/ret_impl(), so we use generic collect() + ret_impl() 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(); // may return void. 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(); // may return void. 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(); // may return void. 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(); // may return void. 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(); // may return void. 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(); // 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 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(); // may return void. 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(); // may return void. 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 //void* obj = oro_rt_malloc(sizeof(LocalOperationCallerImpl<Signature>)); 00679 //return new(obj) LocalOperationCaller<Signature>(*this); 00680 return boost::allocate_shared<LocalOperationCaller<Signature> >(os::rt_allocator<LocalOperationCaller<Signature> >(), *this); 00681 } 00682 }; 00683 } 00684 } 00685 00686 #endif