/** * 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[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