Go to the documentation of this file.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 #include "OperationCallerC.hpp"
00040 #include "../FactoryExceptions.hpp"
00041 #include "DataSourceCommand.hpp"
00042 #include "../Service.hpp"
00043 #include "../Logger.hpp"
00044 #include "Exceptions.hpp"
00045 #include <vector>
00046
00047 namespace RTT {
00048 using namespace detail;
00049
00050
00051 class OperationCallerC::D
00052 {
00053 public:
00054 OperationInterfacePart* ofp;
00055 ExecutionEngine* caller;
00056 std::string mname;
00057 std::vector<DataSourceBase::shared_ptr> args;
00058 DataSourceBase::shared_ptr rta;
00059 DataSourceBase::shared_ptr m;
00060 DataSourceBase::shared_ptr s;
00061
00062 void checkAndCreate() {
00063 Logger::In in("OperationCallerC");
00064 if ( ofp ) {
00065 size_t sz = ofp->arity();
00066 if ( sz == args.size() ) {
00067
00068 m = ofp->produce(args, caller );
00069 try {
00070 s = ofp->produceSend(args, caller );
00071 } catch( no_asynchronous_operation_exception const& ) {
00072
00073 }
00074 args.clear();
00075 if ( !m )
00076 return;
00077 if (rta)
00078 try {
00079 m = new DataSourceCommand( rta->updateAction( m.get() ) );
00080 } catch( bad_assignment& ) {
00081 log(Error) << "Error in OperationCallerC::ret : can not convert return value of type "<< m->getType() << " to given type "<< rta->getType()<<endlog();
00082 }
00083
00084 }
00085 }
00086 }
00087
00088 void newarg(DataSourceBase::shared_ptr na)
00089 {
00090 this->args.push_back( na );
00091 this->checkAndCreate();
00092 }
00093
00094 void ret(AttributeBase* r)
00095 {
00096 this->rta = r->getDataSource();
00097 }
00098
00099 void ret(DataSourceBase::shared_ptr d)
00100 {
00101 this->rta = d;
00102 }
00103
00104 D( OperationInterfacePart* mr, const std::string& name, ExecutionEngine* caller)
00105 : ofp(mr), caller(caller), mname(name), rta(), m(), s()
00106 {
00107 this->checkAndCreate();
00108 }
00109
00110 D(const D& other)
00111 : ofp(other.ofp), caller(other.caller), mname(other.mname),
00112 args( other.args ), rta( other.rta ), m( other.m ), s(other.s)
00113 {
00114 }
00115
00116 ~D()
00117 {
00118 }
00119
00120 };
00121
00122 OperationCallerC::OperationCallerC()
00123 : d(0), m()
00124 {
00125 }
00126
00127 OperationCallerC::OperationCallerC(OperationInterfacePart* mr, const std::string& name, ExecutionEngine* caller)
00128 : d( mr ? new D( mr, name, caller) : 0 ), m(), ofp(mr), mname(name)
00129 {
00130 if ( d && d->m ) {
00131 this->m = d->m;
00132 this->s = d->s;
00133 delete d;
00134 d = 0;
00135 } else {
00136 if (mr == 0)
00137 log(Error) <<"Can not construct OperationCallerC for '"<<name<<"' from null OperationInterfacePart."<<endlog();
00138 }
00139 }
00140
00141 OperationCallerC::OperationCallerC(const OperationCallerC& other)
00142 : d( other.d ? new D(*other.d) : 0 ), m( other.m ? other.m : 0), ofp(other.ofp), mname(other.mname)
00143 {
00144 }
00145
00146 OperationCallerC& OperationCallerC::operator=(const OperationCallerC& other)
00147 {
00148 if ( &other == this )
00149 return *this;
00150 delete d;
00151 d = ( other.d ? new D(*other.d) : 0 );
00152 m = other.m;
00153 s = other.s;
00154 ofp = other.ofp;
00155 mname = other.mname;
00156 return *this;
00157 }
00158
00159 OperationCallerC::~OperationCallerC()
00160 {
00161 delete d;
00162 }
00163
00164 OperationCallerC& OperationCallerC::arg( DataSourceBase::shared_ptr a )
00165 {
00166 if (d)
00167 d->newarg( a );
00168 else {
00169 Logger::log() <<Logger::Warning << "Extra argument discarded for OperationCallerC."<<Logger::endl;
00170 }
00171 if ( d && d->m ) {
00172 this->m = d->m;
00173 this->s = d->s;
00174 delete d;
00175 d = 0;
00176 }
00177 return *this;
00178 }
00179
00180 OperationCallerC& OperationCallerC::ret( AttributeBase* r )
00181 {
00182 if (d)
00183 d->ret( r );
00184 else {
00185 if (m) {
00186 try {
00187 m = new DataSourceCommand(r->getDataSource()->updateAction( m.get() ) );
00188 } catch( bad_assignment& ) {
00189 log(Error) << "Error in OperationCallerC::ret : can not convert return value of type "<< m->getType() << " to given type "<< r->getDataSource()->getType()<<endlog();
00190 }
00191 } else
00192 log(Error) <<"Can not add return argument to invalid OperationCallerC."<<endlog();
00193 }
00194 return *this;
00195 }
00196
00197 OperationCallerC& OperationCallerC::ret(DataSourceBase::shared_ptr r)
00198 {
00199 if (d)
00200 d->ret( r );
00201 else {
00202
00203 if (m)
00204 m = new DataSourceCommand(r->updateAction( m.get() ) );
00205 else
00206 log(Error) <<"Can not add return argument to invalid OperationCallerC."<<endlog();
00207 }
00208 return *this;
00209 }
00210
00211
00212 bool OperationCallerC::call() {
00213 if (m)
00214 return m->evaluate();
00215 else {
00216 Logger::log() <<Logger::Error << "call() called on incomplete OperationCallerC."<<Logger::endl;
00217 if (d) {
00218 size_t sz;
00219 sz = d->ofp->arity();
00220 Logger::log() <<Logger::Error << "Wrong number of arguments provided for method '"+d->mname+"'"<<Logger::nl;
00221 Logger::log() <<Logger::Error << "Expected "<< sz << ", got: " << d->args.size() <<Logger::endl;
00222 }
00223 }
00224 return false;
00225 }
00226
00227 void OperationCallerC::check() {
00228 if (d) {
00229
00230 if (d->ofp)
00231 DataSourceBase::shared_ptr dummy = d->ofp->produce( d->args, d->caller );
00232 else
00233 throw name_not_found_exception( d->mname );
00234 }
00235 }
00236
00237 SendHandleC OperationCallerC::send() {
00238 DataSourceBase::shared_ptr h;
00239 try {
00240 h = ofp->produceHandle();
00241 } catch( no_asynchronous_operation_exception const& nao) {
00242 log(Error) <<"OperationCallerC::send(): Can not send the '" << ofp->getName() << "' operation:" << nao.what() << endlog();
00243 return SendHandleC();
00244 }
00245 if (s) {
00246
00247 #ifndef NDEBUG
00248 bool result =
00249 #endif
00250 h->update( s.get() );
00251 assert( result );
00252 return SendHandleC( s, h, ofp, mname );
00253 }
00254 else {
00255 Logger::log() <<Logger::Error << "send() called on incomplete OperationCallerC."<<Logger::endl;
00256 if (d) {
00257 size_t sz;
00258 sz = d->ofp->arity();
00259 Logger::log() <<Logger::Error << "Wrong number of arguments provided for method '"+d->mname+"'"<<Logger::nl;
00260 Logger::log() <<Logger::Error << "Expected "<< sz << ", got: " << d->args.size() <<Logger::endl;
00261 }
00262 }
00263 return SendHandleC();
00264 }
00265
00266 bool OperationCallerC::ready() const
00267 {
00268 return m != 0;
00269 }
00270
00271 OperationInterfacePart* OperationCallerC::getOrp() const {
00272 return ofp;
00273 }
00274
00275 std::string const& OperationCallerC::getName() const {
00276 return mname;
00277 }
00278
00279 DataSourceBase::shared_ptr OperationCallerC::getCallDataSource() { return m; }
00280 DataSourceBase::shared_ptr OperationCallerC::getSendDataSource() { return s; }
00281 }