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

151 lines
4.7 KiB
C++
Executable File

/**
* Handler for all DUS single mine objects
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, NLST, 2018-06-28
*/
#include "handler_dus_single_mine.h"
#include "object_dus_single_mine.h"
#include "settings.h"
#include "aes_db.h"
#include <QDateTime>
namespace AreaEffectSimulation
{
HandlerDusSingleMine::HandlerDusSingleMine(MainHandler *mainHandler)
: HandlerBaseTmpl<ObjectDusSingleMine>(mainHandler, QStringLiteral("DusSingleMine"), s_areaCount[AesType::AtMineArea], s_areaCountCentral[AesType::AtMineArea])
, m_tabDtc(mainHandler->dds()->tabDtc())
{}
bool HandlerDusSingleMine::init()
{
// create DusSingleMine objects
bool bRet = true;
auto cb = [this, &bRet] (const Database::AesDusSingleMine &data)
{
// Create and init Object
ObjectDusSingleMine *ifs(new ObjectDusSingleMine(m_mainHandler, this));
Core::FunctionReplyObject ret = ifs->createObject(data);
if(ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
bRet = false;
return;
}
// If active or prepared, check if it still can be handled and increment area count
if (ifs->isObjectInTrainingArea())
{
if (totalAreas() >= s_maxActiveAreas[AesType::AtDusSingleMine])
{
ERROR_LOG(m_logger) << "More active DUS single mines in database than allowed - ignoring the rest!";
delete ifs;
return;
}
++m_areaCount;
}
// Push into Map
m_objectMap.insert(ifs->id(), ifs);
if (ifs->effectState() >= AesEffectState::EsCreated) // add active AES to map
m_activeMineIdToAesItemId.insert(ifs->data().mineId, ifs->id());
};
if(!m_mainHandler->db()->select(cb) || !bRet)
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
DEBUG_LOG(m_logger) << "m_exeObjMap.size() = " << m_objectMap.size();
connect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::dusSingleMineStateChanged,
this, &HandlerDusSingleMine::onDusSingleMineState);
connect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::mineTriggeredChanged,
this, &HandlerDusSingleMine::onMineTriggered);
if (!m_tabDtc->enableDusSingleMineState() ||
!m_tabDtc->enableMineTriggered())
{
ERROR_LOG(m_logger) << "Could not initialize TraininAreaBase data topic client";
return false;
}
return true;
}
int HandlerDusSingleMine::totalAreas() const
{
return s_areaCount[AesType::AtDusSingleMine];
}
int HandlerDusSingleMine::totalAreasCentral() const
{
return s_areaCountCentral[AesType::AtDusSingleMine];
}
void HandlerDusSingleMine::onDusSingleMineState(const TrainingAreaBase::DusSingleMineState &data, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
if (totalAreas() >= s_maxActiveAreas[AesType::AtDusSingleMine])
{
WARNING_LOG(m_logger) << "Too many active DUS single mines.";
return;
}
// set old AES item to expired
if (m_activeMineIdToAesItemId.contains(data.mineId()))
{
m_objectMap.value(m_activeMineIdToAesItemId.value(data.mineId()))->setExpired();
m_activeMineIdToAesItemId.remove(data.mineId());
}
if (data.state())
{
Database::AesDusSingleMine newData;
newData.mineId = data.mineId();
newData.effectStart = QDateTime::fromMSecsSinceEpoch(data.effectStart() + Settings::getDusSingleMineEffectStartOffset()); // offset to get away from mine after laying it
if (newData.effectStart <= m_mainHandler->dds()->currentPartitionTime()) // telegram arrived late -> start effect area now
newData.effectStart = QDateTime::fromMSecsSinceEpoch(m_mainHandler->dds()->currentPartitionTimeMSec() + 100); // needs to be slightly in the future
newData.position.rx() = data.position().lon();
newData.position.ry() = data.position().lat();
newData.chargeTypeId = data.chargeTypeId();
ObjectDusSingleMine *ifs(new ObjectDusSingleMine(m_mainHandler, this));
connect(ifs, &ObjectDusSingleMine::effectStateChanged, this, &HandlerDusSingleMine::onEffectStateChanged);
Core::FunctionReplyObject ret = ifs->createObject(newData, true);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << "Could not create DUS single mine object: " << ret.str();
return;
}
m_objectMap.insert(ifs->id(), ifs);
m_activeMineIdToAesItemId.insert(ifs->data().mineId, ifs->id());
}
return;
}
void HandlerDusSingleMine::onMineTriggered(const TrainingAreaBase::MineTriggered &data, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
auto it = m_objectMap.constFind(data.mineAreaId());
if (it == m_objectMap.cend()) // is it a DUS single mine or just a normal mineArea?
return;
it.value()->setExpired();
m_activeMineIdToAesItemId.remove(it.value()->data().mineId);
}
} // Namespace AreaEffectSimulation