Files
qt5-legatus-legacy/Lts/Services/AreaEffectSimulation/effector_state_machine.cpp
T
2026-08-13 18:33:10 +02:00

318 lines
11 KiB
C++
Executable File

// /**
// * Object class for EffectorStateMachine
// * $Id$
// * $HeadURL$
// * $Author$
// */
#include "effector_state_machine.h"
#include "settings.h"
#include <QDateTime>
#include <QDebug>
#include <QMetaEnum>
#include <QRandomGenerator>
namespace AreaEffectSimulation
{
EffectorStateMachine::EffectorStateMachine(AreaEffectSimulation::AesEffectorState initialState, QObject *parent)
: QObject(parent)
, m_currentState(initialState)
, m_logger(getLogger(QStringLiteral("EffectorStateMachine")))
{
}
EffectorStateMachine::~EffectorStateMachine() { stopAllTimer(); }
int EffectorStateMachine::intervalFire()
{
DEBUG_LOG(m_logger) << "intervalFire";
return QRandomGenerator::global()->bounded(Settings::getEffectorIntervalFireMin(), Settings::getEffectorIntervalFireMax() + 1);
}
int EffectorStateMachine::intervalReportFired()
{
DEBUG_LOG(m_logger) << "intervalReportFired";
return QRandomGenerator::global()->bounded(Settings::getEffectorIntervalReportFiredMin(), Settings::getEffectorIntervalReportFiredMax() + 1);
}
int EffectorStateMachine::intervalReportFireReadiness()
{
DEBUG_LOG(m_logger) << "intervalReportFireReadiness";
return QRandomGenerator::global()->bounded(m_intervalReportFireReadinessMin, m_intervalReportFireReadinessMax + 1);
}
int EffectorStateMachine::intervalInitialFireReadiness()
{
DEBUG_LOG(m_logger) << "intervalInitialFireReadiness";
return QRandomGenerator::global()->bounded(Settings::getEffectorInitialReportFireReadinessMin(), Settings::getEffectorInitialReportFireReadinessMax() + 1);
}
void EffectorStateMachine::init()
{
DEBUG_LOG(m_logger) << "EffectorStateMachine::init";
emit logMessage(
QStringLiteral("intervalFire min=%1 max=%2, intervalReportFired min=%3 max=%4, intervalReportFireReadiness min=%5 max=%6 , initialFireReadiness min=%7 max=%8")
.arg(
QString::number(Settings::getEffectorIntervalFireMin()),
QString::number(Settings::getEffectorIntervalFireMax()),
QString::number(Settings::getEffectorIntervalReportFiredMin()),
QString::number(Settings::getEffectorIntervalReportFiredMax()),
QString::number(Settings::getEffectorIntervalReportFireReadinessMin()),
QString::number(Settings::getEffectorIntervalReportFireReadinessMax()),
QString::number(Settings::getEffectorInitialReportFireReadinessMin()),
QString::number(Settings::getEffectorInitialReportFireReadinessMax())));
m_intervalReportFireReadinessMin = Settings::getEffectorIntervalReportFireReadinessMin();
m_intervalReportFireReadinessMax = Settings::getEffectorIntervalReportFireReadinessMax();
if (Settings::getEffectorIntervalFireMin() >= 0)
connect(&m_timerFire, &QTimer::timeout, this, &EffectorStateMachine::fire);
if (Settings::getEffectorIntervalReportFiredMin() >= 0)
connect(&m_timerReportFired, &QTimer::timeout, this, &EffectorStateMachine::reportFired);
if (Settings::getEffectorIntervalReportFireReadinessMin() >= 0)
connect(&m_timerReportFireReadiness, &QTimer::timeout, this, &EffectorStateMachine::reportFireReadiness);
if (Settings::getEffectorInitialReportFireReadinessMin() >= 0)
{
connect(&m_timerInitialFireReadiness, &QTimer::timeout, this, &EffectorStateMachine::reportFireReadiness);
}
}
void EffectorStateMachine::stopAllTimer()
{
m_timerFire.stop();
m_timerReportFired.stop();
m_timerReportFireReadiness.stop();
m_timerInitialFireReadiness.stop();
}
QString EffectorStateMachine::getStateStr(AreaEffectSimulation::AesEffectorState state)
{
switch (state.underlying())
{
case AreaEffectSimulation::AesEffectorState::EsNotReadyToFire:
return QStringLiteral("EstNotReadyToFire");
case AreaEffectSimulation::AesEffectorState::EsReadyToFire:
return QStringLiteral("EstReadyToFire");
case AreaEffectSimulation::AesEffectorState::EsReceivedOrder:
return QStringLiteral("EstReceivedOrder");
case AreaEffectSimulation::AesEffectorState::EsReportedFired:
return QStringLiteral("EstReportedFired");
case AreaEffectSimulation::AesEffectorState::EsFired:
return QStringLiteral("EstFired");
}
return QString{};
}
bool EffectorStateMachine::overrideReportFireReadinessMinMax(int newMin, int newMax)
{
DEBUG_LOG(m_logger) << "Override ReadinessMinMax min: " << newMin << " max: " << newMax;
m_intervalReportFireReadinessMin = newMin;
m_intervalReportFireReadinessMax = newMax;
return true;
}
bool EffectorStateMachine::resetReportFireReadinessMinMax()
{
DEBUG_LOG(m_logger) << "Reset ReadinessMinMax min:" << Settings::getEffectorIntervalReportFireReadinessMin()
<< " max: " << Settings::getEffectorIntervalReportFireReadinessMax();
m_intervalReportFireReadinessMin = Settings::getEffectorIntervalReportFireReadinessMin();
m_intervalReportFireReadinessMax = Settings::getEffectorIntervalReportFireReadinessMax();
return true;
}
bool EffectorStateMachine::reportNotFireReadiness()
{
AreaEffectSimulation::AesEffectorState newState = AreaEffectSimulation::AesEffectorState::EsNotReadyToFire;
QString oldStateStr = getStateStr(m_currentState);
QString newStateStr = getStateStr(newState);
if (m_currentState == newState)
{
emit logMessage(QStringLiteral("Same State from %1 -> %2").arg(oldStateStr, newStateStr));
return false;
}
if (m_currentState == AreaEffectSimulation::AesEffectorState::EsReportedFired)
{
stopAllTimer();
m_currentState = AreaEffectSimulation::AesEffectorState::EsNotReadyToFire;
if (!m_initialFireReadinessDone && (Settings::getEffectorInitialReportFireReadinessMin() >= 0))
{
m_timerInitialFireReadiness.setInterval(intervalInitialFireReadiness());
m_timerInitialFireReadiness.start();
}
}
else
{
emit logMessage(QStringLiteral("No Statechange possible from %1 -> %2").arg(oldStateStr, newStateStr));
return false;
}
QString timestamp = QDateTime::currentDateTime().toString(QStringLiteral("hh:mm:ss"));
emit logMessage(QStringLiteral("[%1] change effect state: %2 -> %3").arg(timestamp, oldStateStr, newStateStr));
DEBUG_LOG(m_logger) << QStringLiteral("[%1] change effect state: %2 -> %3").arg(timestamp, oldStateStr, newStateStr);
emit signalNotReadyToFire();
return true;
}
bool EffectorStateMachine::reportFireReadiness()
{
AreaEffectSimulation::AesEffectorState newState = AreaEffectSimulation::AesEffectorState::EsReadyToFire;
QString oldStateStr = getStateStr(m_currentState);
QString newStateStr = getStateStr(newState);
if (m_currentState == newState)
{
emit logMessage(QStringLiteral("Same State from %1 -> %2").arg(oldStateStr, newStateStr));
return false;
}
if (m_emptyCharge)
{
emit logMessage(QStringLiteral("No Statechange possible from %1 -> %2 because the charge is empty").arg(oldStateStr, newStateStr));
return false;
}
if (m_currentState == AreaEffectSimulation::AesEffectorState::EsReportedFired || m_currentState == AreaEffectSimulation::AesEffectorState::EsNotReadyToFire)
{
stopAllTimer();
m_initialFireReadinessDone = true;
m_currentState = newState;
}
else
{
emit logMessage(QStringLiteral("No Statechange possible from %1 -> %2").arg(oldStateStr, newStateStr));
return false;
}
QString timestamp = QDateTime::currentDateTime().toString(QStringLiteral("hh:mm:ss"));
emit logMessage(QStringLiteral("[%1] change effect state: %2 -> %3").arg(timestamp, oldStateStr, newStateStr));
emit signalReadyToFire();
return true;
}
bool EffectorStateMachine::fireOrder()
{
DEBUG_LOG(m_logger) << "fireOrder";
AreaEffectSimulation::AesEffectorState newState = AreaEffectSimulation::AesEffectorState::EsReceivedOrder;
QString oldStateStr = getStateStr(m_currentState);
QString newStateStr = getStateStr(newState);
if (m_currentState == newState)
{
emit logMessage(QStringLiteral("Same State from %1 -> %2").arg(oldStateStr, newStateStr));
DEBUG_LOG(m_logger) << QStringLiteral("Same State from %1 -> %2").arg(oldStateStr, newStateStr);
return false;
}
if (m_currentState == AreaEffectSimulation::AesEffectorState::EsReadyToFire)
{
stopAllTimer();
m_currentState = newState;
if (Settings::getEffectorIntervalFireMin() >= 0)
{
emit logMessage(QStringLiteral("m_timerFire.start()"));
DEBUG_LOG(m_logger) << QStringLiteral("m_timerFire.start()");
m_timerFire.setInterval(intervalFire());
m_timerFire.start();
}
}
else
{
emit logMessage(QStringLiteral("No Statechange possible from %1 -> %2").arg(oldStateStr, newStateStr));
DEBUG_LOG(m_logger) << QStringLiteral("No Statechange possible from %1 -> %2").arg(oldStateStr, newStateStr);
return false;
}
QString timestamp = QDateTime::currentDateTime().toString(QStringLiteral("hh:mm:ss"));
emit logMessage(QStringLiteral("[%1] change effect state: %2 -> %3").arg(timestamp, oldStateStr, newStateStr));
DEBUG_LOG(m_logger) << QStringLiteral("[%1] change effect state: %2 -> %3").arg(timestamp, oldStateStr, newStateStr);
emit signalReceivedOrder();
return true;
}
bool EffectorStateMachine::fire()
{
AreaEffectSimulation::AesEffectorState newState = AreaEffectSimulation::AesEffectorState::EsFired;
QString oldStateStr = getStateStr(m_currentState);
QString newStateStr = getStateStr(newState);
if (m_currentState == newState)
{
emit logMessage(QStringLiteral("Same State from %1 -> %2").arg(oldStateStr, newStateStr));
return false;
}
if (m_currentState == AreaEffectSimulation::AesEffectorState::EsReadyToFire || m_currentState == AreaEffectSimulation::AesEffectorState::EsReceivedOrder)
{
stopAllTimer();
m_currentState = newState;
if (Settings::getEffectorIntervalReportFiredMin() >= 0)
{
emit logMessage(QStringLiteral("m_timerReportFired.start()"));
m_timerReportFired.setInterval(intervalReportFired());
m_timerReportFired.start();
}
}
else
{
emit logMessage(QStringLiteral("No Statechange possible from %1 -> %2").arg(oldStateStr, newStateStr));
return false;
}
QString timestamp = QDateTime::currentDateTime().toString(QStringLiteral("hh:mm:ss"));
emit logMessage(QStringLiteral("[%1] change effect state: %2 -> %3").arg(timestamp, oldStateStr, newStateStr));
emit signalFired();
return true;
}
bool EffectorStateMachine::reportFired()
{
AreaEffectSimulation::AesEffectorState newState = AreaEffectSimulation::AesEffectorState::EsReportedFired;
QString oldStateStr = getStateStr(m_currentState);
QString newStateStr = getStateStr(newState);
if (m_currentState == newState)
{
emit logMessage(QStringLiteral("Same State from %1 -> %2").arg(oldStateStr, newStateStr));
return false;
}
if (m_currentState == AreaEffectSimulation::AesEffectorState::EsFired)
{
stopAllTimer();
m_currentState = newState;
if ((Settings::getEffectorIntervalReportFireReadinessMin() >= 0) && !m_emptyCharge)
{
emit logMessage(QStringLiteral("m_timerReportFireReadiness.start()"));
m_timerReportFireReadiness.setInterval(intervalReportFireReadiness());
m_timerReportFireReadiness.start();
}
else
{
if (!m_emptyCharge)
emit logMessage(QStringLiteral("Empty charge: dont't start TimerReportFireReadiness"));
}
}
else
{
emit logMessage(QStringLiteral("No Statechange possible from %1 -> %2").arg(oldStateStr, newStateStr));
return false;
}
QString timestamp = QDateTime::currentDateTime().toString(QStringLiteral("hh:mm:ss"));
emit logMessage(QStringLiteral("[%1] change effect state: %2 -> %3").arg(timestamp, oldStateStr, newStateStr));
emit signalReportedFired();
return true;
}
} // namespace AreaEffectSimulation