MCPcopy Create free account
hub / github.com/SoarGroup/Soar / MoveTo_StopBeforePhase

Method MoveTo_StopBeforePhase

Core/KernelSML/src/sml_RunScheduler.cpp:467–556  ·  view source on GitHub ↗

* @brief Users and applications can choose to have agents always * stop before a particular phase. If all agents have finished * finished running, this routine will check whether they * need to be stepped to a different phase. *********************************************************************/

Source from the content-addressed store, hash-verified

465* need to be stepped to a different phase.
466*********************************************************************/
467void RunScheduler::MoveTo_StopBeforePhase(bool forever, smlRunStepSize runStepSize)
468{
469 // If we ran by decision_cycle and we've run the appropriate number of decisions,
470 // then step agent until it reached the correct phase where it should stop.
471 // Just before this point, (in scheduler while loop) we've checked and fired the
472 // OutputComplete and OutputGenerated events, so it should be fine to step
473 // an agent by phases until it gets to StopBefore, and then step the other
474 // agents in turn.
475 //
476 // If an interrupt was requested, it will be detected inside StepInClientThread
477 // and the appropriate events will be generated. The runResult will come back as
478 // INTERRUPTED, and the while loops will exit so that the run stops.
479 //
480 // Support for "Run 0" is somewhat complicated, since we might very well
481 // cross the I/O boundary. So we'll try stepping til OUTPUT done, then generate
482 // Update events, then step again til StopBeforePt is reached. Note: when we support
483 // StopBeforeUpdateWorld, we'll need to explicitly check for that before generating events.
484
485 if ((runStepSize == sml_DECISION) || forever)
486 {
487 for (AgentMapIter iter = m_pKernelSML->m_AgentMap.begin() ; iter != m_pKernelSML->m_AgentMap.end() ; iter++)
488 {
489 AgentSML* pAgentSML = iter->second ;
490 if (pAgentSML->WasAgentOnRunList())
491 {
492 AgentSML* pAgent = pAgentSML ;
493 smlPhase phase = pAgentSML->GetCurrentPhase() ;
494 smlRunResult runResult = pAgentSML->GetResultOfLastRun() ;
495
496 // as in Bug 648, it's possible that a client has requested STOP_AFTER_DECISION
497 // while the agent was stopped at the m_StopBeforePhase, yet the agent run logic has
498 // dropped thru to this point without generating the interrupt yet.
499 if ((m_StopBeforePhase == phase) && (pAgent->GetRunState() == sml_RUNSTATE_STOPPED) &&
500 (pAgent->GetInterruptFlags() & sml_STOP_AFTER_DECISION_CYCLE))
501 {
502 pAgent->SetRunState(sml_RUNSTATE_INTERRUPTED);
503 runResult = pAgent->StepInClientThread(sml_PHASE) ; // force interrupt
504 }
505
506 while ((phase != m_StopBeforePhase) && (sml_RUN_COMPLETED == runResult))
507 {
508 runResult = pAgent->StepInClientThread(sml_PHASE) ;
509 phase = pAgentSML->GetCurrentPhase() ;
510 // don't cross Output-Input boundary here just to get to StopBefore phase for "Run 0"
511 if (sml_INPUT_PHASE == phase)
512 {
513 break;
514 }
515 }
516 pAgentSML->SetResultOfRun(runResult) ;
517
518 // Notify listeners that this agent is finished running
519 /* pAgent->FireRunEndsEvent() ; */ // not if supporting run0 over O/I boundary
520 }
521 }
522 // If agents haven't reached the StopBeforePhase, then agents finished output
523 // and we need to possibly generate the UpdateWorld events before stepping any further.
524 // If not all agents finished output, then nothing will fire.

Callers

nothing calls this directly

Calls 7

endMethod · 0.80
WasAgentOnRunListMethod · 0.80
GetResultOfLastRunMethod · 0.80
GetRunStateMethod · 0.80
StepInClientThreadMethod · 0.80
FireRunEventMethod · 0.80
GetCurrentPhaseMethod · 0.45

Tested by

no test coverage detected