Skip to content

Commit

Permalink
runtime: Add ModelStop exception to signal simulation stop
Browse files Browse the repository at this point in the history
In the runtime, a simulator that is not operational after a process
will also throw the ModelStop exception.
  • Loading branch information
cassava committed Mar 14, 2023
1 parent 68634ca commit c78a4ef
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
13 changes: 12 additions & 1 deletion engine/src/simulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ class SimulationMachine
} catch (cloe::ModelReset& e) {
logger()->error("Unhandled reset request in {} state: {}", id, e.what());
this->push_interrupt(RESET);
} catch (cloe::ModelStop& e) {
logger()->error("Unhandled stop request in {} state: {}", id, e.what());
this->push_interrupt(STOP);
} catch (cloe::ModelAbort& e) {
logger()->error("Unhandled abort request in {} state: {}", id, e.what());
this->push_interrupt(ABORT);
Expand Down Expand Up @@ -832,12 +835,16 @@ StateId SimulationMachine::StepSimulators::impl(SimulationContext& ctx) {
ctx.foreach_simulator([&ctx](cloe::Simulator& simulator) {
try {
cloe::Duration sim_time = simulator.process(ctx.sync);
if (!simulator.is_operational()) {
throw cloe::ModelStop("simulator {} no longer operational", simulator.name());
}
if (sim_time != ctx.sync.time()) {

throw cloe::ModelError("simulator {} did not progress to required time: got {}ms, expected {}ms", simulator.name(), sim_time.count()/1'000'000, ctx.sync.time().count()/1'000'000);
}
} catch (cloe::ModelReset& e) {
throw;
} catch (cloe::ModelStop& e) {
throw;
} catch (cloe::ModelAbort& e) {
throw;
} catch (cloe::ModelError& e) {
Expand Down Expand Up @@ -915,6 +922,10 @@ StateId SimulationMachine::StepControllers::impl(SimulationContext& ctx) {
this->logger()->error("Controller {} reset: {}", ctrl.name(), e.what());
this->state_machine()->reset();
return false;
} catch (cloe::ModelStop& e) {
this->logger()->error("Controller {} stop: {}", ctrl.name(), e.what());
this->state_machine()->stop();
return false;
} catch (cloe::ModelAbort& e) {
this->logger()->error("Controller {} abort: {}", ctrl.name(), e.what());
this->state_machine()->abort();
Expand Down
27 changes: 27 additions & 0 deletions runtime/include/cloe/model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
* ModelReset
* Error used when a model needs to *signal* that it desires a simulation
* reset.
*
* ModelStop
* Error used when a model needs to *signal* that it desires a simulation
* stop.
*/

#pragma once
Expand Down Expand Up @@ -125,6 +129,29 @@ class ModelReset : public ModelError {
}
};

/**
* ModelStop indicates that the model has encountered a request that causes
* it to believe that the simulation should be stopped.
*/
class ModelStop : public ModelError {
public:
using ModelError::ModelError;
virtual ~ModelStop() noexcept = default;

const std::string& explanation() const { return Error::explanation(); }

ModelError explanation(const std::string& explanation) && {
this->set_explanation(explanation);
return std::move(*this);
}

template <typename... Args>
ModelError explanation(const char* format, const Args&... args) && {
this->set_explanation(fmt::format(format, args...));
return std::move(*this);
}
};

/**
* The Model class serves as an interface which Controller and Simulator can
* inherit from.
Expand Down

0 comments on commit c78a4ef

Please sign in to comment.