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