ScriptingService.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: Peter Soetens  Mon Jun 26 13:25:57 CEST 2006  ScriptingService.cxx
00003 
00004                         ScriptingService.cxx -  description
00005                            -------------------
00006     begin                : Mon June 26 2006
00007     copyright            : (C) 2006 Peter Soetens
00008     email                : peter.soetens@fmtc.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 
00040 #include "ScriptingService.hpp"
00041 #include "../Logger.hpp"
00042 #include "../TaskContext.hpp"
00043 #include <algorithm>
00044 #include <functional>
00045 #include <fstream>
00046 #include <iterator>
00047 #include "scripting/rtt-scripting-config.h"
00048 #include "ProgramExceptions.hpp"
00049 #include "StatementProcessor.hpp"
00050 #include "../Service.hpp"
00051 #include "Parser.hpp"
00052 #include "parse_exception.hpp"
00053 #include "../OperationCaller.hpp"
00054 #include "../internal/mystd.hpp"
00055 #include "../plugin/ServicePlugin.hpp"
00056 #include "../internal/GlobalEngine.hpp"
00057 
00058 ORO_SERVICE_NAMED_PLUGIN( RTT::scripting::ScriptingService, "scripting" )
00059 
00060 
00061 namespace RTT {
00062     using namespace detail;
00063     using namespace std;
00064 
00065     ScriptingService::shared_ptr ScriptingService::Create(TaskContext* parent){
00066         shared_ptr sp(new ScriptingService(parent));
00067         parent->provides()->addService( sp );
00068         return sp;
00069     }
00070 
00071     ScriptingService::ScriptingService( TaskContext* parent )
00072         : Service("scripting", parent),
00073           sproc(0)
00074     {
00075         this->doc("Orocos Scripting service. Use this service in order to load or query programs or state machines.");
00076         this->createInterface();
00077         ZeroPeriodWarning = true;
00078         this->addProperty("ZeroPeriodWarning",ZeroPeriodWarning)
00079                         .doc("If this is set to false, the warning log when loading a program or a state machine into a Component"
00080                                         " with a null period will not be printed. Be sure you have something else triggering periodically"
00081                                         " your Component activity unless your script may not work.");
00082     }
00083 
00084     ScriptingService::~ScriptingService()
00085     {
00086         // since we are refcounted, we don't need to inform the owner
00087         // that we're being deleted.
00088         this->clear();
00089         delete sproc;
00090     }
00091 
00092     void ScriptingService::clear() {
00093         while ( !states.empty() ) {
00094             // try to unload all
00095             Logger::log() << Logger::Info << "ScriptingService unloads StateMachine "<< states.begin()->first << "..."<<Logger::endl;
00096 #ifndef ORO_EMBEDDED
00097             try {
00098                 this->unloadStateMachine( states.begin()->first );
00099             }
00100             catch ( program_load_exception& ple) {
00101                 Logger::log() << Logger::Error << ple.what() <<Logger::endl;
00102                 states.erase( states.begin() ); // plainly remove it to avoid endless loop.
00103             }
00104 #else
00105             if (this->unloadStateMachine( states.begin()->first ) == false) {
00106                 Logger::log() << Logger::Error << "Error during unload !" <<Logger::endl;
00107                 states.erase( states.begin() ); // plainly remove it to avoid endless loop.
00108             }
00109 #endif
00110         }
00111         while ( !programs.empty() ) {
00112             // try to unload all
00113             Logger::log() << Logger::Info << "ScriptingService unloads Program "<< programs.begin()->first << "..."<<Logger::endl;
00114 #ifndef ORO_EMBEDDED
00115             try {
00116                 this->unloadProgram( programs.begin()->first );
00117             }
00118             catch ( program_load_exception& ple) {
00119                 Logger::log() << Logger::Error << ple.what() <<Logger::endl;
00120                 programs.erase( programs.begin() ); // plainly remove it to avoid endless loop.
00121             }
00122 #else
00123             if (this->unloadProgram( programs.begin()->first ) == false) {
00124                 Logger::log(Error) << "Error during unload !" <<Logger::endl;
00125                 programs.erase( programs.begin() ); // plainly remove it to avoid endless loop.
00126             }
00127 #endif
00128         }
00129         Service::clear();
00130     }
00131 
00132      StateMachine::Status::StateMachineStatus ScriptingService::getStateMachineStatus(const string& name) const
00133      {
00134          StateMapIt it = states.find(name);
00135          if ( it != states.end() ) {
00136              return it->second->getStatus();
00137          }
00138          return StateMachineStatus::unloaded;
00139      }
00140 
00141      string ScriptingService::getStateMachineStatusStr(const string& name) const
00142      {
00143         switch ( getStateMachineStatus( name ))
00144             {
00145             case StateMachineStatus::inactive:
00146                 return "inactive";
00147                 break;
00148             case StateMachineStatus::stopping:
00149                 return "stopping";
00150                 break;
00151             case StateMachineStatus::stopped:
00152                 return "stopped";
00153                 break;
00154             case StateMachineStatus::requesting:
00155                 return "requesting";
00156                 break;
00157             case StateMachineStatus::running:
00158                 return "running";
00159                 break;
00160             case StateMachineStatus::paused:
00161                 return "paused";
00162                 break;
00163             case StateMachineStatus::active:
00164                 return "active";
00165                 break;
00166             case StateMachineStatus::activating:
00167                 return "activating";
00168                 break;
00169             case StateMachineStatus::deactivating:
00170                 return "deactivating";
00171                 break;
00172             case StateMachineStatus::resetting:
00173                 return "resetting";
00174                 break;
00175             case StateMachineStatus::error:
00176                 return "error";
00177                 break;
00178             case StateMachineStatus::unloaded:
00179                 return "unloaded";
00180                 break;
00181             }
00182         return "na";
00183      }
00184 
00185     bool ScriptingService::loadStateMachine( StateMachinePtr sc )
00186     {
00187         // test if parent ...
00188         if ( sc->getParent() ) {
00189             string error(
00190                 "Could not register StateMachine \"" + sc->getName() +
00191                 "\" in the ScriptingService. It is not a root StateMachine." );
00192             ORO_THROW_OR_RETURN( program_load_exception( error ) , false);
00193         }
00194 
00195         if (this->recursiveCheckLoadStateMachine( sc ) == false)
00196             return false; // throws load_exception
00197 
00198         if ( getOwner()->getPeriod() == 0 && ZeroPeriodWarning) {
00199             log(Warning) << "Loading StateMachine "<< sc->getName()
00200             << " in a TaskContext with getPeriod() == 0."
00201             << " Use setPeriod(period) in order to setup execution of scripts."
00202             << " If you know what you are doing, you may disable this warning using scripting.ZeroPeriodWarning=false"
00203             <<endlog();
00204         }
00205 
00206         this->recursiveLoadStateMachine( sc );
00207         return true;
00208     }
00209 
00210     bool ScriptingService::recursiveCheckLoadStateMachine( StateMachinePtr sc )
00211     {
00212         // test if already present..., this cannot detect corrupt
00213         // trees with double names...
00214         if ( states.find(sc->getName()) != states.end() ) {
00215             string error(
00216                 "Could not register StateMachine \"" + sc->getName() +
00217                 "\" in the ScriptingService. A StateMachine with that name is already present." );
00218             ORO_THROW_OR_RETURN( program_load_exception( error ), false );
00219 
00220             vector<StateMachinePtr>::const_iterator it2;
00221             for (it2 = sc->getChildren().begin(); it2 != sc->getChildren().end(); ++it2)
00222                 {
00223                     if ( this->recursiveCheckLoadStateMachine( *it2 ) == false)
00224                         return false;
00225                 }
00226         }
00227         return true;
00228     }
00229 
00230     void ScriptingService::recursiveLoadStateMachine( StateMachinePtr sc )
00231     {
00232         vector<StateMachinePtr>::const_iterator it;
00233 
00234         // first load parent.
00235         states[sc->getName()] = sc;
00236         mowner->engine()->runFunction( sc.get() );
00237 
00238         // then load children.
00239         for (it = sc->getChildren().begin(); it != sc->getChildren().end(); ++it)
00240             {
00241                 this->recursiveLoadStateMachine( *it );
00242             }
00243 
00244     }
00245 
00246     bool ScriptingService::unloadStateMachine( const string& name )
00247     {
00248         StateMapIt it = states.find(name);
00249 
00250         if ( it != states.end() ) {
00251             // test if parent ...
00252             if ( it->second->getParent() ) {
00253                 string error(
00254                                   "Could not unload StateMachine \"" + it->first +
00255                                   "\" in the ScriptingService. It is not a root StateMachine." );
00256                 ORO_THROW_OR_RETURN( program_unload_exception( error ), false);
00257             }
00258             if (recursiveCheckUnloadStateMachine( it->second ) == false)
00259                 return false;
00260             recursiveUnloadStateMachine( it->second );
00261             return true;
00262         }
00263         return false;
00264     }
00265 
00266     bool ScriptingService::recursiveCheckUnloadStateMachine(StateMachinePtr si)
00267     {
00268         // check children
00269         vector<StateMachinePtr>::const_iterator it2;
00270         for (it2 = si->getChildren().begin();
00271              it2 != si->getChildren().end();
00272              ++it2)
00273         {
00274             StateMapIt it = states.find( (*it2)->getName() );
00275             if ( it == states.end() ) {
00276                 string error(
00277                                   "Could not unload StateMachine \"" + si->getName() +
00278                                   "\" in the ScriptingService. It contains not loaded child "+ (*it2)->getName() );
00279                 ORO_THROW_OR_RETURN( program_unload_exception( error ), false);
00280             }
00281             // all is ok, check child :
00282             if ( this->recursiveCheckUnloadStateMachine( it->second ) == false)
00283                 return false;
00284         }
00285         return true;
00286     }
00287 
00288     void ScriptingService::recursiveUnloadStateMachine(StateMachinePtr sc) {
00289         // first erase children
00290         for (vector<StateMachinePtr>::const_iterator it = sc->getChildren().begin();
00291              it != sc->getChildren().end(); ++it)
00292         {
00293             this->recursiveUnloadStateMachine( *it );
00294         }
00295 
00296         // erase this sc :
00297         StateMap::iterator it = states.find( sc->getName() );
00298 
00299         assert( it != states.end() ); // we checked that this is possible
00300 
00301         // lastly, unload the parent.
00302         states.erase(it);
00303         mowner->engine()->removeFunction( sc.get() );
00304     }
00305 
00306     bool ScriptingService::deleteStateMachine(const string& name)
00307     {
00308         return this->unloadStateMachine(name);
00309     }
00310 
00311     const StateMachinePtr ScriptingService::getStateMachine(const string& name) const
00312     {
00313         StateMapIt it = states.find(name);
00314         return it == states.end() ? StateMachinePtr() : it->second;
00315     }
00316 
00317     StateMachinePtr ScriptingService::getStateMachine(const string& name)
00318     {
00319         StateMapIt it = states.find(name);
00320         return it == states.end() ? StateMachinePtr() : it->second;
00321     }
00322 
00323     vector<string> ScriptingService::getStateMachineList() const
00324     {
00325         return keys(states);
00326     }
00327 
00328     ProgramInterface::Status::ProgramStatus ScriptingService::getProgramStatus(const string& name) const
00329     {
00330         ProgMapIt it = programs.find(name);
00331 
00332         if ( it != programs.end() )
00333             return it->second->getStatus();
00334         return ProgramStatus::unknown;
00335     }
00336 
00337     string ScriptingService::getProgramStatusStr(const string& name) const
00338     {
00339        switch ( getProgramStatus( name ))
00340            {
00341            case ProgramStatus::unknown:
00342                return "unknown";
00343                break;
00344            case ProgramStatus::stopped:
00345                return "stopped";
00346                break;
00347            case ProgramStatus::running:
00348                return "running";
00349                break;
00350            case ProgramStatus::paused:
00351                return "paused";
00352                break;
00353            case ProgramStatus::error:
00354                return "error";
00355                break;
00356            }
00357        return "na";
00358     }
00359 
00360    bool ScriptingService::loadProgram(ProgramInterfacePtr pi)
00361    {
00362        if ( programs.find(pi->getName()) != programs.end() ) {
00363            log(Error) << "Could not load Program "<< pi->getName() << " in ScriptingService: name already in use."<<endlog();
00364            return false;
00365        }
00366        if ( getOwner()->getPeriod() == 0 && ZeroPeriodWarning ) {
00367            log(Warning) << "Loading program " << pi->getName()
00368                            << " in a TaskContext with getPeriod() == 0."
00369                            << " Use setPeriod(period) in order to setup execution of scripts."
00370                            << " If you know what you are doing, you may disable this warning using scripting.ZeroPeriodWarning=false"
00371                            << endlog();
00372        }
00373        programs[pi->getName()] = pi;
00374        pi->reset();
00375        if ( mowner->engine()->runFunction( pi.get() ) == false) {
00376            programs.erase(pi->getName());
00377            log(Error) << "Could not load Program "<< pi->getName() << " in ExecutionEngine."<<endlog();
00378            return false;
00379        }
00380        return true;
00381    }
00382 
00383    bool ScriptingService::unloadProgram(const string& name)
00384    {
00385        ProgMap::iterator it = programs.find(name);
00386 
00387        if ( it != programs.end() )
00388            {
00389                mowner->engine()->removeFunction( it->second.get() );
00390                programs.erase( it );
00391                return true;
00392            }
00393        string error("Could not unload Program \"" + name +
00394                          "\" in the ScriptingService. It does not exist." );
00395        ORO_THROW_OR_RETURN( program_unload_exception( error ), false);
00396    }
00397 
00398    vector<string> ScriptingService::getProgramList() const
00399    {
00400        return keys(programs);
00401    }
00402 
00403    const ProgramInterfacePtr ScriptingService::getProgram(const string& name) const
00404    {
00405        ProgMapIt it = programs.find(name);
00406        return it == programs.end() ? ProgramInterfacePtr() : it->second;
00407    }
00408 
00409    ProgramInterfacePtr ScriptingService::getProgram(const string& name)
00410    {
00411        ProgMapIt it = programs.find(name);
00412        return it == programs.end() ? ProgramInterfacePtr() : it->second;
00413    }
00414 
00415 
00416     bool ScriptingService::doExecute(const string& code)
00417     {
00418         return this->execute(code) >= 0;
00419     }
00420 
00421     bool ScriptingService::doLoadPrograms( const string& filename )
00422     {
00423         return this->loadPrograms(filename, false);
00424     }
00425 
00426     bool ScriptingService::doLoadProgramText( const string& code )
00427     {
00428         return this->loadPrograms(code, "string", false);
00429     }
00430     bool ScriptingService::doUnloadProgram( const string& name )
00431     {
00432         return this->unloadProgram(name, false);
00433     }
00434 
00435     bool ScriptingService::doLoadStateMachines( const string& filename )
00436     {
00437         return this->loadStateMachines(filename, false);
00438     }
00439     bool ScriptingService::doLoadStateMachineText( const string& code )
00440     {
00441         return this->loadStateMachines(code, "string", false);
00442     }
00443     bool ScriptingService::doUnloadStateMachine( const string& name )
00444     {
00445         return this->unloadStateMachine(name, false);
00446     }
00447 
00448     void ScriptingService::createInterface()
00449     {
00450         // OperationCallers for loading and executing scripts
00451         addOperation("eval", &ScriptingService::eval, this).doc("Evaluate then script in the argument").arg("Code", "Statements, functions, program definitions etc.");
00452         addOperation("runScript", &ScriptingService::runScript, this).doc("Run a script from a given file.").arg("Filename", "The filename of the script.");
00453 
00454         addOperation("execute", &ScriptingService::execute, this).doc("Execute a line of code (DEPRECATED).").arg("Code", "A single statement.");
00455         // OperationCallers for loading programs
00456         addOperation("loadPrograms", &ScriptingService::doLoadPrograms, this).doc("Load a program from a given file (DEPRECATED).").arg("Filename", "The filename of the script.");
00457         addOperation("loadProgramText", &ScriptingService::doLoadProgramText, this).doc("Load a program from a string (DEPRECATED).").arg("Code", "A string containing one or more program scripts.");
00458         addOperation("unloadProgram", &ScriptingService::doUnloadProgram, this).doc("Remove a loaded program.").arg("Name", "The name of the loaded Program");
00459 
00460         // Query OperationCallers for programs
00461         addOperation("getProgramList", &ScriptingService::getProgramList, this).doc("Get a list of all loaded program scripts.");
00462         addOperation("getProgramStatus", &ScriptingService::getProgramStatus, this).doc("Get the status of a program?").arg("Name", "The Name of the loaded Program");
00463         addOperation("getProgramStatusStr", &ScriptingService::getProgramStatusStr, this).doc("Get the status of a program as a human readable string.").arg("Name", "The Name of the loaded Program");
00464         addOperation("getProgramLine", &ScriptingService::getProgramLine, this).doc("Get the current line of execution of a program?").arg("Name", "The Name of the loaded Program");
00465         addOperation("getProgramText", &ScriptingService::getProgramText, this).doc("Get the script of a program.").arg("Name", "The Name of the loaded Program");
00466 
00467         // OperationCallers for loading state machines
00468         addOperation("loadStateMachines", &ScriptingService::doLoadStateMachines, this).doc("Load a state machine from a given file (DEPRECATED).").arg("Filename", "The filename of the script.");
00469         addOperation("loadStateMachineText", &ScriptingService::doLoadStateMachineText, this).doc("Load a state machine from a string (DEPRECATED).").arg("Code", "A string containing one or more state machine scripts.");
00470         addOperation("unloadStateMachine", &ScriptingService::doUnloadStateMachine, this).doc("Remove a loaded state machine.").arg("Name", "The name of the loaded State Machine");
00471 
00472         // Query OperationCallers for state machines
00473         addOperation("getStateMachineList", &ScriptingService::getStateMachineList, this).doc("Get a list of all loaded state machines");
00474         addOperation("getStateMachineStatus", &ScriptingService::getStateMachineStatus, this).doc("Get the status of a state machine?").arg("Name", "The Name of the loaded State Machine");
00475         addOperation("getStateMachineStatusStr", &ScriptingService::getStateMachineStatusStr, this).doc("Get the status of a state machine as a human readable string.");
00476         addOperation("getStateMachineLine", &ScriptingService::getStateMachineLine, this).doc("Get the current line of execution of a state machine?").arg("Name", "The Name of the loaded State Machine");
00477         addOperation("getStateMachineText", &ScriptingService::getStateMachineText, this).doc("Get the script of a StateMachine.").arg("Name", "The Name of the loaded StateMachine");
00478 
00479         // Query OperationCallers for programs
00480         addOperation("hasProgram", &ScriptingService::hasProgram, this).doc("Is a program loaded?").arg("Name", "The Name of the loaded Program");
00481         addOperation("isProgramRunning", &ScriptingService::isProgramRunning, this).doc("Is a program running ?").arg("Name", "The Name of the Loaded Program");
00482         addOperation("isProgramPaused", &ScriptingService::isProgramPaused, this).doc("Is a program paused ?").arg("Name", "The Name of the Loaded Program");
00483         addOperation("inProgramError", &ScriptingService::inProgramError, this).doc("Is a program in error ?").arg("Name", "The Name of the Loaded Program");
00484 
00485         // Query OperationCallers for state machines
00486         addOperation("hasStateMachine", &ScriptingService::hasStateMachine, this).doc("Is a state machine loaded?").arg("Name", "The Name of the loaded State Machine");
00487         addOperation("isStateMachineActive", &ScriptingService::isStateMachineActive, this).doc("Is a state machine active ?").arg("Name", "The Name of the Loaded StateMachine");
00488         addOperation("isStateMachineRunning", &ScriptingService::isStateMachineRunning, this).doc("Is a state machine running ?").arg("Name", "The Name of the Loaded StateMachine");
00489         addOperation("isStateMachinePaused", &ScriptingService::isStateMachinePaused, this).doc("Is a state machine paused ?").arg("Name", "The Name of the Loaded StateMachine");
00490         addOperation("inStateMachineError", &ScriptingService::inStateMachineError, this).doc("Is a state machine in error ?").arg("Name", "The Name of the Loaded StateMachine");
00491         addOperation("inStateMachineState", &ScriptingService::inStateMachineState, this).doc("Is a state machine in a given state ?").arg("Name", "The Name of the Loaded StateMachine").arg("State", "The name of the state in which it could be.");
00492         addOperation("getStateMachineState", &ScriptingService::getStateMachineState, this).doc("Get the current state name of a state machine.").arg("Name", "The Name of the Loaded StateMachine");
00493 
00494         // OperationCallers for programs
00495         addOperation("startProgram", &ScriptingService::startProgram, this).doc("Start a program").arg("Name", "The Name of the Loaded Program");
00496         addOperation("stopProgram", &ScriptingService::stopProgram , this).doc("Stop a program").arg("Name", "The Name of the Started Program");
00497 
00498         addOperation("stepProgram", &ScriptingService::stepProgram , this).doc("Step a single program instruction").arg("Name", "The Name of the Paused Program");
00499         addOperation("pauseProgram", &ScriptingService::pauseProgram , this).doc("Pause a program").arg("Name", "The Name of the Started Program");
00500 
00501         // OperationCallers for state machines
00502         // Activate/deactivate:
00503         addOperation("activateStateMachine", &ScriptingService::activateStateMachine , this).doc("Activate a StateMachine").arg("Name", "The Name of the Loaded StateMachine");
00504         addOperation("deactivateStateMachine", &ScriptingService::deactivateStateMachine , this).doc("Deactivate a StateMachine").arg("Name", "The Name of the Stopped StateMachine");
00505 
00506         // start/stop/pause:
00507         addOperation("startStateMachine", &ScriptingService::startStateMachine , this).doc("Start a StateMachine").arg("Name", "The Name of the Activated/Paused StateMachine");
00508         addOperation("pauseStateMachine", &ScriptingService::pauseStateMachine , this).doc("Pause a StateMachine").arg("Name", "The Name of a Started StateMachine");
00509         addOperation("stopStateMachine", &ScriptingService::stopStateMachine , this).doc("Stop a StateMachine").arg("Name", "The Name of the Started/Paused StateMachine");
00510         addOperation("resetStateMachine", &ScriptingService::resetStateMachine , this).doc("Reset a StateMachine").arg("Name", "The Name of the Stopped StateMachine");
00511 
00512         // request states
00513         addOperation("requestStateMachineState", &ScriptingService::requestStateMachineState , this).doc("Request a State change").arg("Name", "The Name of the StateMachine").arg("StateName", "The Name of the State to change to");
00514     }
00515 
00516     int ScriptingService::execute(const string& code ){
00517         if (sproc == 0)
00518             sproc = new StatementProcessor(mowner);
00519         return sproc->execute( code );
00520     }
00521 
00522     ScriptingService::Functions  ScriptingService::loadFunctions( const string& file, bool do_throw/* = false*/ )
00523     {
00524       ifstream inputfile(file.c_str());
00525       if ( !inputfile ) {
00526           Logger::In in("ScriptingService::loadFunctions");
00527           Logger::log() << Logger::Error << "Script "+file+" does not exist." << Logger::endl;
00528           return Functions();
00529       }
00530       string text;
00531       inputfile.unsetf( ios_base::skipws );
00532       istream_iterator<char> streambegin( inputfile );
00533       istream_iterator<char> streamend;
00534       std::copy( streambegin, streamend, back_inserter( text ) );
00535       return this->loadFunctions( text, file, do_throw );
00536     }
00537 
00538     ScriptingService::Functions  ScriptingService::loadFunctions( const string& code, const string& filename, bool mrethrow )
00539     {
00540 
00541       Logger::In in("ScriptingService::loadFunctions");
00542       Parser p(mowner->engine());
00543       Functions exec;
00544       Functions ret;
00545       try {
00546           Logger::log() << Logger::Info << "Parsing file "<<filename << Logger::endl;
00547           ret = p.parseFunction(code, mowner, filename);
00548       }
00549       catch( const file_parse_exception& exc )
00550           {
00551 #ifndef ORO_EMBEDDED
00552               Logger::log() << Logger::Error << filename<<" :"<< exc.what() << Logger::endl;
00553               if ( mrethrow )
00554                   throw;
00555 #endif
00556               return Functions();
00557           }
00558       if ( ret.empty() )
00559           {
00560               Logger::log() << Logger::Debug << "No Functions executed from "<< filename << Logger::endl;
00561               Logger::log() << Logger::Info << filename <<" : Successfully parsed." << Logger::endl;
00562               return Functions();
00563           } else {
00564               // Load all listed functions in the TaskContext's Processor:
00565               for( Parser::ParsedFunctions::iterator it = ret.begin(); it != ret.end(); ++it) {
00566                   Logger::log() << "Queueing Function "<< (*it)->getName() << Logger::endl;
00567                   if ( mowner->engine()->runFunction( it->get() ) == false) {
00568                       Logger::log() << Logger::Error << "Could not run Function '"<< (*it)->getName() <<"' :" << Logger::nl;
00569                       Logger::log() << "Processor not accepting or function queue is full." << Logger::endl;
00570                   } else
00571                       exec.push_back( *it ); // is being executed.
00572               }
00573           }
00574       return exec;
00575 
00576     }
00577 
00578     bool ScriptingService::runScript( const string& file )
00579     {
00580         ifstream inputfile(file.c_str());
00581         if ( !inputfile ) {
00582             Logger::In in("ScriptingService::runScript");
00583             Logger::log() << Logger::Error << "Script "+file+" does not exist." << Logger::endl;
00584             return false;
00585         }
00586         string text;
00587         inputfile.unsetf( ios_base::skipws );
00588         istream_iterator<char> streambegin( inputfile );
00589         istream_iterator<char> streamend;
00590         std::copy( streambegin, streamend, back_inserter( text ) );
00591 
00592         log(Info) << "Running Script "<< file <<" ..." << Logger::endl;
00593         return evalInternal( file, text );
00594     }
00595 
00596     bool ScriptingService::eval(const string& code) {
00597         return evalInternal("eval()", code);
00598     }
00599 
00600     bool ScriptingService::evalInternal(const string& filename, const string& code )
00601     {
00602         Logger::In in("ScriptingService");
00603         Parser parser( GlobalEngine::Instance() );
00604         try {
00605             parser.runScript(code, mowner, this, filename );
00606         }
00607         catch( const file_parse_exception& exc )
00608         {
00609             log(Error) <<filename<<" :"<< exc.what() << endlog();
00610             return false;
00611         }
00612         return true;
00613     }
00614 
00615     bool ScriptingService::loadPrograms( const string& file, bool do_throw /*= false*/ )
00616     {
00617         ifstream inputfile(file.c_str());
00618         if ( !inputfile ) {
00619             Logger::In in("ScriptingService::loadProgram");
00620             Logger::log() << Logger::Error << "Script "+file+" does not exist." << Logger::endl;
00621             return false;
00622         }
00623         string text;
00624         inputfile.unsetf( ios_base::skipws );
00625         istream_iterator<char> streambegin( inputfile );
00626         istream_iterator<char> streamend;
00627         std::copy( streambegin, streamend, back_inserter( text ) );
00628         return this->loadPrograms( text, file, do_throw );
00629     }
00630 
00631     bool ScriptingService::loadPrograms( const string& code, const string& filename, bool mrethrow ){
00632 
00633       Logger::In in("ProgramLoader::loadProgram");
00634       Parser parser(mowner->engine());
00635       Parser::ParsedPrograms pg_list;
00636       try {
00637           Logger::log() << Logger::Info << "Parsing file "<<filename << Logger::endl;
00638           pg_list = parser.parseProgram(code, mowner, filename );
00639       }
00640       catch( const file_parse_exception& exc )
00641           {
00642 #ifndef ORO_EMBEDDED
00643               Logger::log() << Logger::Error <<filename<<" :"<< exc.what() << Logger::endl;
00644               if ( mrethrow )
00645                   throw;
00646 #endif
00647               return false;
00648           }
00649       if ( pg_list.empty() )
00650           {
00651               Logger::log() << Logger::Info << filename <<" : Successfully parsed." << Logger::endl;
00652               return true;
00653           } else {
00654               // Load all listed programs in the TaskContext's Processor:
00655               bool error = false;
00656               string errors;
00657               for( Parser::ParsedPrograms::iterator it = pg_list.begin(); it != pg_list.end(); ++it) {
00658                   try {
00659                       Logger::log() << Logger::Info << "Loading Program '"<< (*it)->getName() <<"'" <<Logger::endl;
00660                       if (this->loadProgram( *it ) == false)
00661                           error = true;
00662                   } catch (program_load_exception& e ) {
00663                       Logger::log() << Logger::Error << "Could not load Program '"<< (*it)->getName() <<"' :" << Logger::nl;
00664 #ifndef ORO_EMBEDDED
00665                       Logger::log() << e.what() << Logger::endl;
00666                       if ( mrethrow )
00667                           errors += "Could not load Program '"+ (*it)->getName() +"' :\n"+e.what()+'\n';
00668 #endif
00669                       error = true;
00670                   }
00671               }
00672 #ifndef ORO_EMBEDDED
00673               if (error && mrethrow )
00674                   throw program_load_exception( errors );
00675 #endif
00676               return !error;
00677           }
00678       // never reached
00679     }
00680 
00681     bool ScriptingService::unloadProgram( const string& name, bool do_throw ){
00682         Logger::In in("ScriptingService::unloadProgram");
00683         try {
00684             Logger::log() << Logger::Info << "Unloading Program '"<< name <<"'"<< Logger::endl;
00685             if (this->unloadProgram(name) == false)
00686                 return false;
00687         } catch (program_unload_exception& e ) {
00688             Logger::log() << Logger::Error << "Could not unload Program '"<< name <<"' :" << Logger::nl;
00689 #ifndef ORO_EMBEDDED
00690             Logger::log() << e.what() << Logger::endl;
00691             if ( do_throw )
00692                 throw;
00693 #endif
00694             return false;
00695         }
00696         return true;
00697     }
00698 
00699 
00700     bool ScriptingService::loadStateMachines( const string& file, bool do_throw /*= false*/  )
00701     {
00702         ifstream inputfile(file.c_str());
00703         if ( !inputfile ) {
00704             Logger::In in("ScriptingService::loadStateMachine");
00705           Logger::log() << Logger::Error << "Script "+file+" does not exist." << Logger::endl;
00706           return false;
00707         }
00708         string text;
00709         inputfile.unsetf( ios_base::skipws );
00710         istream_iterator<char> streambegin( inputfile );
00711         istream_iterator<char> streamend;
00712         std::copy( streambegin, streamend, back_inserter( text ) );
00713       return this->loadStateMachines( text, file, do_throw );
00714     }
00715 
00716     bool ScriptingService::loadStateMachines( const string& code, const string& filename, bool mrethrow )
00717     {
00718         Logger::In in("ScriptingService::loadStateMachine");
00719         Parser parser(mowner->engine());
00720         Parser::ParsedStateMachines pg_list;
00721         try {
00722             Logger::log() << Logger::Info << "Parsing file "<<filename << Logger::endl;
00723             pg_list = parser.parseStateMachine( code, mowner, filename );
00724         }
00725         catch( const file_parse_exception& exc )
00726             {
00727 #ifndef ORO_EMBEDDED
00728                 Logger::log() << Logger::Error <<filename<<" :"<< exc.what() << Logger::endl;
00729                 if ( mrethrow )
00730                     throw;
00731 #endif
00732                 return false;
00733             }
00734         if ( pg_list.empty() )
00735             {
00736                 Logger::log() << Logger::Error << "No StateMachines instantiated in "<< filename << Logger::endl;
00737                 return false;
00738             } else {
00739                 bool error = false;
00740                 string errors;
00741                 // Load all listed stateMachines in the TaskContext's Processor:
00742                 for( Parser::ParsedStateMachines::iterator it = pg_list.begin(); it != pg_list.end(); ++it) {
00743                     try {
00744                         Logger::log() << Logger::Info << "Loading StateMachine '"<< (*it)->getName()<<"'" << Logger::endl;
00745                         if (this->loadStateMachine( *it ) == false)
00746                             return false;
00747                     } catch (program_load_exception& e ) {
00748                         Logger::log() << Logger::Error << "Could not load StateMachine '"<< (*it)->getName()<<"' :" << Logger::nl;
00749 #ifndef ORO_EMBEDDED
00750                         Logger::log() << e.what() << Logger::endl;
00751                         if ( mrethrow )
00752                             errors += "Could not load Program '"+ (*it)->getName() +"' :\n"+e.what()+'\n';
00753 #endif
00754                         error = true;
00755                     }
00756                 }
00757 #ifndef ORO_EMBEDDED
00758                 if ( error && mrethrow )
00759                     throw program_load_exception( errors );
00760 #endif
00761                 return !error;
00762             }
00763         // never reached
00764         return false;
00765     }
00766 
00767     bool ScriptingService::unloadStateMachine( const string& name, bool do_throw ) {
00768         Logger::In in("ScriptingService::unloadStateMachine");
00769         try {
00770             Logger::log() << Logger::Info << "Unloading StateMachine '"<< name <<"'"<< Logger::endl;
00771             if (this->unloadStateMachine(name) == false)
00772                 return false;
00773         } catch (program_unload_exception& e ) {
00774             Logger::log() << Logger::Error << "Could not unload StateMachine '"<< name <<"' :" << Logger::nl;
00775 #ifndef ORO_EMBEDDED
00776             Logger::log() << e.what() << Logger::endl;
00777             if ( do_throw )
00778                 throw;
00779 #endif
00780             return false;
00781         }
00782         return true;
00783     }
00784 
00785     bool ScriptingService::hasProgram(const string& name) const {
00786         return programs.find(name) != programs.end();
00787     }
00788 
00789     int ScriptingService::getProgramLine(const string& name) const {
00790         const ProgramInterfacePtr pi = getProgram(name);
00791         return pi ? pi->getLineNumber() : -1;
00792     }
00793 
00794     string ScriptingService::getProgramText(const string& name ) const {
00795         const ProgramInterfacePtr pi = getProgram(name);
00796         return pi ? pi->getText() : "";
00797     }
00798 
00799     bool ScriptingService::hasStateMachine(const string& name) const {
00800         return states.find(name) != states.end();
00801     }
00802 
00803     string ScriptingService::getStateMachineText(const string& name ) const {
00804         const StateMachinePtr sm = getStateMachine(name);
00805         return sm ? sm->getText() : "";
00806     }
00807 
00808     int ScriptingService::getStateMachineLine(const string& name ) const {
00809         const StateMachinePtr sm = getStateMachine(name);
00810         return sm ? sm->getLineNumber() : -1;
00811     }
00812 
00813     bool ScriptingService::startProgram(const string& name)
00814     {
00815         ProgramInterfacePtr pi = getProgram(name);
00816         if (pi)
00817             return pi->start();
00818         return false;
00819     }
00820 
00821     bool ScriptingService::isProgramRunning(const string& name) const
00822     {
00823         ProgramInterfacePtr pi = getProgram(name);
00824         if (pi)
00825             return pi->isRunning();
00826         return false;
00827     }
00828 
00829     bool ScriptingService::isProgramPaused(const string& name) const
00830     {
00831         ProgramInterfacePtr pi = getProgram(name);
00832         if (pi)
00833             return pi->isPaused();
00834         return false;
00835     }
00836 
00837     bool ScriptingService::inProgramError(const string& name) const
00838     {
00839         ProgramInterfacePtr pi = getProgram(name);
00840         if (pi)
00841             return pi->inError();
00842         return false;
00843     }
00844 
00845     bool ScriptingService::stopProgram(const string& name)
00846     {
00847         ProgramInterfacePtr pi = getProgram(name);
00848         if (pi)
00849             return pi->stop();
00850         return false;
00851     }
00852 
00853     bool ScriptingService::pauseProgram(const string& name)
00854     {
00855         ProgramInterfacePtr pi = getProgram(name);
00856         if (pi)
00857             return pi->pause();
00858         return false;
00859     }
00860 
00861     bool ScriptingService::stepProgram(const string& name)
00862     {
00863         ProgramInterfacePtr pi = getProgram(name);
00864         if (pi)
00865             return pi->step();
00866         return false;
00867     }
00868 
00869     bool ScriptingService::activateStateMachine(const string& name)
00870     {
00871         StateMachinePtr sm = getStateMachine(name);
00872         if (sm)
00873             return sm->activate();
00874         return false;
00875     }
00876 
00877     bool ScriptingService::deactivateStateMachine(const string& name)
00878     {
00879         StateMachinePtr sm = getStateMachine(name);
00880         if (sm)
00881             return sm->deactivate();
00882         return false;
00883     }
00884 
00885     bool ScriptingService::startStateMachine(const string& name)
00886     {
00887         StateMachinePtr sm = getStateMachine(name);
00888         if (sm)
00889             return sm->start();
00890         return false;
00891     }
00892 
00893     bool ScriptingService::pauseStateMachine(const string& name)
00894     {
00895         StateMachinePtr sm = getStateMachine(name);
00896         if (sm)
00897             return sm->pause();
00898         return false;
00899     }
00900 
00901     bool ScriptingService::stopStateMachine(const string& name)
00902     {
00903         StateMachinePtr sm = getStateMachine(name);
00904         if (sm)
00905             return sm->stop();
00906         return false;
00907     }
00908 
00909     bool ScriptingService::isStateMachinePaused(const string& name) const
00910     {
00911         StateMachinePtr sm = getStateMachine(name);
00912         if (sm)
00913             return sm->isPaused();
00914         return false;
00915     }
00916 
00917     bool ScriptingService::isStateMachineActive(const string& name) const
00918     {
00919         StateMachinePtr sm = getStateMachine(name);
00920         if (sm)
00921             return sm->isActive();
00922         return false;
00923     }
00924 
00925     bool ScriptingService::isStateMachineRunning(const string& name) const
00926     {
00927         StateMachinePtr sm = getStateMachine(name);
00928         if (sm)
00929             return sm->isAutomatic();
00930         return false;
00931     }
00932 
00933     bool ScriptingService::inStateMachineError(const string& name) const
00934     {
00935         StateMachinePtr sm = getStateMachine(name);
00936         if (sm)
00937             return sm->inError();
00938         return false;
00939     }
00940 
00941     string ScriptingService::getStateMachineState(const string& name) const
00942     {
00943         StateMachinePtr sm = getStateMachine(name);
00944         if (sm)
00945             return sm->getCurrentStateName();
00946         return "";
00947     }
00948 
00949     bool ScriptingService::requestStateMachineState(const string& name, const string& state)
00950     {
00951         StateMachinePtr sm = getStateMachine(name);
00952         if (sm)
00953             return sm->requestState(state);
00954         return false;
00955     }
00956 
00957     bool ScriptingService::inStateMachineState(const string& name, const string& state) const
00958     {
00959         StateMachinePtr sm = getStateMachine(name);
00960         if (sm)
00961             return sm->inState(state);
00962         return false;
00963     }
00964 
00965     bool ScriptingService::resetStateMachine(const string& name)
00966     {
00967         StateMachinePtr sm = getStateMachine(name);
00968         if (sm)
00969             return sm->reset();
00970         return false;
00971     }
00972 
00973 }


rtt
Author(s): RTT Developers
autogenerated on Sat Jun 8 2019 18:46:18