simfaudes.cppGo 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 |