CommandC.cpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Wed Jan 18 14:11:40 CET 2006  CommandC.cxx 
00003 
00004                         CommandC.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 "CommandC.hpp"
00040 #include "CommandRepository.hpp"
00041 #include "DispatchInterface.hpp"
00042 #include "TryCommand.hpp"
00043 #include "ConditionComposite.hpp"
00044 #include "FactoryExceptions.hpp"
00045 #include "Logger.hpp"
00046 #include <Exceptions.hpp>
00047 #include <vector>
00048 
00049 namespace RTT
00050 {
00051     
00052     
00053     class CommandC::D
00054     {
00055     public:
00056         const CommandRepository::Factory* mcr;
00057         std::string mname;
00058         std::pair<DispatchInterface*,ConditionInterface*> comcon;
00059         std::vector<DataSourceBase::shared_ptr> args;
00060 
00061         void checkAndCreate() {
00062             Logger::In in("CommandC");
00063             if (mcr) {
00064                 if (  mcr->hasMember(mname) == false ) {
00065                     Logger::log() <<Logger::Error << "No such command '"+mname+"' in Command Repository."<<Logger::endl;
00066                     ORO_THROW(name_not_found_exception(mname));
00067                 }
00068                 size_t sz = mcr->getArity(mname);
00069                 if ( sz == args.size() ) {
00070                     // may throw or return '0,0' if no exceptions.
00071                     comcon.first = mcr->produce(mname, args); // the dispatch flag is no longer relevant here.
00072                     args.clear();
00073                     if (comcon.first == 0)
00074                         return;
00075                     // discard the condition, we do not need it.
00076                     delete comcon.second;
00077                 }
00078             }
00079         }
00080 
00081     public:
00082         void newarg(DataSourceBase::shared_ptr na)
00083         {
00084             this->args.push_back( na );
00085             this->checkAndCreate();
00086         }
00087 
00088         D( const CommandRepository::Factory* cr, const std::string& name)
00089             : mcr(cr), mname(name)
00090         {
00091             comcon.first = 0;
00092             this->checkAndCreate();
00093         }
00094 
00095         D(const D& other)
00096             : mcr(other.mcr), mname(other.mname),
00097               args( other.args )
00098         {
00099             if (other.comcon.first )
00100                 comcon.first = other.comcon.first->clone();
00101             else
00102                 comcon.first = 0;
00103         }
00104 
00105         ~D()
00106         {
00107             delete comcon.first;
00108         }
00109 
00110     };
00111 
00112     CommandC::CommandC()
00113         : d(0), cc()
00114     {
00115     }
00116 
00117     CommandC::CommandC(DispatchInterface* di)
00118         : d(0), cc()
00119     {
00120         this->cc.reset( di );
00121     }
00122 
00123     CommandC::CommandC(DispatchInterface::shared_ptr di)
00124         : d(0), cc(di)
00125     {
00126     }
00127 
00128     CommandC::CommandC(const CommandRepository::Factory* cr, const std::string& name)
00129         : d( cr ? new D( cr, name) : 0 ), cc()
00130     {
00131         if ( d->comcon.first ) {
00132             this->cc.reset( d->comcon.first->clone() );
00133             delete d;
00134             d = 0;
00135         }
00136     }
00137 
00138     CommandC::CommandC(const CommandC& other)
00139         : d( other.d ? new D(*other.d) : 0 ), cc()
00140     {
00141         if (other.cc)
00142             this->cc.reset( other.cc->clone() );
00143     }
00144 
00145     CommandC& CommandC::operator=( const CommandC& other )
00146     {
00147         delete d;
00148 
00149         if ( other.d )
00150             d = new D(*other.d);
00151         else {
00152             if (other.cc)
00153                 this->cc.reset( other.cc->clone() );
00154         }
00155         return *this;
00156     }
00157 
00158     CommandC::~CommandC()
00159     {
00160         delete d;
00161     }
00162 
00163     CommandC& CommandC::arg( DataSourceBase::shared_ptr a )
00164     {
00165         if (d)
00166             d->newarg( a );
00167         else {
00168             Logger::log() <<Logger::Warning << "Extra argument discarded for CommandC."<<Logger::endl;
00169         }
00170         if ( d && d->comcon.first ) {
00171             this->cc.reset( d->comcon.first->clone() );
00172             delete d;
00173             d = 0;
00174         }
00175         return *this;
00176     }
00177 
00178     bool CommandC::ready() const {
00179         // if no d pointer present, we have built the command.
00180         // analogous to cc != 0
00181         return d == 0 && cc;
00182     }
00183 
00184     bool CommandC::execute() {
00185         // execute dispatch command
00186         if (cc) {
00187             if ( cc->done() )
00188                 this->reset();
00189             return cc->dispatch();
00190         } else {
00191             Logger::log() <<Logger::Error << "execute() called on incomplete CommandC."<<Logger::endl;
00192             if (d) {
00193                 size_t sz;
00194                 sz = d->mcr->getArity( d->mname );
00195                 Logger::log() <<Logger::Error << "Wrong number of arguments provided for command '"+d->mname+"'"<<Logger::nl;
00196                 Logger::log() <<Logger::Error << "Expected "<< sz << ", got: " << d->args.size() <<Logger::endl;
00197             }
00198         }
00199         return false;
00200     }
00201 
00202     bool CommandC::sent() const{
00203         if (cc)
00204             return cc->sent();
00205         return false;
00206     }
00207 
00208 
00209     bool CommandC::accepted() const {
00210         // check if dispatch command was accepted.
00211         if (cc)
00212             return cc->accepted();
00213         return false;
00214     }
00215 
00216     bool CommandC::executed() const {
00217         // check if dispatch command was executed by the processor
00218         if (cc)
00219             return cc->executed();
00220         return false;
00221     }
00222 
00223     bool CommandC::valid() const {
00224         // check if dispatch command had valid args.
00225         if (cc)
00226             return cc->valid();
00227         return false;
00228     }
00229 
00230     bool CommandC::done() const {
00231         // check if done
00232         if (cc )
00233             return cc->done();
00234         return false;
00235     }
00236 
00237     void CommandC::reset()
00238     {
00239         if (cc)
00240             cc->reset();
00241     }
00242 }

Generated on Tue Mar 25 17:41:40 2008 for OrocosReal-TimeToolkit by  doxygen 1.5.3