/** * Handler for all indirect fire single objects * $Id$ * $HeadURL$ * $Author$ */ #include "handler_air_support_impact.h" #include "main_handler.h" namespace AreaEffectSimulation { HandlerAirSupportImpact::HandlerAirSupportImpact(MainHandler *mainHandler) : HandlerBaseTmpl(mainHandler, QStringLiteral("AirSupportImpact"), s_areaCount[AesType::AtAirSupportImpact], s_areaCountCentral[AesType::AtAirSupportImpact]) , Interface::Fts::AirSupportImpactModifyRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::AirSupportImpactRemoveRequestHandler(mainHandler->dds()->fts()) {} bool HandlerAirSupportImpact::init() { QVector dataVec; // read all indirect air support impact from database if (!m_mainHandler->db()->select(dataVec)) { ERROR_LOG(m_logger) << "Error reading data from database!"; return true; } // create air support impact objects for (const Database::AesAirSupportImpact &dbData : qAsConst(dataVec)) { ObjectAirSupportImpact *ifs(new ObjectAirSupportImpact(m_mainHandler, this)); connect(ifs, &ObjectAirSupportImpact::effectStateChanged, this, &HandlerAirSupportImpact::onEffectStateChanged); Core::FunctionReplyObject ret = ifs->createObject(dbData); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); return false; } if (totalAreas() >= s_maxActiveAreas[AesType::AtAirSupportImpact]) { ERROR_LOG(m_logger) << "More active air support in database than allowed - ignoring the rest!"; delete ifs; continue; } if (ifs->isObjectInTrainingArea()) ++m_areaCount; m_objectMap.insert(ifs->id(), ifs); connect(ifs, &ObjectAirSupportImpact::newAiv, this, &HandlerAirSupportImpact::newAiv); connect(ifs, &ObjectAirSupportImpact::removeAiv, this, &HandlerAirSupportImpact::removeAiv); } return true; } int HandlerAirSupportImpact::totalAreas() const { return s_areaCount[AesType::AtAirSupportImpact]; } int HandlerAirSupportImpact::totalAreasCentral() const { return s_areaCountCentral[AesType::AtAirSupportImpact]; } static void fillData(const AirSupportImpactModifyRequest &src, Database::AesAirSupportImpact &dst) { if (src.id() < 0) // is the id given as negative? set id -> used by OC-Laptop dst.id = src.id(); dst.impactPosition.rx() = src.impactPosition().lon(); dst.impactPosition.ry() = src.impactPosition().lat(); dst.name = QString::fromStdString(src.name()); dst.effectStart = src.effectStart().is_set() && src.effectStart().get() > 0 ? QDateTime::fromMSecsSinceEpoch(src.effectStart().get()) : QDateTime(); dst.effectDuration = 1000; // 1sec 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.flightTime = src.flightTime(); dst.externalId = src.externalId().is_set() ? src.externalId().get() : 0; } void HandlerAirSupportImpact::onAirSupportImpactModifyRequest(const rti::core::SampleIdentity &cookie, const AirSupportImpactModifyRequest &request) { DEBUG_LOG(m_logger) << "onAirSupportModifyRequest: " << request << " ..."; Core::FunctionReplyObject ret = airSupportImpactModifyRequest(request); if (ret.error()) WARNING_LOG(m_logger) << ret(); bool bSuccess = m_mainHandler->dds()->fts()->airSupportImpactModifyReply(cookie, ret); DEBUG_LOG(m_logger) << "onAirSupportModifyRequest: " << request << " ... Done (bSuccess="<< bSuccess << ")" << ", ret.id()=" << ret.id(); } Core::FunctionReplyObject HandlerAirSupportImpact::airSupportImpactCreateRequest(const AirSupportImpactModifyRequest &request) { if (totalAreas() >= s_maxActiveAreas[AesType::AtAirSupportImpact] && request.effectStart().is_set()) { ERROR_LOG(m_logger) << LOGFUNCTION << " Too many active air support impacts, request:" << request; return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active air support impacts.")); } Database::AesAirSupportImpact newData; fillData(request, newData); // check: effectStart > time(NULL) ? ObjectAirSupportImpact *ifs(new ObjectAirSupportImpact(m_mainHandler, this)); connect(ifs, &ObjectAirSupportImpact::effectStateChanged, this, &HandlerAirSupportImpact::onEffectStateChanged); const Core::FunctionReplyObject ret = ifs->createObject(newData); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << LOGFUNCTION << " could no createObject, request:" << request; return ret; } m_objectMap.insert(ifs->id(), ifs); if (ifs->isObjectInTrainingArea()) { ++m_areaCount; DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtairSupport] = " << m_areaCount; } connect(ifs, &ObjectAirSupportImpact::newAiv, this, &HandlerAirSupportImpact::newAiv); connect(ifs, &ObjectAirSupportImpact::removeAiv, this, &HandlerAirSupportImpact::removeAiv); DEBUG_LOG(m_logger) << LOGFUNCTION << " created, request:" << request; return ret; } Core::FunctionReplyObject HandlerAirSupportImpact::airSupportImpactModifyRequest(const AirSupportImpactModifyRequest &request) { Core::FunctionReplyObject ret; if (request.id() == 0 || ((request.id() < 0) && (getObjectFromMap(m_objectMap, std::abs(request.id()), ret) == nullptr))) { DEBUG_LOG(m_logger) << LOGFUNCTION << " handle as createRequest, request:" << request; return airSupportImpactCreateRequest(request); } ObjectAirSupportImpact *ifs = getObjectFromMap(m_objectMap, std::abs(request.id()), ret); if (ifs == nullptr) { ERROR_LOG(m_logger) << LOGFUNCTION << " getObjectFromMap failed, request:" << request; 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::AtAirSupportImpact] && request.effectStart().is_set() && !ifs->isActivationTimeSet() && !ifs->isObjectModifiable()) { ERROR_LOG(m_logger) << LOGFUNCTION << " Too many active air support impacts, request:" << request; return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active air support impacts.")); } Database::AesAirSupportImpact aes(ifs->data()); fillData(request, aes); if (request.id() < 0 && checkStateForSfm(ifs)) { DEBUG_LOG(m_logger) << "Overwrite air support impact Effect State for OC"; aes.effectStateId = AesEffectState::EsPrepared; } ret = ifs->updateObject(aes); DEBUG_LOG(m_logger) << LOGFUNCTION << " request:" << request << " -> reply: " << ret() << " (reply" << ret.id() << ")"; return ret; } void HandlerAirSupportImpact::onAirSupportImpactRemoveRequest(const rti::core::SampleIdentity &cookie, const Core::RemoveElementRequest &request) { DEBUG_LOG(m_logger) << "onAirSupportImpactRemoveRequest: " << request << " ..."; bool bSuccess = m_mainHandler->dds()->fts()->airSupportImpactRemoveReply(cookie, removeReply(&AreaEffectSimulation::DatabaseInterface::removeAesAirSupportImpact, request)); DEBUG_LOG(m_logger) << "onAirSupportImpactRemoveRequest: " << request << " ... Done (bSuccess=" << bSuccess << ")"; } } // namespace AreaEffectSimulation