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