Orocos Real-Time Toolkit
2.6.0
|
00001 /*************************************************************************** 00002 tag: Peter Soetens Wed Jan 18 14:11:40 CET 2006 OperationCallerC.cxx 00003 00004 OperationCallerC.cxx - description 00005 ------------------- 00006 begin : Wed January 18 2006 00007 copyright : (C) 2006 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.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 #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 // may throw or return nill 00068 m = ofp->produce(args, caller ); 00069 try { 00070 s = ofp->produceSend(args, caller ); 00071 } catch( no_asynchronous_operation_exception const& /*e*/) { 00072 // leave s empty. 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& /*ba*/ ) { 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& /*ba*/ ) { 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 // no d, store manually: 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 // something went wrong, let producer throw 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 // evaluate and copy result of s to handle and pass handle to SendHandleC. 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; 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 }