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

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen