1126 lines
46 KiB
C++
Executable File
1126 lines
46 KiB
C++
Executable File
/**
|
|
* Send AES data to NGS
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Hannes Baeuerle, SLSE, 2017-05-08
|
|
*/
|
|
|
|
#include "aes_handler.h"
|
|
#include "ngs_handler.h"
|
|
#include <Common/participantposition.h>
|
|
|
|
#include <AreaEffectSimulation/aes_enums.hpp>
|
|
#include <AreaEffectSimulation/aes_translation.h>
|
|
#include <LtsUtilsCore/dds_bitarray.h>
|
|
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
|
|
#include <EntityTypeStruct.h>
|
|
|
|
#include <QTimer>
|
|
#include <QDateTime>
|
|
|
|
|
|
|
|
using namespace AreaEffectSimulation;
|
|
namespace HighLevelArchitecture
|
|
{
|
|
static MineCorridorModifyRequest *makeMinefieldBreachRequest(const MineCorridor& mc)
|
|
{
|
|
MineCorridorModifyRequest *req = new MineCorridorModifyRequest;
|
|
req->effectDuration(mc.effectDuration());
|
|
req->effectStart(mc.effectStart());
|
|
req->externalId(mc.externalId());
|
|
req->id(mc.id());
|
|
req->name(mc.name());
|
|
req->participantId(mc.participantId());
|
|
req->partyId(mc.partyId());
|
|
req->segments(mc.segments());
|
|
req->width(mc.width());
|
|
|
|
return req;
|
|
}
|
|
|
|
static MineAreaModifyRequest *makeMinefieldRequest(const MineArea& ma)
|
|
{
|
|
if (ma.segments().size() <= 0)
|
|
return nullptr;
|
|
|
|
MineAreaModifyRequest *req = new MineAreaModifyRequest;
|
|
req->chargeStruct().chargeTypeId(ma.chargeStruct().chargeTypeId());
|
|
req->density(ma.density());
|
|
req->distance(0.5);
|
|
req->effectDuration(ma.effectDuration());
|
|
req->effectMarkingInTa(ma.effectMarkingInTa());
|
|
req->effectStart(ma.effectStart());
|
|
req->externalId(ma.externalId());
|
|
req->id(ma.id());
|
|
req->isCenterLine(ma.isCenterLine());
|
|
req->isLaidHidden(ma.isLaidHidden());
|
|
req->layingProcedureType(ma.layingProcedureType());
|
|
req->name(ma.name());
|
|
req->participantId(ma.participantId());
|
|
req->partyId(ma.partyId());
|
|
for (const MineSegment &ms : ma.segments())
|
|
req->segments().push_back(ms.positionStart());
|
|
const MineSegment &lastSegment = ma.segments().at(ma.segments().size()-1);
|
|
|
|
req->segments().push_back(Core::GeoPosition2D(lastSegment.positionEnd().lon(), lastSegment.positionEnd().lat()));
|
|
|
|
req->width(ma.width());
|
|
return req;
|
|
}
|
|
|
|
AesHandler::AesHandler(NgsHandler *ngsHandler)
|
|
: m_ngsHandler(ngsHandler)
|
|
, m_dtcAes(nullptr)
|
|
, m_ftcAes(nullptr)
|
|
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
|
, m_logger(getLogger("AesHandler"))
|
|
{
|
|
|
|
}
|
|
|
|
void AesHandler::onMineAreaModifyReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
if (replyObject.error())
|
|
WARNING_LOG(m_logger) << "ModifyReply: " << replyObject();
|
|
else
|
|
DEBUG_LOG(m_logger) << "ModifyReply: " << replyObject();
|
|
m_requestHelper->requestReply(replyObject);
|
|
}
|
|
|
|
int64_t AesHandler::externalId(int aesItemId) const
|
|
{
|
|
AesItem aesItem;
|
|
if (!m_dtcAes->aesItemFromId(aesItemId, aesItem))
|
|
return 0;
|
|
return aesItem.externalId();
|
|
}
|
|
|
|
bool AesHandler::init()
|
|
{
|
|
m_dtcAes = Interface::Dtc::create(m_ngsHandler->ddsHandler()->ddsConnector());
|
|
m_ftcAes = Interface::Ftc::create(m_ngsHandler->ddsHandler()->ddsConnector());
|
|
|
|
connect(m_dtcAes.get(), &Interface::Dtc::aesItemViewChanged,
|
|
this, &AesHandler::onAesItemViewChanged);
|
|
connect(m_dtcAes.get(), &Interface::Dtc::triggeredImpactsChanged,
|
|
this, &AesHandler::onTriggeredImpactsChanged);
|
|
#ifdef SUPPORT_AES_EFFECTS
|
|
connect(m_dtcAes.get(), &Interface::Dtc::effectsChanged,
|
|
this, &AesHandler::onEffectsChanged);
|
|
#endif // SUPPORT_AES_EFFECTS
|
|
connect(m_dtcAes.get(), &Interface::Dtc::explosionSingleChanged,
|
|
this, &AesHandler::onAesExplosionSingleChanged);
|
|
connect(m_dtcAes.get(), &Interface::Dtc::mineAreaChanged,
|
|
this, &AesHandler::onAesMineAreaChanged);
|
|
connect(m_dtcAes.get(), &Interface::Dtc::mineCorridorChanged,
|
|
this, &AesHandler::onAesMineCorridorChanged);
|
|
connect(m_dtcAes.get(), &Interface::Dtc::nContaminationChanged,
|
|
this, &AesHandler::onAesNContaminationChanged);
|
|
connect(m_dtcAes.get(), &Interface::Dtc::bCContaminationChanged,
|
|
this, &AesHandler::onAesBCContaminationChanged);
|
|
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::aesNameChanged,
|
|
this, &AesHandler::onAesNameChanged);
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::aesForceIdentifierChanged,
|
|
this, &AesHandler::onAesForceIdentifierChanged);
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::aesActivationTimeChanged,
|
|
this, &AesHandler::onAesActivationTimeChanged);
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::aesChargeChanged,
|
|
this, &AesHandler::onAesChargeChanged);
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::aesDurationChanged,
|
|
this, &AesHandler::onAesDurationChanged);
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::aesPointsDataChanged,
|
|
this, &AesHandler::onAesPointsDataChanged);
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::aesRemoveItem,
|
|
this, &AesHandler::onAesRemoveItem);
|
|
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::newMinefield,
|
|
this, &AesHandler::onNewMinefield);
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::newMinefieldBreach,
|
|
this, &AesHandler::onNewMinefieldBreach);
|
|
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::munitionDetonation,
|
|
this, &AesHandler::onMunitionDetonation);
|
|
|
|
#ifdef SUPPORT_EXPLOSION_CLUSTER_SINGLE_EFFECT
|
|
connect(m_ngsHandler->ngsConnector().get(), &NgsConnector::munitionDetonationExplosionClusterSingleEffectOnly,
|
|
this, &AesHandler::onMunitionDetonationExplosionClusterSingleEffect);
|
|
#endif
|
|
|
|
|
|
return m_dtcAes->enableAesItemView() &&
|
|
m_dtcAes->enableExplosionSingle() &&
|
|
m_dtcAes->enableMineArea() &&
|
|
m_dtcAes->enableTriggeredImpacts() &&
|
|
#ifdef SUPPORT_EXPLOSION_CLUSTER_SINGLE_EFFECT
|
|
m_ftcAes->enableExplosionClusterSingleEffectOnlyModify() &&
|
|
#endif
|
|
#ifdef SUPPORT_AES_EFFECTS // GUEZE-2570 / EXPLOSION_CLUSTER
|
|
m_dtcAes->enableEffects() &&
|
|
#endif
|
|
m_dtcAes->enableMineCorridor() &&
|
|
m_ftcAes->enableMineCorridorModify() &&
|
|
m_ftcAes->enableMineCorridorRemove() &&
|
|
m_dtcAes->enableNContamination() &&
|
|
m_dtcAes->enableBCContamination() &&
|
|
m_ftcAes->enableMineAreaRemove() &&
|
|
m_ftcAes->enableMineAreaModify() &&
|
|
m_ftcAes->enableExplosionSingleModify();
|
|
}
|
|
|
|
void AesHandler::onAesItemViewChanged(const AesItemView &data, DataModification modType)
|
|
{
|
|
if (m_logger.isDebugEnabled())
|
|
{
|
|
QStringList formString;
|
|
formString.reserve(data.form().size());
|
|
|
|
for (const auto &pos : data.form())
|
|
formString << ParticipantPosition(pos).toString();
|
|
|
|
DEBUG_LOG(m_logger) << "\n##############################"
|
|
<< "\n##### AesItemViewChanged #####"
|
|
<< "\n##############################"
|
|
<< "\nid: " << data.id()
|
|
<< "\nsampleTime: " << data.sampleTime()
|
|
<< "\naesTypeId: " << toString(data.aesTypeId())
|
|
<< "\naesItemId: " << data.aesItemId()
|
|
<< "\nform: " << formString.join(QStringLiteral(", "))
|
|
<< "\nboundingBoxBottomLeft: " << ParticipantPosition(data.boundingBoxBottomLeft()).toString()
|
|
<< "\nboundingBoxTopRight: " << ParticipantPosition(data.boundingBoxTopRight()).toString()
|
|
<< "\neffectStateId: " << toString(data.effectStateId())
|
|
<< "\npartyId: " << (data.partyId().is_set() ? QString::number(data.partyId().get()) : QStringLiteral("not set"))
|
|
<< "\nchargeTypeId: " << data.chargeStruct().chargeTypeId()
|
|
<< "\neffectStart: " << data.effectStart() << "\n";
|
|
}
|
|
|
|
if (modType == DataModification::eRemoved ||
|
|
data.effectStateId() == AesEffectState::EsExpired ||
|
|
data.effectStateId() == AesEffectState::EsRemoved)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Item view with id " << data.aesItemId() << " removed";
|
|
m_aesItemViews.remove(data.aesItemId());
|
|
m_takenIndicesForAesItem.remove(data.aesItemId());
|
|
m_ngsHandler->ngsConnector()->setItemForm(data.aesItemId());
|
|
}
|
|
// Only care about Explosion Areas for triggered impacts and for storing:
|
|
else if (data.effectStateId() == AesEffectState::EsPrepared &&
|
|
data.aesTypeId() == AesType_def::AtExplosionAreaSingleExplosions)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Item view with id " << data.aesItemId() << " added";
|
|
m_aesItemViews.insert(data.aesItemId(), data);
|
|
m_takenIndicesForAesItem.insert(data.aesItemId(), QVector<int32_t>());
|
|
}
|
|
// On BCContaminations directly update in NgsConnector:
|
|
else if (data.aesTypeId() == AesType_def::AtBCContamination)
|
|
{
|
|
m_ngsHandler->ngsConnector()->setItemForm(data.aesItemId(), data.aesTypeId().underlying(), data.form());
|
|
DEBUG_LOG(m_logger) << "Item view with id " << data.aesItemId() << " directly updated in ngsConnector";
|
|
}
|
|
}
|
|
|
|
void AesHandler::onTriggeredImpactsChanged(const TriggeredImpacts &data, DataModification modType)
|
|
{
|
|
if (m_logger.isDebugEnabled())
|
|
{
|
|
QString bitfield = QStringLiteral("[ ");
|
|
for (uint8_t bit : data.bitfield())
|
|
{
|
|
bitfield.append(QString::number(bit));
|
|
bitfield.append(QStringLiteral(" "));
|
|
}
|
|
bitfield.append(QStringLiteral("]"));
|
|
|
|
DEBUG_LOG(m_logger) << "\n#####################################"
|
|
<< "\n##### triggered impacts changed #####"
|
|
<< "\n#####################################"
|
|
<< "\nid: " << data.id()
|
|
<< "\naesItemId: " << data.aesItemId()
|
|
<< "\naesTypeId: " << toString(data.aesTypeId())
|
|
<< "\nbitfield: " << bitfield
|
|
<< "\nimpactCount: " << data.impactCount()
|
|
<< "\nsampleTime: " << data.sampleTime() << "\n";
|
|
}
|
|
|
|
// Clean up if removed / Don't care if not in before.
|
|
if (modType == DataModification::eRemoved)
|
|
{
|
|
m_aesItemViews.remove(data.aesItemId());
|
|
m_takenIndicesForAesItem.remove(data.aesItemId());
|
|
return;
|
|
}
|
|
if (data.aesTypeId() != AesType_def::AtExplosionAreaSingleExplosions)
|
|
return;
|
|
// If no aesItemView, no takenIndices also. They are in sync.
|
|
if (!m_aesItemViews.contains(data.aesItemId()))
|
|
return;
|
|
const AesItemView &aesItemView = m_aesItemViews[data.aesItemId()];
|
|
|
|
|
|
// Triggered Impacts are either belonging to Explosion Areas or Mine Areas.
|
|
int chargeTypeId = m_dtcAes->explosionArea(data.aesItemId()).chargeStruct().chargeTypeId();
|
|
if (chargeTypeId <= 0)
|
|
return;
|
|
|
|
rpr2::ForceIdentifierEnum8::ET forceId = aesItemView.partyId().is_set() ? m_ngsHandler->ppmHandler()->forceIdentifierFromPartyId(aesItemView.partyId().get()) : rpr2::ForceIdentifierEnum8::Other;
|
|
|
|
for (int32_t bitFieldIdx = 0; bitFieldIdx < data.impactCount(); ++bitFieldIdx)
|
|
{
|
|
// no break, because every bit can be a hit
|
|
if (LtsUtils::BitArray::testBit(data.bitfield(), bitFieldIdx) ||
|
|
m_takenIndicesForAesItem.value(data.aesItemId()).contains(bitFieldIdx))
|
|
continue;
|
|
|
|
m_takenIndicesForAesItem[data.aesItemId()].append(bitFieldIdx);
|
|
ParticipantPosition pos(aesItemView.form()[bitFieldIdx], data.sampleTime());
|
|
m_ngsHandler->ngsConnector()->sendMunitionDetonation(pos, chargeTypeId, forceId);
|
|
}
|
|
}
|
|
|
|
#ifdef SUPPORT_AES_EFFECTS
|
|
void AesHandler::onEffectsChanged(const Effects &data, DataModification modType)
|
|
{
|
|
// GUEZE-2570 3D Wirksim - Umstellung HLA auf ExplosionCluster
|
|
// Part1: DDS -> HLA
|
|
|
|
const int aesItemId = data.aesItemId();
|
|
|
|
// Clean up if removed / Don't care if not in before.
|
|
if (modType == DataModification::eRemoved)
|
|
{
|
|
m_handledImpactsStorage.removeAesItem(aesItemId);
|
|
return;
|
|
}
|
|
if (data.aesTypeId() != AesType_def::AtExplosionClusterSingleExplosions)
|
|
return;
|
|
|
|
const std::vector<AreaEffectSimulation::SingleEffect> &singleEffectsRef = data.singleEffects();
|
|
if (singleEffectsRef.empty())
|
|
return;
|
|
|
|
// if explosionCluster could not be found, the values is also 0; No extra check needed.
|
|
const AreaEffectSimulation::ExplosionCluster &exCluster = m_dtcAes->explosionCluster(aesItemId);
|
|
if (exCluster.id() != aesItemId)
|
|
return;
|
|
|
|
// If neither Party nor Participant is set or participant id is smaller than 0, this is an external one that should not be published!
|
|
// Fix for [GUEZE-3601] External impacts are being published for a second time by us
|
|
if (!exCluster.partyId().is_set() &&
|
|
(!exCluster.participantId().is_set() || exCluster.participantId().get() <= 0))
|
|
return;
|
|
|
|
const int chargeTypeId = exCluster.chargeStruct().chargeTypeId();
|
|
if (chargeTypeId <= 0)
|
|
return;
|
|
|
|
//
|
|
// real work:
|
|
//
|
|
|
|
// partyId to forceId:
|
|
const rpr2::ForceIdentifierEnum8::ET forceId = exCluster.partyId().is_set() ? m_ngsHandler->ppmHandler()->forceIdentifierFromPartyId(exCluster.partyId().get()) : rpr2::ForceIdentifierEnum8::Other;
|
|
|
|
|
|
int curSeIndex = -1;
|
|
for (const AreaEffectSimulation::SingleEffect &se : qAsConst(singleEffectsRef))
|
|
{
|
|
++curSeIndex;
|
|
// only SesTriggered are relevant:
|
|
if (se.singleEffectState() != AreaEffectSimulation::AesSingleEffectState_def::SesTriggered)
|
|
continue;
|
|
|
|
// compare current triggered idx with triggered idx of the past
|
|
if (m_handledImpactsStorage.isIndexProcessed(aesItemId, curSeIndex))
|
|
continue;
|
|
|
|
// send to ngsHandler
|
|
// ParticipantPosition pos(aesItemView.form()[bitFieldIdx], data.sampleTime());
|
|
ParticipantPosition pos(se.position(), se.singleEffectTime());
|
|
m_ngsHandler->ngsConnector()->sendMunitionDetonation(pos, chargeTypeId, forceId);
|
|
|
|
// update storage
|
|
m_handledImpactsStorage.setIndexProcessed(aesItemId, curSeIndex);
|
|
} // for
|
|
}
|
|
#endif // SUPPORT_AES_EFFECTS
|
|
|
|
void AesHandler::onAesExplosionSingleChanged(const ExplosionSingle &data, DataModification modType)
|
|
{
|
|
Q_UNUSED(modType);
|
|
|
|
// Maybe this works also...?
|
|
// if (data.externalId() > 0)
|
|
// return;
|
|
DEBUG_LOG(m_logger) << "\n####################################"
|
|
<< "\n##### single explosion changed #####"
|
|
<< "\n####################################"
|
|
<< "\nid: " << data.id()
|
|
<< "\nname: " << data.name()
|
|
<< "\nisDeleted: " << data.isDeleted()
|
|
<< "\nisUsed: " << data.isUsed()
|
|
<< "\nsampleTime: " << data.sampleTime()
|
|
<< "\nchargeTypeId: " << data.chargeStruct().chargeTypeId()
|
|
<< "\neffectDuration: " << data.effectDuration()
|
|
<< "\neffectStart: " << (data.effectStart().is_set() ? QString::number(data.effectStart().get()) : QStringLiteral("not set"))
|
|
<< "\neffectStateId: " << toString(data.effectStateId())
|
|
<< "\npartyId: " << (data.partyId().is_set() ? QString::number(data.partyId().get()) : QStringLiteral("not set"))
|
|
<< "\nparticipantId: " << (data.participantId().is_set() ? QString::number(data.participantId().get()) : QStringLiteral("not set"))
|
|
<< "\nimpactPosition: " << ParticipantPosition(data.impactPosition()).toString()
|
|
<< "\nfireRequestTime: " << data.fireRequestTime()
|
|
<< "\naltitude: " << data.altitude()
|
|
<< "\npurpose: " << data.purpose() << "\n";
|
|
|
|
if (data.effectStateId() != AesEffectState::EsActivated)
|
|
return;
|
|
|
|
// If neither Party nor Participant is set or participant id is smaller than 0, this is an external one that should not be published!
|
|
if (!data.partyId().is_set() &&
|
|
(!data.participantId().is_set() || data.participantId().get() <= 0))
|
|
return;
|
|
|
|
// If it's active (it's only one second active and not likely to have several updates in the meantime...
|
|
ParticipantPosition pos(data.impactPosition(), data.effectStart().is_set() ? data.effectStart().get() : data.sampleTime());
|
|
rpr2::ForceIdentifierEnum8::ET forceId = data.partyId().is_set() ? m_ngsHandler->ppmHandler()->forceIdentifierFromPartyId(data.partyId().get()) : rpr2::ForceIdentifierEnum8::Other;
|
|
m_ngsHandler->ngsConnector()->sendMunitionDetonation(pos, data.chargeStruct().chargeTypeId(), forceId);
|
|
|
|
}
|
|
|
|
void AesHandler::onAesMineAreaChanged(const MineArea &data, DataModification modType)
|
|
{
|
|
Q_UNUSED(modType);
|
|
|
|
DEBUG_LOG(m_logger) << "\n#############################"
|
|
<< "\n##### mine area changed #####"
|
|
<< "\n#############################"
|
|
<< "\nid: " << data.id()
|
|
<< "\nname: " << data.name()
|
|
<< "\nisDeleted: " << data.isDeleted()
|
|
<< "\nisUsed: " << data.isUsed()
|
|
<< "\nsampleTime: " << data.sampleTime()
|
|
<< "\nchargeTypeId: " << data.chargeStruct().chargeTypeId()
|
|
<< "\neffectDuration: " << data.effectDuration()
|
|
<< "\neffectStart: " << (data.effectStart().is_set() ? QString::number(data.effectStart().get()) : QStringLiteral("not set"))
|
|
<< "\neffectStateId: " << toString(data.effectStateId())
|
|
<< "\npartyId: " << (data.partyId().is_set() ? QString::number(data.partyId().get()) : QStringLiteral("not set"))
|
|
<< "\nparticipantId: " << (data.participantId().is_set() ? QString::number(data.participantId().get()) : QStringLiteral("not set"))
|
|
<< "\n";
|
|
|
|
m_ngsHandler->ngsConnector()->guezMineField(data);
|
|
}
|
|
|
|
void AesHandler::onAesMineCorridorChanged(const MineCorridor &data, DataModification modType)
|
|
{
|
|
Q_UNUSED(modType);
|
|
|
|
DEBUG_LOG(m_logger) << "\n#################################"
|
|
<< "\n##### mine corridor changed #####"
|
|
<< "\n#################################"
|
|
<< "\nid: " << data.id()
|
|
<< "\nname: " << data.name()
|
|
<< "\nisDeleted: " << data.isDeleted()
|
|
<< "\nisUsed: " << data.isUsed()
|
|
<< "\nsampleTime: " << data.sampleTime()
|
|
<< "\nchargeTypeId: " << data.chargeStruct().chargeTypeId()
|
|
<< "\neffectDuration: " << data.effectDuration()
|
|
<< "\neffectStart: " << (data.effectStart().is_set() ? QString::number(data.effectStart().get()) : QStringLiteral("not set"))
|
|
<< "\neffectStateId: " << toString(data.effectStateId())
|
|
<< "\npartyId: " << (data.partyId().is_set() ? QString::number(data.partyId().get()) : QStringLiteral("not set"))
|
|
<< "\nparticipantId: " << (data.participantId().is_set() ? QString::number(data.participantId().get()) : QStringLiteral("not set"))
|
|
<< "\n";
|
|
|
|
m_ngsHandler->ngsConnector()->guezMineFieldBreach(data);
|
|
|
|
}
|
|
|
|
void AesHandler::onAesNContaminationChanged(const NContamination &data, DataModification modType)
|
|
{
|
|
Q_UNUSED(modType);
|
|
m_ngsHandler->ngsConnector()->guezNuclearAgent(data);
|
|
|
|
DEBUG_LOG(m_logger) << "\n####################################"
|
|
<< "\n##### n contamination changed #####"
|
|
<< "\n####################################"
|
|
<< "\nid: " << data.id()
|
|
<< "\nname: " << data.name()
|
|
<< "\nisDeleted: " << data.isDeleted()
|
|
<< "\nisUsed: " << data.isUsed()
|
|
<< "\nsampleTime: " << data.sampleTime()
|
|
<< "\nchargeTypeId: " << data.chargeStruct().chargeTypeId()
|
|
<< "\neffectDuration: " << data.effectDuration()
|
|
<< "\neffectStart: " << (data.effectStart().is_set() ? QString::number(data.effectStart().get()) : QStringLiteral("not set"))
|
|
<< "\neffectStateId: " << toString(data.effectStateId())
|
|
<< "\npartyId: " << (data.partyId().is_set() ? QString::number(data.partyId().get()) : QStringLiteral("not set"))
|
|
<< "\nparticipantId: " << (data.participantId().is_set() ? QString::number(data.participantId().get()) : QStringLiteral("not set"))
|
|
<< "\n";
|
|
|
|
}
|
|
|
|
void AesHandler::onAesBCContaminationChanged(const BCContamination &data, DataModification modType)
|
|
{
|
|
Q_UNUSED(modType);
|
|
m_ngsHandler->ngsConnector()->guezChemicalAgent(data);
|
|
|
|
DEBUG_LOG(m_logger) << "\n####################################"
|
|
<< "\n##### bc contamination changed #####"
|
|
<< "\n####################################"
|
|
<< "\nid: " << data.id()
|
|
<< "\nname: " << data.name()
|
|
<< "\nisDeleted: " << data.isDeleted()
|
|
<< "\nisUsed: " << data.isUsed()
|
|
<< "\nsampleTime: " << data.sampleTime()
|
|
<< "\nchargeTypeId: " << data.chargeStruct().chargeTypeId()
|
|
<< "\neffectDuration: " << data.effectDuration()
|
|
<< "\neffectStart: " << (data.effectStart().is_set() ? QString::number(data.effectStart().get()) : QStringLiteral("not set"))
|
|
<< "\neffectStateId: " << toString(data.effectStateId())
|
|
<< "\npartyId: " << (data.partyId().is_set() ? QString::number(data.partyId().get()) : QStringLiteral("not set"))
|
|
<< "\nparticipantId: " << (data.participantId().is_set() ? QString::number(data.participantId().get()) : QStringLiteral("not set"))
|
|
<< "\n";
|
|
|
|
}
|
|
|
|
bool AesHandler::isModifiable(const AreaEffectSimulation::AesItem &item)
|
|
{
|
|
return (item.effectStateId() == AesEffectState_def::EsCreated ||
|
|
item.effectStateId() == AesEffectState_def::EsPrepared ||
|
|
item.effectStateId() == AesEffectState_def::EsUnknown ||
|
|
item.effectStateId() == AesEffectState_def::EsReceived);
|
|
}
|
|
|
|
// HLA -> DDS
|
|
void AesHandler::onAesNameChanged(qint64 identifierInt, const std::string &newName)
|
|
{
|
|
// No "isModifiable(item)" used here, as Name is more likely changeable.
|
|
int aesItemId = 0;
|
|
AesType type = m_dtcAes->aesItemIdFromExternalId(identifierInt, aesItemId);
|
|
|
|
switch (type.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtMineCorridor:
|
|
{
|
|
MineCorridorModifyRequest *req = static_cast<MineCorridorModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineCorridor item = m_dtcAes->mineCorridor(aesItemId);
|
|
if (item.name() == newName)
|
|
return;
|
|
req = makeMinefieldBreachRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
req->name(newName);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
{
|
|
MineAreaModifyRequest *req = static_cast<MineAreaModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineArea item = m_dtcAes->mineArea(aesItemId);
|
|
if (item.name() == newName)
|
|
return;
|
|
req = makeMinefieldRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
req->name(newName);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionArea:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingle:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtAirSupportImpact:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtUnknown:
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
case AreaEffectSimulation::AesType_def::AtFunctionalArea:
|
|
case AreaEffectSimulation::AesType_def::AtBorderline:
|
|
case AreaEffectSimulation::AesType_def::AtTechnicalArea:
|
|
case AreaEffectSimulation::AesType_def::AtReconArea:
|
|
case AreaEffectSimulation::AesType_def::AtDusSingleMine:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionAreaSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtMineAreaSingleMines:
|
|
case AreaEffectSimulation::AesType_def::AtGasPipe:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentral:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentralTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrap:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMine:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionCluster:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterGunToTargetLine:
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void AesHandler::onAesRemoveItem(qint64 identifierInt)
|
|
{
|
|
int aesItemId = 0;
|
|
AesType type = m_dtcAes->aesItemIdFromExternalId(identifierInt, aesItemId);
|
|
Core::RemoveElementRequest req(aesItemId);
|
|
|
|
DEBUG_LOG(m_logger) << "Remove Item for " << aesItemId << " requested. Type: " << type;
|
|
|
|
switch (type.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtMineCorridor:
|
|
{
|
|
m_requestHelper->startSingleRequest([req, this]()
|
|
{
|
|
return m_ftcAes->mineCorridorRemoveRequest(req, this);
|
|
});
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
{
|
|
m_requestHelper->startSingleRequest([req, this]()
|
|
{
|
|
return m_ftcAes->mineAreaRemoveRequest(req, this);
|
|
});
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
return; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionArea:
|
|
return; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingle:
|
|
return; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtAirSupportImpact:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtUnknown:
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
case AreaEffectSimulation::AesType_def::AtFunctionalArea:
|
|
case AreaEffectSimulation::AesType_def::AtBorderline:
|
|
case AreaEffectSimulation::AesType_def::AtTechnicalArea:
|
|
case AreaEffectSimulation::AesType_def::AtReconArea:
|
|
case AreaEffectSimulation::AesType_def::AtDusSingleMine:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionAreaSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtMineAreaSingleMines:
|
|
case AreaEffectSimulation::AesType_def::AtGasPipe:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentral:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentralTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrap:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMine:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionCluster:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterGunToTargetLine:
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
void AesHandler::onAesActivationTimeChanged(qint64 identifierInt, qint64 msecsSinceEpoch)
|
|
{
|
|
int aesItemId = 0;
|
|
AesType type = m_dtcAes->aesItemIdFromExternalId(identifierInt, aesItemId);
|
|
|
|
qint64 earliest = QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() + 5000;
|
|
if (msecsSinceEpoch < earliest && msecsSinceEpoch > 0)
|
|
msecsSinceEpoch = earliest;
|
|
|
|
switch (type.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtMineCorridor:
|
|
{
|
|
MineCorridorModifyRequest *req = static_cast<MineCorridorModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineCorridor item = m_dtcAes->mineCorridor(aesItemId);
|
|
if ((item.effectStart().is_set() && item.effectStart().get() == msecsSinceEpoch) || !isModifiable(item))
|
|
return;
|
|
req = makeMinefieldBreachRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
req->effectStart(msecsSinceEpoch);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
{
|
|
DEBUG_LOG(m_logger) << "onAesActivationTimeChanged / MineArea";
|
|
MineAreaModifyRequest *req = static_cast<MineAreaModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
if (!req)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onAesActivationTimeChanged / MineArea - Request NOT found";
|
|
AreaEffectSimulation::MineArea item = m_dtcAes->mineArea(aesItemId);
|
|
if ((item.effectStart().is_set() && item.effectStart().get() == msecsSinceEpoch) || !isModifiable(item))
|
|
return;
|
|
req = makeMinefieldRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
req->effectStart(msecsSinceEpoch);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionArea:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingle:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtAirSupportImpact:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtUnknown:
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
case AreaEffectSimulation::AesType_def::AtFunctionalArea:
|
|
case AreaEffectSimulation::AesType_def::AtBorderline:
|
|
case AreaEffectSimulation::AesType_def::AtTechnicalArea:
|
|
case AreaEffectSimulation::AesType_def::AtReconArea:
|
|
case AreaEffectSimulation::AesType_def::AtDusSingleMine:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionAreaSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtMineAreaSingleMines:
|
|
case AreaEffectSimulation::AesType_def::AtGasPipe:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentral:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentralTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrap:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMine:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionCluster:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterGunToTargetLine:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// HLA -> DDS
|
|
void AesHandler::onAesForceIdentifierChanged(qint64 identifierInt, int partyId)
|
|
{
|
|
int aesItemId = 0;
|
|
AesType type = m_dtcAes->aesItemIdFromExternalId(identifierInt, aesItemId);
|
|
|
|
switch (type.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtMineCorridor:
|
|
{
|
|
MineCorridorModifyRequest *req = static_cast<MineCorridorModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineCorridor item = m_dtcAes->mineCorridor(aesItemId);
|
|
if (item.partyId() == partyId || !isModifiable(item))
|
|
return;
|
|
req = makeMinefieldBreachRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
req->partyId(partyId);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
{
|
|
MineAreaModifyRequest *req = static_cast<MineAreaModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineArea item = m_dtcAes->mineArea(aesItemId);
|
|
if (item.partyId() == partyId || !isModifiable(item))
|
|
return;
|
|
req = makeMinefieldRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
req->partyId(partyId);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionArea:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingle:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtAirSupportImpact:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtUnknown:
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
case AreaEffectSimulation::AesType_def::AtFunctionalArea:
|
|
case AreaEffectSimulation::AesType_def::AtBorderline:
|
|
case AreaEffectSimulation::AesType_def::AtTechnicalArea:
|
|
case AreaEffectSimulation::AesType_def::AtReconArea:
|
|
case AreaEffectSimulation::AesType_def::AtDusSingleMine:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionAreaSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtMineAreaSingleMines:
|
|
case AreaEffectSimulation::AesType_def::AtGasPipe:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentral:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentralTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrap:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMine:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionCluster:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterGunToTargetLine:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static inline int checkDuration(quint32 u_time, quint32 div, NGL::INGLLogger &logger)
|
|
{
|
|
const auto maxDuration = std::numeric_limits<int>::max() / div;
|
|
if (u_time > maxDuration)
|
|
{
|
|
WARNING_LOG(logger) << "Got an effect duration which is too long for us - limiting to "
|
|
<< maxDuration << "msec";
|
|
u_time = maxDuration;
|
|
Q_ASSERT(false);
|
|
}
|
|
const int timeMSec = static_cast<int>(u_time);
|
|
return timeMSec;
|
|
}
|
|
|
|
void AesHandler::onAesDurationChanged(qint64 identifierInt, quint32 u_time)
|
|
{
|
|
int aesItemId = 0;
|
|
AesType type = m_dtcAes->aesItemIdFromExternalId(identifierInt, aesItemId);
|
|
|
|
switch (type.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtMineCorridor:
|
|
{
|
|
MineCorridorModifyRequest *req = static_cast<MineCorridorModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
const int timeMSec = checkDuration(u_time, 60 * 60 * 1000, m_logger); // Hours
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineCorridor item = m_dtcAes->mineCorridor(aesItemId);
|
|
if (item.effectDuration() == timeMSec || !isModifiable(item))
|
|
return;
|
|
req = makeMinefieldBreachRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
req->effectDuration(timeMSec);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
{
|
|
MineAreaModifyRequest *req = static_cast<MineAreaModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
const int timeMSec = checkDuration(u_time, 60 * 60 * 1000, m_logger); // Hours
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineArea item = m_dtcAes->mineArea(aesItemId);
|
|
if (item.effectDuration() == timeMSec || !isModifiable(item))
|
|
return;
|
|
req = makeMinefieldRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
req->effectDuration(timeMSec);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionArea:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingle:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtAirSupportImpact:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtUnknown:
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
case AreaEffectSimulation::AesType_def::AtFunctionalArea:
|
|
case AreaEffectSimulation::AesType_def::AtBorderline:
|
|
case AreaEffectSimulation::AesType_def::AtTechnicalArea:
|
|
case AreaEffectSimulation::AesType_def::AtReconArea:
|
|
case AreaEffectSimulation::AesType_def::AtDusSingleMine:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionAreaSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtMineAreaSingleMines:
|
|
case AreaEffectSimulation::AesType_def::AtGasPipe:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentral:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentralTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrap:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMine:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionCluster:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterGunToTargetLine:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
void AesHandler::onAesChargeChanged(qint64 identifierInt, int chargeTypeId)
|
|
{
|
|
int aesItemId = 0;
|
|
AesType type = m_dtcAes->aesItemIdFromExternalId(identifierInt, aesItemId);
|
|
|
|
switch (type.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtMineCorridor:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
{
|
|
MineAreaModifyRequest *req = static_cast<MineAreaModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineArea item = m_dtcAes->mineArea(aesItemId);
|
|
if (item.chargeStruct().chargeTypeId() == chargeTypeId && !isModifiable(item))
|
|
return;
|
|
req = makeMinefieldRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
req->chargeStruct().chargeTypeId(chargeTypeId);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionArea:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingle:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtAirSupportImpact:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtUnknown:
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
case AreaEffectSimulation::AesType_def::AtFunctionalArea:
|
|
case AreaEffectSimulation::AesType_def::AtBorderline:
|
|
case AreaEffectSimulation::AesType_def::AtTechnicalArea:
|
|
case AreaEffectSimulation::AesType_def::AtReconArea:
|
|
case AreaEffectSimulation::AesType_def::AtDusSingleMine:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionAreaSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtMineAreaSingleMines:
|
|
case AreaEffectSimulation::AesType_def::AtGasPipe:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentral:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentralTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrap:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMine:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionCluster:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterGunToTargetLine:
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool getCorridorSegment(const std::vector<Core::GeoPosition2D> &pointsDataIn,
|
|
std::vector<Core::GeoPosition2D> &segmentsOut,
|
|
double &widthOut)
|
|
{
|
|
// P0 P3
|
|
// L *-------------------* L
|
|
// i | | i
|
|
// n * S0 S1 * n
|
|
// e | | e
|
|
// 1 *-------------------* 2
|
|
// P1 P2
|
|
|
|
// Calculate width = P0->P1
|
|
// Calculate S0, S1
|
|
|
|
if (pointsDataIn.size() != 4)
|
|
return false;
|
|
|
|
ParticipantPosition p0(pointsDataIn[0]);
|
|
ParticipantPosition p1(pointsDataIn[1]);
|
|
ParticipantPosition p2(pointsDataIn[2]);
|
|
ParticipantPosition p3(pointsDataIn[3]);
|
|
|
|
LtsCoordTrans::UtmCoordinate utmP0 = LtsCoordTrans::UtmCoordinate::fromGeographic(p0.toPoint());
|
|
LtsCoordTrans::UtmCoordinate utmP1 = LtsCoordTrans::UtmCoordinate::fromGeographic(p1.toPoint(), utmP0.zone);
|
|
LtsCoordTrans::UtmCoordinate utmP2 = LtsCoordTrans::UtmCoordinate::fromGeographic(p2.toPoint(), utmP0.zone);
|
|
LtsCoordTrans::UtmCoordinate utmP3 = LtsCoordTrans::UtmCoordinate::fromGeographic(p3.toPoint(), utmP0.zone);
|
|
|
|
QLineF line1(utmP0.x, utmP0.y, utmP1.x, utmP1.y);
|
|
widthOut = line1.length();
|
|
line1.setLength(0.5 * line1.length());
|
|
|
|
LtsCoordTrans::UtmCoordinate utmS0(utmP0.zone, line1.p2().x(), line1.p2().y(), utmP0.northp);
|
|
|
|
QLineF line2(utmP2.x, utmP2.y, utmP3.x, utmP3.y);
|
|
widthOut = line2.length();
|
|
line2.setLength(0.5 * line2.length());
|
|
|
|
LtsCoordTrans::UtmCoordinate utmS1(utmP0.zone, line2.p2().x(), line2.p2().y(), utmP0.northp);
|
|
|
|
segmentsOut.resize(2);
|
|
segmentsOut[0] = Core::GeoPosition2D(utmS0.geographic().x(), utmS0.geographic().y());
|
|
segmentsOut[1] = Core::GeoPosition2D(utmS1.geographic().x(), utmS1.geographic().y());
|
|
|
|
return true;
|
|
}
|
|
|
|
void AesHandler::onAesPointsDataChanged(qint64 identifierInt, const std::vector<Core::GeoPosition2D> &pos)
|
|
{
|
|
int aesItemId = 0;
|
|
AesType type = m_dtcAes->aesItemIdFromExternalId(identifierInt, aesItemId);
|
|
|
|
DEBUG_LOG(m_logger) << "Points Data changed for Aes Item ID: " << aesItemId << ". Type: " << type;
|
|
|
|
switch (type.underlying())
|
|
{
|
|
case AreaEffectSimulation::AesType_def::AtBCContamination:
|
|
break;
|
|
case AreaEffectSimulation::AesType_def::AtMineCorridor:
|
|
{
|
|
MineCorridorModifyRequest *req = static_cast<MineCorridorModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineCorridor item = m_dtcAes->mineCorridor(aesItemId);
|
|
if (!isModifiable(item))
|
|
return;
|
|
req = makeMinefieldBreachRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
|
|
double width;
|
|
std::vector<Core::GeoPosition2D> segments;
|
|
if (!getCorridorSegment(pos, segments, width))
|
|
{
|
|
ERROR_LOG(m_logger) << "Could not calculate Mine Area from given Points Data!";
|
|
return;
|
|
}
|
|
req->segments(segments);
|
|
req->width(width);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtMineArea:
|
|
{
|
|
MineAreaModifyRequest *req = static_cast<MineAreaModifyRequest*>(m_pendingRequests.value(aesItemId));
|
|
if (!req)
|
|
{
|
|
AreaEffectSimulation::MineArea item = m_dtcAes->mineArea(aesItemId);
|
|
if (!isModifiable(item))
|
|
return;
|
|
req = makeMinefieldRequest(item);
|
|
addRequestToQueue(aesItemId, req);
|
|
}
|
|
|
|
double width;
|
|
std::vector<Core::GeoPosition2D> segments;
|
|
if (!getCorridorSegment(pos, segments, width))
|
|
{
|
|
ERROR_LOG(m_logger) << "Could not calculate Mine Area from given Points Data!";
|
|
return;
|
|
}
|
|
req->segments(segments);
|
|
req->isCenterLine(true);
|
|
req->width(width);
|
|
break;
|
|
}
|
|
case AreaEffectSimulation::AesType_def::AtNContamination:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionArea:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingle:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtAirSupportImpact:
|
|
break; // Maybe handled later
|
|
case AreaEffectSimulation::AesType_def::AtUnknown:
|
|
case AreaEffectSimulation::AesType_def::AtDangerArea:
|
|
case AreaEffectSimulation::AesType_def::AtFunctionalArea:
|
|
case AreaEffectSimulation::AesType_def::AtBorderline:
|
|
case AreaEffectSimulation::AesType_def::AtTechnicalArea:
|
|
case AreaEffectSimulation::AesType_def::AtReconArea:
|
|
case AreaEffectSimulation::AesType_def::AtDusSingleMine:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionAreaSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtMineAreaSingleMines:
|
|
case AreaEffectSimulation::AesType_def::AtGasPipe:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentral:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionSingleCentralTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrap:
|
|
case AreaEffectSimulation::AesType_def::AtBoobyTrapSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMine:
|
|
case AreaEffectSimulation::AesType_def::AtOffRouteMineSecondary:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionCluster:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleExplosions:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterSingleTrajectory:
|
|
case AreaEffectSimulation::AesType_def::AtExplosionClusterGunToTargetLine:
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool AesHandler::onNewMinefield(const MineAreaModifyRequest &ma)
|
|
{
|
|
if (!ma.externalId())
|
|
return false;
|
|
|
|
return m_requestHelper->startSingleRequest([this, ma]()
|
|
{
|
|
return m_ftcAes->mineAreaModifyRequest(ma, this);
|
|
});
|
|
}
|
|
template <>
|
|
void AesHandler::onSendRequest(const MineAreaModifyRequest &item)
|
|
{
|
|
onNewMinefield(item);
|
|
}
|
|
|
|
bool AesHandler::onNewMinefieldBreach(const MineCorridorModifyRequest &mc)
|
|
{
|
|
if (!mc.externalId().is_set())
|
|
return false;
|
|
|
|
return m_requestHelper->startSingleRequest([this, mc]()
|
|
{
|
|
return m_ftcAes->mineCorridorModifyRequest(mc, this);
|
|
});
|
|
}
|
|
template <>
|
|
void AesHandler::onSendRequest(const MineCorridorModifyRequest &item)
|
|
{
|
|
onNewMinefieldBreach(item);
|
|
}
|
|
|
|
void AesHandler::onMunitionDetonation(const ExplosionSingleModifyRequest &es)
|
|
{
|
|
if (!es.externalId().is_set())
|
|
return;
|
|
|
|
m_requestHelper->startSingleRequest([this, es]()
|
|
{
|
|
return m_ftcAes->explosionSingleModifyRequest(es, this);
|
|
});
|
|
}
|
|
|
|
#ifdef SUPPORT_EXPLOSION_CLUSTER_SINGLE_EFFECT
|
|
void AesHandler::onMunitionDetonationExplosionClusterSingleEffect(const ExplosionClusterSingleEffectOnlyRequest &es)
|
|
{
|
|
if (!es.externalId().is_set())
|
|
return;
|
|
|
|
m_requestHelper->startSingleRequest([this, es]()
|
|
{
|
|
return m_ftcAes->explosionClusterSingleEffectOnlyModifyRequest(es, this);
|
|
});
|
|
}
|
|
#endif // SUPPORT_EXPLOSION_CLUSTER_SINGLE_EFFECT
|
|
|
|
template <>
|
|
void AesHandler::onSendRequest(const ExplosionSingleModifyRequest &item)
|
|
{
|
|
onMunitionDetonation(item);
|
|
}
|
|
|
|
template <typename T>
|
|
void AesHandler::addRequestToQueue(int aesItemId, T *request)
|
|
{
|
|
m_pendingRequests.insert(aesItemId, request);
|
|
QTimer::singleShot(100, this, [this, request, aesItemId]()
|
|
{
|
|
onSendRequest(*request);
|
|
m_pendingRequests.take(aesItemId);
|
|
delete request;
|
|
});
|
|
}
|
|
|
|
} // namespace HighLevelArchitecture
|