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

299 lines
11 KiB
C++
Executable File

/**
* Handler for all exercise objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-03
*/
#include "handler_ncontamination.h"
#include "Utils/polygons.h"
#include <QPolygonF>
namespace AreaEffectSimulation
{
HandlerNContamination::HandlerNContamination(MainHandler *mainHandler)
: HandlerBaseTmpl<ObjectNContamination>(mainHandler, QStringLiteral("NContamination"), s_areaCount[AesType::AtNContamination], s_areaCountCentral[AesType::AtNContamination])
, Interface::Fts::NContaminationModifyRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::NContaminationRemoveRequestHandler(mainHandler->dds()->fts())
{}
bool HandlerNContamination::init()
{
QVector<Database::AesNContamination> dataVec;
// read all NContaminations from database
if (!m_mainHandler->db()->select(dataVec))
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return true;
}
DEBUG_LOG(m_logger) << "TotalC: " << totalAreasCentral() << " Total: " << totalAreas();
for (const Database::AesNContamination &dbData : qAsConst(dataVec))
{
ObjectNContamination *ifs(new ObjectNContamination(m_mainHandler, this));
connect(ifs, &ObjectNContamination::effectStateChanged, this, &HandlerNContamination::onEffectStateChanged);
connect(ifs, &ObjectNContamination::changedToCentral, this, &HandlerNContamination::onChangedToCentral);
Core::FunctionReplyObject ret = ifs->createObject(dbData);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
return false;
}
if(!ifs->data().isCentral)
{
if (totalAreas() >= (s_maxActiveAreas[AesType::AtBCContamination] + s_maxActiveAreas[AesType::AtNContamination]))
{
ERROR_LOG(m_logger) << "More active n contaminations in database than allowed - ignoring the rest!";
ifs->removeObject();
delete ifs;
continue;
}
}
else
{
if (totalAreasCentral() >= (s_maxActiveAreasCentral[AesType::AtBCContamination] + s_maxActiveAreasCentral[AesType::AtNContamination]))
{
ERROR_LOG(m_logger) << "More active n contaminations in database than allowed - ignoring the rest!";
ifs->removeObject();
delete ifs;
continue;
}
}
if (ifs->isObjectInTrainingArea())
{
if (ifs->data().isCentral)
++m_areaCountCentral;
else
++m_areaCount;
}
m_objectMap.insert(ifs->id(), ifs);
connect(ifs, &ObjectNContamination::newAiv, this, &HandlerNContamination::newAiv);
connect(ifs, &ObjectNContamination::removeAiv, this, &HandlerNContamination::removeAiv);
}
DEBUG_LOG(m_logger) << "m_exeObjMap.size() = " << m_objectMap.size();
return true;
}
int HandlerNContamination::totalAreas() const
{
return s_areaCount[AesType::AtBCContamination] + s_areaCount[AesType::AtNContamination];
}
int HandlerNContamination::totalAreasCentral() const
{
return s_areaCountCentral[AesType::AtBCContamination] + s_areaCountCentral[AesType::AtNContamination];
}
void HandlerNContamination::onChangedToCentral()
{
s_areaCount[AesType::AtNContamination]--;
s_areaCountCentral[AesType::AtNContamination]++;
DEBUG_LOG(m_logger) << "m_areaCount after Recount = " << m_areaCount;
DEBUG_LOG(m_logger) << "m_areaCountCentral after Recount = " << m_areaCountCentral;
}
static void fillData(const NContaminationModifyRequest &src, Database::AesNContamination &dst)
{
if (src.id() < 0) // is the id given as negative? set id -> used by OC-Laptop
dst.id = src.id();
dst.name = QString::fromStdString(src.name());
dst.effectStart = src.effectStart().is_set() && src.effectStart().get() > 0 ? QDateTime::fromMSecsSinceEpoch(src.effectStart().get()) : QDateTime();
dst.effectDuration = src.effectDuration();
dst.impactPosition.rx() = src.impactPosition().lon();
dst.impactPosition.ry() = src.impactPosition().lat();
dst.impactRadius = src.impactRadius();
dst.borderLengthInner = src.borderLengthInner();
dst.borderLengthOuter = src.borderLengthOuter();
dst.spanAngle = src.spanAngle();
dst.rotationAngle = src.rotationAngle();
dst.detonationValue = src.detonationValue();
dst.partyId = src.partyId().is_set() ? src.partyId().get() : 0;
dst.chargeTypeId = src.chargeTypeId();
dst.participantId = src.participantId().is_set() ? src.participantId().get() : 0;
dst.externalId = src.externalId().is_set() ? src.externalId().get() : 0;
dst.weatherSourceId = src.weatherSource();
}
void HandlerNContamination::onNContaminationModifyRequest(const rti::core::SampleIdentity &cookie,
const NContaminationModifyRequest &request)
{
DEBUG_LOG(m_logger) << "onNContaminationModifyRequest: " << request;
const Core::FunctionReplyObject ret = nContaminationModifyRequest(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->nContaminationModifyReply(cookie, ret);
}
Core::FunctionReplyObject HandlerNContamination::nContaminationCreateRequest(const NContaminationModifyRequest &request)
{
Database::AesNContamination newData;
fillData(request, newData);
// check: effectStart > time(NULL) ?
ObjectNContamination *ifs(new ObjectNContamination(m_mainHandler, this));
connect(ifs, &ObjectNContamination::effectStateChanged, this, &HandlerNContamination::onEffectStateChanged);
Core::FunctionReplyObject ret = ifs->createObject(newData);
if (ret.error())
{
delete ifs;
return ret;
}
if (ifs->data().isCentral)
{
if (totalAreasCentral() >= (s_maxActiveAreasCentral[AesType::AtNContamination] + s_maxActiveAreasCentral[AesType::AtBCContamination]) && request.effectStart().is_set())
{
ifs->removeObject(); //Not finally deleted from db after this,Fallback if DB deletion is not working correct
ifs->removeObjectFromDb();
delete ifs;
return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active central N or B/C contamination areas."));
}
}
else
{
if (totalAreas() >= (s_maxActiveAreas[AesType::AtNContamination] + s_maxActiveAreas[AesType::AtBCContamination]) && request.effectStart().is_set())
{
ifs->removeObject(); //Not finally deleted from db after this,Fallback if DB deletion is not working correct
ifs->removeObjectFromDb();
delete ifs;
return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active N or B/C contamination areas."));
}
}
if (ifs->data().isCentral)
{
++m_areaCountCentral;
DEBUG_LOG(m_logger) << "s_areaCountCentral[AesType::AtBCContamination] = " << m_areaCountCentral;
}
else if (ifs->isObjectInTrainingArea())
{
++m_areaCount;
DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtNContamination] = " << m_areaCount;
}
m_objectMap.insert(ifs->id(), ifs);
connect(ifs, &ObjectNContamination::newAiv, this, &HandlerNContamination::newAiv);
connect(ifs, &ObjectNContamination::removeAiv, this, &HandlerNContamination::removeAiv);
return ret;
}
Core::FunctionReplyObject HandlerNContamination::nContaminationModifyRequest(const NContaminationModifyRequest &request)
{
Core::FunctionReplyObject ret;
if (request.id() == 0 || ((request.id() < 0) && !getObjectFromMap(m_objectMap, std::abs(request.id()), ret)))
return nContaminationCreateRequest(request);
ObjectNContamination *ifs = getObjectFromMap(m_objectMap, std::abs(request.id()), ret);
if (!ifs)
return ret;
// Anzahl aktiver Areas ist erreicht, der Wirkbeginn ist (soll) gesetzt sein, aber die Area war
// vorher noch ohne Wirkbeginn
// if (totalAreas() >= (s_maxActiveAreas[AesType::AtBCContamination] + s_maxActiveAreas[AesType::AtNContamination]) && request.effectStart().is_set() && !ifs->isObjectModifiable())
// return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Too many active N contamination areas."));
Database::AesNContamination aea(ifs->data());
fillData(request, aea);
// Calculate new polygon here. Not nice, though
auto poly = Polygons::nContamination(aea);
std::vector<Core::GeoPosition> _form;
ObjectBase::ddsVecFromPoly(poly, _form);
bool isCentral = ifs->checkIsCentral(_form);
bool wasCentral = ifs->data().isCentral;
/*!
* If the effect start added after creation, the max amount need to be checked
*/
if(!ifs->isActivationTimeSet() && request.effectStart().is_set())
{
if (isCentral)
{
if (totalAreasCentral() >= (s_maxActiveAreasCentral[AesType::AtNContamination] + s_maxActiveAreasCentral[AesType::AtBCContamination]) /*&& request.effectStart().is_set()*/)
{
return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active central N or B/C contamination areas."));
}
}
else
{
if (totalAreas() >= (s_maxActiveAreas[AesType::AtNContamination] + s_maxActiveAreas[AesType::AtBCContamination]) /*&& request.effectStart().is_set()*/) // upper if-condition handle start-time
{
return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active N or B/C contamination areas."));
}
}
}
// For counting, only Elements being at least prepared are important:
if (request.effectStart().is_set() && ifs->isObjectModifiable())
{
DEBUG_LOG(m_logger) << "isCentral: " << isCentral;
DEBUG_LOG(m_logger) << "wasCentral: " << wasCentral;
// only change if element changed from central to training area or vice versa
if (isCentral != wasCentral)
{
// Change from central to training area
if (wasCentral)
{
if (totalAreas() >= (s_maxActiveAreas[AesType::AtBCContamination] + s_maxActiveAreas[AesType::AtNContamination]))
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Too many active N or B/C contamination areas."));
m_areaCount++;
m_areaCountCentral--;
DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtBCContamination] = " << m_areaCount;
DEBUG_LOG(m_logger) << "s_areaCountCentral[AesType::AtBCContamination] = " << m_areaCountCentral;
}
else // Change from training area to central
{
if (totalAreasCentral() >= (s_maxActiveAreasCentral[AesType::AtBCContamination] + s_maxActiveAreasCentral[AesType::AtNContamination]))
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Too many active central N or B/C contamination areas."));
m_areaCount--;
m_areaCountCentral++;
DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtBCContamination] = " << m_areaCount;
DEBUG_LOG(m_logger) << "s_areaCountCentral[AesType::AtBCContamination] = " << m_areaCountCentral;
}
}
}
if (request.id() < 0 && checkStateForSfm(ifs))
{
DEBUG_LOG(m_logger) << "Overwrite n contamination Effect State for OC";
aea.effectStateId = AesEffectState::EsPrepared;
}
return ifs->updateObject(aea);
}
void HandlerNContamination::onNContaminationRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request)
{
m_mainHandler->dds()->fts()->nContaminationRemoveReply(cookie, removeReply(&DatabaseInterface::removeAesNContamination, request));
}
} // Namespace AreaEffectSimulation