OperationCallerC.cpp
Go to the documentation of this file.
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 }


rtt
Author(s): RTT Developers
autogenerated on Thu Jan 2 2014 11:35:22