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

247 lines
8.5 KiB
C++
Executable File

/**
* Handler for all exercise objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-03
*/
#include "handler_effect_show.h"
#include "handler_effect_show_vehicle_status.h"
#include "handler_tab_data.h"
#include "handler_mdm_data.h"
#include "object_effect_show_vehicle_status.h"
#include "esm_db.h"
#include "initialization.h"
#include <QCoreApplication>
namespace EffectShowManagement
{
//=============================================================================
HandlerEffectShowVehicleStatus::HandlerEffectShowVehicleStatus(Initialization *mainHandler,
QObject *parent)
: QObject(parent)
, m_mainHandler(mainHandler)
, m_logger(getLogger("HandlerEffectShowVehicleStatus"))
{
m_timerVehicleStatus.setSingleShot(true);
}
//=============================================================================
HandlerEffectShowVehicleStatus::~HandlerEffectShowVehicleStatus()
{
qDeleteAll(m_effectShowVehicleStatusObjMap);
}
//=============================================================================
bool HandlerEffectShowVehicleStatus::init()
{
DEBUG_LOG(m_logger) << "Begin HandlerEffectShowVehicleStatus";
// create EffectShowVehicleStatuss objects
auto cbEsvs = [this] (const Database::EsmEffectShowVehicleStatus &data)
{
ObjectEffectShowVehicleStatus *ifs(new ObjectEffectShowVehicleStatus(m_mainHandler));
ifs->set(data);
DEBUG_LOG(m_logger) << "HandlerEffectShowVehicleStatus::init getParticipantId :" << ifs->getParticipantId();
m_effectShowVehicleStatusObjMap.insert(ifs->getParticipantId(), ifs);
};
if (!m_mainHandler->db()->select(cbEsvs))
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
// check status from data base after statusRequestInterval
QTimer::singleShot(HandlerEffectShowVehicleStatus::delayAfterStart, this, &HandlerEffectShowVehicleStatus::onStatusRequest);
// provision of timer for timeout vehicle status
connect(&m_timerVehicleStatus, &QTimer::timeout, this, &HandlerEffectShowVehicleStatus::onTimeoutVehicleStatus);
m_timerVehicleStatus.setSingleShot(true);
if (m_effectShowVehicleStatusObjMap.size() != 0)
onTimeoutVehicleStatus();
DEBUG_LOG(m_logger) << "m_effectShowVehicleStatusObjMap.size() = " << m_effectShowVehicleStatusObjMap.size();
return true;
}
//=============================================================================
int HandlerEffectShowVehicleStatus::getNumOfEffectShowActors() const
{
int res = 0;
auto it = m_effectShowVehicleStatusObjMap.begin();
while (it != m_effectShowVehicleStatusObjMap.end())
{
if (it.value()->getOperational())
res++;
}
return res;
}
//=============================================================================
int HandlerEffectShowVehicleStatus::getIdOfEffectShowActor(int seq)
{
int num = 0;
auto it = m_effectShowVehicleStatusObjMap.begin();
while (it != m_effectShowVehicleStatusObjMap.end())
{
if (it.value()->getOperational())
{
if (seq == num) return it.value()->getIdOfEffectShowActor();
num++;
}
}
return -1; // illegal seq-number
}
//=============================================================================
bool HandlerEffectShowVehicleStatus::isOperational(int id) const
{
for (auto it = m_effectShowVehicleStatusObjMap.begin();
it != m_effectShowVehicleStatusObjMap.end(); ++it)
{
if (it.value()->getIdOfEffectShowActor() == id)
return it.value()->getOperational();
}
return false;
}
//=============================================================================
void HandlerEffectShowVehicleStatus::vehicleStatusReceived(const ConvertFromTab::VehicleStatus_t &vehicleStatus)
{
DEBUG_LOG(m_logger) << "vehicleStatusReceived: " << vehicleStatus.equipmentNumber
<< ' ' << vehicleStatus.timestamp << ' ' << m_mainHandler->dds()->currentPartitionTime();
HandlerPpmData::Participant_t actor = m_mainHandler->handlerPpmData()->getIdAndNameOfEffectShowActor(vehicleStatus.equipmentNumber);
if (actor.id == -1)
return;
ObjectEffectShowVehicleStatus *ifs = m_effectShowVehicleStatusObjMap.value(actor.id);
if (ifs == nullptr)
{
// create new object
ifs = new ObjectEffectShowVehicleStatus(m_mainHandler);
ifs->set(vehicleStatus);
ifs->set(actor);
ifs->createObject(); // write into db and publish data
m_effectShowVehicleStatusObjMap.insert(ifs->getParticipantId(), ifs); // insert object into map
}
else
{
// update object
ifs->set(vehicleStatus);
ifs->set(actor);
ifs->updateObject(); // update db and publish data
}
onTimeoutVehicleStatus();
}
//=============================================================================
void HandlerEffectShowVehicleStatus::effectShowActorChanged(const HandlerPpmData::Participant_t &data, DataModification modType)
{
DEBUG_LOG(m_logger) << "onEffectShowActorChanged: " << data.equipmentNumber;
auto it = m_effectShowVehicleStatusObjMap.find(data.id);
if (it == m_effectShowVehicleStatusObjMap.end()) return; // participant not allocated to any order
if (modType == DataModification::eRemoved)
{
it.value()->removeObject(); // remove vehicle status object
}
else
{
it.value()->set(data);
it.value()->updateObject(); // update and publish Object
}
}
//=============================================================================
void HandlerEffectShowVehicleStatus::onStatusRequest()
{
qint64 currentTime = m_mainHandler->dds()->currentPartitionTime();
if (currentTime == 0)
{
QTimer::singleShot(HandlerEffectShowVehicleStatus::statusRequestInterval, this, &HandlerEffectShowVehicleStatus::onStatusRequest);
return; // wait for the clock
}
if (m_statusRequest.size() == 0)
{
// check timestamp after init() one time
for (auto it = m_effectShowVehicleStatusObjMap.begin(); it != m_effectShowVehicleStatusObjMap.end(); ++it)
{
if ((currentTime - it.value()->getTimestamp()) > HandlerEffectShowVehicleStatus::statusTimeout)
{
it.value()->setOperational(false); // reset operational status
m_statusRequest.append(it.value()->getParticipantId()); // order status request
}
}
}
if (m_statusRequest.size() != 0)
{
// sent status request
int equipmentNumber = m_statusRequest[m_statusRequest.size() - 1];
HandlerPpmData::Participant_t actor = m_mainHandler->handlerPpmData()->getIdAndNameOfEffectShowActor(equipmentNumber);
auto it = m_effectShowVehicleStatusObjMap.find(actor.id);
if (it != m_effectShowVehicleStatusObjMap.end())
{
DEBUG_LOG(m_logger) << "Status Request equipment number: " << equipmentNumber << ' ' << it.value()->getIdOfEffectShowActor();
m_mainHandler->handlerTabData()->effectShowVehicleStatusRequest(equipmentNumber, it.value()->getIdOfEffectShowActor());
}
// remove request order
m_statusRequest.removeLast();
}
// activate timer, if further vehicle status requests to be done
if (m_statusRequest.size() != 0)
QTimer::singleShot(HandlerEffectShowVehicleStatus::statusRequestInterval, this, &HandlerEffectShowVehicleStatus::onStatusRequest);
}
//=============================================================================
void HandlerEffectShowVehicleStatus::onTimeoutVehicleStatus()
{
if (m_timerVehicleStatus.isActive())
return; // timeout already active
qint64 currentTime = m_mainHandler->dds()->currentPartitionTime();
if (currentTime == 0)
{
m_timerVehicleStatus.start(HandlerEffectShowVehicleStatus::delayAfterStart);
return; // wait for partition time
}
bool activateTimer = false;
qint64 maxAge = 0;
// determine the next vehicle status for timeout observation
for (auto it = m_effectShowVehicleStatusObjMap.begin(); it != m_effectShowVehicleStatusObjMap.end(); ++it)
{
if (it.value()->getOperational())
{
qint64 age = currentTime - it.value()->getTimestamp();
DEBUG_LOG(m_logger) << currentTime << ' ' << it.value()->getTimestamp();
if ((age + 1000) >= HandlerEffectShowVehicleStatus::statusTimeout)
{
it.value()->setOperational(false); // reset operational status
}
else
{
activateTimer = true;
if (age > maxAge)
maxAge = age;
}
}
}
// activate timer for timeout observation, if needed
if (activateTimer)
m_timerVehicleStatus.start(HandlerEffectShowVehicleStatus::statusTimeout - maxAge);
DEBUG_LOG(m_logger) << "onTimeoutVehicleStatus(): " << activateTimer << ' ' << maxAge;
}
} // Namespace EffectShowManagement