/** * Handler for all off route mines * $Id$ * $HeadURL$ * $Author$ * Created by Hanna E. Rathje, SLSE, 2023-07-13 */ #include "handler_off_route_mine.h" namespace AreaEffectSimulation { HandlerOffRouteMine::HandlerOffRouteMine(MainHandler *mainHandler) : HandlerBaseTmpl(mainHandler, QStringLiteral("OffRouteMine"), s_areaCount[AesType::AtOffRouteMine], s_areaCountCentral[AesType::AtOffRouteMine]) , Interface::Fts::OffRouteMineModifyRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::OffRouteMineRemoveRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::OffRouteMineTriggerRequestHandler(mainHandler->dds()->fts()) {} bool HandlerOffRouteMine::init() { bool bRet = true; auto cb = [this, &bRet] (const Database::AesOffRouteMine &data) { ObjectOffRouteMine *ifs(new ObjectOffRouteMine(m_mainHandler, this)); connect(ifs, &ObjectOffRouteMine::effectStateChanged, this, &HandlerOffRouteMine::onEffectStateChanged); Core::FunctionReplyObject ret = ifs->createObject(data); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); bRet = false; return; } if (totalAreasCentral() >= s_maxActiveAreasCentral[AesType::AtOffRouteMine]) { ERROR_LOG(m_logger) << "More active off route mines in database than allowed - ignoring the rest!"; ifs->removeObject(); delete ifs; return; } m_objectMap.insert(ifs->id(), ifs); connect(ifs, &ObjectOffRouteMine::newAiv, this, &HandlerOffRouteMine::newAiv); connect(ifs, &ObjectOffRouteMine::removeAiv, this, &HandlerOffRouteMine::removeAiv); if (ifs->isObjectInTrainingArea()) { ++m_areaCount; DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtBCContamination] = " << m_areaCount; } }; if (!m_mainHandler->db()->select(cb) || !bRet) { ERROR_LOG(m_logger) << "Error reading data from database!"; return true; } DEBUG_LOG(m_logger) << "m_exeObjMap.size() = " << m_objectMap.size(); return true; } int HandlerOffRouteMine::totalAreas() const { return s_areaCount[AesType::AtOffRouteMine]; } int HandlerOffRouteMine::totalAreasCentral() const { return s_areaCountCentral[AesType::AtOffRouteMine]; } static void fillData(const OffRouteMineModifyRequest &src, Database::AesOffRouteMine &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.area().cornerBottomLeft().lon(); dst.impactPosition.ry() = src.area().cornerBottomLeft().lat(); dst.width = src.area().width(); dst.length = src.area().height(); dst.rotationAngle = src.area().rotation(); dst.impactRadius = src.impactRadius().is_set() ? src.impactRadius().get() : 0; dst.partyId = src.partyId().is_set() ? src.partyId().get() : 0; dst.chargeTypeId = src.chargeTypeId(); dst.isCentral = true; dst.triggered = false; //dst.participantId = src.participantId().is_set() ? src.participantId().get() : 0; //dst.externalId = src.externalId().is_set() ? src.externalId().get() : 0; } void HandlerOffRouteMine::onOffRouteMineModifyRequest(const rti::core::SampleIdentity &cookie, const OffRouteMineModifyRequest &request) { DEBUG_LOG(m_logger) << "onOffRouteMineModifyRequest: " << request; const Core::FunctionReplyObject ret = offRouteMineModifyRequest(request); if (ret.error()) WARNING_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->offRouteMineModifyReply(cookie, ret); } Core::FunctionReplyObject HandlerOffRouteMine::offRouteMineCreateRequest(const OffRouteMineModifyRequest &request) { if (totalAreasCentral() >= (s_maxActiveAreasCentral[AesType::AtOffRouteMine]) && request.effectStart().is_set()) return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active off route mines.")); Database::AesOffRouteMine newData; fillData(request, newData); ObjectOffRouteMine *ifs(new ObjectOffRouteMine(m_mainHandler, this)); connect(ifs, &ObjectOffRouteMine::effectStateChanged, this, &HandlerOffRouteMine::onEffectStateChanged); Core::FunctionReplyObject ret = ifs->createObject(newData); if (ret.error()) { delete ifs; return ret; } connect(ifs, &ObjectOffRouteMine::newAiv, this, &HandlerOffRouteMine::newAiv); connect(ifs, &ObjectOffRouteMine::removeAiv, this, &HandlerOffRouteMine::removeAiv); if (ifs->isObjectInTrainingArea()) { ++m_areaCountCentral; DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtOffRouteMine] = " << m_areaCount; } m_objectMap.insert(ifs->id(), ifs); return ret; } Core::FunctionReplyObject HandlerOffRouteMine::offRouteMineModifyRequest(const OffRouteMineModifyRequest &request) { Core::FunctionReplyObject ret; ObjectOffRouteMine *ifs = nullptr; if (request.id() == 0 || ((request.id() < 0) && !getObjectFromMap(m_objectMap, std::abs(request.id()), ret))) return offRouteMineCreateRequest(request); ifs = getObjectFromMap(m_objectMap, std::abs(request.id()), ret); if (!ifs) return ret; if (request.effectStart().is_set() && (request.effectStart().get() + request.effectDuration() < m_mainHandler->dds()->currentPartitionTime().toMSecsSinceEpoch())) return removeObject(ifs); // Anzahl aktiver Areas ist erreicht, der Wirkbeginn ist (soll) gesetzt sein, aber die Area war // vorher noch ohne Wirkbeginn /*! * If the effect start added after creation, the max amount need to be checked !*/ if (totalAreasCentral() >= (s_maxActiveAreasCentral[AesType::AtOffRouteMine]) && request.effectStart().is_set() && !ifs->isActivationTimeSet() // check if time before change was not setted. /*&& !ifs->isObjectModifiable()*/) { return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Too many active off route mines.")); } Database::AesOffRouteMine aea(ifs->data()); fillData(request, aea); if (request.id() < 0 && checkStateForSfm(ifs)) { DEBUG_LOG(m_logger) << "Overwrite off route mine Effect State for OC"; aea.effectStateId = AesEffectState::EsPrepared; } return ifs->updateObject(aea); } void HandlerOffRouteMine::onOffRouteMineRemoveRequest(const rti::core::SampleIdentity &cookie, const Core::RemoveElementRequest &request) { m_mainHandler->dds()->fts()->offRouteMineRemoveReply(cookie, removeReply(&DatabaseInterface::removeAesOffRouteMine, request)); } void HandlerOffRouteMine::onOffRouteMineTriggerRequest(const rti::core::SampleIdentity &cookie, const OffRouteMineTriggerRequest &request) { DEBUG_LOG(m_logger) << "onOffRouteMineTriggerRequest: " << request; const Core::FunctionReplyObject ret = offRouteMineTriggerRequest(request); if (ret.error()) WARNING_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->offRouteMineTriggerReply(cookie, ret); } Core::FunctionReplyObject HandlerOffRouteMine::offRouteMineTriggerRequest(const OffRouteMineTriggerRequest &request) { Core::FunctionReplyObject ret; ObjectOffRouteMine *ifs = getObjectFromMap(m_objectMap, std::abs(request.id()), ret); if (!ifs) return ret; Database::AesOffRouteMine aea(ifs->data()); DEBUG_LOG(m_logger) << "Overwrite off route mine Effect State "; aea.effectStateId = AesEffectState_def::EsExpired; aea.triggered = request.triggered(); aea.effectDuration = aea.effectStart.msecsTo(QDateTime::currentDateTimeUtc()); if (aea.effectDuration < 0) aea.effectDuration = 1; return ifs->updateObject(aea); } } // Namespace AreaEffectSimulation