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
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
00087
00088 this->clear();
00089 delete sproc;
00090 }
00091
00092 void ScriptingService::clear() {
00093 while ( !states.empty() ) {
00094
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() );
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() );
00108 }
00109 #endif
00110 }
00111 while ( !programs.empty() ) {
00112
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() );
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() );
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
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;
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
00213
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
00235 states[sc->getName()] = sc;
00236 mowner->engine()->runFunction( sc.get() );
00237
00238
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
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
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
00282 if ( this->recursiveCheckUnloadStateMachine( it->second ) == false)
00283 return false;
00284 }
00285 return true;
00286 }
00287
00288 void ScriptingService::recursiveUnloadStateMachine(StateMachinePtr sc) {
00289
00290 for (vector<StateMachinePtr>::const_iterator it = sc->getChildren().begin();
00291 it != sc->getChildren().end(); ++it)
00292 {
00293 this->recursiveUnloadStateMachine( *it );
00294 }
00295
00296
00297 StateMap::iterator it = states.find( sc->getName() );
00298
00299 assert( it != states.end() );
00300
00301
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
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
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
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
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
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
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
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
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
00502
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
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
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 )
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
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 );
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 )
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
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
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 )
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
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
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 }