Commit ca9715b6 authored by Aaron Bray's avatar Aaron Bray
Browse files

Merge branch 'feature/stop_on_fatal' into '3.x'

Stop advancement on fatal

See merge request !72
parents 5760adde 9d6358cf
903d8c96da6874d281aef3ba8ceb85ce22e4dc0b97165d59ea7d0032e375b318f24a0afc8e678786ef93f3de16ad0230f911783fc6afabd96c528477ca1dbe2a
\ No newline at end of file
a6ae4763bd6a4494ea043b6747eea76bcc450a728ac191e30c4736a352075050d72ee4a616b79e48597814de4d6debb216d32cf2b7811c3e56e6d28f065e957e
\ No newline at end of file
5c8187576a331e5adfb5e2ee04cacd6baba36aae443cf7a5bc22501e93dec4a6be32029037880e0255ad47c16fc29e927d4a556a11e6e907f4b1e6c373a71a8a
\ No newline at end of file
d2f0bfd3bd4186e947258570aa9919f79697e28fff42059e93160c4ff8fd44967f25362bd5a9090cdab3f7e5774b348e2276ea431bf102c36a07246517518638
\ No newline at end of file
......@@ -178,7 +178,7 @@ public:
/// through the API at this time.
///
//--------------------------------------------------------------------------------------------------
virtual void AdvanceModelTime() = 0;
virtual bool AdvanceModelTime() = 0;
//--------------------------------------------------------------------------------------------------
/// \brief
......@@ -189,7 +189,7 @@ public:
/// through the API at this time.
///
//--------------------------------------------------------------------------------------------------
virtual void AdvanceModelTime(double time, const TimeUnit& unit) = 0;
virtual bool AdvanceModelTime(double time, const TimeUnit& unit) = 0;
//--------------------------------------------------------------------------------------------------
/// \brief
......
......@@ -13,7 +13,7 @@ public:
class Controller
{
public:
virtual void AdvanceTime() = 0;
virtual bool AdvanceTime() = 0;
virtual SEEngineTracker* GetEngineTracker() = 0;
virtual double GetTimeStep(const TimeUnit& unit) = 0;
};
......
......@@ -87,12 +87,14 @@ public:
Fatal
};
void SetLogLevel(Level level);
Level GetLogLevel();
Level GetLogLevel() const;
virtual void SetLogTime(const SEScalarTime* time);
virtual void SetForward(LoggerForward* forward);
virtual bool HasForward();
virtual bool HasForward() const;
virtual void AddForward(LoggerForward* forward);
virtual void RemoveForward(LoggerForward* forward);
virtual void RemoveForwards();
virtual void Debug(std::string const& msg, std::string const& origin = Loggable::empty);
virtual void Debug(std::stringstream &msg, std::string const& origin = Loggable::empty);
......@@ -119,7 +121,7 @@ protected:
virtual std::string FormatLogMessage(std::string const& origin, std::string const& msg);
LoggerForward* m_Forward;
std::vector<LoggerForward*> m_Forwards;
const SEScalarTime* m_time;
std::stringstream m_ss;
......
......@@ -15,7 +15,7 @@ public:
{
}
virtual ~log_lib()
virtual ~log_lib()
{
if (_file.is_open())
_file.close();
......@@ -70,9 +70,8 @@ void Logger::Initialize() {}
void Logger::Deinitialize() {}
//logger constructor
Logger::Logger(const std::string& logFilename)
Logger::Logger(const std::string& logFilename)
{
m_Forward = nullptr;
m_time = nullptr;
_log_lib = new log_lib();
SetLogFile(logFilename);
......@@ -120,22 +119,34 @@ void Logger::SetLogLevel(Logger::Level l)
}
//This function will return the priority of the logger
Logger::Level Logger::GetLogLevel()
Logger::Level Logger::GetLogLevel() const
{
return _log_lib->_log_level;
}
void Logger::SetForward(LoggerForward* forward)
bool Logger::HasForward() const
{
m_Forward = forward;
return !m_Forwards.empty();
}
void Logger::AddForward(LoggerForward* forward)
{
if (forward != nullptr && std::find(m_Forwards.begin(), m_Forwards.end(), forward) == m_Forwards.end())
m_Forwards.push_back(forward);
}
void Logger::RemoveForward(LoggerForward* forward)
{
auto idx = std::find(m_Forwards.begin(), m_Forwards.end(), forward);
if (idx != m_Forwards.end())
m_Forwards.erase(idx);
}
bool Logger::HasForward()
void Logger::RemoveForwards()
{
return m_Forward == nullptr ? false : true;
m_Forwards.clear();
}
std::string Logger::FormatLogMessage(const std::string& msg, const std::string& origin)
std::string Logger::FormatLogMessage(const std::string& msg, const std::string& origin)
{
m_ss.str("");
m_ss.clear();
......@@ -148,118 +159,118 @@ std::string Logger::FormatLogMessage(const std::string& msg, const std::string&
return origin + " : " + m_ss.str();
}
void Logger::Debug(std::string const& msg, const std::string& origin)
void Logger::Debug(std::string const& msg, const std::string& origin)
{
if (_log_lib->log(Level::Debug))
{
_log_lib->log(Level::Debug, FormatLogMessage(msg, origin));
if (m_Forward != nullptr)
m_Forward->ForwardDebug(m_ss.str().c_str(), origin.c_str());
for (auto fwd : m_Forwards)
fwd->ForwardDebug(m_ss.str().c_str(), origin.c_str());
}
}
void Logger::Debug(std::stringstream &msg, const std::string& origin)
void Logger::Debug(std::stringstream& msg, const std::string& origin)
{
Debug(msg.str(), origin);
msg.str("");
msg.clear();
}
void Logger::Debug(std::ostream &msg, const std::string& origin)
void Logger::Debug(std::ostream& msg, const std::string& origin)
{
std::stringstream ss;
ss << msg.rdbuf();
Debug(ss.str(), origin);
}
void Logger::Info(const std::string& msg, const std::string& origin)
void Logger::Info(const std::string& msg, const std::string& origin)
{
if (_log_lib->log(Level::Info))
{
_log_lib->log(Level::Info, FormatLogMessage(msg, origin));
if (m_Forward != nullptr)
m_Forward->ForwardInfo(m_ss.str().c_str(), origin.c_str());
for (auto fwd : m_Forwards)
fwd->ForwardInfo(m_ss.str().c_str(), origin.c_str());
}
}
void Logger::Info(std::stringstream &msg, const std::string& origin)
void Logger::Info(std::stringstream& msg, const std::string& origin)
{
Info(msg.str(), origin);
msg.str("");
msg.clear();
}
void Logger::Info(const std::stringstream &msg, const std::string& origin)
void Logger::Info(const std::stringstream& msg, const std::string& origin)
{
Info(msg.str(), origin);
}
void Logger::Info(std::ostream &msg, const std::string& origin)
void Logger::Info(std::ostream& msg, const std::string& origin)
{
std::stringstream ss;
ss << msg.rdbuf();
Info(ss.str(), origin);
}
void Logger::Warning(const std::string& msg, const std::string& origin)
void Logger::Warning(const std::string& msg, const std::string& origin)
{
if (_log_lib->log(Level::Warn))
{
_log_lib->log(Level::Warn, FormatLogMessage(msg, origin));
if (m_Forward != nullptr)
m_Forward->ForwardWarning(m_ss.str().c_str(), origin.c_str());
for (auto fwd : m_Forwards)
fwd->ForwardWarning(m_ss.str().c_str(), origin.c_str());
}
}
void Logger::Warning(std::stringstream &msg, const std::string& origin)
void Logger::Warning(std::stringstream& msg, const std::string& origin)
{
Warning(msg.str(), origin);
msg.str("");
msg.clear();
}
void Logger::Warning(std::ostream &msg, const std::string& origin)
void Logger::Warning(std::ostream& msg, const std::string& origin)
{
std::stringstream ss;
ss << msg.rdbuf();
Warning(ss.str(), origin);
}
void Logger::Error(const std::string& msg, const std::string& origin)
void Logger::Error(const std::string& msg, const std::string& origin)
{
if (_log_lib->log(Level::Error))
{
_log_lib->log(Level::Error, FormatLogMessage(msg, origin));
if (m_Forward != nullptr)
m_Forward->ForwardError(m_ss.str().c_str(), origin.c_str());
for (auto fwd : m_Forwards)
fwd->ForwardError(m_ss.str().c_str(), origin.c_str());
}
}
void Logger::Error(std::stringstream &msg, const std::string& origin)
void Logger::Error(std::stringstream& msg, const std::string& origin)
{
Error(msg.str(), origin);
msg.str("");
msg.clear();
}
void Logger::Error(std::ostream &msg, const std::string& origin)
void Logger::Error(std::ostream& msg, const std::string& origin)
{
std::stringstream ss;
ss << msg.rdbuf();
Error(ss.str(), origin);
}
void Logger::Fatal(const std::string& msg, const std::string& origin)
void Logger::Fatal(const std::string& msg, const std::string& origin)
{
if (_log_lib->log(Level::Fatal))
{
_log_lib->log(Level::Fatal, FormatLogMessage(msg, origin));
if (m_Forward != nullptr)
m_Forward->ForwardFatal(m_ss.str().c_str(), origin.c_str());
for (auto fwd : m_Forwards)
fwd->ForwardFatal(m_ss.str().c_str(), origin.c_str());
}
}
void Logger::Fatal(std::stringstream &msg, const std::string& origin)
void Logger::Fatal(std::stringstream& msg, const std::string& origin)
{
Fatal(msg.str(), origin);
msg.str("");
msg.clear();
}
void Logger::Fatal(std::ostream &msg, const std::string& origin)
void Logger::Fatal(std::ostream& msg, const std::string& origin)
{
std::stringstream ss;
ss << msg.rdbuf();
......@@ -319,30 +330,30 @@ void Loggable::Debug(std::ostream& msg, const std::string& origin) const
Debug(ss.str(), origin);
}
void Loggable::Info(const std::stringstream &msg, const std::string& origin) const
void Loggable::Info(const std::stringstream& msg, const std::string& origin) const
{
Info(msg.str(), origin);
}
void Loggable::Info(std::ostream &msg, const std::string& origin) const
void Loggable::Info(std::ostream& msg, const std::string& origin) const
{
std::stringstream ss;
ss << msg.rdbuf();
Info(ss.str(), origin);
}
void Loggable::Warning(const std::string& msg, const std::string& origin) const
void Loggable::Warning(const std::string& msg, const std::string& origin) const
{
if (m_Logger)
m_Logger->Warning(msg, origin);
}
void Loggable::Warning(std::stringstream &msg, const std::string& origin) const
void Loggable::Warning(std::stringstream& msg, const std::string& origin) const
{
Warning(msg.str(), origin);
msg.str("");
msg.clear();
}
void Loggable::Warning(std::ostream &msg, const std::string& origin) const
void Loggable::Warning(std::ostream& msg, const std::string& origin) const
{
std::stringstream ss;
ss << msg.rdbuf();
......@@ -379,19 +390,19 @@ void Loggable::Info(std::stringstream& msg, const std::string& origin) const
msg.clear();
}
void Loggable::Fatal(const std::string& msg, const std::string& origin) const
void Loggable::Fatal(const std::string& msg, const std::string& origin) const
{
std::cerr << "FATAL:" << msg << " : " << origin << std::endl;
if (m_Logger)
m_Logger->Fatal(msg, origin);
}
void Loggable::Fatal(std::stringstream &msg, const std::string& origin) const
void Loggable::Fatal(std::stringstream& msg, const std::string& origin) const
{
Fatal(msg.str(), origin);
msg.str("");
msg.clear();
}
void Loggable::Fatal(std::ostream &msg, const std::string& origin) const
void Loggable::Fatal(std::ostream& msg, const std::string& origin) const
{
std::stringstream ss;
ss << msg.rdbuf();
......
......@@ -52,7 +52,7 @@ PulseEngineThunk::PulseEngineThunk() : SEEventHandler()
data = new PulseEngineThunk::pimpl;
data->eng = std::unique_ptr<PulseEngine>((PulseEngine*)CreatePulseEngine().release());
data->eng->GetLogger()->LogToConsole(false);
data->eng->GetLogger()->SetForward(this);
data->eng->GetLogger()->AddForward(this);
}
PulseEngineThunk::~PulseEngineThunk()
{
......@@ -306,7 +306,7 @@ bool PulseEngineThunk::AdvanceTimeStep()
bool success = true;
try
{
data->eng->AdvanceModelTime();
success = data->eng->AdvanceModelTime();
}
catch (CommonDataModelException& ex)
{
......
......@@ -47,6 +47,27 @@
#include "utils/FileUtils.h"
class FatalListner : public LoggerForward
{
public:
FatalListner(SEEventManager& mgr, SEScalarTime& ct) : m_Events (mgr), m_CurrentTime(ct) {};
~FatalListner() = default;
virtual void ForwardDebug(const std::string& msg, const std::string& origin) { }
virtual void ForwardInfo(const std::string& msg, const std::string& origin) { }
virtual void ForwardWarning(const std::string& msg, const std::string& origin) { }
virtual void ForwardError(const std::string& msg, const std::string& origin) { }
virtual void ForwardFatal(const std::string& msg, const std::string& origin)
{
m_Events.SetEvent(eEvent::IrreversibleState, true, m_CurrentTime);
}
protected:
SEEventManager& m_Events;
SEScalarTime& m_CurrentTime;
};
PulseData::PulseData(Logger* logger) : Loggable(logger)
{
m_State = EngineState::NotReady;
......@@ -206,6 +227,9 @@ PulseController::PulseController(Logger* logger) : PulseData(logger)
}
PulseController::~PulseController()
{
m_Logger->RemoveForward(m_LogForward);
SAFE_DELETE(m_LogForward);
SAFE_DELETE(m_Stabilizer);
SAFE_DELETE(m_Substances);
......@@ -289,6 +313,9 @@ void PulseController::Allocate()
m_BlackBoxes = new PulseBlackBoxes(*this);
m_Circuits = new PulseCircuits(*this);
m_LogForward = new FatalListner(*m_EventManager, m_CurrentTime);
m_Logger->AddForward(m_LogForward);
}
bool PulseController::SetConfigurationOverride(const SEEngineConfiguration* config)
......@@ -527,6 +554,8 @@ void PulseController::SetSimulationTime(const SEScalarTime& time)
bool PulseController::IsReady() const
{
if (m_State == EngineState::Fatal)
return false;
if (m_State == EngineState::NotReady)
{
Error("Engine is not ready to process, Initialize the engine or Load a state.");
......@@ -535,17 +564,21 @@ bool PulseController::IsReady() const
return true;
}
void PulseController::AdvanceModelTime()
bool PulseController::AdvanceModelTime()
{
if (!IsReady())
return;
if (m_EventManager->IsEventActive(eEvent::IrreversibleState))
return;
return false;
PreProcess();
Process();
PostProcess();
if (m_EventManager->IsEventActive(eEvent::IrreversibleState))
{
m_State = EngineState::Fatal;
return false;
}
m_EventManager->UpdateEvents(m_Config->GetTimeStep());
m_CurrentTime.Increment(m_Config->GetTimeStep());
m_SimulationTime.Increment(m_Config->GetTimeStep());
......@@ -555,15 +588,19 @@ void PulseController::AdvanceModelTime()
// TODO Figure out a way to track what overrides were used and which were not
m_ScalarOverrides.clear();
return true;
}
void PulseController::AdvanceModelTime(double time, const TimeUnit& unit)
bool PulseController::AdvanceModelTime(double time, const TimeUnit& unit)
{
double time_s = Convert(time, unit, TimeUnit::s) + m_SpareAdvanceTime_s;
int count = (int)(time_s / GetTimeStep().GetValue(TimeUnit::s));
for (int i = 0; i < count; i++)
AdvanceModelTime();
if (!AdvanceModelTime())
return false;
m_SpareAdvanceTime_s = time_s - (count * GetTimeStep().GetValue(TimeUnit::s));
return true;
}
void PulseController::AtSteadyState(EngineState state)
......@@ -798,12 +835,3 @@ bool PulseController::GetPatientAssessment(SEPatientAssessment& assessment) cons
Error("Unsupported patient assessment");
return false;
}
void PulseController::ForwardFatal(const std::string& msg, const std::string& origin)
{
std::string err;
err.append(msg);
err.append(" ");
err.append(origin);
throw PhysiologyEngineException(err);
}
......@@ -48,7 +48,8 @@ enum class EngineState { NotReady=0,
AtInitialStableState,
SecondaryStabilization,
AtSecondaryStableState,
Active };
Active,
Fatal};
// Keep enums in sync with appropriate proto file !!
......@@ -202,6 +203,7 @@ protected:
SEPatient* m_CurrentPatient=nullptr;
SEEventManager* m_EventManager=nullptr;
LoggerForward* m_LogForward=nullptr;
SEAdvanceHandler* m_AdvanceHandler=nullptr;
......@@ -241,8 +243,8 @@ public:
virtual void SetSimulationTime(const SEScalarTime& time);
virtual void AdvanceModelTime();
virtual void AdvanceModelTime(double time, const TimeUnit& unit);
virtual bool AdvanceModelTime();
virtual bool AdvanceModelTime(double time, const TimeUnit& unit);
virtual bool ProcessAction(const SEAction& action);
virtual bool GetPatientAssessment(SEPatientAssessment& assessment) const;
......@@ -278,8 +280,6 @@ protected:
virtual void Process();
virtual void PostProcess();
virtual void ForwardFatal(const std::string& msg, const std::string& origin);
PulseConfiguration const* m_ConfigOverride=nullptr;
PulseStabilizationController* m_Stabilizer=nullptr;
};
......@@ -290,7 +290,7 @@ public:
PulseStabilizationController(PulseController& pc) : _pc(pc) {}
~PulseStabilizationController() = default;
virtual void AdvanceTime() override { _pc.AdvanceModelTime(); }
virtual bool AdvanceTime() override { return _pc.AdvanceModelTime(); }
virtual SEEngineTracker* GetEngineTracker() override
{
return &_pc.GetData().GetEngineTracker();
......
......@@ -87,14 +87,14 @@ void PulseEngine::SetSimulationTime(const SEScalarTime& time)
return m_PulseController->SetSimulationTime(time);
}
void PulseEngine::AdvanceModelTime()
bool PulseEngine::AdvanceModelTime()
{
m_PulseController->AdvanceModelTime();
return m_PulseController->AdvanceModelTime();
}
void PulseEngine::AdvanceModelTime(double time, const TimeUnit& unit)
bool PulseEngine::AdvanceModelTime(double time, const TimeUnit& unit)
{
m_PulseController->AdvanceModelTime(time, unit);
return m_PulseController->AdvanceModelTime(time, unit);
}
bool PulseEngine::ProcessAction(const SEAction& action)
......
......@@ -41,8 +41,8 @@ public:
virtual double GetSimulationTime(const TimeUnit& unit) const override;
virtual void SetSimulationTime(const SEScalarTime& time) override;
virtual void AdvanceModelTime() override;
virtual void AdvanceModelTime(double time, const TimeUnit& unit) override;
virtual bool AdvanceModelTime() override;
virtual bool AdvanceModelTime(double time, const TimeUnit& unit) override;
virtual bool ProcessAction(const SEAction& action) override;
virtual const SEActionManager& GetActionManager() const override;
......
......@@ -13,7 +13,7 @@ int main()
//HowToSandbox();
HowToEngineUse();
//HowToEngineUse();
//HowToCreateAPatient();
//HowToSerialize();
......@@ -29,7 +29,7 @@ int main()
//HowToCPR();
//HowToEnvironmentChange();
//HowToExercise();
//HowToHemorrhage();
HowToHemorrhage();
//HowToLobarPneumonia();
//HowToMechanicalVentilation();
//HowToPulmonaryFibrosis();
......@@ -56,15 +56,17 @@ HowToTracker::~HowToTracker()
{
}
void HowToTracker::AdvanceModelTime(double time_s)
bool HowToTracker::AdvanceModelTime(double time_s)
{
// This samples the engine at each time step
int count = static_cast<int>(time_s / m_dT_s);
for (int i = 0; i < count; i++)
{
m_Engine.AdvanceModelTime(); // Compute 1 time step
if(!m_Engine.AdvanceModelTime()) // Compute 1 time step
return false;
// Pull Track will pull data from the engine and append it to the file
m_Engine.GetEngineTracker()->TrackData(m_Engine.GetSimulationTime(TimeUnit::s));
}
return true;
}
......@@ -54,5 +54,5 @@ public:
~HowToTracker();
// This class will operate on seconds
void AdvanceModelTime(double time_s);
bool AdvanceModelTime(double time_s);
};
\ No newline at end of file
......@@ -117,7 +117,7 @@ void HowToEngineUse()
// and PulseEngine will log and also call the provided method with the message.
// You can specify a set of functions to be called for any one of the log levels
MyLogger myLogger;
pe->GetLogger()->SetForward(&myLogger);
pe->GetLogger()->AddForward(&myLogger);
pe->GetLogger()->Info("HowTo_EngineUse");
// You can tell the PulseEngine to also notify you of any events as well
......@@ -179,9 +179,13 @@ void HowToEngineUse()