Orocos Real-Time Toolkit  2.5.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 void dispose() { assert(false); }
00100 
00101             virtual void setExecutor(ExecutionEngine* ee) {
00102             }
00103 
00104             virtual void setCaller(ExecutionEngine* ee) {
00105             }
00106 
00107 
00113             result_type call_impl() {
00114                 mmeth.call();
00115                 return sendargs.getResult();
00116             }
00117 
00118             template<class T1>
00119             result_type call_impl( T1 a1 ) {
00120                 sendargs.store( a1 );
00121                 mmeth.call();
00122                 return sendargs.getResult();
00123             }
00124 
00125             template<class T1, class T2>
00126             result_type call_impl( T1 a1, T2 a2 ) {
00127                 sendargs.store( a1, a2 );
00128                 mmeth.call();
00129                 return sendargs.getResult();
00130             }
00131 
00132             template<class T1, class T2, class T3>
00133             result_type call_impl( T1 a1, T2 a2, T3 a3 ) {
00134                 sendargs.store( a1, a2, a3 );
00135                 mmeth.call();
00136                 return sendargs.getResult();
00137             }
00138 
00139             template<class T1, class T2, class T3, class T4>
00140             result_type call_impl( T1 a1, T2 a2, T3 a3, T4 a4 ) {
00141                 sendargs.store( a1, a2, a3, a4 );
00142                 mmeth.call();
00143                 return sendargs.getResult();
00144             }
00145 
00146             template<class T1, class T2, class T3, class T4, class T5, class T6>
00147             result_type call_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6 ) {
00148                 sendargs.store( a1, a2, a3, a4, a5, a6 );
00149                 mmeth.call();
00150                 return sendargs.getResult();
00151             }
00152 
00153             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00154             result_type call_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7 ) {
00155                 sendargs.store( a1, a2, a3, a4, a5, a6, a7 );
00156                 mmeth.call();
00157                 return sendargs.getResult();
00158             }
00159 
00160             template<class T1, class T2, class T3, class T4, class T5>
00161             result_type call_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5 ) {
00162                 sendargs.store( a1, a2, a3, a4, a5 );
00163                 mmeth.call();
00164                 return sendargs.getResult();
00165             }
00166 
00167             SendHandle<Signature> send_impl() {
00168                 mhandle = mmeth.send();
00169                 // @todo: get remote collect from rt allocation.
00170                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00171             }
00172 
00173             template<class T1>
00174             SendHandle<Signature> send_impl( T1 a1 ) {
00175                 sendargs.store( a1 );
00176                 mhandle = mmeth.send();
00177                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00178             }
00179 
00180             template<class T1, class T2>
00181             SendHandle<Signature> send_impl( T1 a1, T2 a2 ) {
00182                 sendargs.store( a1, a2 );
00183                 mhandle = mmeth.send();
00184                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00185             }
00186 
00187             template<class T1, class T2, class T3>
00188             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3 ) {
00189                 sendargs.store( a1, a2, a3 );
00190                 mhandle = mmeth.send();
00191                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00192             }
00193 
00194             template<class T1, class T2, class T3, class T4>
00195             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4 ) {
00196                 sendargs.store( a1, a2, a3, a4 );
00197                 mhandle = mmeth.send();
00198                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00199             }
00200 
00201             template<class T1, class T2, class T3, class T4, class T5>
00202             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5 ) {
00203                 sendargs.store( a1, a2, a3, a4, a5 );
00204                 mhandle = mmeth.send();
00205                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00206             }
00207 
00208             template<class T1, class T2, class T3, class T4, class T5, class T6>
00209             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6 ) {
00210                 sendargs.store( a1, a2, a3, a4, a5, a6 );
00211                 mhandle = mmeth.send();
00212                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00213             }
00214 
00215             template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00216             SendHandle<Signature> send_impl( T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7 ) {
00217                 sendargs.store( a1, a2, a3, a4, a5, a6, a7 );
00218                 mhandle = mmeth.send();
00219                 return SendHandle<Signature>( boost::make_shared< RemoteOperationCaller<OperationCallerT> >( mhandle ) );
00220             }
00221 
00222             SendStatus collectIfDone_impl() {
00223                 if ( mhandle.collectIfDone() == SendSuccess ) {
00224                     return SendSuccess;
00225                 } else
00226                     return SendNotReady;
00227             }
00228 
00229             template<class T1>
00230             SendStatus collectIfDone_impl( T1& a1 ) {
00231                 collectargs.store( a1 );
00232                 if (  mhandle.collectIfDone() == SendSuccess ) {
00233                     return SendSuccess;
00234                 } else
00235                     return SendNotReady;
00236             }
00237 
00238             template<class T1, class T2>
00239             SendStatus collectIfDone_impl( T1& a1, T2& a2 ) {
00240                 collectargs.store( a1, a2);
00241                 if (  mhandle.collectIfDone() == SendSuccess ) {
00242                     return SendSuccess;
00243                 }
00244                 return SendNotReady;
00245             }
00246 
00247             template<class T1, class T2, class T3>
00248             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3 ) {
00249                 collectargs.store( a1, a2, a3);
00250                 if (  mhandle.collectIfDone() == SendSuccess ) {
00251                     return SendSuccess;
00252                 } else
00253                     return SendNotReady;
00254             }
00255 
00256             template<class T1, class T2, class T3, class T4>
00257             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4 ) {
00258                 collectargs.store( a1, a2, a3, a4);
00259                 if (  mhandle.collectIfDone() == SendSuccess ) {
00260                     return SendSuccess;
00261                 } else
00262                     return SendNotReady;
00263             }
00264 
00265             template<class T1, class T2, class T3, class T4, class T5, class T6>
00266             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5, T6& a6 ) {
00267                 collectargs.store( a1, a2, a3, a4, a5, a6);
00268                 if (  mhandle.collectIfDone() == SendSuccess ) {
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                 collectargs.store( a1, a2, a3, a4, a5, a6, a7 );
00277                 if (  mhandle.collectIfDone() == SendSuccess ) {
00278                     return SendSuccess;
00279                 } else
00280                     return SendNotReady;
00281             }
00282 
00283             template<class T1, class T2, class T3, class T4, class T5>
00284             SendStatus collectIfDone_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5 ) {
00285                 collectargs.store( a1, a2, a3, a4, a5);
00286                 if (  mhandle.collectIfDone() == SendSuccess ) {
00287                     return SendSuccess;
00288                 } else
00289                     return SendNotReady;
00290             }
00291 
00292             SendStatus collect_impl() {
00293                 return mhandle.collect();
00294             }
00295             template<class T1>
00296             SendStatus collect_impl( T1& a1 ) {
00297                 collectargs.store( a1 );
00298                 return  mhandle.collect();
00299             }
00300 
00301             template<class T1, class T2>
00302             SendStatus collect_impl( T1& a1, T2& a2 ) {
00303                 collectargs.store( a1, a2);
00304                 return mhandle.collect();
00305             }
00306 
00307             template<class T1, class T2, class T3>
00308             SendStatus collect_impl( T1& a1, T2& a2, T3& a3 ) {
00309                 collectargs.store( a1, a2, a3);
00310                 return mhandle.collect();
00311             }
00312 
00313             template<class T1, class T2, class T3, class T4>
00314             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4 ) {
00315                 collectargs.store( a1, a2, a3, a4);
00316                 return mhandle.collect();
00317             }
00318 
00319             template<class T1, class T2, class T3, class T4, class T5>
00320             SendStatus collect_impl( T1& a1, T2& a2, T3& a3, T4& a4, T5& a5 ) {
00321                 collectargs.store( a1, a2, a3, a4, a5);
00322                 return mhandle.collect();
00323             }
00324 
00325             result_type ret_impl()
00326             {
00327                 return sendargs.getResult(); // may return void.
00328             }
00329 
00335             template<class T1>
00336             result_type ret_impl(T1 a1)
00337             {
00338                 sendargs.store( a1 );
00339                 mhandle.collectIfDone();
00340                 return sendargs.getResult(); // may return void.
00341             }
00342 
00343             template<class T1,class T2>
00344             result_type ret_impl(T1 a1, T2 a2)
00345             {
00346                 sendargs.store( a1, a2 );
00347                 mhandle.collectIfDone();
00348                 return sendargs.getResult(); // may return void.
00349             }
00350 
00351             template<class T1,class T2, class T3>
00352             result_type ret_impl(T1 a1, T2 a2, T3 a3)
00353             {
00354                 sendargs.store( a1, a2, a3 );
00355                 mhandle.collectIfDone();
00356                 return sendargs.getResult(); // may return void.
00357             }
00358 
00359             template<class T1,class T2, class T3, class T4>
00360             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4)
00361             {
00362                 sendargs.store( a1, a2, a3, a4 );
00363                 mhandle.collectIfDone();
00364                 return sendargs.getResult(); // may return void.
00365             }
00366 
00367             template<class T1,class T2, class T3, class T4, class T5, class T6>
00368             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
00369             {
00370                 sendargs.store( a1, a2, a3, a4, a5, a6 );
00371                 mhandle.collectIfDone();
00372                 return sendargs.getResult(); // may return void.
00373             }
00374 
00375             template<class T1,class T2, class T3, class T4, class T5, class T6, class T7>
00376             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
00377             {
00378                 sendargs.store( a1, a2, a3, a4, a5, a6, a7 );
00379                 mhandle.collectIfDone();
00380                 return sendargs.getResult(); // may return void.
00381             }
00382 
00383             template<class T1,class T2, class T3, class T4, class T5>
00384             result_type ret_impl(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
00385             {
00386                 sendargs.store( a1, a2, a3, a4, a5);
00387                 mhandle.collectIfDone();
00388                 return sendargs.getResult(); // may return void.
00389             }
00390         };
00391 
00392 
00408         template<class OperationCallerT>
00409         class RemoteOperationCaller
00410             : public Invoker<OperationCallerT,RemoteOperationCallerImpl<OperationCallerT> >
00411         {
00412         public:
00413             typedef OperationCallerT Signature;
00414 
00421             RemoteOperationCaller(OperationInterfacePart* of, std::string name, ExecutionEngine* caller)
00422             {
00423                 // create the method.
00424                 this->mmeth = OperationCallerC(of, name, caller);
00425                 // add the arguments to the method.
00426                 this->sendargs.initArgs( this->mmeth );
00427                 this->sendargs.initRet(  this->mmeth );
00428             }
00429 
00430             RemoteOperationCaller(const SendHandleC& sh )
00431             {
00432                 this->mhandle = sh;
00433                 this->collectargs.initArgs( this->mhandle );
00434                 // no need to collect on remote operations.
00435                 this->mhandle.setAutoCollect(false);
00436             }
00437 
00438             virtual void readArguments() {}
00439 
00440             virtual bool ready() const {
00441                 return this->mmeth.ready();
00442             }
00443 
00444             virtual bool execute() {
00445                 return this->mmeth.call();
00446             }
00447 
00448             virtual bool setThread(ExecutionThread, ExecutionEngine* ) {
00449                 return false;
00450             }
00451 
00452             virtual base::OperationCallerBase<OperationCallerT>* cloneI(ExecutionEngine* caller) const {
00453                 RemoteOperationCaller<OperationCallerT>* rm = new RemoteOperationCaller<OperationCallerT>( this->mmeth.getOrp(), this->mmeth.getName(), caller);
00454                 return rm;
00455             }
00456         };
00457     }
00458 }
00459 #endif