Orocos Real-Time Toolkit  2.6.0
RemoteOperationCaller.hpp
00001 /***************************************************************************
00002   tag: FMTC  do nov 2 13:06:09 CET 2006  RemoteOperationCaller.hpp
00003 
00004                         RemoteOperationCaller.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_REMOTE_METHOD_HPP
00040 #define ORO_REMOTE_METHOD_HPP
00041 
00042 #include <boost/function.hpp>
00043 #include <string>
00044 #include "../base/OperationCallerBase.hpp"
00045 #include "OperationCallerC.hpp"
00046 #include "DataSourceStorage.hpp"
00047 #include "Invoker.hpp"
00048 
00049 #include <boost/fusion/include/vector_tie.hpp>
00050 #include <boost/fusion/include/filter_if.hpp>
00051 #include <boost/fusion/include/as_vector.hpp>
00052 
00053 
00054 
00055 namespace RTT
00056 {
00057     namespace internal
00058     {
00059         namespace bf = ::boost::fusion;
00060 
00070         template<class OperationCallerT>
00071         class RemoteOperationCallerImpl
00072             : public base::OperationCallerBase<OperationCallerT>,
00073               public internal::CollectBase<OperationCallerT>
00074         {
00075         protected:
00076             OperationCallerC mmeth;
00077             SendHandleC mhandle;
00078             DataSourceStorage<OperationCallerT> sendargs;
00079             DataSourceStorage<typename CollectType<OperationCallerT>::type > collectargs;
00080         public:
00081             typedef OperationCallerT Signature;
00082             typedef typename boost::function_traits<OperationCallerT>::result_type result_type;
00083 
00087             RemoteOperationCallerImpl()
00088                 : mmeth(), mhandle()
00089             {}
00090 
00094             RemoteOperationCallerImpl(SendHandleC handle)
00095                 : mmeth(), mhandle(handle)
00096             {}
00097 
00098             virtual void executeAndDispose() { assert(false); }
00099             virtual bool isError() const { return false; }
00100             virtual void dispose() { assert(false); }
00101 
00107             result_type call_impl() {
00108                 mmeth.call();
00109                 return sendargs.getResult();
00110             }
00111 
00112             template<class T1>
00113             result_type call_impl( T1 a1 ) {
00114                 sendargs.store( a1 );
00115                 mmeth.call();
00116                 return sendargs.getResult();
00117             }
00118 
00119             template<class T1, class T2>
00120             result_type call_impl( T1 a1, T2 a2 ) {
00121                 sendargs.store( a1, a2 );
00122                 mmeth.call();
00123                 return sendargs.getResult();
00124             }
00125 
00126             template<class T1, class T2, class T3>
00127             result_type call_impl( T1 a1, T2 a2, T3 a3 ) {
00128                 sendargs.store( a1, a2, a3 );
00129                 mmeth.call();
00130                 return sendargs.getResult();
00131             }
00132 
00133             template<class T1, class T2, class T3, class T4>
00134             result_type call_impl( T1 a1, T2 a2, T3 a3, T4 a4 ) {
00135                 sendargs.store( a1, a2, a3, a4 );
00136                 mmeth.call();
00137                 return sendargs.getResult();
00138             }
00139 
00140             template<class T1, class T2, class T3, class T4, class T5, class T6>
00141             result_type call_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6 ) {
00142                 sendargs.store( a1, a2, a3, a4, a5, a6 );
00143                 mmeth.call();
00144                 return sendargs.getResult();
00145             }
00146 
00147             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00148             result_type call_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7 ) {
00149                 sendargs.store( a1, a2, a3, a4, a5, a6, a7 );
00150                 mmeth.call();
00151                 return sendargs.getResult();
00152             }
00153 
00154             template<class T1, class T2, class T3, class T4, class T5>
00155             result_type call_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5 ) {
00156                 sendargs.store( a1, a2, a3, a4, a5 );
00157                 mmeth.call();
00158                 return sendargs.getResult();
00159             }
00160 
00161             SendHandle<Signature> send_impl() {
00162                 mhandle = mmeth.send();
00163                 // @todo: get remote collect from rt allocation.
00164                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00165             }
00166 
00167             template<class T1>
00168             SendHandle<Signature> send_impl( T1 a1 ) {
00169                 sendargs.store( a1 );
00170                 mhandle = mmeth.send();
00171                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00172             }
00173 
00174             template<class T1, class T2>
00175             SendHandle<Signature> send_impl( T1 a1, T2 a2 ) {
00176                 sendargs.store( a1, a2 );
00177                 mhandle = mmeth.send();
00178                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00179             }
00180 
00181             template<class T1, class T2, class T3>
00182             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3 ) {
00183                 sendargs.store( a1, a2, a3 );
00184                 mhandle = mmeth.send();
00185                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00186             }
00187 
00188             template<class T1, class T2, class T3, class T4>
00189             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4 ) {
00190                 sendargs.store( a1, a2, a3, a4 );
00191                 mhandle = mmeth.send();
00192                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00193             }
00194 
00195             template<class T1, class T2, class T3, class T4, class T5>
00196             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5 ) {
00197                 sendargs.store( a1, a2, a3, a4, a5 );
00198                 mhandle = mmeth.send();
00199                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00200             }
00201 
00202             template<class T1, class T2, class T3, class T4, class T5, class T6>
00203             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6 ) {
00204                 sendargs.store( a1, a2, a3, a4, a5, a6 );
00205                 mhandle = mmeth.send();
00206                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00207             }
00208 
00209             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00210             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7 ) {
00211                 sendargs.store( a1, a2, a3, a4, a5, a6, a7 );
00212                 mhandle = mmeth.send();
00213                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00214             }
00215 
00216             SendStatus collectIfDone_impl() {
00217                 if ( mhandle.collectIfDone() == SendSuccess ) {
00218                     return SendSuccess;
00219                 } else
00220                     return SendNotReady;
00221             }
00222 
00223             template<class T1>
00224             SendStatus collectIfDone_impl( T1& a1 ) {
00225                 collectargs.store( a1 );
00226                 if (  mhandle.collectIfDone() == SendSuccess ) {
00227                     return SendSuccess;
00228                 } else
00229                     return SendNotReady;
00230             }
00231 
00232             template<class T1, class T2>
00233             SendStatus collectIfDone_impl( T1& a1, T2& a2 ) {
00234                 collectargs.store( a1, a2);
00235                 if (  mhandle.collectIfDone() == SendSuccess ) {
00236                     return SendSuccess;
00237                 }
00238                 return SendNotReady;
00239             }
00240 
00241             template<class T1, class T2, class T3>
00242             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3 ) {
00243                 collectargs.store( a1, a2, a3);
00244                 if (  mhandle.collectIfDone() == SendSuccess ) {
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                 collectargs.store( a1, a2, a3, a4);
00253                 if (  mhandle.collectIfDone() == SendSuccess ) {
00254                     return SendSuccess;
00255                 } else
00256                     return SendNotReady;
00257             }
00258 
00259             template<class T1, class T2, class T3, class T4, class T5, class T6>
00260             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6 ) {
00261                 collectargs.store( a1, a2, a3, a4, a5, a6);
00262                 if (  mhandle.collectIfDone() == SendSuccess ) {
00263                     return SendSuccess;
00264                 } else
00265                     return SendNotReady;
00266             }
00267 
00268             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00269             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6, T7& a7 ) {
00270                 collectargs.store( a1, a2, a3, a4, a5, a6, a7 );
00271                 if (  mhandle.collectIfDone() == SendSuccess ) {
00272                     return SendSuccess;
00273                 } else
00274                     return SendNotReady;
00275             }
00276 
00277             template<class T1, class T2, class T3, class T4, class T5>
00278             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5 ) {
00279                 collectargs.store( a1, a2, a3, a4, a5);
00280                 if (  mhandle.collectIfDone() == SendSuccess ) {
00281                     return SendSuccess;
00282                 } else
00283                     return SendNotReady;
00284             }
00285 
00286             SendStatus collect_impl() {
00287                 return mhandle.collect();
00288             }
00289             template<class T1>
00290             SendStatus collect_impl( T1& a1 ) {
00291                 collectargs.store( a1 );
00292                 return  mhandle.collect();
00293             }
00294 
00295             template<class T1, class T2>
00296             SendStatus collect_impl( T1& a1, T2& a2 ) {
00297                 collectargs.store( a1, a2);
00298                 return mhandle.collect();
00299             }
00300 
00301             template<class T1, class T2, class T3>
00302             SendStatus collect_impl( T1& a1, T2& a2, T3& a3 ) {
00303                 collectargs.store( a1, a2, a3);
00304                 return mhandle.collect();
00305             }
00306 
00307             template<class T1, class T2, class T3, class T4>
00308             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4 ) {
00309                 collectargs.store( a1, a2, a3, a4);
00310                 return mhandle.collect();
00311             }
00312 
00313             template<class T1, class T2, class T3, class T4, class T5>
00314             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5 ) {
00315                 collectargs.store( a1, a2, a3, a4, a5);
00316                 return mhandle.collect();
00317             }
00318 
00319             result_type ret_impl()
00320             {
00321                 return sendargs.getResult(); // may return void.
00322             }
00323 
00329             template<class T1>
00330             result_type ret_impl(T1 a1)
00331             {
00332                 sendargs.store( a1 );
00333                 mhandle.collectIfDone();
00334                 return sendargs.getResult(); // may return void.
00335             }
00336 
00337             template<class T1,class T2>
00338             result_type ret_impl(T1 a1, T2 a2)
00339             {
00340                 sendargs.store( a1, a2 );
00341                 mhandle.collectIfDone();
00342                 return sendargs.getResult(); // may return void.
00343             }
00344 
00345             template<class T1,class T2, class T3>
00346             result_type ret_impl(T1 a1, T2 a2, T3 a3)
00347             {
00348                 sendargs.store( a1, a2, a3 );
00349                 mhandle.collectIfDone();
00350                 return sendargs.getResult(); // may return void.
00351             }
00352 
00353             template<class T1,class T2, class T3, class T4>
00354             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00355             {
00356                 sendargs.store( a1, a2, a3, a4 );
00357                 mhandle.collectIfDone();
00358                 return sendargs.getResult(); // may return void.
00359             }
00360 
00361             template<class T1,class T2, class T3, class T4, class T5, class T6>
00362             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00363             {
00364                 sendargs.store( a1, a2, a3, a4, a5, a6 );
00365                 mhandle.collectIfDone();
00366                 return sendargs.getResult(); // may return void.
00367             }
00368 
00369             template<class T1,class T2, class T3, class T4, class T5, class T6, class T7>
00370             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00371             {
00372                 sendargs.store( a1, a2, a3, a4, a5, a6, a7 );
00373                 mhandle.collectIfDone();
00374                 return sendargs.getResult(); // may return void.
00375             }
00376 
00377             template<class T1,class T2, class T3, class T4, class T5>
00378             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00379             {
00380                 sendargs.store( a1, a2, a3, a4, a5);
00381                 mhandle.collectIfDone();
00382                 return sendargs.getResult(); // may return void.
00383             }
00384         };
00385 
00386 
00402         template<class OperationCallerT>
00403         class RemoteOperationCaller
00404             : public Invoker<OperationCallerT,RemoteOperationCallerImpl<OperationCallerT> >
00405         {
00406         public:
00407             typedef OperationCallerT Signature;
00408 
00415             RemoteOperationCaller(OperationInterfacePart* of, std::string name, ExecutionEngine* caller)
00416             {
00417                 // create the method.
00418                 this->mmeth = OperationCallerC(of, name, caller);
00419                 // add the arguments to the method.
00420                 this->sendargs.initArgs( this->mmeth );
00421                 this->sendargs.initRet(  this->mmeth );
00422             }
00423 
00424             RemoteOperationCaller(const SendHandleC& sh )
00425             {
00426                 this->mhandle = sh;
00427                 this->collectargs.initArgs( this->mhandle );
00428                 // no need to collect on remote operations.
00429                 this->mhandle.setAutoCollect(false);
00430             }
00431 
00432             virtual bool ready() const {
00433                 return this->mmeth.ready();
00434             }
00435 
00436             virtual base::OperationCallerBase<OperationCallerT>* cloneI(ExecutionEngine* caller) const {
00437                 RemoteOperationCaller<OperationCallerT>* rm = new RemoteOperationCaller<OperationCallerT>( this->mmeth.getOrp(), this->mmeth.getName(), caller);
00438                 return rm;
00439             }
00440         };
00441     }
00442 }
00443 #endif