Files
qt5-legatus-legacy/Lts/Proxies/TrainingAreaBase/recv_from_dds_aes.h
T
2026-08-13 18:33:10 +02:00

406 lines
16 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Aes Handler for TetraRadioProxy
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-07-12
*/
#pragma once
#include <QObject>
#include <QMap>
#include <QSet>
#include <QTimer>
#include <memory>
#include <unordered_map>
#include <AreaEffectSimulation/aes_dtc.h>
#include <ProjectDataManagement/pdm_dtc.h>
#include "pdm_handler.h"
#include "tab_db.h"
#include "logger.h"
#include "send_to_tab.h"
#include "training_area_telegrams.h"
namespace TrainingAreaBase
{
class DatabaseInterface;
class MainHandler;
class PositionHandler;
class SendCesHitRequest;
class AesStateHandler
{
public:
explicit AesStateHandler(MainHandler *mainHandler);
bool init();
int createAesTetraId(int aesDdsId, bool &alreadyExists);
int getAesTetraId(int aesDdsId) const
{
return m_ddsId2TetraId.value(aesDdsId);
}
int getAesDdsId(int aesTetraId) const
{
return m_tetraId2ddsId.value(aesTetraId);
}
// we assume, that aesDdsId and aesTetraId are correct
bool update(int aesDdsId, int aesTetraId, bool bSentToTetra);
bool isAlreadySentToTetra(int aesDdsId) const
{
return m_aesInTetraAvailable.contains(aesDdsId);
}
private:
// must be in sync ...
QMap<int, int> m_tetraId2ddsId;
QMap<int, int> m_ddsId2TetraId;
QSet<int> m_aesInTetraAvailable;
std::shared_ptr<DatabaseInterface> m_dbInterface;
int m_exerciseId;
LOGGER_T m_logger;
};
/**
* Listen on Aes Topics and create appropriate Tetra-Telegrams (current XDR-Telegrams)
* Make sure to assign a proper id and only publish aes which needs to go to tetra
*/
class RecvFromDdsAes : public QObject
{
Q_OBJECT
public:
RecvFromDdsAes(MainHandler *mainHandler,
const std::shared_ptr<SendToTab> &txCallback,
QObject *parent = nullptr);
~RecvFromDdsAes();
bool init();
std::shared_ptr<const AesStateHandler> aesStateHandler() const
{
return m_aesStateHandler;
}
int ddsIdFromTetraId(int aesTetraId) const
{
return m_aesStateHandler->getAesDdsId(aesTetraId);
}
int tetraIdFromDdsId(int aesId) const
{
return m_aesStateHandler->getAesTetraId(aesId);
}
int aesChargeId(int aesId) const;
TetraIcd::AreaEffectSimulationType aesTypeFromId(int aesId) const;
bool sendSingleFireSMArt(const SendCesHitRequest &request);
const QVector<TetraIcd::TrainingAreaTelegram*> sentAesTelegrams() const
{
return m_sentAesTelegrams;
}
void resetAllDusMines();
// [GUEZE-3469] Funktionsraum dekontaminiert faelschlicherweise:
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> dtcAes() const { return m_dtcAes;} ///< Pointer to DTC AreaEffectSimulation interface object
private:
template<typename T>
void handleEffectSimulation(const T &data, DataModification modType, TetraIcd::AreaEffectSimulationType aesType);
/*!
*\details Save all central area effect siumulations ´, dont send to tetra, needed for CesHitRequest
*/
template<typename T>
void fillCentralChangesTable(const T &data);
template <typename T>
void handleSendToTetra(const T &data, TetraIcd::AreaEffectSimulationType aesType);
void onAirSupportImpactChanged(const AreaEffectSimulation::AirSupportImpact &data, DataModification modType);
void onBcContaminationChanged(const AreaEffectSimulation::BCContamination &data, DataModification modType);
void onExplosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType);
void onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType);
void onMineAreaChanged(const AreaEffectSimulation::MineArea &data, DataModification modType);
void onNContaminationChanged(const AreaEffectSimulation::NContamination &data, DataModification modType);
void onFunctionalAreaChanged(const AreaEffectSimulation::FunctionalArea &data, DataModification modType);
void onTechnicalAreaChanged(const AreaEffectSimulation::TechnicalArea &data, DataModification modType);
void onTriggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType);
void onDusMineStateChanged(const AreaEffectSimulation::DusMineState &data, DataModification modType);
void onDusSingleMineChanged(const AreaEffectSimulation::DusSingleMine &data, DataModification modType);
void onGasPipeChanged(const AreaEffectSimulation::GasPipe &data, DataModification modType);
void onBoobyTrapChanged(const AreaEffectSimulation::BoobyTrap &data, DataModification modType);
void onOffRouteMineChanged(const AreaEffectSimulation::OffRouteMine &data, DataModification modType);
void onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, DataModification modType);
void onEffectsChanged(const AreaEffectSimulation::Effects &data, DataModification modType);
void sendCreateEffectSimulation(const AreaEffectSimulation::AirSupportImpact &aes, int aesTetraId);
void sendCreateEffectSimulation(const AreaEffectSimulation::BCContamination &aes, int aesTetraId);
void sendCreateEffectSimulation(const AreaEffectSimulation::ExplosionArea &aes, int aesTetraId);
void sendCreateEffectSimulation(const AreaEffectSimulation::ExplosionCluster &aes, int aesTetraId);
void sendCreateEffectSimulation(const AreaEffectSimulation::ExplosionSingle &aes, int aesTetraId, int equipmentNumber = 0);
void sendCreateEffectSimulation(const AreaEffectSimulation::MineArea &aes, int aesTetraId);
void sendCreateEffectSimulation(const AreaEffectSimulation::NContamination &aes, int aesTetraId);
void sendCreateEffectSimulation(const AreaEffectSimulation::FunctionalArea &aes, int aesTetraId);
void sendCreateEffectSimulation(const AreaEffectSimulation::TechnicalArea &aes, int aesTetraId);
void sendCreateEffectSimulation(const AreaEffectSimulation::DusSingleMine &aes, int aesTetraId);
void sendCreateEffectSimulation(const AreaEffectSimulation::GasPipe &aes, int aesTetraId);
void sendModifyEffectSimulationName(TetraIcd::AreaEffectSimulationType aesType, int aesTetraId, const std::string &name, int aesId);
void sendRemoveEffectSimulation(TetraIcd::AreaEffectSimulationType aesType, int aesDdsId);
void sendPauseEffectSimulation(int aesDdsId);
template<typename T>
void sendResumeEffectSimulation(const T &)
{
static_assert(std::is_base_of<AreaEffectSimulation::AesItem, T>::value, "Given type for sendResumeEffectSimulation is not an aes item!");
}
// If you to do anything special for type X in dataChanged, do it here
void doSpecialization(const AreaEffectSimulation::ExplosionArea &data, std::unordered_map<int, AreaEffectSimulation::ExplosionArea> &cont)
{
cont[data.id()].remainExplosionNumber(data.remainExplosionNumber());
}
template<typename T>
void doSpecialization(const T &data, std::unordered_map<int, T> &cont)
{
Q_UNUSED(data);
Q_UNUSED(cont);
}
template<typename T>
bool dataChanged(const T &data, std::unordered_map<int, T> &cont, bool &onlyNameChanged)
{
onlyNameChanged = false;
auto it = cont.find(data.id());
T dataTmp(data);
dataTmp.sampleTime(0);
if (it == cont.end())
{
cont.emplace(std::make_pair(data.id(), std::move(dataTmp)));
DEBUG_LOG(m_logger) << "new AES Item: " << data;
return true;
}
// do not check AES state, it is handled beforehand
it->second.effectStateId(data.effectStateId());
// for Explosion Area we have to always save the remainExplosionNumber value
doSpecialization(data, cont);
if (it->second == dataTmp)
{
DEBUG_LOG(m_logger) << "nothing changed for AES Item: " << data;
return false;
}
// check if only name changed
T tmp(it->second);
tmp.name(data.name());
tmp.sampleTime(data.sampleTime()); // sample time always 0 for objects in map
onlyNameChanged = (tmp == data);
std::swap(it->second, dataTmp); // with sampleTime = 0
DEBUG_LOG(m_logger) << "changed AES Item: " << data;
return true;
}
bool dataChanged(const AreaEffectSimulation::AirSupportImpact &current, bool &onlyNameChanged)
{
return dataChanged(current, m_currentAirSupportImpacts, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::BCContamination &current, bool &onlyNameChanged)
{
return dataChanged(current, m_currentBCContaminations, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::ExplosionArea &current, bool &onlyNameChanged)
{
AreaEffectSimulation::ExplosionArea copy(current);
// Todo: Something else to set?
copy.remainExplosionNumber(0);
return dataChanged(copy, m_currentExplosionArea, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::ExplosionCluster &current, bool &onlyNameChanged)
{
AreaEffectSimulation::ExplosionCluster copy(current);
// Todo: Something else to set?
copy.remainExplosionNumber(0);
return dataChanged(copy, m_currentExplosionCluster, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::ExplosionSingle &current, bool &onlyNameChanged)
{
return dataChanged(current, m_currentExplosionSingle, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::MineArea &current, bool &onlyNameChanged)
{
return dataChanged(current, m_currentMineArea, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::NContamination &current, bool &onlyNameChanged)
{
return dataChanged(current, m_currentNContamination, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::FunctionalArea &current, bool &onlyNameChanged)
{
return dataChanged(current, m_currentFunctionalArea, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::TechnicalArea &current, bool &onlyNameChanged)
{
return dataChanged(current, m_currentTechnicalArea, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::DusSingleMine &current, bool &onlyNameChanged)
{
return dataChanged(current, m_currentDusSingleMine, onlyNameChanged);
}
bool dataChanged(const AreaEffectSimulation::GasPipe &current, bool &onlyNameChanged)
{
return dataChanged(current, m_currentGasPipes, onlyNameChanged);
}
/*!
* \brief dataChanged
* \param current
* \details BoobyTrap is complete central, not going to tetra, the bool is just used as a placeholder
* \return
*/
bool dataChanged(const AreaEffectSimulation::BoobyTrap &current)
{
bool placeholder;
Q_UNUSED(placeholder);
return dataChanged(current, m_currentBoobyTraps, placeholder);
}
/*!
* \brief dataChanged
* \param current
* \details OffRouteMine is complete central, not going to tetra, the bool is just used as a placeholder
* \return
*/
bool dataChanged(const AreaEffectSimulation::OffRouteMine &current)
{
bool placeholder;
Q_UNUSED(placeholder);
return dataChanged(current, m_currentOffRouteMines, placeholder);
}
template <typename T>
void resetStartTime(int aesDdsId, T &cont)
{
auto it = cont.find(aesDdsId);
if (it == cont.end())
return;
it->second.effectStart(0);
}
void resetStartTime(const AreaEffectSimulation::AirSupportImpact &current)
{
resetStartTime(current.id(), m_currentBCContaminations);
}
void resetStartTime(const AreaEffectSimulation::BCContamination &current)
{
resetStartTime(current.id(), m_currentBCContaminations);
}
void resetStartTime(const AreaEffectSimulation::ExplosionArea &current)
{
resetStartTime(current.id(), m_currentExplosionArea);
}
void resetStartTime(const AreaEffectSimulation::ExplosionCluster &current)
{
resetStartTime(current.id(), m_currentExplosionCluster);
}
void resetStartTime(const AreaEffectSimulation::ExplosionSingle &current)
{
resetStartTime(current.id(), m_currentExplosionSingle);
}
void resetStartTime(const AreaEffectSimulation::MineArea &current)
{
resetStartTime(current.id(), m_currentMineArea);
}
void resetStartTime(const AreaEffectSimulation::NContamination &current)
{
resetStartTime(current.id(), m_currentNContamination);
}
void resetStartTime(const AreaEffectSimulation::FunctionalArea &current)
{
resetStartTime(current.id(), m_currentFunctionalArea);
}
void resetStartTime(const AreaEffectSimulation::TechnicalArea &current)
{
resetStartTime(current.id(), m_currentTechnicalArea);
}
void resetStartTime(const AreaEffectSimulation::DusSingleMine &current)
{
resetStartTime(current.id(), m_currentDusSingleMine);
}
void resetStartTime(const AreaEffectSimulation::GasPipe &current)
{
resetStartTime(current.id(), m_currentGasPipes);
}
void resetStartTime(const AreaEffectSimulation::BoobyTrap &current)
{
resetStartTime(current.id(), m_currentBoobyTraps);
}
void resetStartTime(const AreaEffectSimulation::OffRouteMine &current)
{
resetStartTime(current.id(), m_currentOffRouteMines);
}
std::shared_ptr<PdmHandler> pdm();
template<typename T>
void txData(const T &tele)
{
m_txCallback->txData(tele);
m_sentAesTelegrams.push_back(new T(tele));
m_sentAesTelegramsAesIds.push_back(tele.aesDdsId);
m_checkOutdatedTelegramsTimer->start();
DEBUG_LOG(m_logger) << "Appending " << tele.type()<< " to m_sentAesTelegrams";
}
void onCheckOutdatedTelegrams();
void onSendDusMineReactivationTimeout();
private:
std::unordered_map<int, AreaEffectSimulation::AirSupportImpact> m_currentAirSupportImpacts;
std::unordered_map<int, AreaEffectSimulation::BCContamination> m_currentBCContaminations;
std::unordered_map<int, AreaEffectSimulation::ExplosionArea> m_currentExplosionArea;
std::unordered_map<int, AreaEffectSimulation::ExplosionCluster> m_currentExplosionCluster;
std::unordered_map<int, AreaEffectSimulation::ExplosionSingle> m_currentExplosionSingle;
std::unordered_map<int, AreaEffectSimulation::MineArea> m_currentMineArea;
std::unordered_map<int, AreaEffectSimulation::TriggeredImpacts> m_temporarySingleMineState;
std::unordered_map<int, AreaEffectSimulation::NContamination> m_currentNContamination;
std::unordered_map<int, AreaEffectSimulation::FunctionalArea> m_currentFunctionalArea;
std::unordered_map<int, AreaEffectSimulation::TechnicalArea> m_currentTechnicalArea;
std::unordered_map<int, AreaEffectSimulation::DusSingleMine> m_currentDusSingleMine;
std::unordered_map<int, AreaEffectSimulation::GasPipe> m_currentGasPipes;
/*!
* \brief m_currentBoobyTraps (Verdeckte Ladung)
* \details Added for 3D Wirksim
* \author Niklas Schmidt
*/
std::unordered_map<int, AreaEffectSimulation::BoobyTrap> m_currentBoobyTraps;
/*!
* \brief m_currentOffRouteMines
* \details Added for 3D Wirksim
* \author Niklas Schmidt
*/
std::unordered_map<int, AreaEffectSimulation::OffRouteMine> m_currentOffRouteMines;
//std::unordered_map<int, AreaEffectSimulation::DangerZoneExplosion> m_currentDangerExplosionZones; //TODO: Not yet implemented in Aes (Gefahrenbereich Steilfeuer)
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
std::shared_ptr<SendToTab> m_txCallback;
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_dtcAes;
std::shared_ptr<AesStateHandler> m_aesStateHandler;
QMap<int, AreaEffectSimulation::AesEffectState> m_currentEffectState;
QMap<int, AreaEffectSimulation::DusMine> m_allReactivatableDusMines; // united map of all DUS-mines independet of matched minearea/status
QVector<int> m_minesToSend;
std::shared_ptr<PositionHandler> m_posHandler;
MainHandler *m_mainHandler;
QTimer *m_checkOutdatedTelegramsTimer;
QTimer *m_sendDusMineReactivtionTimer;
QVector<TetraIcd::TrainingAreaTelegram*> m_sentAesTelegrams;
QVector<int> m_sentAesTelegramsAesIds;
LOGGER_T m_logger;
};
}