sp_lpexecutor.cpp

Go to the documentation of this file.
00001 /** @file sp_lpexecutor.cpp Executor with logging facilities  */
00002 
00003 /* 
00004    FAU Discrete Event Systems Library (libfaudes)
00005 
00006    Copyright (C) 2007, 2008 Thomas Moor
00007    Copyright (C) 2007  Ruediger Berndt
00008    Exclusive copyright is granted to Klaus Schmidt
00009 
00010 */
00011 
00012 
00013 #include "sp_lpexecutor.h"
00014 
00015 namespace faudes {
00016 
00017 
00018 // std faudes type
00019 FAUDES_TYPE_IMPLEMENTATION(LoggingExecutor,LoggingExecutor,ParallelExecutor)
00020 
00021 // LoggingExecutor(void)
00022 LoggingExecutor::LoggingExecutor(void) 
00023   : ParallelExecutor(), pLogTokenWriter(0), mLogFile(""), mLogMode(0) 
00024 {
00025   FD_DX("LoggingExecutor(" << this << ")::LoggingExecutor()");
00026   TraceClear(0);
00027 }
00028 
00029 // LoggingExecutor(void)
00030 LoggingExecutor::LoggingExecutor(const LoggingExecutor& rOther) 
00031   : ParallelExecutor(), pLogTokenWriter(0), mLogFile(""), mLogMode(0) 
00032 {
00033   FD_DX("LoggingExecutor(" << this << ")::LoggingExecutor()");
00034   TraceClear(0);
00035   DoAssign(rOther);
00036 }
00037 
00038 // LoggingExecutor(rFileName)
00039 LoggingExecutor::LoggingExecutor(const std::string& rFileName) 
00040   : ParallelExecutor(), pLogTokenWriter(0), mLogFile(""), mLogMode(0) 
00041 {
00042   FD_DX("LoggingExecutor(" << this << ")::LoggingExecutor(" << rFileName << ")");
00043   TraceClear(0);
00044   Read(rFileName);
00045 }
00046 
00047 // LoggingExecutor
00048 LoggingExecutor::~LoggingExecutor(void) { 
00049   FD_DX("LoggingExecutor(" << this << ")::~LoggingExecutor()");
00050   LogClose();
00051 }
00052 
00053 // DoAssign(other)
00054 void LoggingExecutor::DoAssign(const LoggingExecutor& rOther) {
00055   FD_DX("LoggingExecutor(" << this << ")::DoAssign(other)");
00056   // my members
00057   mConditions.Assign(rOther.mConditions);
00058   // base
00059   ParallelExecutor::DoAssign(rOther);
00060 }
00061 
00062 // Compile()
00063 void LoggingExecutor::Compile(void) {
00064   FD_DX("LoggingExecutor(" << this << ")::Compile(): #" << Size());
00065   // call base
00066   ParallelExecutor::Compile();
00067   // care about my members
00068   CompileConditions();
00069   FD_DX("LoggingExecutor(" << this << ")::Compile(): done");
00070 }
00071 
00072 // Reset()
00073 void LoggingExecutor::Reset(void) {
00074   FD_DX("LoggingExecutor(" << this << ")::Reset()");
00075   // log trace
00076   LogWritePause();
00077   // call base (incl compile)
00078   ParallelExecutor::Reset();
00079   // log trace
00080   LogWriteResume();
00081   // clear and initialise trace (base was called first)
00082   TraceClear();
00083   // figure initial state
00084   ConditionsReset();
00085 }
00086 
00087 
00088 // Clear()
00089 void LoggingExecutor::Clear(void) {
00090   FD_DX("LoggingExecutor(" << this << ")::Clear()");
00091   // clear my members
00092   LogClose();
00093   mConditions.Clear();
00094   mBreakCondition=false;
00095   TraceClear();
00096   // call base
00097   ParallelExecutor::Clear();
00098 }
00099 
00100 //DoWrite(rTr,rLabel)
00101 void LoggingExecutor::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00102   (void) pContext;
00103   std::string label=rLabel;
00104   if(label=="") label = "Executor";
00105   rTw.WriteBegin(label);
00106   ParallelExecutor::DoWrite(rTw,"Generators");
00107   mConditions.Write(rTw,"Conditions",this);
00108   rTw.WriteEnd(label);
00109 }
00110 
00111 //DoRead(rTr,rLabel)
00112 void LoggingExecutor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00113   (void) pContext;
00114   FD_DC("LoggingExecutor::DoRead(rTr, " << rLabel<<")");
00115   std::string label=rLabel;
00116   if(label=="") label = "Executor";
00117   rTr.ReadBegin(label);
00118   while(!rTr.Eos(label)) {
00119     // peek token
00120     Token token;
00121     rTr.Peek(token);
00122     // case 1: generators
00123     if(token.Type()==Token::Begin)
00124     if(token.StringValue()=="Generators") {
00125       ParallelExecutor::DoReadGenerators(rTr);
00126       continue;
00127     }
00128     // case 2: conditions
00129     if(token.Type()==Token::Begin)
00130     if(token.StringValue()=="Conditions") {
00131       mConditions.Read(rTr,"Conditions",this);
00132       continue;
00133     }
00134     // else report error
00135     std::stringstream errstr;
00136     errstr << "Invalid token, generators or conditions section expected, " << rTr.FileLine();
00137     throw Exception("LoggingExecutor::DoRead", errstr.str(), 502);
00138   }
00139   rTr.ReadEnd(label);
00140   Reset();
00141 }
00142 
00143 
00144 
00145 // ExecuteTime(time) 
00146 bool LoggingExecutor::ExecuteTime(tpTime::Type time) {
00147   // call base
00148   bool res=ParallelExecutor::ExecuteTime(time);
00149   // bail out 
00150   if(!res) return false;
00151   // update trace (after base)
00152   TraceUpdateTime();
00153   // done
00154   return res;
00155 }
00156 
00157 // ExecuteEvent(event) 
00158 bool LoggingExecutor::ExecuteEvent(Idx event) {
00159   // call base
00160   bool res=ParallelExecutor::ExecuteEvent(event);
00161   // bail out 
00162   if(!res) return false;
00163   // process conditions
00164   ConditionsProcess();
00165   // record log
00166   LogWriteTime();
00167   LogWriteEvent();
00168   LogWriteState();
00169   // record trace
00170   TraceUpdateTransition(event);
00171   return true;
00172 }  
00173 
00174 
00175 // set logic time
00176 void LoggingExecutor::CurrentStep(int step) {
00177   FD_DX("LoggingExecutor(" << this << ")::CurrentStep(step)");
00178   // call base
00179   ParallelExecutor::CurrentStep(step);
00180   // clear trace
00181   TraceClear();
00182   mConditions.Reset();
00183 }
00184 
00185 // set physical time
00186 void LoggingExecutor::CurrentTime(tpTime::Type time) {
00187   FD_DX("LoggingExecutor(" << this << ")::CurrentTime(time)");
00188   // call base
00189   ParallelExecutor::CurrentTime(time);
00190   // clear trace
00191   TraceClear();
00192   mConditions.Reset();
00193 }
00194 
00195 // set current state (clear trace)
00196 bool LoggingExecutor::CurrentParallelTimedState(const ParallelTimedState& ptstate) {
00197   FD_DX("LoggingExecutor(" << this << ")::CurrentParallelTimedState(ptstate)");
00198   // call base
00199   bool res=ParallelExecutor::CurrentParallelTimedState(ptstate);
00200   // clear trace
00201   TraceClear();
00202   ConditionsReset();
00203   return res;
00204 }
00205 
00206 
00207 
00208 // get conditions
00209 const SimConditionSet& LoggingExecutor::Conditions(void) const {
00210   return mConditions;
00211 }
00212 
00213 // set conditions
00214 void LoggingExecutor::Conditions(const SimConditionSet& rConditions) {
00215     FD_DC("ProposingExecutor::DoRead(rTr,): loop X");
00216   mConditions=rConditions;
00217     FD_DC("ProposingExecutor::DoRead(rTr, ): loop Y");
00218   CompileConditions();
00219     FD_DC("ProposingExecutor::DoRead(rTr, loop Z");
00220 }
00221 
00222 // get condition
00223 const AttributeSimCondition& LoggingExecutor::Condition(const std::string& rName) const {
00224   return mConditions.Attribute(mConditions.Index(rName));
00225 }
00226 
00227 // get condition
00228 const AttributeSimCondition& LoggingExecutor::Condition(Idx cond) const {
00229   return mConditions.Attribute(cond);
00230 }
00231 
00232 /*
00233 // get condition pointer
00234 AttributeSimCondition* LoggingExecutor::Conditionp(const std::string& rName) {
00235   return mConditions.Attributep(mConditions.Index(rName));
00236 }
00237 */
00238 
00239 /*
00240 // get condition pointer
00241 AttributeSimCondition* LoggingExecutor::Conditionp(Idx cond) {
00242   return mConditions.Attributep(cond);
00243 }
00244 */
00245 
00246 // add/edit one condition
00247 Idx LoggingExecutor::SetCondition(const std::string& rName, const AttributeSimCondition& rCondition) {
00248   Idx cond=mConditions.Insert(rName,rCondition);
00249   CompileConditions();
00250   return cond;
00251 }
00252 
00253 // edit one condition
00254 void LoggingExecutor::SetCondition(Idx cond, const AttributeSimCondition& rCondition) {
00255   mConditions.Insert(cond,rCondition);
00256   CompileConditions();
00257 }
00258 
00259 // remove condition
00260 void LoggingExecutor::ClrCondition(const std::string& rName) {
00261   mConditions.Erase(rName);  
00262   CompileConditions();
00263 }
00264 
00265 // remove condition
00266 void LoggingExecutor::ClrCondition(Idx cond) {
00267   mConditions.Erase(cond);  
00268   CompileConditions();
00269 }
00270 
00271 // token io
00272 void LoggingExecutor::ConditionsWrite(TokenWriter& rTw, const std::string& rLabel) const {
00273   mConditions.Write(rTw,rLabel);
00274 }
00275 
00276 // token io
00277 void LoggingExecutor::ConditionsRead(TokenReader& rTr, const std::string& rLabel) {
00278   mConditions.Read(rTr,rLabel);
00279   CompileConditions();
00280 }
00281 
00282 
00283 // iterators
00284 LoggingExecutor::ConditionIterator LoggingExecutor::ConditionsBegin(void) const {
00285   return mConditions.Begin();
00286 }
00287 
00288 // iterators
00289 LoggingExecutor::ConditionIterator LoggingExecutor::ConditionsEnd(void) const {
00290   return mConditions.End();
00291 }
00292 
00293 // set up internal datastructure
00294 void LoggingExecutor::CompileConditions(void) {
00295   FD_DX("LoggingExecutor::CompileConditions()");
00296   // need a lock to prevent realocation of attributes
00297   mConditions.Lock();
00298   // have a minmal copy to avoid pointless iterations
00299   mEnabledConditions.clear();
00300   ConditionIterator cit=mConditions.Begin();
00301   for(; cit != mConditions.End(); ++cit) {
00302     FD_DX("LoggingExecutor::CompileConditions(): compile " << mConditions.Str(*cit));
00303     AttributeSimCondition* pattr=mConditions.Attributep(*cit);
00304     mConditions.DValid();
00305     // reject if not enabled
00306     if(!pattr->Enabled()) continue; 
00307     // reject incompatible dims
00308     if(pattr->IsStateCondition()) 
00309     if(pattr->StateCondition().mStateSets.size()!=Size()) continue; 
00310     // have it
00311     mEnabledConditions.push_back(pattr); 
00312   }
00313   // reset all states (incl disabled)
00314   mConditions.Reset();
00315   mBreakCondition=false;
00316   FD_DX("LoggingExecutor(" << this << ")::CompileConditions(): #" << mEnabledConditions.size());
00317 }
00318 
00319 // logging: reset
00320 void LoggingExecutor::ConditionsReset(void) {
00321   FD_DX("LoggingExecutor(" << this << ")::ConditionsReset()");
00322   CompileConditions();
00323   ConditionsProcess();
00324 }
00325 
00326 // logging: test
00327 void LoggingExecutor::ConditionsProcess(void) {
00328   FD_DX("LoggingExecutor(" << this << ")::ConditionsProcess()");
00329   mBreakCondition=false;
00330   std::vector<AttributeSimCondition*>::iterator ait=mEnabledConditions.begin();
00331   // loop over all enabled conditions
00332   for(; ait != mEnabledConditions.end(); ++ait) {
00333     AttributeSimCondition* pattr= *ait;
00334     // case 1: event condition
00335     if(pattr->IsEventCondition()) {
00336       // positive edge
00337       if(!pattr->Satisfied())
00338       if(pattr->EventCondition().mStart.Exists(mRecentEvent)) {
00339         pattr->Satisfied(true,CurrentTime());
00340         if(pattr->Breakpoint()) mBreakCondition=true;
00341       }
00342       // negative edge
00343       if(pattr->Satisfied())
00344       if(pattr->EventCondition().mStop.Exists(mRecentEvent)) {
00345         pattr->Satisfied(false,CurrentTime());
00346       }
00347       continue;
00348     }
00349     // case 2: state condition
00350     if(pattr->IsStateCondition()) {
00351       // stage a: figure state
00352        bool satisfied;
00353        if(pattr->StateCondition().mAllFlag) {
00354          // conjunctive
00355          satisfied=true;
00356          for(Idx i=0; i<Size(); i++) {
00357      Idx state = CurrentParallelState().at(i);
00358            const StateSet& set = pattr->StateCondition().mStateSets.at(i);
00359            if(set.Empty()) continue;
00360            if(!set.Exists(state)) {
00361              satisfied=false;
00362              break;
00363      }
00364          }
00365        } else {
00366          // disjunctive
00367          satisfied=false;
00368          for(Idx i=0; i<Size(); i++) {
00369      Idx state = CurrentParallelState().at(i);
00370            if(pattr->StateCondition().mStateSets.at(i).Exists(state)) {
00371              satisfied=true;
00372              break;
00373      }
00374          }
00375        }
00376        // state b: figure edge  
00377        if(!pattr->Satisfied() && satisfied) {
00378         pattr->Satisfied(true,CurrentTime());
00379         if(pattr->Breakpoint()) mBreakCondition=true;
00380       }
00381       if(pattr->Satisfied() && !satisfied) {
00382         pattr->Satisfied(false,CurrentTime());
00383       }
00384       continue;       
00385     }
00386   } // loop conditions
00387 }
00388 
00389 
00390 //  logging io: start
00391 void LoggingExecutor::LogOpen(TokenWriter& rTw, int logmode) {
00392   FD_DX("LoggingExecutor(" << this << ")::LogOpen()");
00393   pLogTokenWriter= &rTw; 
00394   mLogFile="";
00395   mLogMode=logmode;
00396   pLogTokenWriter->WriteBegin("ExecutionLog");
00397   pLogTokenWriter->WriteBegin("Mode");
00398   if(mLogMode & Statistics) pLogTokenWriter->WriteOption("Statistics");
00399   if(mLogMode & States) pLogTokenWriter->WriteOption("States");
00400   if(mLogMode & Events) pLogTokenWriter->WriteOption("Events");
00401   if(mLogMode & Time) pLogTokenWriter->WriteOption("Time");
00402   pLogTokenWriter->WriteEnd("Mode");
00403   LogWriteTime();
00404   LogWriteState();
00405 }
00406 
00407 //  logging io: start
00408 void LoggingExecutor::LogOpen(const std::string& rFileName, int logmode, std::ios::openmode openmode) {
00409   FD_DX("LoggingExecutor(" << this << ")::LogOpen(" << rFileName << ")");
00410   pLogTokenWriter= new TokenWriter(rFileName,openmode);
00411   LogOpen(*pLogTokenWriter, logmode);
00412   mLogFile=rFileName;
00413 }
00414 
00415 
00416 //  logging io: stop
00417 void LoggingExecutor::LogClose(void) {
00418   if(mLogMode & Statistics) {
00419     LogWriteStatistics();
00420   }
00421   if(mLogMode != 0) {
00422     FD_DX("LoggingExecutor(" << this << ")::LogClose(" << mLogFile << ")");
00423     *pLogTokenWriter << "\n";
00424     *pLogTokenWriter << "\n";
00425     pLogTokenWriter->WriteEnd("ExecutionLog");
00426   }
00427   if(mLogFile!="") {
00428     delete pLogTokenWriter;
00429   }
00430   mLogFile="";
00431   pLogTokenWriter=0;
00432   mLogMode=0;
00433 }
00434 
00435 // logging: report statistics
00436 void LoggingExecutor::LogWriteStatistics(void) {
00437   if(!(mLogMode & Statistics)) return;
00438   FD_DX("LoggingExecutor(" << this << ")::LogWriteStatistics()");
00439   *pLogTokenWriter << "\n";
00440   *pLogTokenWriter << "\n";
00441   pLogTokenWriter->WriteBegin("Statistics");
00442   std::vector<AttributeSimCondition*>::iterator ait=mEnabledConditions.begin();
00443   for(; ait != mEnabledConditions.end(); ++ait) {
00444     AttributeSimCondition* pattr= *ait;
00445     pattr->mSamplesPeriod.Compile();
00446     pattr->mSamplesPeriod.Write(*pLogTokenWriter);
00447     pattr->mSamplesDuration.Compile();
00448     pattr->mSamplesDuration.Write(*pLogTokenWriter);
00449     *pLogTokenWriter << "\n";
00450   }
00451   pLogTokenWriter->WriteEnd("Statistics");
00452   *pLogTokenWriter << "\n";
00453   *pLogTokenWriter << "\n";
00454 }
00455 
00456 // logging: report state
00457 void LoggingExecutor::LogWriteState(void) {
00458   if(!(mLogMode & States)) return;
00459   if(mLogMode & Time) {
00460     CurrentParallelTimedState().Write(*pLogTokenWriter,"TimedState",this);
00461   } else
00462     CurrentParallelTimedState().Write(*pLogTokenWriter,"DiscreteState",this);
00463   *pLogTokenWriter << "\n";
00464 }
00465 
00466 // logging: report event
00467 void LoggingExecutor::LogWriteEvent(void) {
00468   if(!(mLogMode & Events)) return;
00469   if(!(mLogMode & States)) {
00470     pLogTokenWriter->WriteString(Alphabet().SymbolicName(mRecentEvent));
00471     *pLogTokenWriter << "\n";
00472   } else {
00473     pLogTokenWriter->WriteBegin("Event");
00474     pLogTokenWriter->WriteString(Alphabet().SymbolicName(mRecentEvent));
00475     pLogTokenWriter->WriteEnd("Event");
00476   }
00477 }
00478 
00479 // loggging report time
00480 void LoggingExecutor::LogWriteTime(void) {
00481   if(!(mLogMode & Time)) return;
00482   if(!(mLogMode & States)) {
00483     pLogTokenWriter->WriteFloat(CurrentTime());
00484     *pLogTokenWriter << "\n";
00485   } else {
00486     pLogTokenWriter->WriteBegin("Time");
00487     pLogTokenWriter->WriteFloat(CurrentTime());
00488     pLogTokenWriter->WriteEnd("Time");
00489   }
00490 }
00491 
00492 // logging: pause
00493 void LoggingExecutor::LogWritePause(void) {
00494   FD_DX("LoggingExecutor(" << this << ")::LogWritePause()");
00495   if(mLogMode == 0) return;
00496   LogWriteStatistics();
00497   *pLogTokenWriter << "\n";
00498   pLogTokenWriter->WriteEnd("ExecutionLog");
00499   *pLogTokenWriter << "\n";
00500   *pLogTokenWriter << "\n";
00501   *pLogTokenWriter << "\n";
00502 }
00503 
00504 // logging report pause
00505 void LoggingExecutor::LogWriteResume(void) {
00506   FD_DX("LoggingExecutor(" << this << ")::LogWriteResume()");
00507   if(mLogMode == 0) return;
00508   pLogTokenWriter->WriteBegin("ExecutionLog");
00509   LogWriteState();
00510 }
00511 
00512 // trace: clear all
00513 void LoggingExecutor::TraceClear(int length) {
00514   FD_DX("LoggingExecutor(" << this << ")::TraceClear(" << length <<")");
00515   // clear
00516   mTraceBuffer.clear();
00517   mTraceTimeToStep.clear();
00518   // set max length
00519   if(length>-2) mTraceMax=length;
00520   // set first step
00521   mTraceFirstStep=CurrentStep();
00522   // bail out
00523   if(mTraceMax==0) return;
00524   // set first entry
00525   TraceAddSample();
00526 }
00527 
00528 // trace: access
00529 LoggingExecutor::TraceIterator LoggingExecutor::TraceBegin(void) const {
00530   return mTraceBuffer.begin();
00531 }
00532 
00533 // trace: access
00534 LoggingExecutor::TraceIterator LoggingExecutor::TraceEnd(void) const {
00535   return mTraceBuffer.end();
00536 }
00537 
00538 // trace: access
00539 const LoggingExecutor::TraceSample* LoggingExecutor::TraceAtStep(int step) const {
00540   int n = step-mTraceFirstStep;
00541   if(n<0) return 0;
00542   if(((unsigned int)n)>=mTraceBuffer.size()) return 0;
00543   return &mTraceBuffer[n];
00544 }
00545 
00546 // trace: access
00547 const LoggingExecutor::TraceSample* LoggingExecutor::TraceAtTime(tpTime::Type time) const {
00548   std::map<tpTime::Type,int>::const_iterator sit=mTraceTimeToStep.find(time);
00549   if(sit== mTraceTimeToStep.end()) 
00550     return 0;
00551   int step = sit->second;
00552   return TraceAtStep(step);
00553 }
00554 
00555 // trace: access
00556 const LoggingExecutor::TraceSample* LoggingExecutor::TraceCurrent(void) const {
00557   if(mTraceBuffer.size()==0) return 0;
00558   return  &mTraceBuffer.back(); 
00559 }
00560 
00561 // trace: access
00562 const LoggingExecutor::TraceSample* LoggingExecutor::TraceRecent(void) const {
00563   if(mTraceBuffer.size()<2) return 0;
00564   return  &mTraceBuffer[mTraceBuffer.size()-2];
00565 }
00566 
00567 // trace: access
00568 const LoggingExecutor::TraceSample* LoggingExecutor::TraceFirst(void) const {
00569   if(mTraceBuffer.size()<1) return 0;
00570   return  &mTraceBuffer[0];
00571 }
00572 
00573 // trace: access
00574 int LoggingExecutor::TraceLength(void) const {
00575   return mTraceBuffer.size();
00576 }
00577 
00578 // trace: add empty sample
00579 void LoggingExecutor::TraceAddSample(void) {
00580   // initialize new sample
00581   TraceSample sample;
00582   sample.mState=CurrentParallelTimedState();
00583   sample.mStep=CurrentStep();
00584   sample.mTime=CurrentTime(); 
00585   sample.mDuration=0;
00586   sample.mEvent=0;            
00587   // add to buffer
00588   mTraceBuffer.push_back(sample);
00589   // drop first sample
00590   if(mTraceMax>0) 
00591     while(mTraceBuffer.size()> (unsigned int) mTraceMax)
00592       mTraceBuffer.pop_front();
00593   // fix timing
00594   if(mTraceMax>0) 
00595     mTraceFirstStep=mTraceBuffer.front().mStep;
00596   // todo: time map
00597 }
00598 
00599 // trace:: update after transition
00600 void LoggingExecutor::TraceUpdateTransition(Idx event) {
00601   // bail out
00602   if(mTraceMax==0) return;
00603   // fix last entry
00604   TraceSample& sample=mTraceBuffer.back();
00605   sample.mEvent=event;
00606   sample.mDuration=CurrentTime()-sample.mTime;
00607   // add entry
00608   TraceAddSample();
00609 }
00610 
00611 // trace:: update time
00612 void LoggingExecutor::TraceUpdateTime(void) {
00613   // bail out
00614   if(mTraceMax==0) return;
00615   // fix last entry
00616   TraceSample& sample=mTraceBuffer.back();
00617   sample.mDuration=CurrentTime()-sample.mTime;
00618 }
00619 
00620 
00621 
00622 // trace: tokenwriter output
00623 void LoggingExecutor::TraceWrite(TokenWriter& rTw, const TraceSample& sample) const {
00624   rTw.WriteBegin("Sample");
00625   rTw.WriteComment(" State " + PTSStr(sample.mState));
00626   rTw << sample.mStep;
00627   rTw << sample.mTime;
00628   rTw << sample.mDuration;
00629   rTw << "\n";
00630   if(sample.mEvent>0) 
00631     rTw << EventName(sample.mEvent);
00632   rTw.WriteEnd("Sample");
00633 }
00634 
00635 // trace: console output
00636 void LoggingExecutor::TraceWrite(const TraceSample& sample) const {
00637   TokenWriter tw(TokenWriter::Stdout);
00638   TraceWrite(tw, sample);
00639 }
00640 
00641 // trace: console output (all)
00642 void LoggingExecutor::TraceWrite() const {
00643   for(TraceIterator sit=TraceBegin(); sit!=TraceEnd(); sit++) {
00644     TraceWrite(*sit);
00645   };
00646 }
00647 
00648 // trace: string output
00649 std::string LoggingExecutor::TraceToString(const TraceSample& sample) const {
00650   TokenWriter tw(TokenWriter::String);
00651   TraceWrite(tw, sample);
00652   return tw.Str();
00653 }
00654 
00655 // Revert executors state to past step from buffer
00656 bool LoggingExecutor::RevertToStep(Idx step) {
00657   FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << ")");
00658   bool res=true;
00659   const TraceSample* samplep = TraceAtStep(step);
00660   if(!samplep) return false;
00661   FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): found step");
00662   // set state
00663   res=ParallelExecutor::CurrentParallelTimedState(samplep->mState);
00664   if(!res) return false;
00665   // care log trace
00666   LogWritePause();
00667   // set time
00668   ParallelExecutor::CurrentTime(samplep->mTime);
00669   ParallelExecutor::CurrentStep(samplep->mStep);
00670   LogWriteResume();
00671   // care trace: remove
00672   FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): fixing trace");
00673   while(mTraceBuffer.size()>0) {
00674     const TraceSample& lsample= mTraceBuffer.back();
00675     if(lsample.mStep<=step) break;
00676     mTraceBuffer.pop_back();
00677   }
00678   // care trace: invalidate last sample
00679   if(mTraceBuffer.size()>0) {
00680     TraceSample& lsample= mTraceBuffer.back();
00681     lsample.mEvent=0;
00682     lsample.mDuration=0;
00683   }
00684   // clear condition state
00685   mConditions.Reset();
00686   FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): done");
00687   return true;
00688 }
00689 
00690 } // namespace faudes
00691 
00692 

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