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(), mcaller(0)
00105 {}
00106
00112 OperationCaller(std::string name, ExecutionEngine* caller = 0)
00113 : Base(), mname(name), mcaller(caller)
00114 {}
00115
00123 OperationCaller(const OperationCaller& m)
00124 : Base(m.impl ? boost::shared_ptr< base::OperationCallerBase<Signature> >(m.impl->cloneI(m.mcaller)) : m.impl ),
00125 mname(m.mname), mcaller(m.mcaller)
00126 {}
00127
00137 OperationCaller& operator=(const OperationCaller& m)
00138 {
00139 if ( this == &m )
00140 return *this;
00141 mname = m.mname;
00142 mcaller = m.mcaller;
00143 if (m.impl)
00144 this->impl.reset( m.impl->cloneI(mcaller) );
00145 else
00146 this->impl.reset();
00147 return *this;
00148 }
00149
00159 OperationCaller(boost::shared_ptr<base::DisposableInterface> implementation, ExecutionEngine* caller = 0)
00160 : Base( boost::dynamic_pointer_cast< base::OperationCallerBase<Signature> >(implementation) ),
00161 mname(), mcaller(caller)
00162 {
00163 if ( !this->impl && implementation ) {
00164 log(Error) << "Tried to construct OperationCaller from incompatible local operation."<< endlog();
00165 } else {
00166 if (this->impl) {
00167 this->impl.reset( this->impl->cloneI(mcaller) );
00168 }
00169 }
00170 }
00171
00180 OperationCaller(OperationInterfacePart* part, ExecutionEngine* caller = 0)
00181 : Base(),
00182 mname(), mcaller(caller)
00183 {
00184 if (part) {
00185 mname = part->getName();
00186 this->impl = boost::dynamic_pointer_cast< base::OperationCallerBase<Signature> >( part->getLocalOperation() );
00187 setupOperationCaller( part );
00188 }
00189 }
00190
00199 OperationCaller(const std::string& name, ServicePtr service, ExecutionEngine* caller = 0)
00200 : Base(),
00201 mname(name), mcaller(caller)
00202 {
00203 if (service) {
00204 this->impl = boost::dynamic_pointer_cast< base::OperationCallerBase<Signature> >( service->getLocalOperation(name) );
00205 if (service->hasMember(name))
00206 setupOperationCaller( service->getOperation(name) );
00207 }
00208 }
00209
00218 OperationCaller& operator=(boost::shared_ptr<base::DisposableInterface> implementation)
00219 {
00220 if (this->impl && this->impl == implementation)
00221 return *this;
00222 OperationCaller<Signature> tmp(implementation);
00223 *this = tmp;
00224 return *this;
00225 }
00226
00236 OperationCaller& operator=(OperationInterfacePart* part)
00237 {
00238 if (part == 0) {
00239 log(Warning) << "Assigning OperationCaller from null part."<<endlog();
00240 this->impl.reset();
00241 }
00242 if (this->impl && this->impl == part->getLocalOperation() )
00243 return *this;
00244 OperationCaller<Signature> tmp(part);
00245 *this = tmp;
00246 return *this;
00247 }
00248
00256 OperationCaller& operator=(ServicePtr service)
00257 {
00258 if ( !service ) {
00259 log(Warning) << "Assigning OperationCaller from null service."<<endlog();
00260 this->impl.reset();
00261 }
00262 if (this->mname.empty()) {
00263 log(Error) << "Can't initialise unnamed OperationCaller from service '"<<service->getName() <<"'."<<endlog();
00264 return *this;
00265 }
00266 OperationCaller<Signature> tmp(mname,service);
00267 *this = tmp;
00268 return *this;
00269 }
00270
00271 #ifdef ORO_TEST_OPERATION_CALLER
00272
00281 template<class M, class ObjectType>
00282 OperationCaller(std::string name, M meth, ObjectType object, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0, ExecutionThread et = ClientThread)
00283 : Base( OperationCallerBasePtr(new internal::LocalOperationCaller<Signature>(meth, object, ee, caller, et) ) ),
00284 mname(name), mcaller(caller)
00285 {}
00286
00294 template<class M>
00295 OperationCaller(std::string name, M meth, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0, ExecutionThread et = ClientThread)
00296 : Base( OperationCallerBasePtr(new internal::LocalOperationCaller<Signature>(meth,ee,caller, et) ) ),
00297 mname(name), mcaller(caller)
00298 {}
00299 #endif
00300 #ifdef ORO_REMOTING
00301
00307 template<class M>
00308 OperationCaller(std::string name, OperationInterfacePart* orp, ExecutionEngine* caller = 0)
00309 : Base( OperationCallerBasePtr(new internal::RemoteOperationCaller<Signature>(orp,caller) ) ),
00310 mname(name)
00311 {}
00312 #endif
00313
00317 ~OperationCaller()
00318 {
00319 }
00320
00326 bool ready() const {
00327 return this->impl && this->impl->ready();
00328 }
00329
00333 std::string const& getName() const {return mname;}
00334
00335 bool setImplementation(boost::shared_ptr<base::DisposableInterface> implementation, ExecutionEngine* caller = 0) {
00336 *this = implementation;
00337 if ( this->impl ) {
00338 this->mcaller = caller;
00339 this->impl->setCaller(caller);
00340 }
00341 return ready();
00342 }
00343
00344 bool setImplementationPart(OperationInterfacePart* orp, ExecutionEngine* caller = 0) {
00345 OperationCaller<Signature> tmp(orp, caller);
00346 if (tmp.ready()) {
00347 *this = tmp;
00348 return true;
00349 }
00350 return false;
00351 }
00352
00356 const OperationCallerBasePtr getOperationCallerImpl() const {
00357 return this->impl;
00358 }
00359
00363 void setOperationCallerImpl( OperationCallerBasePtr new_impl) const {
00364 this->impl = new_impl;
00365 }
00366
00367 void setCaller(ExecutionEngine* caller) {
00368 this->mcaller = caller;
00369 if (this->impl)
00370 this->impl->setCaller(caller);
00371 }
00372
00373 void disconnect()
00374 {
00375 this->impl.reset();
00376 }
00377 protected:
00383 void setupOperationCaller(OperationInterfacePart* part) {
00384 if ( !this->impl ) {
00385 #ifdef ORO_REMOTING
00386
00387 try {
00388 this->impl.reset( new internal::RemoteOperationCaller<Signature>( part, mname, mcaller ));
00389 } catch( std::exception& e ) {
00390 log(Error) << "Constructing RemoteOperationCaller for "<< mname <<" was not possible."<<endlog();
00391 log(Error) << "Probable cause: " << e.what() <<endlog();
00392 return;
00393 }
00394 if (this->impl->ready()) {
00395 log(Debug) << "Constructed OperationCaller from remote implementation '"<< mname<<"'."<< endlog();
00396 this->impl->setCaller(mcaller);
00397 } else {
00398 this->impl.reset();
00399 log(Error) << "Tried to construct OperationCaller from incompatible operation '"<< mname<<"'."<< endlog();
00400 }
00401 #else
00402 log(Error) << "Tried to construct remote OperationCaller but ORO_REMOTING was disabled."<< endlog();
00403 #endif
00404 } else {
00405
00406 this->impl.reset( this->impl->cloneI(mcaller) );
00407 }
00408 }
00409
00410 };
00411
00412 #ifdef ORO_TEST_OPERATION_CALLER
00413
00421 template<class F, class O>
00422 OperationCaller< typename internal::UnMember<F>::type > method(std::string name, F method, O object, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0) {
00423 return OperationCaller< typename internal::UnMember<F>::type >(name, method, object, ee, caller);
00424 }
00425
00433 template<class F>
00434 OperationCaller<F> method(std::string name, F method, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0) {
00435 return OperationCaller<F>(name, method, ee, caller);
00436 }
00444 template<class F>
00445 OperationCaller< typename internal::ArgMember<F>::type > method_ds(std::string name, F method, ExecutionEngine* ee = 0, ExecutionEngine* caller = 0) {
00446 return OperationCaller< typename internal::ArgMember<F>::type >(name, method, ee, caller);
00447 }
00448 #endif
00449 }
00450
00451 #endif