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_TASK_OPERATION_CALLER_HPP
00040 #define ORO_TASK_OPERATION_CALLER_HPP
00041
00042 #include <string>
00043 #include <boost/function.hpp>
00044 #include "base/OperationCallerBase.hpp"
00045 #ifdef ORO_TEST_OPERATION_CALLER
00046 #include "internal/UnMember.hpp"
00047 #include "internal/LocalOperationCaller.hpp"
00048 #endif
00049 #include "internal/InvokerSignature.hpp"
00050 #include "base/OperationCallerBaseInvoker.hpp"
00051 #include "Logger.hpp"
00052 #include "Service.hpp"
00053 #ifdef ORO_REMOTING
00054 #include "OperationInterface.hpp"
00055 #include "internal/RemoteOperationCaller.hpp"
00056 #endif
00057
00058 namespace RTT
00059 {
00081 template<class SignatureT>
00082 class OperationCaller
00083 : public internal::InvokerSignature<boost::function_traits<SignatureT>::arity,
00084 SignatureT,
00085 boost::shared_ptr< base::OperationCallerBase<SignatureT> > >,
00086 public base::OperationCallerBaseInvoker
00087 {
00088 std::string mname;
00089 ExecutionEngine* mcaller;
00090 public:
00091 typedef SignatureT Signature;
00092 typedef internal::InvokerSignature<boost::function_traits<Signature>::arity,
00093 Signature,
00094 boost::shared_ptr< base::OperationCallerBase<Signature> > > Base;
00095 typedef typename boost::function_traits<Signature>::result_type result_type;
00096 typedef boost::function_traits<Signature> traits;
00097 typedef boost::shared_ptr< base::OperationCallerBase<Signature> > OperationCallerBasePtr;
00098
00103 OperationCaller()
00104 : Base(), mname()
00105 {}
00106
00111 OperationCaller(std::string name, ExecutionEngine* caller = 0)
00112 : Base(), mname(name), mcaller(caller)
00113 {}
00114
00122 OperationCaller(const OperationCaller& m)
00123 : Base(m.impl ? boost::shared_ptr< base::OperationCallerBase<Signature> >(m.impl->cloneI(m.mcaller)) : m.impl ),
00124 mname(m.mname), mcaller(m.mcaller)
00125 {}
00126
00136 OperationCaller& operator=(const OperationCaller& m)
00137 {
00138 if ( this == &m )
00139 return *this;
00140 mname = m.mname;
00141 mcaller = m.mcaller;
00142 if (m.impl)
00143 this->impl.reset( m.impl->cloneI(mcaller) );
00144 else
00145 this->impl.reset();
00146 return *this;
00147 }
00148
00158 OperationCaller(boost::shared_ptr<base::DisposableInterface> implementation, ExecutionEngine* caller = 0)
00159 : Base( boost::dynamic_pointer_cast< base::OperationCallerBase<Signature> >(implementation) ),
00160 mname(), mcaller(caller)
00161 {
00162 if ( !this->impl && implementation ) {
00163 log(Error) << "Tried to construct OperationCaller from incompatible local operation."<< endlog();
00164 } else {
00165 if (this->impl) {
00166 this->impl.reset( this->impl->cloneI(mcaller) );
00167 }
00168 }
00169 }
00170
00179 OperationCaller(OperationInterfacePart* part, ExecutionEngine* caller = 0)
00180 : Base(),
00181 mname(), mcaller(caller)
00182 {
00183 if (part) {
00184 mname = part->getName();
00185 this->impl = boost::dynamic_pointer_cast< base::OperationCallerBase<Signature> >( part->getLocalOperation() );
00186 setupOperationCaller( part );
00187 }
00188 }
00189
00198 OperationCaller(const std::string& name, ServicePtr service, ExecutionEngine* caller = 0)
00199 : Base(),
00200 mname(name), mcaller(caller)
00201 {
00202 if (service) {
00203 this->impl = boost::dynamic_pointer_cast< base::OperationCallerBase<Signature> >( service->getLocalOperation(name) );
00204 if (service->hasMember(name))
00205 setupOperationCaller( service->getOperation(name) );
00206 }
00207 }
00208
00217 OperationCaller& operator=(boost::shared_ptr<base::DisposableInterface> implementation)
00218 {
00219 if (this->impl && this->impl == implementation)
00220 return *this;
00221 OperationCaller<Signature> tmp(implementation);
00222 *this = tmp;
00223 return *this;
00224 }
00225
00235 OperationCaller& operator=(OperationInterfacePart* part)
00236 {
00237 if (part == 0) {
00238 log(Warning) << "Assigning OperationCaller from null part."<<endlog();
00239 this->impl.reset();
00240 }
00241 if (this->impl && this->impl == part->getLocalOperation() )
00242 return *this;
00243 OperationCaller<Signature> tmp(part);
00244 *this = tmp;
00245 return *this;
00246 }
00247
00255 OperationCaller& operator=(ServicePtr service)
00256 {
00257 if ( !service ) {
00258 log(Warning) << "Assigning OperationCaller from null service."<<endlog();
00259 this->impl.reset();
00260 }
00261 if (this->mname.empty()) {
00262 log(Error) << "Can't initialise unnamed OperationCaller from service '"<<service->getName() <<"'."<<endlog();
00263 return *this;
00264 }
00265 OperationCaller<Signature> tmp(mname,service);
00266 *this = tmp;
00267 return *this;
00268 }
00269
00270 #ifdef ORO_TEST_OPERATION_CALLER
00271
00279 template<class M, class ObjectType>
00280 OperationCaller(std::string name, M meth, ObjectType object, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0, ExecutionThread et = ClientThread)
00281 : Base( OperationCallerBasePtr(new internal::LocalOperationCaller<Signature>(meth, object, ee, caller, et) ) ),
00282 mname(name), mcaller(caller)
00283 {}
00284
00291 template<class M>
00292 OperationCaller(std::string name, M meth, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0, ExecutionThread et = ClientThread)
00293 : Base( OperationCallerBasePtr(new internal::LocalOperationCaller<Signature>(meth,ee,caller, et) ) ),
00294 mname(name), mcaller(caller)
00295 {}
00296 #endif
00297 #ifdef ORO_REMOTING
00298
00304 template<class M>
00305 OperationCaller(std::string name, OperationInterfacePart* orp, ExecutionEngine* caller = 0)
00306 : Base( OperationCallerBasePtr(new internal::RemoteOperationCaller<Signature>(orp,caller) ) ),
00307 mname(name)
00308 {}
00309 #endif
00310
00314 ~OperationCaller()
00315 {
00316 }
00317
00323 bool ready() const {
00324 return this->impl && this->impl->ready();
00325 }
00326
00327
00331 std::string const& getName() const {return mname;}
00332
00333 bool setImplementation(boost::shared_ptr<base::DisposableInterface> implementation, ExecutionEngine* caller = 0) {
00334 *this = implementation;
00335 if ( this->impl ) {
00336 this->mcaller = caller;
00337 this->impl->setCaller(caller);
00338 }
00339 return ready();
00340 }
00341
00342 bool setImplementationPart(OperationInterfacePart* orp, ExecutionEngine* caller = 0) {
00343 OperationCaller<Signature> tmp(orp, caller);
00344 if (tmp.ready()) {
00345 *this = tmp;
00346 return true;
00347 }
00348 return false;
00349 }
00350
00354 const OperationCallerBasePtr getOperationCallerImpl() const {
00355 return this->impl;
00356 }
00357
00361 void setOperationCallerImpl( OperationCallerBasePtr new_impl) const {
00362 this->impl = new_impl;
00363 }
00364
00365 void setCaller(ExecutionEngine* caller) {
00366 this->mcaller = caller;
00367 if (this->impl)
00368 this->impl->setCaller(caller);
00369 }
00370
00371 void disconnect()
00372 {
00373 this->impl.reset();
00374 }
00375 protected:
00381 void setupOperationCaller(OperationInterfacePart* part) {
00382 if ( !this->impl ) {
00383 #ifdef ORO_REMOTING
00384
00385 try {
00386 this->impl.reset( new internal::RemoteOperationCaller<Signature>( part, mname, mcaller ));
00387 } catch( std::exception& e ) {
00388 log(Error) << "Constructing RemoteOperationCaller for "<< mname <<" was not possible."<<endlog();
00389 log(Error) << "Probable cause: " << e.what() <<endlog();
00390 return;
00391 }
00392 if (this->impl->ready()) {
00393 log(Debug) << "Constructed OperationCaller from remote implementation '"<< mname<<"'."<< endlog();
00394 this->impl->setCaller(mcaller);
00395 } else {
00396 this->impl.reset();
00397 log(Error) << "Tried to construct OperationCaller from incompatible operation '"<< mname<<"'."<< endlog();
00398 }
00399 #else
00400 log(Error) << "Tried to construct remote OperationCaller but ORO_REMOTING was disabled."<< endlog();
00401 #endif
00402 } else {
00403
00404 this->impl.reset( this->impl->cloneI(mcaller) );
00405 }
00406 }
00407
00408 };
00409
00410 #ifdef ORO_TEST_OPERATION_CALLER
00411
00418 template<class F, class O>
00419 OperationCaller< typename internal::UnMember<F>::type > method(std::string name, F method, O object, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0) {
00420 return OperationCaller< typename internal::UnMember<F>::type >(name, method, object, ee, caller);
00421 }
00422
00429 template<class F>
00430 OperationCaller<F> method(std::string name, F method, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0) {
00431 return OperationCaller<F>(name, method, ee, caller);
00432 }
00439 template<class F>
00440 OperationCaller< typename internal::ArgMember<F>::type > method_ds(std::string name, F method, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0) {
00441 return OperationCaller< typename internal::ArgMember<F>::type >(name, method, ee, caller);
00442 }
00443 #endif
00444 }
00445
00446 #endif