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