LocalOperationCaller.hpp
Go to the documentation of this file.
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                 self.reset();
00128             }
00129 
00130             SendHandle<Signature> do_send(shared_ptr cl) {
00131                 //std::cout << "Sending clone..."<<std::endl;
00132                 ExecutionEngine* receiver = this->getMessageProcessor();
00133                 cl->self = cl;
00134                 if ( receiver && receiver->process( cl.get() ) ) {
00135                     return SendHandle<Signature>( cl );
00136                 } else {
00137                     cl->dispose();
00138                     // cleanup. Done by shared_ptr.
00139                     return SendHandle<Signature>();
00140                 }
00141             }
00142             // We need a handle object !
00143             SendHandle<Signature> send_impl() {
00144                 return do_send( this->cloneRT() );
00145             }
00146 
00147             template<class T1>
00148             SendHandle<Signature> send_impl( T1 a1 ) {
00149                 // bind types from Storage<Function>
00150                 shared_ptr cl = this->cloneRT();
00151                 cl->store( a1 );
00152                 return do_send(cl);
00153             }
00154 
00155             template<class T1, class T2>
00156             SendHandle<Signature> send_impl( T1 a1, T2 a2 ) {
00157                 // bind types from Storage<Function>
00158                 shared_ptr cl = this->cloneRT();
00159                 cl->store( a1,a2 );
00160                 return do_send(cl);
00161             }
00162 
00163             template<class T1, class T2, class T3>
00164             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3 ) {
00165                 // bind types from Storage<Function>
00166                 shared_ptr cl = this->cloneRT();
00167                 cl->store( a1,a2,a3 );
00168                 return do_send(cl);
00169             }
00170 
00171             template<class T1, class T2, class T3, class T4>
00172             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4 ) {
00173                 // bind types from Storage<Function>
00174                 shared_ptr cl = this->cloneRT();
00175                 cl->store( a1,a2,a3,a4 );
00176                 return do_send(cl);
00177             }
00178 
00179             template<class T1, class T2, class T3, class T4, class T5>
00180             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5 ) {
00181                 // bind types from Storage<Function>
00182                 shared_ptr cl = this->cloneRT();
00183                 cl->store( a1,a2,a3,a4,a5 );
00184                 return do_send(cl);
00185             }
00186 
00187             template<class T1, class T2, class T3, class T4, class T5, class T6>
00188             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6 ) {
00189                 // bind types from Storage<Function>
00190                 shared_ptr cl = this->cloneRT();
00191                 cl->store( a1,a2,a3,a4,a5,a6 );
00192                 return do_send(cl);
00193             }
00194 
00195             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00196             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7 ) {
00197                 // bind types from Storage<Function>
00198                 shared_ptr cl = this->cloneRT();
00199                 cl->store( a1,a2,a3,a4,a5,a6,a7 );
00200                 return do_send(cl);
00201             }
00202 
00203 
00204             SendStatus collectIfDone_impl() {
00205                 if ( this->retv.isExecuted()) {
00206                     this->retv.checkError();
00207                     return SendSuccess;
00208                 } else
00209                     return SendNotReady;
00210             }
00211 
00212             // collect_impl belongs in LocalOperationCallerImpl because it would need
00213             // to be repeated in each BindStorage spec.
00214             template<class T1>
00215             SendStatus collectIfDone_impl( T1& a1 ) {
00216                 if ( this->retv.isExecuted()) {
00217                     this->retv.checkError();
00218                     bf::vector_tie(a1) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00219                     return SendSuccess;
00220                 } else
00221                     return SendNotReady;
00222             }
00223 
00224             template<class T1, class T2>
00225             SendStatus collectIfDone_impl( T1& a1, T2& a2 ) {
00226                 if ( this->retv.isExecuted()) {
00227                     this->retv.checkError();
00228                     bf::vector_tie(a1,a2) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00229                     return SendSuccess;
00230                 }
00231                 return SendNotReady;
00232             }
00233 
00234             template<class T1, class T2, class T3>
00235             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3 ) {
00236                 if ( this->retv.isExecuted()) {
00237                     this->retv.checkError();
00238                     bf::vector_tie(a1,a2,a3) = 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, class T3, class T4>
00245             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4 ) {
00246                 if ( this->retv.isExecuted()) {
00247                     this->retv.checkError();
00248                     bf::vector_tie(a1,a2,a3,a4) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00249                     return SendSuccess;
00250                 } else
00251                     return SendNotReady;
00252             }
00253 
00254             template<class T1, class T2, class T3, class T4, class T5>
00255             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5 ) {
00256                 if ( this->retv.isExecuted()) {
00257                     this->retv.checkError();
00258                     bf::vector_tie(a1,a2,a3,a4,a5) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00259                     return SendSuccess;
00260                 } else
00261                     return SendNotReady;
00262             }
00263 
00264             template<class T1, class T2, class T3, class T4, class T5, class T6>
00265             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6 ) {
00266                 if ( this->retv.isExecuted()) {
00267                     this->retv.checkError();
00268                     bf::vector_tie(a1,a2,a3,a4,a5,a6) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00269                     return SendSuccess;
00270                 } else
00271                     return SendNotReady;
00272             }
00273 
00274             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00275             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7 ) {
00276                 if ( this->retv.isExecuted()) {
00277                     this->retv.checkError();
00278                     bf::vector_tie(a1,a2,a3,a4,a5,a6,a7) = bf::filter_if< is_arg_return<boost::remove_reference<mpl::_> > >(this->vStore);
00279                     return SendSuccess;
00280                 } else
00281                     return SendNotReady;
00282             }
00283 
00284             bool checkCaller() {
00285                 if (!this->caller) {
00286                     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();
00287                     log(Error) << "Use this->engine() in a component or GlobalEngine::Instance() in a non-component function. Returning a CollectFailure." <<endlog();
00288                     return false;
00289                 }
00290                 return true;
00291             }
00292 
00293             SendStatus collect_impl() {
00294                 if (!checkCaller()) return CollectFailure;
00295                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00296                 return this->collectIfDone_impl();
00297             }
00298             template<class T1>
00299             SendStatus collect_impl( T1& a1 ) {
00300                 if (!checkCaller()) return CollectFailure;
00301                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00302                 return this->collectIfDone_impl(a1);
00303             }
00304 
00305             template<class T1, class T2>
00306             SendStatus collect_impl( T1& a1, T2& a2 ) {
00307                 if (!checkCaller()) return CollectFailure;
00308                 this->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                 if (!checkCaller()) return CollectFailure;
00315                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00316                 return this->collectIfDone_impl(a1,a2,a3);
00317             }
00318 
00319             template<class T1, class T2, class T3, class T4>
00320             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4) {
00321                 if (!checkCaller()) return CollectFailure;
00322                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00323                 return this->collectIfDone_impl(a1,a2,a3,a4);
00324             }
00325 
00326             template<class T1, class T2, class T3, class T4, class T5>
00327             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5) {
00328                 if (!checkCaller()) return CollectFailure;
00329                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00330                 return this->collectIfDone_impl(a1,a2,a3,a4, a5);
00331             }
00332 
00333             template<class T1, class T2, class T3, class T4, class T5, class T6>
00334             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6) {
00335                 if (!checkCaller()) return CollectFailure;
00336                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00337                 return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6);
00338             }
00339 
00340             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00341             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7) {
00342                 if (!checkCaller()) return CollectFailure;
00343                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00344                 return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6,a7);
00345             }
00346 
00350             template<class Xignored>
00351             result_type call_impl()
00352             {
00353                 if ( this->isSend() ) {
00354                     SendHandle<Signature> h = send_impl();
00355                     if ( h.collect() == SendSuccess )
00356                         return h.ret();
00357                     else
00358                         throw SendFailure;
00359                 } else {
00360 #ifdef ORO_SIGNALLING_OPERATIONS
00361                     if (this->msig) this->msig->emit();
00362 #endif
00363                     if ( this->mmeth )
00364                         return this->mmeth(); // ClientThread
00365                     else
00366                         return NA<result_type>::na();
00367                 }
00368             }
00369 
00370 
00374             template<class T1>
00375             result_type call_impl(T1 a1)
00376             {
00377                 SendHandle<Signature> h;
00378                 if ( this->isSend() ) {
00379                     h = send_impl<T1>(a1);
00380                     // collect_impl may take diff number of arguments than
00381                     // call_impl/ret_impl(), so we use generic collect() + ret_impl()
00382                     if ( h.collect() == SendSuccess )
00383                         return h.ret(a1);
00384                     else
00385                         throw SendFailure;
00386                 } else{
00387 #ifdef ORO_SIGNALLING_OPERATIONS
00388                     if (this->msig) this->msig->emit(a1);
00389 #endif
00390                     if ( this->mmeth )
00391                         return this->mmeth(a1);
00392                     else
00393                         return NA<result_type>::na();
00394                 }
00395                 return NA<result_type>::na();
00396             }
00397 
00398             template<class T1, class T2>
00399             result_type call_impl(T1 a1, T2 a2)
00400             {
00401                 SendHandle<Signature> h;
00402                 if ( this->isSend() ) {
00403                     h = send_impl<T1,T2>(a1,a2);
00404                     if ( h.collect() == SendSuccess )
00405                         return h.ret(a1,a2);
00406                     else
00407                         throw SendFailure;
00408                 } else {
00409 #ifdef ORO_SIGNALLING_OPERATIONS
00410                     if (this->msig) this->msig->emit(a1,a2);
00411 #endif
00412                     if ( this->mmeth )
00413                         return this->mmeth(a1,a2);
00414                     else
00415                         return NA<result_type>::na();
00416                 }
00417                 return NA<result_type>::na();
00418             }
00419 
00420             template<class T1, class T2, class T3>
00421             result_type call_impl(T1 a1, T2 a2, T3 a3)
00422             {
00423                 SendHandle<Signature> h;
00424                 if ( this->isSend() ) {
00425                     h = send_impl<T1,T2,T3>(a1,a2,a3);
00426                     if ( h.collect() == SendSuccess )
00427                         return h.ret(a1,a2,a3);
00428                     else
00429                         throw SendFailure;
00430                 } else {
00431 #ifdef ORO_SIGNALLING_OPERATIONS
00432                     if (this->msig) this->msig->emit(a1,a2,a3);
00433 #endif
00434                     if ( this->mmeth )
00435                         return this->mmeth(a1,a2,a3);
00436                     else
00437                         return NA<result_type>::na();
00438                 }
00439                 return NA<result_type>::na();
00440             }
00441 
00442             template<class T1, class T2, class T3, class T4>
00443             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00444             {
00445                 SendHandle<Signature> h;
00446                 if ( this->isSend() ) {
00447                     h = send_impl<T1,T2,T3,T4>(a1,a2,a3,a4);
00448                     if ( h.collect() == SendSuccess )
00449                         return h.ret(a1,a2,a3,a4);
00450                     else
00451                         throw SendFailure;
00452                 } else {
00453 #ifdef ORO_SIGNALLING_OPERATIONS
00454                     if (this->msig) this->msig->emit(a1,a2,a3,a4);
00455 #endif
00456                     if ( this->mmeth )
00457                         return this->mmeth(a1,a2,a3,a4);
00458                     else
00459                         return NA<result_type>::na();
00460                 }
00461                 return NA<result_type>::na();
00462             }
00463 
00464             template<class T1, class T2, class T3, class T4, class T5>
00465             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00466             {
00467                 SendHandle<Signature> h;
00468                 if (this->isSend()) {
00469                     h = send_impl<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
00470                     if ( h.collect() == SendSuccess )
00471                         return h.ret(a1,a2,a3,a4,a5);
00472                     else
00473                         throw SendFailure;
00474                 } else {
00475 #ifdef ORO_SIGNALLING_OPERATIONS
00476                     if (this->msig) this->msig->emit(a1,a2,a3,a4,a5);
00477 #endif
00478                     if ( this->mmeth )
00479                         return this->mmeth(a1,a2,a3,a4,a5);
00480                     else
00481                         return NA<result_type>::na();
00482                 }
00483                 return NA<result_type>::na();
00484             }
00485 
00486             template<class T1, class T2, class T3, class T4, class T5, class T6>
00487             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00488             {
00489                 SendHandle<Signature> h;
00490                 if (this->isSend()) {
00491                     h = send_impl<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6);
00492                     if ( h.collect() == SendSuccess )
00493                         return h.ret(a1,a2,a3,a4,a5,a6);
00494                     else
00495                         throw SendFailure;
00496                 } else {
00497 #ifdef ORO_SIGNALLING_OPERATIONS
00498                     if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6);
00499 #endif
00500                     if ( this->mmeth )
00501                         return this->mmeth(a1,a2,a3,a4,a5,a6);
00502                     else
00503                         return NA<result_type>::na();
00504                 }
00505                 return NA<result_type>::na();
00506             }
00507 
00508             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00509             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00510             {
00511                 SendHandle<Signature> h;
00512                 if (this->isSend()) {
00513                     h = send_impl<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7);
00514                     if ( h.collect() == SendSuccess )
00515                         return h.ret(a1,a2,a3,a4,a5,a6,a7);
00516                     else
00517                         throw SendFailure;
00518                 } else {
00519 #ifdef ORO_SIGNALLING_OPERATIONS
00520                     if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6,a7);
00521 #endif
00522                     if ( this->mmeth )
00523                         return this->mmeth(a1,a2,a3,a4,a5,a6,a7);
00524                     else
00525                         return NA<result_type>::na();
00526                 }
00527                 return NA<result_type>::na();
00528             }
00529 
00530             result_type ret_impl()
00531             {
00532                 this->retv.checkError();
00533                 return this->retv.result(); // may return void.
00534             }
00535 
00541             template<class T1>
00542             result_type ret_impl(T1 a1)
00543             {
00544                 this->retv.checkError();
00545                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00546                 bf::vector<T1> vArgs( boost::ref(a1) );
00547                 if ( this->retv.isExecuted())
00548                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00549                 return this->retv.result(); // may return void.
00550             }
00551 
00552             template<class T1,class T2>
00553             result_type ret_impl(T1 a1, T2 a2)
00554             {
00555                 this->retv.checkError();
00556                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00557                 bf::vector<T1,T2> vArgs( boost::ref(a1), boost::ref(a2) );
00558                 if ( this->retv.isExecuted())
00559                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg< boost::remove_reference<mpl::_> > >(this->vStore);
00560                 return this->retv.result(); // may return void.
00561             }
00562 
00563             template<class T1,class T2, class T3>
00564             result_type ret_impl(T1 a1, T2 a2, T3 a3)
00565             {
00566                 this->retv.checkError();
00567                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00568                 bf::vector<T1,T2,T3> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3) );
00569                 if ( this->retv.isExecuted())
00570                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00571                 return this->retv.result(); // may return void.
00572             }
00573 
00574             template<class T1,class T2, class T3, class T4>
00575             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00576             {
00577                 this->retv.checkError();
00578                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00579                 bf::vector<T1,T2,T3,T4> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4) );
00580                 if ( this->retv.isExecuted())
00581                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00582                 return this->retv.result(); // may return void.
00583             }
00584 
00585             template<class T1,class T2, class T3, class T4, class T5>
00586             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00587             {
00588                 this->retv.checkError();
00589                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00590                 bf::vector<T1,T2,T3,T4,T5> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5) );
00591                 if ( this->retv.isExecuted())
00592                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00593                 return this->retv.result(); // may return void.
00594             }
00595 
00596             template<class T1,class T2, class T3, class T4, class T5, class T6>
00597             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00598             {
00599                 this->retv.checkError();
00600                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00601                 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) );
00602                 if ( this->retv.isExecuted())
00603                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00604                 return this->retv.result(); // may return void.
00605             }
00606 
00607             template<class T1,class T2, class T3, class T4, class T5, class T6, class T7>
00608             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00609             {
00610                 this->retv.checkError();
00611                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00612                 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) );
00613                 if ( this->retv.isExecuted())
00614                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00615                 return this->retv.result(); // may return void.
00616             }
00617 
00618             virtual shared_ptr cloneRT() const = 0;
00619         protected:
00620             typedef BindStorage<FunctionT> Store;
00626             typename base::OperationCallerBase<FunctionT>::shared_ptr self;
00627         };
00628 
00638         template<class FunctionT>
00639         struct LocalOperationCaller
00640             : public Invoker<FunctionT,LocalOperationCallerImpl<FunctionT> >
00641         {
00642             typedef FunctionT Signature;
00643             typedef typename boost::function_traits<Signature>::result_type result_type;
00644             typedef boost::function_traits<Signature> traits;
00645 
00646             typedef boost::shared_ptr<LocalOperationCaller> shared_ptr;
00647 
00653             LocalOperationCaller()
00654             {}
00655 
00665             template<class M, class ObjectType>
00666             LocalOperationCaller(M meth, ObjectType object, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread)
00667             {
00668                 this->setCaller( caller );
00669                 this->setOwner(ee );
00670                 this->setThread( et, ee );
00671                 this->mmeth = OperationCallerBinder<Signature>()(meth, object);
00672             }
00673 
00679             template<class M>
00680             LocalOperationCaller(M meth, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread )
00681             {
00682                 this->setCaller( caller );
00683                 this->setOwner( ee );
00684                 this->setThread( et, ee );
00685                 this->mmeth = meth;
00686             }
00687 
00688             boost::function<Signature> getOperationCallerFunction() const
00689             {
00690                 return this->mmeth;
00691             }
00692 
00693 #ifdef ORO_SIGNALLING_OPERATIONS
00694             void setSignal(typename Signal<Signature>::shared_ptr sig) {
00695                 this->msig = sig;
00696             }
00697 #endif
00698             base::OperationCallerBase<Signature>* cloneI(ExecutionEngine* caller) const
00699             {
00700                 LocalOperationCaller<Signature>* ret = new LocalOperationCaller<Signature>(*this);
00701                 ret->setCaller( caller ); // mandatory !
00702                 return ret;
00703             }
00704 
00705             typename LocalOperationCallerImpl<Signature>::shared_ptr cloneRT() const
00706             {
00707                 // returns identical copy of this;
00708                 return boost::allocate_shared<LocalOperationCaller<Signature> >(os::rt_allocator<LocalOperationCaller<Signature> >(), *this);
00709             }
00710         };
00711     }
00712 }
00713 
00714 #endif


rtt
Author(s): RTT Developers
autogenerated on Fri Sep 9 2016 04:01:54