318 lines
11 KiB
C++
Executable File
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
|