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                 //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 
00312             template<class T1, class T2, class T3, class T4>
00313             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4) {
00314                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00315                 return this->collectIfDone_impl(a1,a2,a3,a4);
00316             }
00317 
00318             template<class T1, class T2, class T3, class T4, class T5>
00319             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5) {
00320                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00321                 return this->collectIfDone_impl(a1,a2,a3,a4, a5);
00322             }
00323 
00324             template<class T1, class T2, class T3, class T4, class T5, class T6>
00325             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6) {
00326                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00327                 return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6);
00328             }
00329 
00330             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00331             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7) {
00332                 this->caller->waitForMessages( boost::bind(&Store::RStoreType::isExecuted,boost::ref(this->retv)) );
00333                 return this->collectIfDone_impl(a1,a2,a3,a4,a5,a6,a7);
00334             }
00335 
00339             result_type call_impl()
00340             {
00341 
00342                 if ( this->isSend() ) {
00343                     SendHandle<Signature> h = send_impl();
00344                     if ( h.collect() == SendSuccess )
00345                         return h.ret();
00346                     else
00347                         throw SendFailure;
00348                 } else {
00349 #ifdef ORO_SIGNALLING_OPERATIONS
00350                     if (this->msig) this->msig->emit();
00351 #endif
00352                     if ( this->mmeth )
00353                         return this->mmeth(); // ClientThread
00354                     else
00355                         return NA<result_type>::na();
00356                 }
00357             }
00358 
00359 
00363             template<class T1>
00364             result_type call_impl(T1 a1)
00365             {
00366                 SendHandle<Signature> h;
00367                 if ( this->isSend() ) {
00368                     h = send_impl<T1>(a1);
00369                     // collect_impl may take diff number of arguments than
00370                     // call_impl/ret_impl(), so we use generic collect() + ret_impl()
00371                     if ( h.collect() == SendSuccess )
00372                         return h.ret(a1);
00373                     else
00374                         throw SendFailure;
00375                 } else{
00376 #ifdef ORO_SIGNALLING_OPERATIONS
00377                     if (this->msig) this->msig->emit(a1);
00378 #endif
00379                     if ( this->mmeth )
00380                         return this->mmeth(a1);
00381                     else
00382                         return NA<result_type>::na();
00383                 }
00384                 return NA<result_type>::na();
00385             }
00386 
00387             template<class T1, class T2>
00388             result_type call_impl(T1 a1, T2 a2)
00389             {
00390                 SendHandle<Signature> h;
00391                 if ( this->isSend() ) {
00392                     h = send_impl<T1,T2>(a1,a2);
00393                     if ( h.collect() == SendSuccess )
00394                         return h.ret(a1,a2);
00395                     else
00396                         throw SendFailure;
00397                 } else {
00398 #ifdef ORO_SIGNALLING_OPERATIONS
00399                     if (this->msig) this->msig->emit(a1,a2);
00400 #endif
00401                     if ( this->mmeth )
00402                         return this->mmeth(a1,a2);
00403                     else
00404                         return NA<result_type>::na();
00405                 }
00406                 return NA<result_type>::na();
00407             }
00408 
00409             template<class T1, class T2, class T3>
00410             result_type call_impl(T1 a1, T2 a2, T3 a3)
00411             {
00412                 SendHandle<Signature> h;
00413                 if ( this->isSend() ) {
00414                     h = send_impl<T1,T2,T3>(a1,a2,a3);
00415                     if ( h.collect() == SendSuccess )
00416                         return h.ret(a1,a2,a3);
00417                     else
00418                         throw SendFailure;
00419                 } else {
00420 #ifdef ORO_SIGNALLING_OPERATIONS
00421                     if (this->msig) this->msig->emit(a1,a2,a3);
00422 #endif
00423                     if ( this->mmeth )
00424                         return this->mmeth(a1,a2,a3);
00425                     else
00426                         return NA<result_type>::na();
00427                 }
00428                 return NA<result_type>::na();
00429             }
00430 
00431             template<class T1, class T2, class T3, class T4>
00432             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00433             {
00434                 SendHandle<Signature> h;
00435                 if ( this->isSend() ) {
00436                     h = send_impl<T1,T2,T3,T4>(a1,a2,a3,a4);
00437                     if ( h.collect() == SendSuccess )
00438                         return h.ret(a1,a2,a3,a4);
00439                     else
00440                         throw SendFailure;
00441                 } else {
00442 #ifdef ORO_SIGNALLING_OPERATIONS
00443                     if (this->msig) this->msig->emit(a1,a2,a3,a4);
00444 #endif
00445                     if ( this->mmeth )
00446                         return this->mmeth(a1,a2,a3,a4);
00447                     else
00448                         return NA<result_type>::na();
00449                 }
00450                 return NA<result_type>::na();
00451             }
00452 
00453             template<class T1, class T2, class T3, class T4, class T5>
00454             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00455             {
00456                 SendHandle<Signature> h;
00457                 if (this->isSend()) {
00458                     h = send_impl<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
00459                     if ( h.collect() == SendSuccess )
00460                         return h.ret(a1,a2,a3,a4,a5);
00461                     else
00462                         throw SendFailure;
00463                 } else {
00464 #ifdef ORO_SIGNALLING_OPERATIONS
00465                     if (this->msig) this->msig->emit(a1,a2,a3,a4,a5);
00466 #endif
00467                     if ( this->mmeth )
00468                         return this->mmeth(a1,a2,a3,a4,a5);
00469                     else
00470                         return NA<result_type>::na();
00471                 }
00472                 return NA<result_type>::na();
00473             }
00474 
00475             template<class T1, class T2, class T3, class T4, class T5, class T6>
00476             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00477             {
00478                 SendHandle<Signature> h;
00479                 if (this->isSend()) {
00480                     h = send_impl<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6);
00481                     if ( h.collect() == SendSuccess )
00482                         return h.ret(a1,a2,a3,a4,a5,a6);
00483                     else
00484                         throw SendFailure;
00485                 } else {
00486 #ifdef ORO_SIGNALLING_OPERATIONS
00487                     if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6);
00488 #endif
00489                     if ( this->mmeth )
00490                         return this->mmeth(a1,a2,a3,a4,a5,a6);
00491                     else
00492                         return NA<result_type>::na();
00493                 }
00494                 return NA<result_type>::na();
00495             }
00496 
00497             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00498             result_type call_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00499             {
00500                 SendHandle<Signature> h;
00501                 if (this->isSend()) {
00502                     h = send_impl<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7);
00503                     if ( h.collect() == SendSuccess )
00504                         return h.ret(a1,a2,a3,a4,a5,a6,a7);
00505                     else
00506                         throw SendFailure;
00507                 } else {
00508 #ifdef ORO_SIGNALLING_OPERATIONS
00509                     if (this->msig) this->msig->emit(a1,a2,a3,a4,a5,a6,a7);
00510 #endif
00511                     if ( this->mmeth )
00512                         return this->mmeth(a1,a2,a3,a4,a5,a6,a7);
00513                     else
00514                         return NA<result_type>::na();
00515                 }
00516                 return NA<result_type>::na();
00517             }
00518 
00519             result_type ret_impl()
00520             {
00521                 this->retv.checkError();
00522                 return this->retv.result(); // may return void.
00523             }
00524 
00530             template<class T1>
00531             result_type ret_impl(T1 a1)
00532             {
00533                 this->retv.checkError();
00534                 typedef mpl::and_<boost::is_reference<mpl::_>, mpl::not_<boost::is_const<boost::remove_reference<mpl::_> > > > pred;
00535                 bf::vector<T1> vArgs( boost::ref(a1) );
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>
00542             result_type ret_impl(T1 a1, T2 a2)
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,T2> vArgs( boost::ref(a1), boost::ref(a2) );
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, class T3>
00553             result_type ret_impl(T1 a1, T2 a2, T3 a3)
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,T3> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3) );
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, class T4>
00564             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
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,T4> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4) );
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, class T5>
00575             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
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,T5> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5) );
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, class T6>
00586             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
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,T6> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5), boost::ref(a6) );
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, class T7>
00597             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
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,T7> vArgs( boost::ref(a1), boost::ref(a2), boost::ref(a3), boost::ref(a4), boost::ref(a5), boost::ref(a6), boost::ref(a7) );
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             virtual shared_ptr cloneRT() const = 0;
00608         protected:
00609             typedef BindStorage<FunctionT> Store;
00615             typename base::OperationCallerBase<FunctionT>::shared_ptr self;
00616         };
00617 
00627         template<class FunctionT>
00628         struct LocalOperationCaller
00629             : public Invoker<FunctionT,LocalOperationCallerImpl<FunctionT> >
00630         {
00631             typedef FunctionT Signature;
00632             typedef typename boost::function_traits<Signature>::result_type result_type;
00633             typedef boost::function_traits<Signature> traits;
00634 
00635             typedef boost::shared_ptr<LocalOperationCaller> shared_ptr;
00636 
00642             LocalOperationCaller()
00643             {}
00644 
00655             template<class M, class ObjectType>
00656             LocalOperationCaller(M meth, ObjectType object, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread, ExecutionEngine* oe = NULL )
00657             {
00658                 this->setExecutor( ee );
00659                 this->setCaller( caller );
00660                 this->setOwner(oe);
00661                 this->setThread( et, ee );
00662                 this->mmeth = OperationCallerBinder<Signature>()(meth, object);
00663             }
00664 
00670             template<class M>
00671             LocalOperationCaller(M meth, ExecutionEngine* ee, ExecutionEngine* caller, ExecutionThread et = ClientThread, ExecutionEngine* oe = NULL )
00672             {
00673                 this->setExecutor( ee );
00674                 this->setCaller( caller );
00675                 this->setOwner(oe);
00676                 this->setThread( et, ee );
00677                 this->mmeth = meth;
00678             }
00679 
00680             boost::function<Signature> getOperationCallerFunction() const
00681             {
00682                 return this->mmeth;
00683             }
00684 
00685 #ifdef ORO_SIGNALLING_OPERATIONS
00686             void setSignal(typename Signal<Signature>::shared_ptr sig) {
00687                 this->msig = sig;
00688             }
00689 #endif
00690             base::OperationCallerBase<Signature>* cloneI(ExecutionEngine* caller) const
00691             {
00692                 LocalOperationCaller<Signature>* ret = new LocalOperationCaller<Signature>(*this);
00693                 ret->setCaller( caller );
00694 #ifdef ORO_SIGNALLING_OPERATIONS
00695                 ret->setSignal( this->msig );
00696 #endif
00697                 return ret;
00698             }
00699 
00700             typename LocalOperationCallerImpl<Signature>::shared_ptr cloneRT() const
00701             {
00702                 //void* obj = oro_rt_malloc(sizeof(LocalOperationCallerImpl<Signature>));
00703                 //return new(obj) LocalOperationCaller<Signature>(*this);
00704                 return boost::allocate_shared<LocalOperationCaller<Signature> >(os::rt_allocator<LocalOperationCaller<Signature> >(), *this);
00705             }
00706         };
00707     }
00708 }
00709 
00710 #endif


rtt
Author(s): RTT Developers
autogenerated on Thu Jan 2 2014 11:35:22