00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
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                 
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(); 
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(); 
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(); 
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(); 
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(); 
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(); 
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(); 
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(); 
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                 
00418                 this->mmeth = OperationCallerC(of, name, caller);
00419                 
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                 
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