libFAUDES

Sections

Index

simfaudes.cpp

Go to the documentation of this file.
00001 /** @file simfaudes.cpp  Simple simulator application for faudes generators  
00002 
00003 This tutorial demonstrates how to build a simulator application from
00004 the class faudes::ProposingExecutor. When compiled with the 
00005 IO device plugin, the faudes::DeviceExecutor is used to run a 
00006 hardware-in-the-loop simulation.
00007 
00008 @code
00009 ~/libfaudes/plugins/simulator/tutorial> ./simfaudes -?
00010 
00011 simfaudes: usage: 
00012 
00013   simfaudes [-q][-v][-i][-bc] [-bt <nnn>][-bs <nnn>] [-l <logfile>] [-ls] [-le] [-lt] <simfile> 
00014 
00015 where 
00016   <simfile>: simulation configuration file or generator file
00017 
00018   -q:  less console output 
00019   -qq: absolutely no console output 
00020   -v:  more console output
00021   -vv: even more console output
00022   -i: interactive mode 
00023 
00024   -bc: break on condition
00025   -bt <nnn>: break on time <nnn> 
00026   -bs <nnn>: break on step <nnn> 
00027 
00028   -l <logfile>: log to <logfile> 
00029   -ls: log states
00030   -le: log events
00031   -lt: log time
00032   -la: log all
00033   -t <nnn>: fifo trace buffer length <nnn> 
00034 
00035   -d <devfile>: use io device configured from file
00036   -dt <nnn>: tolerance in time synchronisation
00037   -dr: executer reset on device request
00038 @endcode
00039 
00040 
00041 You may test the simulator with the examples provided in the data
00042 directory:
00043 
00044 @code
00045 
00046 ~/libfaudes/plugins/simulator/tutorial>./simfaudes -bs 5 data/gausstest.sim 
00047 % simfaudes: ========================================= current state:
00048 <DiscreteState> "idle"         </DiscreteState>
00049 % simfaudes: ========================================= current time:
00050 <Time> 0 </Time>
00051 % simfaudes: ========================================= proposed action:
00052 <ProposedTime> 205 </ProposedTime>
00053 <ProposedEvent> "alpha" </ProposedEvent>
00054 % simfaudes: ========================================= execute event:
00055 <ExecutedEvent> "alpha" </ExecutedEvent>
00056 % simfaudes: ========================================= current state:
00057 <DiscreteState> "busy"         </DiscreteState>
00058 % simfaudes: ========================================= current time:
00059 <Time> 205 </Time>
00060 % simfaudes: ========================================= found conditions satisfied:
00061 <SatisfiedConditions> "BusyCond"     </SatisfiedConditions>
00062 % simfaudes: ========================================= proposed action:
00063 <ProposedTime> 51 </ProposedTime>
00064 % simfaudes: ========================================= current state:
00065 <DiscreteState> "busy"         </DiscreteState>
00066 % simfaudes: ========================================= current time:
00067 <Time> 256 </Time>
00068 % simfaudes: ========================================= found conditions satisfied:
00069 <SatisfiedConditions> "BusyCond"     </SatisfiedConditions>
00070 % simfaudes: ========================================= proposed action:
00071 <ProposedTime> 39 </ProposedTime>
00072 <ProposedEvent> "beta" </ProposedEvent>
00073 % simfaudes: ========================================= execute event:
00074 <ExecutedEvent> "beta" </ExecutedEvent>
00075 % simfaudes: ========================================= current state:
00076 <DiscreteState> "idle"         </DiscreteState>
00077 % simfaudes: ========================================= current time:
00078 <Time> 295 </Time>
00079 % simfaudes: ========================================= found conditions satisfied:
00080 <SatisfiedConditions> "IdleCond"     </SatisfiedConditions>
00081 % simfaudes: ========================================= proposed action:
00082 <ProposedTime> 191 </ProposedTime>
00083 <ProposedEvent> "alpha" </ProposedEvent>
00084 % simfaudes: ========================================= execute event:
00085 <ExecutedEvent> "alpha" </ExecutedEvent>
00086 % simfaudes: ========================================= current state:
00087 <DiscreteState> "busy"         </DiscreteState>
00088 % simfaudes: ========================================= current time:
00089 <Time> 486 </Time>
00090 % simfaudes: ========================================= found conditions satisfied:
00091 <SatisfiedConditions> "BusyCond"     </SatisfiedConditions>
00092 % simfaudes: ========================================= proposed action:
00093 <ProposedTime> 51 </ProposedTime>
00094 % simfaudes: =========================================  end simulation 
00095 
00096 @endcode
00097 
00098 The code is straight forward: after some command line parsing
00099 for behavioural configuration, it reads a proposing executor from file
00100 and loops to execute the proposed transitions. 
00101 
00102 
00103 @ingroup Tutorials
00104 
00105 @include simfaudes.cpp
00106 
00107 */
00108 
00109 
00110 #include "libfaudes.h"
00111 #include <signal.h>
00112 
00113 using namespace faudes;
00114 
00115 // fix windows/mingw definition                                                          
00116 #ifdef FAUDES_WINEXTRA
00117 #define sleep(sec) Sleep((sec) * 1000)
00118 #define usleep(usec) Sleep((usec) / 1000)
00119 #define SIGQUIT SIGBREAK
00120 #define SIGHUP SIGBREAK
00121 #define strsignal(sig) "unknown"
00122 #endif
00123 
00124 
00125 // global vars used in exit handler          
00126 DeviceExecutor mExecutor;
00127 int mConsoleOut=0;
00128 std::string mMark="% simfaudes: ========================================= ";
00129 
00130 // simulator clean-up on exit
00131 void simfaudes_exit(void);
00132 
00133 // signal handler recursion flag
00134 volatile sig_atomic_t signal_in_progress = 0;
00135 
00136 // signal handler to stop devices
00137 void catch_signal(int sig) {
00138   // detect recursion, pass on
00139   if(signal_in_progress) raise(sig);
00140   signal_in_progress = 1;
00141   // report
00142   std::cerr << "simfaudes: signal " << strsignal(sig) << std::endl;
00143   // call my exit function
00144   simfaudes_exit();
00145   // re-install default handler
00146   signal(sig, SIG_DFL);
00147   // pass on signal
00148   raise(sig);
00149 }
00150 
00151 
00152 // clean-up on exit
00153 void simfaudes_exit(void) {
00154 #ifdef FAUDES_PLUGIN_IODEVICE
00155   // report device performance
00156   if(vDevice* dev=mExecutor.Devicep()) {
00157     dev->WritePerformance();
00158   }
00159   // stop all devices
00160   vDevice::StopAll();
00161 #endif
00162   // report statistics
00163   if(mConsoleOut>=-1) {
00164     std::cout << mMark << " end simulation #" << mExecutor.Size() << std::endl;
00165     for(ProposingExecutor::ConditionIterator cit=mExecutor.ConditionsBegin();  
00166         cit!=mExecutor.ConditionsEnd(); cit++) {
00167       if(!mExecutor.Condition(*cit).Enabled()) continue;
00168       std::cout << mMark << "statistics for simulation condition \"" << 
00169          mExecutor.Conditions().SymbolicName(*cit) << "\"" << std::endl;
00170       mExecutor.Condition(*cit).mSamplesPeriod.Compile();
00171       std::cout << mExecutor.Condition(*cit).mSamplesPeriod.Str();
00172       mExecutor.Condition(*cit).mSamplesDuration.Compile();
00173       std::cout << mExecutor.Condition(*cit).mSamplesDuration.Str() << std::endl;
00174     }
00175   }
00176   // close log file
00177   mExecutor.LogClose();
00178   // reset incl device if such  
00179   mExecutor.Reset();
00180 }
00181 
00182 // print usage info and exit
00183 void usage_exit(const std::string& message="") {
00184   if(message!="") {
00185     std::cout << "simfaudes: " << message << std::endl;
00186     std::cout << "" << std::endl;
00187     exit(-1);
00188   }
00189   std::cout << "simfaudes: version " << FDVersionString() << std::endl;
00190   std::cout << "" << std::endl;
00191   std::cout << "simfaudes: usage: " << std::endl;
00192   std::cout << "  simfaudes [-q][-v][-i][-bc] [-bt <nnn>][-bs <nnn>] [-l <logfile>] [-ls] [-le] [-lt] <simfile> " << std::endl;
00193   std::cout << "where " << std::endl;
00194   std::cout << "  <simfile>: simulation configuration file" << std::endl;
00195   std::cout << "" << std::endl;
00196   std::cout << "  -q:  less console output " << std::endl;
00197   std::cout << "  -qq: absolutely no console output " << std::endl;
00198   std::cout << "  -v:  more console output" << std::endl;
00199   std::cout << "  -vv: even more console output" << std::endl;
00200   std::cout << "  -i: interactive mode " << std::endl;
00201   std::cout << "" << std::endl;
00202   std::cout << "  -bc: break on condition" << std::endl;
00203   std::cout << "  -bt <nnn>: break on time <nnn> " << std::endl;
00204   std::cout << "  -bs <nnn>: break on step <nnn> " << std::endl;
00205   std::cout << "" << std::endl;
00206   std::cout << "  -l <logfile>: log to <logfile> " << std::endl;
00207   std::cout << "  -ls: log states" << std::endl;
00208   std::cout << "  -le: log events" << std::endl;
00209   std::cout << "  -lt: log time" << std::endl;
00210   std::cout << "  -la: log all" << std::endl;
00211   std::cout << "  -t <nnn>: fifo trace buffer length <nnn> " << std::endl;
00212 #ifdef FAUDES_PLUGIN_IODEVICE
00213   std::cout << "" << std::endl;
00214   std::cout << "  -d <devfile>: use io device configured from file" << std::endl;
00215   std::cout << "  -dt <nnn>: tolerance in time synchronisation" << std::endl;
00216   std::cout << "  -dr: executer reset on device request" << std::endl;
00217 #endif
00218   std::cout << "" << std::endl;
00219   std::cout << "" << std::endl;
00220   exit(-1);
00221 }
00222 
00223 // parse commandline, read executor and run executor
00224 int main(int argc, char* argv[])
00225 {
00226 
00227 
00228   // install my signal handler
00229   signal(SIGTERM, catch_signal);
00230   signal(SIGINT, catch_signal);
00231   signal(SIGQUIT, catch_signal);
00232   signal(SIGHUP, catch_signal);
00233   signal(SIGABRT, catch_signal);
00234 
00235   // install my exit fnct
00236   atexit(simfaudes_exit);
00237 
00238   // default behaviour
00239   mConsoleOut=0;
00240   bool mInteractive=false;
00241   std::string mSimFile="";
00242   std::string mDevFile="";
00243   tpTime::Type mTolerance=-1;
00244   bool mBreakCondition=false;
00245   tpTime::Type mBreakTime=tpTime::Max;
00246   int mBreakStep=-1;
00247   std::string mLogFile="";
00248   int mLogMode=0;
00249   int mTraceLength=5;
00250   bool mResetRequest=false;
00251 
00252   // primitive commad line parsing
00253   for(int i=1; i<argc; i++) {
00254     std::string option(argv[i]);
00255     // option: quiet
00256     if((option=="-q") || (option=="--quiet")) {
00257       mConsoleOut=-1;
00258       continue;
00259     }
00260     // option: more quiet
00261     if((option=="-qq") || (option=="--quietquiet")) {
00262       mConsoleOut=-2;
00263       continue;
00264     }
00265     // option: verbose
00266     if((option=="-v") || (option=="--verbose")) {
00267       mConsoleOut=1;
00268       continue;
00269     }
00270     // option: more verbose
00271     if((option=="-vv") || (option=="--verboseverbose")) {
00272       mConsoleOut=2;
00273       continue;
00274     }
00275     // option: interactive
00276     if((option=="-i") || (option=="--interactive")) {
00277       mInteractive=true;
00278       continue;
00279     }
00280     // option: io device
00281     if((option=="-d") || (option=="--device")) {
00282       i++; if(i>=argc) usage_exit();
00283       mDevFile=argv[i];
00284       continue;
00285     }
00286     // option: io device tolerance
00287     if((option=="-dt") || (option=="--tolerance")) {
00288       i++; if(i>=argc) usage_exit();
00289       mTolerance=(tpTime::Type) ToIdx(argv[i]);
00290       continue;
00291     }
00292     // option: io device reset request
00293     if((option=="-dr") || (option=="--resetrequest")) {
00294       mResetRequest=true;
00295       continue;
00296     }
00297     // option: break condition
00298     if((option=="-bc") || (option=="--breakcondition")) {
00299       mBreakCondition=true;
00300       continue;
00301     }
00302     // option: break time
00303     if((option=="-bt") || (option=="--breaktime")) {
00304       i++; if(i>=argc) usage_exit();
00305       mBreakTime=(tpTime::Type) ToIdx(argv[i]);
00306       continue;
00307     }
00308     // option: break step
00309     if((option=="-bs") || (option=="--breakstep")) {
00310       i++; if(i>=argc) usage_exit();
00311       mBreakStep=(int) ToIdx(argv[i]);
00312       continue;
00313     }
00314     // option: log file
00315     if((option=="-l") || (option=="--logfile")) {
00316       i++; if(i>=argc) usage_exit();
00317       mLogFile=argv[i];
00318       continue;
00319     }
00320     // option: log states
00321     if((option=="-ls") || (option=="--logstates")) {
00322       mLogMode |= LoggingExecutor::States;
00323       continue;
00324     }
00325     // option: log events
00326     if((option=="-le") || (option=="--logevents")) {
00327       mLogMode |= LoggingExecutor::Events;
00328       continue;
00329     }
00330     // option: log time
00331     if((option=="-lt") || (option=="--logtime")) {
00332       mLogMode |= LoggingExecutor::Time;
00333       continue;
00334     }
00335     // option: log all
00336     if((option=="-la") || (option=="--logall")) {
00337       mLogMode |= 0xff;
00338       continue;
00339     }
00340     // option: trace
00341     if((option=="-t") || (option=="--trace")) {
00342       i++; if(i>=argc) usage_exit();
00343       mTraceLength=(int) ToIdx(argv[i]);
00344       continue;
00345     }
00346     // option: help
00347     if((option=="-?") || (option=="--help")) {
00348       usage_exit();
00349       continue;
00350     }
00351     // option: unknown
00352     if(option.c_str()[0]=='-') {
00353       usage_exit("unknown option "+ option);
00354       continue;
00355     }
00356     // filename
00357     if(mSimFile!="")
00358       usage_exit("more than one filname specified" );
00359     mSimFile=option;
00360   }
00361 
00362   // insist in filename
00363   if(mSimFile=="")
00364       usage_exit("you must specify a filename" );
00365 
00366   // dont have both, interactive and sync physics
00367   if(mDevFile!="" && mInteractive) 
00368       usage_exit("you must not specify both interactive and synchrone mode");
00369   
00370   // relaxed read configuration: test for generator file  
00371   bool gfile=false;        
00372   TokenReader* tr = new TokenReader(mSimFile);
00373   Token token;
00374   tr->Peek(token);
00375   if(token.Type()==Token::Begin)
00376   if(token.StringValue()=="Generator") 
00377     gfile=true;  
00378 
00379   // read congiguration
00380   if(gfile) {
00381     mExecutor.Insert(mSimFile);
00382     mExecutor.Reset();
00383   } else {        
00384     mExecutor.Read(mSimFile);
00385     mExecutor.Reset();
00386   }
00387 
00388   // report configuration
00389   if(mConsoleOut>=1) {
00390     std::cout << mMark << "dumping configuration"  << std::endl;
00391     // generators
00392     for(Idx i=0; i< mExecutor.Size(); i++) {
00393       std::cout << mMark << "found generator #" << i+1 << 
00394   ": " <<  mExecutor.At(i).Generator().Name() << std::endl;
00395     }
00396     // event attributes
00397     for(EventSet::Iterator eit=mExecutor.Alphabet().Begin();  
00398         eit!=mExecutor.Alphabet().End(); eit++) {
00399       std::cout << mMark << "found event attributes for \"" << 
00400          mExecutor.EventName(*eit) << "\"" << std::endl;
00401       std::cout << mExecutor.Alphabet().Attribute(*eit).ToString() << std::endl;
00402     }
00403     // conditions
00404     for(ProposingExecutor::ConditionIterator cit=mExecutor.ConditionsBegin();  
00405         cit!=mExecutor.ConditionsEnd(); cit++) {
00406       std::cout << mMark << "found simulation condition \"" << 
00407          mExecutor.Conditions().SymbolicName(*cit) << "\"" << std::endl;
00408       std::cout << mExecutor.Condition(*cit).ToString() << std::endl;
00409     }
00410   }
00411 
00412   // report generators
00413   if(mConsoleOut>=2) {
00414     // generators
00415     for(Idx i=0; i< mExecutor.Size(); i++) {
00416       std::cout << mMark << "generator #" << i+1 << std::endl;
00417       mExecutor.At(i).Generator().DWrite();
00418     }
00419   }
00420 
00421   // initialze log file
00422   if(mLogFile!="") {
00423     mExecutor.LogOpen(mLogFile,mLogMode | LoggingExecutor::Statistics);
00424   }
00425   if(mLogFile=="" && mLogMode!=0) {
00426     TokenWriter* ptw= new TokenWriter(TokenWriter::Stdout);
00427     mExecutor.LogOpen(*ptw, mLogMode | LoggingExecutor::Statistics);
00428   }
00429 
00430   // set trace buffer
00431   mExecutor.TraceClear(mTraceLength);
00432 
00433   // ************************************************  synchronous prep
00434   if(mDevFile!="") {
00435 #ifdef FAUDES_PLUGIN_IODEVICE
00436 
00437     // create device from file
00438     vDevice* dev=vDevice::FromFile(mDevFile);
00439 
00440     
00441 #ifdef FAUDES_IODEVICE_SIMPLENET
00442 #ifdef FAUDES_WINEXTRA
00443     // if its a net device on windows, initialise winsocks
00444     if(dynamic_cast<nDevice*>(dev)) {
00445       WSADATA wsaData;
00446       if(WSAStartup(MAKEWORD(2,2), &wsaData)!=0) {
00447         usage_exit("cannot start winsock (network error)");
00448       }
00449     }
00450 #endif
00451 #endif
00452 
00453     // report
00454     if(mConsoleOut>=0) 
00455       std::cout << mMark << "Execute via IO device: \""<< dev->Name() << "\"" << std::endl;
00456 
00457     // set tolerance
00458     if(mTolerance!=-1) mExecutor.ToleranceTime(mTolerance);
00459 
00460     // assign device to executor ad wait for startuo to complete
00461     mExecutor.Devicep(dev);
00462     mExecutor.Reset(); 
00463     if(mBreakTime==tpTime::UnDef)  mBreakTime=tpTime::Max;
00464     mExecutor.DeviceStart();
00465     while(dev->Status()!=vDevice::Up) {
00466       std::cout << mMark << "Starting IO device \""<< dev->Name() << "\" Status: " << dev->StatusString() << std::endl;
00467       sleep(1);
00468     }
00469     dev->CurrentTime(0); // sync time; dont use reset, since we would loose events
00470     std::cout << mMark << "IO device \""<< dev->Name() << "\" is Up" << std::endl;
00471 #else
00472     // cannot run device without plugin
00473     usage_exit("cannot load device \""+mDevFile+"\": device plugin not present");
00474 #endif
00475 
00476   }
00477   
00478 
00479   // ************************************************* interactive loop
00480   bool mRunning=true;
00481   bool mInterTemp=mInteractive;
00482   SimConditionSet mSatisfied;
00483   mSatisfied.Name("SatisfiedConditions");
00484   while(mRunning) {
00485     // report current state
00486     if(mConsoleOut>=2) {
00487       std::cout << mMark << "current state:" << std::endl;
00488       std::cout << mExecutor.CurrentParallelTimedState().ToString("TimedState",&mExecutor) << std::endl;
00489     }  
00490     // report current state
00491     if(mConsoleOut>=0 && mConsoleOut<2) {
00492       std::cout << mMark << "current state:" << std::endl;
00493       std::cout << mExecutor.CurrentParallelTimedState().ToString("DiscreteState",&mExecutor) << std::endl;
00494     }  
00495     // report current time
00496     if(mConsoleOut>=1) {
00497       std::cout << mMark << "current time:" << std::endl;
00498       std::cout << "<Time> " << mExecutor.CurrentTime() << " </Time>" << std::endl;
00499       std::cout << "<Step> " << mExecutor.CurrentStep() << " </Step>" << std::endl;
00500     }  
00501     // report current time
00502     if(mConsoleOut==0) {
00503       std::cout << mMark << "current time:" << std::endl;
00504       std::cout << "<Time> " << mExecutor.CurrentTime() << " </Time>" << std::endl;
00505     }  
00506     // report satisfied conditions
00507     if(mConsoleOut>=0) {
00508       mSatisfied.Clear();
00509       for(ProposingExecutor::ConditionIterator cit=mExecutor.ConditionsBegin();  
00510           cit!=mExecutor.ConditionsEnd(); cit++) {
00511         if(mExecutor.Condition(*cit).Satisfied()) mSatisfied.Insert(*cit);
00512       }
00513       if(mSatisfied.Size()>0) {
00514         std::cout << mMark << "found conditions satisfied:" << std::endl;
00515         std::cout << mSatisfied.ToString() << std::endl;
00516       }
00517     }
00518     // report internal state
00519     if(mConsoleOut>=2) {
00520       std::cout << mMark << "simulation event states:" << std::endl;
00521       std::cout << mExecutor.EventStatesToString() << std::endl;
00522     }
00523     // report enabled transitions
00524     if(mConsoleOut>=1) {
00525       std::cout << mMark << "enabled events:" << std::endl;
00526       std::cout << mExecutor.EnabledEvents().ToString() << std::endl;
00527       std::cout << mMark << "enabled interval:" << std::endl;
00528       std::cout << mExecutor.EnabledInterval().Str() << std::endl;
00529       std::cout << mMark << "enabled time:" << std::endl;
00530       std::cout << mExecutor.EnabledTime().Str() << std::endl;
00531     }  
00532     // test break: time up
00533     if(mExecutor.CurrentTime() >= tpTime::Max) {
00534       if(mConsoleOut>=-1) std::cout << mMark << "time is up" << std::endl;
00535       mInterTemp=false;
00536       mRunning=false;
00537       break;
00538     }
00539     // test break: condition
00540     if(mExecutor.BreakCondition() && (mBreakCondition || mInteractive)) {
00541      if(mConsoleOut>=-1) std::cout << mMark << "break condition triggered" << std::endl;
00542       mInterTemp=mInteractive;
00543       mRunning=mInteractive;
00544     }
00545     // test break: time
00546     if(mBreakTime!=tpTime::UnDef)
00547     if(mExecutor.CurrentTime() >= mBreakTime) {
00548       if(mConsoleOut>=-1) std::cout << mMark << "break time reached" << std::endl;
00549       mInterTemp=mInteractive;
00550       mRunning=mInteractive;
00551     }
00552     // test break: step
00553     if(mBreakStep>=0)
00554     if(mExecutor.CurrentStep() >= mBreakStep) {
00555       if(mConsoleOut>=-1) std::cout << mMark << "break step reached" << std::endl;
00556       mInterTemp=mInteractive;
00557       mRunning=mInteractive;
00558     }
00559     // test break: synchronous device
00560     if(!mExecutor.IsSynchronous()) {
00561       if(mConsoleOut>=-1) std::cout << mMark << "device out of sync" << std::endl;
00562       mInterTemp=false;
00563       mRunning=false;
00564       break;
00565     }
00566     // proposed action
00567     TimedEvent mPropTrans=mExecutor.ProposeNextTransition();
00568     if(mConsoleOut>=0) {
00569       std::cout << mMark << "proposed action:" << std::endl;
00570       if(mPropTrans.Time>0) 
00571         std::cout << "<ProposedTime> " << ToStringInteger(mPropTrans.Time) << " </ProposedTime>" << std::endl;
00572       if(mPropTrans.Event!=0) 
00573         std::cout << "<ProposedEvent> \"" << mExecutor.EventName(mPropTrans.Event)  << "\" </ProposedEvent>" << std::endl;
00574       if((mPropTrans.Time<=0) && (mPropTrans.Event==0) )
00575         std::cout << "+DeadLock+" << std::endl;
00576     }
00577     // record transition
00578     Idx mEvent=0;
00579     // ask choice
00580     while(mInterTemp) {
00581        std::cout << mMark << "enter command:" << std::endl;
00582        std::string line;
00583        std::getline(std::cin,line);
00584        // separate cmd from arg
00585        std::string choice;
00586        std::string param;
00587        std::istringstream sline(line);
00588        sline >> choice;
00589        sline >> param;
00590        // convert to int
00591        int ichoice =-1;
00592        std::istringstream schoice(choice);
00593        schoice >> ichoice;
00594        if(!schoice) ichoice=-1;
00595        int iparam =-1;
00596        std::istringstream sparam(param);
00597        sparam >> iparam;
00598        if(!sparam) iparam=-1;
00599        // convert to symbol
00600        std::string nchoice=choice;
00601        if(choice.length()>2)
00602        if(choice.at(0)=='"' && choice.at(choice.length()-1)== '"')
00603          nchoice=choice.substr(1,choice.length()-2);
00604        // switch cases
00605        bool err=false;
00606        if(choice=="x" || choice == "exit") {
00607          mRunning=false;
00608        } else
00609        if(choice=="p" || choice=="proposal" || choice=="") {
00610          mExecutor.ExecuteTime(mPropTrans.Time);
00611          if(mExecutor.ExecuteEvent(mPropTrans.Event)) 
00612            mEvent=mPropTrans.Event;
00613        } else
00614        if(choice=="r" || choice=="run") {
00615          mInterTemp=false;
00616        } else
00617        if(choice=="v" || choice=="revert") {
00618          int step = mExecutor.CurrentStep()-1;
00619          if(iparam!=-1) step=iparam;
00620          std::cout << mMark << "revert to step " << step << std::endl;
00621          mExecutor.RevertToStep(step);          
00622        } else
00623        if(choice=="t" || choice=="trace") {
00624          std::cout << mMark << "system trace" << std::endl;
00625          mExecutor.TraceWrite();
00626          continue;
00627        } else
00628        if(ichoice>0) {
00629          mExecutor.ExecuteTime(ichoice);
00630        } else
00631        if(mExecutor.Alphabet().Exists(nchoice)) {
00632          if(mExecutor.ExecuteEvent(mExecutor.EventIndex(nchoice)))
00633            mEvent=mExecutor.EventIndex(nchoice);
00634        } else {
00635          std::cout << mMark << "simfaudes interactive mode" << std::endl;
00636          std::cout << "%"  << std::endl;
00637          std::cout << "%  execute time and/or transitions"  << std::endl;
00638          std::cout << "%  * <nn> to pass a specified duration <nn> (excl brackets)" << std::endl;
00639          std::cout << "%  * \"event\" to execute an event (incl quotes)" << std::endl;
00640          std::cout << "%  * [P] or [Ret] to execute the recent proPosal " << std::endl;
00641          std::cout << "%"  << std::endl;
00642          std::cout << "%  show trace and revert"  << std::endl;
00643          std::cout << "%  * [T] to show a Trace of recent events and states" << std::endl;
00644          std::cout << "%  * [V] <nn> to reVert to step <nn> (obmit <nn> for one step backward) "<< std::endl;
00645          std::cout << "%"  << std::endl;
00646          std::cout << "%  other"  << std::endl;
00647          std::cout << "%  * [X] to eXit" << std::endl<< std::endl;
00648          err=true;
00649        }
00650        if(!err) break;
00651     }  
00652     // execute proposal
00653     if(!mInterTemp && mDevFile=="") {
00654        mExecutor.ExecuteTime(mPropTrans.Time);
00655        if(mExecutor.ExecuteEvent(mPropTrans.Event))
00656          mEvent=mPropTrans.Event;
00657     }
00658 #ifdef FAUDES_PLUGIN_IODEVICE
00659     // sync step
00660     if(mDevFile!="") {
00661       // reset request ?
00662       bool rr= mExecutor.DeviceResetRequest();
00663       if(rr && mConsoleOut>=0 && !mResetRequest) {
00664         std::cout << mMark << "ignoring reset request" << std::endl;
00665         rr=false;
00666       }
00667       if(rr && mConsoleOut>=0) 
00668         std::cout << mMark << "reset on request" << std::endl;
00669       if(rr) 
00670         mExecutor.Reset();
00671       // sync proposal
00672       if(!rr) {
00673         if(mConsoleOut>=0 && mPropTrans.Time>0) 
00674            std::cout << mMark << "sync wait" << std::endl;
00675         mEvent=mExecutor.SyncStep();
00676         mExecutor.SyncTime();
00677       }
00678     }
00679 #endif
00680     // report event
00681     if(mConsoleOut>=0 && mEvent!=0) {
00682       std::cout << mMark << "execute event:" << std::endl;
00683       std::cout << "<ExecutedEvent> \"" << mExecutor.EventName(mEvent)  << "\" </ExecutedEvent>"
00684         << std::endl;
00685     }  
00686 
00687   } // loop: while mRunning
00688 
00689   return 0;
00690 }

libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3