Commit 505d98ce authored by Aaron Bray's avatar Aaron Bray
Browse files

Refactor events so the are not related to specific things in the engine

parent 25f1841b
......@@ -3,7 +3,6 @@
#pragma once
class SEEventHandler;
class SEAdvanceHandler;
class SEPatient;
class SEPatientConfiguration;
......@@ -31,6 +30,7 @@ class SEElectroCardioGram;
class SECompartmentManager;
class SEActionManager;
class SEConditionManager;
class SEEventManager;
class SEEngineTracker;
class SEEngineConfiguration;
......@@ -210,9 +210,10 @@ public:
//--------------------------------------------------------------------------------------------------
/// \brief
/// Add a callback object that will be called whenever a pateint or anesthesia machine event changes state
/// Retrieves the associated event manager.
///
//--------------------------------------------------------------------------------------------------
virtual void SetEventHandler(SEEventHandler* handler) = 0;
virtual const SEEventManager& GetEventManager() const = 0;
//--------------------------------------------------------------------------------------------------
/// \brief
......
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#pragma once
#include "patient/SEPatient.h"
#include "system/equipment/anesthesiamachine/SEAnesthesiaMachine.h"
class CDM_DECL SEEventHandler
{
public:
SEEventHandler() {};
virtual ~SEEventHandler(){};
virtual void HandlePatientEvent(ePatient_Event type, bool active, const SEScalarTime* time = nullptr)=0;
virtual void HandleAnesthesiaMachineEvent(eAnesthesiaMachine_Event type, bool active, const SEScalarTime* time = nullptr) = 0;
};
\ No newline at end of file
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#include "stdafx.h"
#include "engine/SEEventManager.h"
#include "properties/SEScalarTime.h"
SEEventManager::SEEventManager(Logger* logger) : Loggable(logger)
{
Clear();
}
SEEventManager::~SEEventManager()
{
}
void SEEventManager::Clear()
{
m_EventHandler = nullptr;
m_EventState.clear();
m_EventDuration_s.clear();
}
void SEEventManager::SetEvent(eEvent type, bool active, const SEScalarTime& time)
{
bool b = false;// Default is off
if (m_EventState.find(type) != m_EventState.end())
b = m_EventState[type];
if (b == active)
return;//No Change
if (active != b)
{
m_ss.str("");
m_ss << "[Event] " << time << ", ";
if (active)
{
switch (type)
{
case eEvent::Antidiuresis:
m_ss << " Patient has Antidiuresis";
break;
case eEvent::Asystole:
m_ss << " Patient has Asystole";
break;
case eEvent::Bradycardia:
m_ss << " Patient has Bradycardia";
break;
case eEvent::Bradypnea:
m_ss << " Patient has Bradypnea";
break;
case eEvent::BrainOxygenDeficit:
m_ss << " Oxygen tension in the brain is dangerously low";
break;
case eEvent::CardiacArrest:
m_ss << " Patient has Cardiac Arrest";
break;
case eEvent::CardiogenicShock:
m_ss << " Patient has Cardiogenic Shock";
break;
case eEvent::CriticalBrainOxygenDeficit:
m_ss << " Oxygen tension in the brain is critically low";
break;
case eEvent::Dehydration:
m_ss << " Patient has entered state of Dehydration";
break;
case eEvent::Diuresis:
m_ss << " Patient has entered Diuresis";
break;
case eEvent::Fasciculation:
m_ss << "Patient has Fasciculation";
break;
case eEvent::FunctionalIncontinence:
m_ss << " Patient has involuntarily emptied their bladder";
break;
case eEvent::Hypercapnia:
m_ss << " Patient has Hypercapnia";
break;
case eEvent::Hyperglycemia:
m_ss << " Patient has Hyperglycemia";
break;
case eEvent::Hyperthermia:
m_ss << " Patient is Hyperthermic";
break;
case eEvent::Hypoglycemia:
m_ss << " Patient has Hypoglycemia";
break;
case eEvent::Hypothermia:
m_ss << " Patient is Hypothermic";
break;
case eEvent::Hypoxia:
m_ss << " Patient has Hypoxia";
break;
case eEvent::IntracranialHypertension:
m_ss << " Patient has Intracranial Hypertension";
break;
case eEvent::IntracranialHypotension:
m_ss << " Patient has Intracranial Hypotension";
break;
case eEvent::HypovolemicShock:
m_ss << " Patient is in Hypovolemic Shock";
break;
case eEvent::IrreversibleState:
m_ss << " Patient has entered irreversible state";
break;
case eEvent::Ketoacidosis:
m_ss << " Patient has Ketoacidosis";
break;
case eEvent::LacticAcidosis:
m_ss << " Patient has LacticAcidosis";
break;
case eEvent::MaximumPulmonaryVentilationRate:
m_ss << " Patient's Respiratory Driver has exceeded the maximum target pulmonary ventilation rate, setting value to the maximum allowable rate";
break;
case eEvent::MetabolicAcidosis:
m_ss << " The patient is in a state of metabolic acidosis";
break;
case eEvent::MetabolicAlkalosis:
m_ss << " The patient is in a state of metabolic alkalosis";
break;
case eEvent::MildAcuteRespiratoryDistress:
m_ss << " The patient has Mild Acute Respiratory Distress";
break;
case eEvent::ModerateAcuteRespiratoryDistress:
m_ss << " The patient has Moderate Acute Respiratory Distress";
break;
case eEvent::MyocardiumOxygenDeficit:
m_ss << " The patient's heart is not receiving enough oxygen";
break;
case eEvent::Natriuresis:
m_ss << " Patient has Natriuresis";
break;
case eEvent::NutritionDepleted:
m_ss << " Patient has depleted all nutrition in body";
break;
case eEvent::RenalHypoperfusion:
m_ss << " Patient has Renal Hypoperfusion";
break;
case eEvent::SevereAcuteRespiratoryDistress:
m_ss << " The patient has Severe Acute Respiratory Distress";
break;
case eEvent::Tachycardia:
m_ss << " Patient has Tachycardia";
break;
case eEvent::Tachypnea:
m_ss << " Patient has Tachypnea";
break;
case eEvent::Fatigue:
m_ss << "Patient has fatigue";
break;
case eEvent::StartOfCardiacCycle:
case eEvent::StartOfExhale:
case eEvent::StartOfInhale:
m_ss.str("");// make m_ss empty and nothing will be logged, this event does not need to get logged each activation
break;
// Equipment
case eEvent::AnesthesiaMachineOxygenBottleOneExhausted:
m_ss << "Anesthesia Machine Oxygen Bottle 1 has been exhausted";
break;
case eEvent::AnesthesiaMachineOxygenBottleTwoExhausted:
m_ss << "Anesthesia Machine Oxygen Bottle 2 has been exhausted";
break;
case eEvent::AnesthesiaMachineReliefValveActive:
m_ss << "Anesthesi aMachine Relief valve active - pressure exceeded";
break;
default:
m_ss << " Engine has entered state : " << eEvent_Name(type);
}
}
else
{
switch (type)
{
case eEvent::Antidiuresis:
m_ss << " Patient no longer is in Antidiuresis";
break;
case eEvent::Asystole:
m_ss << " Patient no longer is in Asystole";
break;
case eEvent::Bradycardia:
m_ss << " Patient no longer has Bradycardia";
break;
case eEvent::Bradypnea:
m_ss << " Patient no longer has Bradypnea";
break;
case eEvent::BrainOxygenDeficit:
m_ss << " Oxygen tension in the brain has increased above the danger threshold";
break;
case eEvent::CardiacArrest:
m_ss << " Patient no longer has Cardiac Arrest";
break;
case eEvent::CardiogenicShock:
m_ss << " Patient no longer has Cardiogenic Shock";
break;
case eEvent::CriticalBrainOxygenDeficit:
m_ss << " Oxygen tension in the brain has increased above the critical threshold";
break;
case eEvent::Dehydration:
m_ss << " Patient no longer is in Dehydration state";
break;
case eEvent::Diuresis:
m_ss << " Patient no longer has Diuresis";
break;
case eEvent::Fasciculation:
m_ss << "Patient no longer has fasciculations";
break;
case eEvent::FunctionalIncontinence:
m_ss << " Patient has an empty bladder";
break;
case eEvent::Hypercapnia:
m_ss << " Patient no longer has Hypercapnia";
break;
case eEvent::Hyperglycemia:
m_ss << " Patient no longer has Hyperglycemia";
break;
case eEvent::Hyperthermia:
m_ss << " Patient is no longer has Hyperthermic";
break;
case eEvent::Hypoglycemia:
m_ss << " Patient no longer has Hypoglycemia";
break;
case eEvent::Hypothermia:
m_ss << " Patient is no longer has Hypothermic";
break;
case eEvent::Hypoxia:
m_ss << " Patient no longer has Hypoxia";
break;
case eEvent::HypovolemicShock:
m_ss << " Patient is no longer in Hypovolemic Shock";
break;
case eEvent::IntracranialHypertension:
m_ss << " Patient no longer has Intracranial Hypertension";
break;
case eEvent::IntracranialHypotension:
m_ss << " Patient no longer has Intracranial Hypotension";
break;
case eEvent::IrreversibleState:
m_ss << " Patient no longer is in irreversible state?!";
break;
case eEvent::Ketoacidosis:
m_ss << " Patient no longer has Ketoacidosis";
break;
case eEvent::LacticAcidosis:
m_ss << " Patient no longer has LacticAcidosis";
break;
case eEvent::MaximumPulmonaryVentilationRate:
m_ss << " Patient's Respiratory Driver is no longer exceeding the maximum target pulmonary ventilation rate";
break;
case eEvent::MetabolicAcidosis:
m_ss << " The patient is no longer in a state of metabolic acidosis";
break;
case eEvent::MetabolicAlkalosis:
m_ss << " The patient is no longer in a state of metabolic alkalosis";
break;
case eEvent::MildAcuteRespiratoryDistress:
m_ss << " Patient no longer has a Mild Acute Respiratory Distress";
break;
case eEvent::ModerateAcuteRespiratoryDistress:
m_ss << " Patient no longer has a Moderate Acute Respiratory Distress";
break;
case eEvent::MyocardiumOxygenDeficit:
m_ss << " Patient no longer has a Myocardium Oxygen Deficit";
break;
case eEvent::Natriuresis:
m_ss << " Patient no longer has Natriuresis";
break;
case eEvent::NutritionDepleted:
m_ss << " Patient has nutrition in body";
break;
case eEvent::RenalHypoperfusion:
m_ss << " Patient no longer has Renal Hypoperfusion";
break;
case eEvent::SevereAcuteRespiratoryDistress:
m_ss << " Patient no longer has a Severe Acute Respiratory Distress";
break;
case eEvent::Tachycardia:
m_ss << " Patient no longer has Tachycardia";
break;
case eEvent::Tachypnea:
m_ss << " Patient no longer has Tachypnea";
break;
case eEvent::Fatigue:
m_ss << "Patient is no longer fatigued";
break;
case eEvent::StartOfCardiacCycle:
case eEvent::StartOfExhale:
case eEvent::StartOfInhale:
m_ss.str("");// make m_ss empty and nothing will be logged, this event does not need to get logged each activation
break;
// Equipment
case eEvent::AnesthesiaMachineOxygenBottleOneExhausted:
m_ss << "Anesthesia Machine Oxygen Bottle 1 has been replenished";
break;
case eEvent::AnesthesiaMachineOxygenBottleTwoExhausted:
m_ss << "Anesthesia Machine Oxygen Bottle 2 has been replenished";
break;
case eEvent::AnesthesiaMachineReliefValveActive:
m_ss << "Anesthesia Machine Relief valve inactive - pressure below setting";
break;
default:
m_ss << " Engine has exited state : " << eEvent_Name(type);
}
}
if (!m_ss.str().empty())
Info(m_ss);
}
m_EventState[type] = active;
m_EventDuration_s[type] = 0;
if (m_EventHandler != nullptr)
m_EventHandler->HandleEvent(type, active, &time);
}
bool SEEventManager::IsEventActive(eEvent e) const
{
auto i = m_EventState.find(e);
if (i == m_EventState.end())
return false;
return i->second;
}
double SEEventManager::GetEventDuration(eEvent e, const TimeUnit& unit) const
{
auto i = m_EventDuration_s.find(e);
if (i == m_EventDuration_s.end())
return 0;
return Convert(i->second, TimeUnit::s, unit);
}
void SEEventManager::OverrideActiveState(eEvent e, const SEScalarTime& duration)
{
m_EventState[e] = true;
m_EventDuration_s[e] = duration.GetValue(TimeUnit::s);
}
void SEEventManager::UpdateEvents(const SEScalarTime& timeStep)
{
for (auto& itr : m_EventDuration_s)
itr.second += timeStep.GetValue(TimeUnit::s);
}
void SEEventManager::ForwardEvents(SEEventHandler* handler) const
{
m_EventHandler = handler;
}
\ No newline at end of file
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#pragma once
// Keep enums in sync with appropriate schema/cdm/Event.proto file !!
enum class eEvent
{
Antidiuresis = 0,
Asystole = 1,
Bradycardia = 2,
Bradypnea = 3,
BrainOxygenDeficit = 4,
CardiacArrest = 5,
CardiogenicShock = 6,
CriticalBrainOxygenDeficit = 7,
Dehydration = 8,
Diuresis = 9,
Fasciculation = 10,
Fatigue = 11,
FunctionalIncontinence = 12,
Hypercapnia = 13,
Hyperglycemia = 14,
Hyperthermia = 15,
Hypoglycemia = 16,
Hypothermia = 17,
Hypoxia = 18,
HypovolemicShock = 19,
IntracranialHypertension = 20,
IntracranialHypotension = 21,
IrreversibleState = 22,
Ketoacidosis = 23,
LacticAcidosis = 24,
MaximumPulmonaryVentilationRate = 25,
MetabolicAcidosis = 26,
MetabolicAlkalosis = 27,
MildAcuteRespiratoryDistress = 28,
ModerateAcuteRespiratoryDistress = 29,
MyocardiumOxygenDeficit = 30,
Natriuresis = 31,
NutritionDepleted = 32,
RenalHypoperfusion = 33,
RespiratoryAcidosis = 34,
RespiratoryAlkalosis = 35,
StartOfCardiacCycle = 36,
StartOfExhale = 37,
StartOfInhale = 38,
SevereAcuteRespiratoryDistress = 39,
Tachycardia = 40,
Tachypnea = 41,
// Equipment
AnesthesiaMachineOxygenBottleOneExhausted = 1000,
AnesthesiaMachineOxygenBottleTwoExhausted = 1001,
AnesthesiaMachineReliefValveActive = 1002
};
extern const std::string& eEvent_Name(eEvent m);
class CDM_DECL SEEventHandler
{
public:
SEEventHandler() {};
virtual ~SEEventHandler() {};
virtual void HandleEvent(eEvent type, bool active, const SEScalarTime* time = nullptr) = 0;
};
class CDM_DECL SEEventManager : public Loggable
{
public:
SEEventManager(Logger* logger);
virtual ~SEEventManager();
void Clear();
// Essentially a load, this will set the state to active and set its duration
virtual void OverrideActiveState(eEvent state, const SEScalarTime& duration);
virtual const std::map<eEvent, bool>& GetEventStates() const { return m_EventState; }
virtual void SetEvent(eEvent e, bool active, const SEScalarTime& time);
virtual bool IsEventActive(eEvent e) const;
virtual double GetEventDuration(eEvent e, const TimeUnit& unit) const;
virtual void UpdateEvents(const SEScalarTime& timeStep);
/** @name ForwardEvents
* @brief - Set a callback class to invoke when any event changes
* @details - Note that the handler callback can and will be called in the middle of a time step
* So system and compartment objects may not be completely up to date when called.
* Use the PhysiologyEngineInterface::SetEventHandler to ensure that all engine
* data is up to date at the time the callback is invoked
*/
virtual void ForwardEvents(SEEventHandler* handler) const;
virtual SEEventHandler* GetEventHandler() { return m_EventHandler; }
protected:
std::stringstream m_ss;
mutable SEEventHandler* m_EventHandler;
std::map<eEvent, bool> m_EventState;
std::map<eEvent, double> m_EventDuration_s;
};
......@@ -24,6 +24,7 @@ set( IO_PB_CDM_FILES ${_cur_dir}/PBUtils.h
${_cur_dir}/PBEngine.cpp
${_cur_dir}/PBEngineEnums.cpp
${_cur_dir}/PBEnums.cpp
${_cur_dir}/PBEvents.cpp
${_cur_dir}/PBEnvironment.h
${_cur_dir}/PBEnvironment.cpp
${_cur_dir}/PBEnvironmentActions.h
......
......@@ -50,21 +50,6 @@ void PBAnesthesiaMachine::Serialize(const cdm::AnesthesiaMachineData& src, SEAne
if (src.has_oxygenbottletwo())
PBAnesthesiaMachine::Load(src.oxygenbottletwo(), dst.GetOxygenBottleTwo());
SEScalarTime time;
for (int i = 0; i < src.activeevent_size(); i++)
{
const cdm::AnesthesiaMachineData::ActiveEventData& e = src.activeevent(i);
if (e.has_duration())
PBProperty::Load(e.duration(), time);
{
dst.m_ss << "Active AnesthesiaMachine event " << e.event() << " does not have time associated with it";
dst.Warning(dst.m_ss);
time.SetValue(0, TimeUnit::s);
}
dst.m_EventState[(eAnesthesiaMachine_Event)e.event()] = true;
dst.m_EventDuration_s[(eAnesthesiaMachine_Event)e.event()] = time.GetValue(TimeUnit::s);
}
dst.StateChange();
}
......@@ -103,24 +88,6 @@ void PBAnesthesiaMachine::Serialize(const SEAnesthesiaMachine& src, cdm::Anesthe
dst.set_allocated_oxygenbottleone(PBAnesthesiaMachine::Unload(*src.m_OxygenBottleOne));
if (src.HasOxygenBottleTwo())
dst.set_allocated_oxygenbottletwo(PBAnesthesiaMachine::Unload(*src.m_OxygenBottleTwo));
SEScalarTime time;
for (auto itr : src.m_EventState)
{
if (!itr.second)
continue;
auto it2 = src.m_EventDuration_s.find(itr.first);
if (it2 == src.m_EventDuration_s.end())// This should not happen...
time.SetValue(0, TimeUnit::s);
else
time.SetValue(it2->second, TimeUnit::s);
cdm::AnesthesiaMachineData_ActiveEventData* eData = dst.add_activeevent();
eData->set_event((cdm::eAnesthesiaMachine_Event)itr.first);
eData->set_allocated_duration(PBProperty::Unload(time));
}
}
void PBAnesthesiaMachine::Load(const cdm::AnesthesiaMachineChamberData& src, SEAnesthesiaMachineChamber& dst)
......
......@@ -5,11 +5,6 @@
#include "bind/cpp/cdm/AnesthesiaMachine.pb.h"
#include "system/equipment/anesthesiamachine/SEAnesthesiaMachine.h"
const std::string& eAnesthesiaMachine_Event_Name(eAnesthesiaMachine_Event m)
{
return cdm::eAnesthesiaMachine_Event_Name((cdm::eAnesthesiaMachine_Event)m);
}
const std::string& eAnesthesiaMachine_OxygenSource_Name(eAnesthesiaMachine_OxygenSource m)
{
return cdm::AnesthesiaMachineData::eOxygenSource_Name((cdm::AnesthesiaMachineData::eOxygenSource)m);
......
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#include "stdafx.h"
#include "bind/cpp/cdm/Events.pb.h"
#include "engine/SEEventManager.h"
#include "utils/FileUtils.h"
const std::string& eEvent_Name(eEvent m)
{
return cdm::eEvent_Name((cdm::eEvent)m);
}
\ No newline at end of file
......@@ -75,21 +75,6 @@ void PBPatient::Serialize(const cdm::PatientData& src, SEPatient& dst)
PBProperty::Load(src.totallungcapacity(), dst.GetTotalLungCapacity());
if (src.has_vitalcapacity())
PBProperty::Load(src.vitalcapacity(), dst.GetVitalCapacity());
SEScalarTime time;
for (int i = 0; i < src.activeevent_size(); i++)
{
const cdm::PatientData::ActiveEventData& e = src.activeevent(i);
if (e.has_duration())
PBProperty::Load(e.duration(), time);
{
dst.m_ss << "Active Patient event " << cdm::ePatient_Event_Name(e.event()) << " does not have time associated with it";
dst.Warning(dst.m_ss);
time.SetValue(0, TimeUnit::s);
}
dst.m_EventState[(ePatient_Event)e.event()] = true;
dst.m_EventDuration_s[(ePatient_Event)e.event()] = time.GetValue(TimeUnit::s);
}
}
cdm::PatientData* PBPatient::Unload(const SEPatient& src)
......@@ -159,24 +144,6 @@ void PBPatient::Serialize(const SEPatient& src, cdm::PatientData& dst)
dst.set_allocated_totallungcapacity(PBProperty::Unload(*src.m_TotalLungCapacity));
if (src.HasVitalCapacity())
dst.set_allocated_vitalcapacity(PBProperty::Unload(*src.m_VitalCapacity));
SEScalarTime time;
for (auto itr : src.m_EventState)
{