Orocos Real-Time Toolkit
2.6.0
|
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