/** * 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 namespace AreaEffectSimulation { HandlerDusSingleMine::HandlerDusSingleMine(MainHandler *mainHandler) : HandlerBaseTmpl(mainHandler, QStringLiteral("DusSingleMine"), s_areaCount[static_cast(AesType::AtMineArea)], s_areaCountCentral[static_cast(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[static_cast(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[static_cast(AesType::AtDusSingleMine)]; } int HandlerDusSingleMine::totalAreasCentral() const { return s_areaCountCentral[static_cast(AesType::AtDusSingleMine)]; } void HandlerDusSingleMine::onDusSingleMineState(const TrainingAreaBase::DusSingleMineState &data, DataModification modType) { if (modType == DataModification::eRemoved) return; if (totalAreas() >= s_maxActiveAreas[static_cast(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