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             SendStatus collect_impl() {
00285                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00286                 return this->collectIfDone_impl();
00287             }
00288             template<class T1>
00289             SendStatus collect_impl( T1& a1 ) {
00290                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00291                 return this->collectIfDone_impl(a1);
00292             }
00293 
00294             template<class T1, class T2>
00295             SendStatus collect_impl( T1& a1, T2& a2 ) {
00296                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00297                 return this->collectIfDone_impl(a1,a2);
00298             }
00299 
00300             template<class T1, class T2, class T3>
00301             SendStatus collect_impl( T1& a1, T2& a2, T3& a3 ) {
00302                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00303                 return this->collectIfDone_impl(a1,a2,a3);
00304             }
00305 
00306             template<class T1, class T2, class T3, class T4>
00307             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4) {
00308                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00309                 return this->collectIfDone_impl(a1,a2,a3,a4);
00310             }
00311 
00312             template<class T1, class T2, class T3, class T4, class T5>
00313             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5) {
00314                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00315                 return this->collectIfDone_impl(a1,a2,a3,a4, a5);
00316             }
00317 
00318             template<class T1, class T2, class T3, class T4, class T5, class T6>
00319             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6) {
00320                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00321                 return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6);
00322             }
00323 
00324             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00325             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7) {
00326                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00327                 return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6,a7);
00328             }
00329 
00333             result_type call_impl()
00334             {
00335 
00336                 if ( this->isSend() ) {
00337                     SendHandle<Signature> h = send_impl();
00338                     if ( h.collect() == SendSuccess )
00339                         return h.ret();
00340                     else
00341                         throw SendFailure;
00342                 } else {
00343 #ifdef ORO_SIGNALLING_OPERATIONS
00344                     if (this->msig) this->msig->emit();
00345 #endif
00346                     if ( this->mmeth )
00347                         return this->mmeth(); // ClientThread
00348                     else
00349                         return NA<result_type>::na();
00350                 }
00351             }
00352 
00353 
00357             template<class T1>
00358             result_type call_impl(T1 a1)
00359             {
00360                 SendHandle<Signature> h;
00361                 if ( this->isSend() ) {
00362                     h = send_impl<T1>(a1);
00363                     // collect_impl may take diff number of arguments than
00364                     // call_impl/ret_impl(), so we use generic collect() + ret_impl()
00365                     if ( h.collect() == SendSuccess )
00366                         return h.ret(a1);
00367                     else
00368                         throw SendFailure;
00369                 } else{
00370 #ifdef ORO_SIGNALLING_OPERATIONS
00371                     if (this->msig) this->msig->emit(a1);
00372 #endif
00373                     if ( this->mmeth )
00374                         return this->mmeth(a1);
00375                     else
00376                         return NA<result_type>::na();
00377                 }
00378                 return NA<result_type>::na();
00379             }
00380 
00381             template<class T1, class T2>
00382             result_type call_impl(T1 a1, T2 a2)
00383             {
00384                 SendHandle<Signature> h;
00385                 if ( this->isSend() ) {
00386                     h = send_impl<T1,T2>(a1,a2);
00387                     if ( h.collect() == SendSuccess )
00388                         return h.ret(a1,a2);
00389                     else
00390                         throw SendFailure;
00391                 } else {
00392 #ifdef ORO_SIGNALLING_OPERATIONS
00393                     if (this->msig) this->msig->emit(a1,a2);
00394 #endif
00395                     if ( this->mmeth )
00396                         return this->mmeth(a1,a2);
00397                     else
00398                         return NA<result_type>::na();
00399                 }
00400                 return NA<result_type>::na();
00401             }
00402 
00403             template<class T1, class T2, class T3>
00404             result_type call_impl(T1 a1, T2 a2, T3 a3)
00405             {
00406                 SendHandle<Signature> h;
00407                 if ( this->isSend() ) {
00408                     h = send_impl<T1,T2,T3>(a1,a2,a3);
00409                     if ( h.collect() == SendSuccess )
00410                         return h.ret(a1,a2,a3);
00411                     else
00412                         throw SendFailure;
00413                 } else {
00414 #ifdef ORO_SIGNALLING_OPERATIONS
00415                     if (this->msig) this->msig->emit(a1,a2,a3);
00416 #endif
00417                     if ( this->mmeth )
00418                         return this->mmeth(a1,a2,a3);
00419                     else
00420                         return NA<result_type>::na();
00421                 }
00422                 return NA<result_type>::na();
00423             }
00424 
00425             template<class T1, class T2, class T3, class T4>
00426             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00427             {
00428                 SendHandle<Signature> h;
00429                 if ( this->isSend() ) {
00430                     h = send_impl<T1,T2,T3,T4>(a1,a2,a3,a4);
00431                     if ( h.collect() == SendSuccess )
00432                         return h.ret(a1,a2,a3,a4);
00433                     else
00434                         throw SendFailure;
00435                 } else {
00436 #ifdef ORO_SIGNALLING_OPERATIONS
00437                     if (this->msig) this->msig->emit(a1,a2,a3,a4);
00438 #endif
00439                     if ( this->mmeth )
00440                         return this->mmeth(a1,a2,a3,a4);
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>
00448             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00449             {
00450                 SendHandle<Signature> h;
00451                 if (this->isSend()) {
00452                     h = send_impl<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
00453                     if ( h.collect() == SendSuccess )
00454                         return h.ret(a1,a2,a3,a4,a5);
00455                     else
00456                         throw SendFailure;
00457                 } else {
00458 #ifdef ORO_SIGNALLING_OPERATIONS
00459                     if (this->msig) this->msig->emit(a1,a2,a3,a4,a5);
00460 #endif
00461                     if ( this->mmeth )
00462                         return this->mmeth(a1,a2,a3,a4,a5);
00463                     else
00464                         return NA<result_type>::na();
00465                 }
00466                 return NA<result_type>::na();
00467             }
00468 
00469             template<class T1, class T2, class T3, class T4, class T5, class T6>
00470             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00471             {
00472                 SendHandle<Signature> h;
00473                 if (this->isSend()) {
00474                     h = send_impl<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6);
00475                     if ( h.collect() == SendSuccess )
00476                         return h.ret(a1,a2,a3,a4,a5,a6);
00477                     else
00478                         throw SendFailure;
00479                 } else {
00480 #ifdef ORO_SIGNALLING_OPERATIONS
00481                     if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6);
00482 #endif
00483                     if ( this->mmeth )
00484                         return this->mmeth(a1,a2,a3,a4,a5,a6);
00485                     else
00486                         return NA<result_type>::na();
00487                 }
00488                 return NA<result_type>::na();
00489             }
00490 
00491             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00492             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00493             {
00494                 SendHandle<Signature> h;
00495                 if (this->isSend()) {
00496                     h = send_impl<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7);
00497                     if ( h.collect() == SendSuccess )
00498                         return h.ret(a1,a2,a3,a4,a5,a6,a7);
00499                     else
00500                         throw SendFailure;
00501                 } else {
00502 #ifdef ORO_SIGNALLING_OPERATIONS
00503                     if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6,a7);
00504 #endif
00505                     if ( this->mmeth )
00506                         return this->mmeth(a1,a2,a3,a4,a5,a6,a7);
00507                     else
00508                         return NA<result_type>::na();
00509                 }
00510                 return NA<result_type>::na();
00511             }
00512 
00513             result_type ret_impl()
00514             {
00515                 this->retv.checkError();
00516                 return this->retv.result(); // may return void.
00517             }
00518 
00524             template<class T1>
00525             result_type ret_impl(T1 a1)
00526             {
00527                 this->retv.checkError();
00528                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00529                 bf::vector<T1> vArgs( boost::ref(a1) );
00530                 if ( this->retv.isExecuted())
00531                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00532                 return this->retv.result(); // may return void.
00533             }
00534 
00535             template<class T1,class T2>
00536             result_type ret_impl(T1 a1, T2 a2)
00537             {
00538                 this->retv.checkError();
00539                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00540                 bf::vector<T1,T2> vArgs( boost::ref(a1), boost::ref(a2) );
00541                 if ( this->retv.isExecuted())
00542                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg< boost::remove_reference<mpl::_> > >(this->vStore);
00543                 return this->retv.result(); // may return void.
00544             }
00545 
00546             template<class T1,class T2, class T3>
00547             result_type ret_impl(T1 a1, T2 a2, T3 a3)
00548             {
00549                 this->retv.checkError();
00550                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00551                 bf::vector<T1,T2,T3> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3) );
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(); // may return void.
00555             }
00556 
00557             template<class T1,class T2, class T3, class T4>
00558             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00559             {
00560                 this->retv.checkError();
00561                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00562                 bf::vector<T1,T2,T3,T4> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4) );
00563                 if ( this->retv.isExecuted())
00564                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00565                 return this->retv.result(); // may return void.
00566             }
00567 
00568             template<class T1,class T2, class T3, class T4, class T5>
00569             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00570             {
00571                 this->retv.checkError();
00572                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00573                 bf::vector<T1,T2,T3,T4,T5> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5) );
00574                 if ( this->retv.isExecuted())
00575                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00576                 return this->retv.result(); // may return void.
00577             }
00578 
00579             template<class T1,class T2, class T3, class T4, class T5, class T6>
00580             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00581             {
00582                 this->retv.checkError();
00583                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00584                 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) );
00585                 if ( this->retv.isExecuted())
00586                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00587                 return this->retv.result(); // may return void.
00588             }
00589 
00590             template<class T1,class T2, class T3, class T4, class T5, class T6, class T7>
00591             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00592             {
00593                 this->retv.checkError();
00594                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00595                 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) );
00596                 if ( this->retv.isExecuted())
00597                     as_vector(bf::filter_if< pred >(vArgs)) = bf::filter_if< is_out_arg<boost::remove_reference<mpl::_> > >(this->vStore);
00598                 return this->retv.result(); // may return void.
00599             }
00600 
00601             virtual shared_ptr cloneRT() const = 0;
00602         protected:
00603             typedef BindStorage<FunctionT> Store;
00609             typename base::OperationCallerBase<FunctionT>::shared_ptr self;
00610         };
00611 
00621         template<class FunctionT>
00622         struct LocalOperationCaller
00623             : public Invoker<FunctionT,LocalOperationCallerImpl<FunctionT> >
00624         {
00625             typedef FunctionT Signature;
00626             typedef typename boost::function_traits<Signature>::result_type result_type;
00627             typedef boost::function_traits<Signature> traits;
00628 
00629             typedef boost::shared_ptr<LocalOperationCaller> shared_ptr;
00630 
00636             LocalOperationCaller()
00637             {}
00638 
00648             template<class M, class ObjectType>
00649             LocalOperationCaller(M meth, ObjectType object, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread)
00650             {
00651                 this->setCaller( caller );
00652                 this->setOwner(ee );
00653                 this->setThread( et, ee );
00654                 this->mmeth = OperationCallerBinder<Signature>()(meth, object);
00655             }
00656 
00662             template<class M>
00663             LocalOperationCaller(M meth, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread )
00664             {
00665                 this->setCaller( caller );
00666                 this->setOwner( ee );
00667                 this->setThread( et, ee );
00668                 this->mmeth = meth;
00669             }
00670 
00671             boost::function<Signature> getOperationCallerFunction() const
00672             {
00673                 return this->mmeth;
00674             }
00675 
00676 #ifdef ORO_SIGNALLING_OPERATIONS
00677             void setSignal(typename Signal<Signature>::shared_ptr sig) {
00678                 this->msig = sig;
00679             }
00680 #endif
00681             base::OperationCallerBase<Signature>* cloneI(ExecutionEngine* caller) const
00682             {
00683                 LocalOperationCaller<Signature>* ret = new LocalOperationCaller<Signature>(*this);
00684                 ret->setCaller( caller ); // mandatory !
00685                 return ret;
00686             }
00687 
00688             typename LocalOperationCallerImpl<Signature>::shared_ptr cloneRT() const
00689             {
00690                 // returns identical copy of this;
00691                 return boost::allocate_shared<LocalOperationCaller<Signature> >(os::rt_allocator<LocalOperationCaller<Signature> >(), *this);
00692             }
00693         };
00694     }
00695 }
00696 
00697 #endif


rtt
Author(s): RTT Developers
autogenerated on Wed Aug 26 2015 16:15:49