/** * @RDE_HEADER@ * Handler for all exercise objects * $Id$ * $HeadURL$ * $Author$ * Created by Norbert Thoden, SLSE, 2023-10 */ #include "handler_explosion_cluster.h" #include "handler_charge_administration.h" #include #include #include #include #include // for TrajectoryGenerator #include namespace AreaEffectSimulation { HandlerExplosionCluster::HandlerExplosionCluster(MainHandler *mainHandler) : HandlerBaseTmpl(mainHandler, QStringLiteral("HandlerExplosionCluster"), s_areaCount[static_cast(AesType::AtExplosionCluster)], s_areaCountCentral[static_cast(AesType::AtExplosionCluster)]) , Interface::Fts::ExplosionClusterModifyRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::ExplosionClusterSingleEffectOnlyModifyRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::ExplosionClusterOcModifyRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::ExplosionClusterRemoveRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::ExplosionClusterPauseResumeRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::TargetPositionsModifyRequestHandler(mainHandler->dds()->fts()) , Interface::Fts::ExplosionClusterReleaseReceivedRequestHandler(mainHandler->dds()->fts()) { } bool HandlerExplosionCluster::init() { // create explosion cluster objects bool bRet = true; auto cb = [this, &bRet] (const Database::AesExplosionCluster &data) { ObjectExplosionCluster *ifs(new ObjectExplosionCluster(m_mainHandler, this)); connect(ifs, &ObjectExplosionCluster::effectStateChanged, this, &HandlerExplosionCluster::onEffectStateChanged); Core::FunctionReplyObject ret = ifs->createObject(data); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); bRet = false; return true; } // Context NASAT: check via chargeTypeId: const bool bChargeIsAirSupport = m_mainHandler->dds()->pdmDtc()->gearClassFromChargeTypeId(ifs->data().chargeTypeId) == ProjectDataManagement::GearClass::GearClass_AirSupport; ifs->setAirSupportSource(bChargeIsAirSupport); if(!ifs->data().isCentral) { if (bChargeIsAirSupport) { // Note: s_currentAirSupportCount is updated via overloaded recountActiveAreas if(s_currentAirSupportCount >= s_maxAirSupportCount) { ERROR_LOG(m_logger) << "More active air supports in database than allowed - ignoring the rest!"; ifs->removeObject(); delete ifs; return true; } } else if (totalAreas() >= s_maxActiveAreas[static_cast(AesType::AtExplosionCluster)]) { ERROR_LOG(m_logger) << "More active explosion areas in database than allowed - ignoring the rest!"; ifs->removeObject(); delete ifs; return true; } } else { if (totalAreasCentral() >= (s_maxActiveAreasCentral[static_cast(AesType::AtExplosionCluster)])) { ERROR_LOG(m_logger) << "More active explosion areas in database than allowed - ignoring the rest!"; ifs->removeObject(); delete ifs; return true; } } if (ifs->isObjectInTrainingArea()) { if (ifs->data().isCentral) ++m_areaCountCentral; else ++m_areaCount; } m_objectMap.insert(ifs->id(), ifs); connect(ifs, &ObjectExplosionCluster::newAiv, this, &HandlerExplosionCluster::newAiv); connect(ifs, &ObjectExplosionCluster::removeAiv, this, &HandlerExplosionCluster::removeAiv); return true; }; 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(); DEBUG_LOG(m_logger) << "m_areaCount = " << m_areaCount; DEBUG_LOG(m_logger) << "m_areaCountCentral = " << m_areaCountCentral; return true; } int HandlerExplosionCluster::totalAreas() const { return s_areaCount[static_cast(AesType::AtExplosionCluster)]; } int HandlerExplosionCluster::totalAreasCentral() const { return s_areaCountCentral[static_cast(AesType::AtExplosionCluster)] ; } static void fillData(const ExplosionClusterModifyRequest &src, Database::AesExplosionCluster &dst, MainHandler *mainHandler) { 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.element = QString::fromStdString(src.element); dst.impactPosition.rx() = src.area.cornerBottomLeft.lon; dst.impactPosition.ry() = src.area.cornerBottomLeft.lat; dst.impactLength = src.area.height; dst.impactWidth = src.area.width; dst.rotationAngle = src.area.rotation; const bool bIsPointSimilar = (src.explosionGeometry == AreaEffectSimulation::AesExplosionGeometry::EgAimPoint) || (src.explosionGeometry == AreaEffectSimulation::AesExplosionGeometry::EgPoint); if (bIsPointSimilar && ((src.area.width <= 0) || (src.area.height <= 0))) { const Core::GeoPosition2D &cornerBottomLeft = src.area.cornerBottomLeft; const double impactDiameter = mainHandler->dds()->pdmDtc()->impactRadius(src.chargeStruct.chargeTypeId, src.chargeStruct.igniterTypeId, src.chargeStruct.igniterFunctionId) * 2.0; // GUEZE-2634 const QPointF bottomLeft(Polygons::centerPoint2BottomLeft(QPointF(cornerBottomLeft.lon, cornerBottomLeft.lat), impactDiameter, impactDiameter, 0)); dst.impactPosition.rx() = bottomLeft.x(); dst.impactPosition.ry() = bottomLeft.y(); dst.impactLength = impactDiameter; dst.impactWidth = impactDiameter; } dst.explosionGeometryId = src.explosionGeometry; dst.zog = src.tla; dst.effectStart = src.effectStart.is_set() && src.effectStart.get() > 0 ? QDateTime::fromMSecsSinceEpoch(src.effectStart.get()) : QDateTime(); dst.effectDuration = src.effectDuration; dst.effectSourceId = src.effectSourceId; dst.chargeTypeId = src.chargeStruct.chargeTypeId; dst.igniterTypeId = src.chargeStruct.igniterTypeId; dst.igniterFunctionId = src.chargeStruct.igniterFunctionId; dst.firePurposeId = src.firePurposeId; dst.partyId = src.partyId.is_set() ? src.partyId.get() : 0; dst.participantId = src.participantId.is_set() ? src.participantId.get() : -1; // -1 -> avoid trajectory // dst.firingGeoPosition // not provided, has to be retrieved from dds dst.impactCount = src.impactCount; dst.mhpCountRequest = src.mhpCount; if (src.mhpRotation.is_set()) dst.mhpRotationRequest = src.mhpRotation.get(); else dst.mhpRotationRequest = ObjectExplosionCluster::s_invalid_rotation_angle; dst.altitude = -1; dst.peakHeight = src.peakHeight; dst.flightDuration = src.flightDuration; // dst.originatorId = src.o(); // dst.firePurpose = QString::fromStdString(src.purpose()); // dst.fireRequestTime = QDateTime::fromMSecsSinceEpoch(src.fireRequestTime()); dst.effectMarkingInTa = src.effectMarkingInTa; dst.externalId = src.externalId.is_set() ? src.externalId.get() : 0; dst.launchVelocity = src.launchVelocity; dst.launchAngleDeg = src.launchAngleDeg; dst.dropAngle = src.dropAngle; dst.tapTimepoint = src.tapTime; dst.lcPrf = src.lcAttack; dst.lcTermination = src.lcTermination; dst.cloudBase = src.cloudBase; dst.properties = QString::fromStdString(src.properties); dst.esmParticipantIds = LtsUtils::IntArray(src.esmParticipantIds); } void HandlerExplosionCluster::onExplosionClusterModifyRequest(const rti::core::SampleIdentity &cookie, const ExplosionClusterModifyRequest &request) { DEBUG_LOG(m_logger) << "************************************ onExplosionClusterModifyRequest: " << request; Core::FunctionReplyObject ret = explosionClusterModifyRequest(cookie, request); if (ret.error()) WARNING_LOG(m_logger) << ret() << ", effectStart :" << request.effectStart; ret.setAdditionalInfo(request.properties.c_str()); m_mainHandler->dds()->fts()->explosionClusterModifyReply(cookie, ret); } void HandlerExplosionCluster::onExplosionClusterSingleEffectOnlyModifyRequest(const rti::core::SampleIdentity &cookie, const ExplosionClusterSingleEffectOnlyRequest &request) { DEBUG_LOG(m_logger) << "************************************ onExplosionClusterSingleEffectModifyRequest: " << request; // generalize the specific request to the common one. (similar an 'upcast') // in other words: ExplosionClusterSingleEffectOnlyRequest -> ExplosionClusterModifyRequest: ExplosionClusterModifyRequest ecCommonModifyRequest; ecCommonModifyRequest.id = request.id; ecCommonModifyRequest.externalId = request.externalId; ecCommonModifyRequest.effectStart = request.effectStart; ecCommonModifyRequest.effectDuration = 1000; // charge and geometry: ecCommonModifyRequest.explosionGeometry = AreaEffectSimulation::AesExplosionGeometry::EgPoint; // ecCommonModifyRequest.zog(0); int igniterTypeId = 102; // from pdm_igniter_type (Impact Default) ecCommonModifyRequest.chargeStruct.igniterTypeId = igniterTypeId; ecCommonModifyRequest.chargeStruct.chargeTypeId = request.chargeTypeId; // height, width are <=0 -> area will be adjusted using impactRadius of charge: ecCommonModifyRequest.area.cornerBottomLeft = request.impactPosition; ecCommonModifyRequest.area.height = 0; ecCommonModifyRequest.area.width = 0; ecCommonModifyRequest.mhpCount = 1; ecCommonModifyRequest.impactCount = 1; ecCommonModifyRequest.name = request.name; // ZpNummer ecCommonModifyRequest.element = request.element; // element ecCommonModifyRequest.partyId = request.partyId; ecCommonModifyRequest.participantId = -1; // -1 -> avoid trajectory Core::FunctionReplyObject ret = explosionClusterModifyRequest(cookie, ecCommonModifyRequest); if (ret.error()) WARNING_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->explosionClusterSingleEffectOnlyModifyReply(cookie, ret); } void HandlerExplosionCluster::onExplosionClusterOcModifyRequest(const rti::core::SampleIdentity &cookie, const ExplosionClusterOcModifyRequest &request) { DEBUG_LOG(m_logger) << "************************************ onExplosionClusterOcModifyRequest: " << request; // generalize the specific request to the common one. (similar an 'upcast') // in other words: ExplosionClusterSingleEffectOnlyRequest -> ExplosionClusterModifyRequest: ExplosionClusterModifyRequest ecCommonModifyRequest; ecCommonModifyRequest.id = request.id; //ecCommonModifyRequest.externalId(request.externalId()); ecCommonModifyRequest.effectStart = request.effectStart; ecCommonModifyRequest.effectDuration = request.effectDuration; // charge and geometry: ecCommonModifyRequest.area = request.area; if (request.impactCount == 1) ecCommonModifyRequest.explosionGeometry = AreaEffectSimulation::AesExplosionGeometry::EgPoint; else ecCommonModifyRequest.explosionGeometry = AreaEffectSimulation::AesExplosionGeometry::EgArea; // ecCommonModifyRequest.zog(0); ecCommonModifyRequest.mhpCount = request.mhpCount; ecCommonModifyRequest.impactCount = request.impactCount; ecCommonModifyRequest.mhpRotation = request.mhpRotation; // was FtImpact ecCommonModifyRequest.chargeStruct.igniterTypeId = request.chargeStruct.igniterTypeId; ecCommonModifyRequest.chargeStruct.chargeTypeId = request.chargeStruct.chargeTypeId; ecCommonModifyRequest.name = request.name; // ZpNummer ecCommonModifyRequest.element = ecCommonModifyRequest.element; // element ecCommonModifyRequest.partyId = request.partyId; // ecCommonModifyRequest.participantId(-1); // -1 -> avoid trajectory // ToDo: no trajectory needed, but how can we transfer the rotation of MhpAreas? // ToDo: no trajectory needed, but how can we transfer the rotation of MhpAreas? // ToDo: no trajectory needed, but how can we transfer the rotation of MhpAreas? // ToDo: how to transfer request.mhpRotation?? Core::FunctionReplyObject ret = explosionClusterModifyRequest(cookie, ecCommonModifyRequest); if (ret.error()) WARNING_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->explosionClusterOcModifyReply(cookie, ret); } Core::FunctionReplyObject HandlerExplosionCluster::explosionClusterCreateRequest(const ExplosionClusterModifyRequest &request) { // HLA Interface is using externalId... // external (externalId>0) -> no partyId required // external (externalId==0) -> partyId required const int externalIdValue = request.externalId.is_set() ? request.externalId.get() : 0; const ProjectDataManagement::GearClass gearClass = m_mainHandler->gearClassOfChargeTypeId(request.chargeStruct.chargeTypeId); const bool bDoClaimPlannedCharge = (request.id == 0) && (externalIdValue==0) && (gearClass != ProjectDataManagement::GearClass::GearClass_AirSupport); if (bDoClaimPlannedCharge) { int chargeNeeded = request.impactCount; if (chargeNeeded <= 0) return Core::FunctionReplyObject(tr_lts("dds", "Invalid impact count (<= 0).")); if (request.id == 0) { int chargeLeft = m_mainHandler->chargeAdministrationHandler()->availableCharge(request.chargeStruct.chargeTypeId, request.partyId.get()); QString chargeName= QString::fromStdString(m_mainHandler->dds()->pdmDtc()->chargeType(request.chargeStruct.chargeTypeId).name); QString fireUnitName; if (request.participantId.is_set()) fireUnitName = QString::fromStdString(m_mainHandler->dds()->ppmDtc()->participant(request.participantId.get()).designator); if (chargeNeeded > chargeLeft) return Core::FunctionReplyObject(tr_lts("dds", "Invalid impact count. Fire Unit '%1' has %2 charges (%3), but for this cluster %4 are needed.")) .arg(fireUnitName) .arg((chargeLeft)) .arg(chargeName) .arg(chargeNeeded); } } Database::AesExplosionCluster newData; fillData(request, newData, m_mainHandler); if (!request.properties.empty() && (!request.effectStart.is_set() || request.effectStart.get() == 0)) { QJsonObject propertiesObject = QJsonDocument::fromJson(QByteArray::fromStdString(request.properties)).object(); newData.isUsingEffectStateReceived = propertiesObject.value(QStringLiteral("useReceived")).toBool(); } // check: effectStart > time(NULL) ? ObjectExplosionCluster *ifs(new ObjectExplosionCluster(m_mainHandler, this)); connect(ifs, &ObjectExplosionCluster::effectStateChanged, this, &HandlerExplosionCluster::onEffectStateChanged); // Context NASAT: check via chargeTypeId: const ProjectDataManagement::GearClass gc = m_mainHandler->dds()->pdmDtc()->gearClassFromChargeTypeId(request.chargeStruct.chargeTypeId); const bool bChargeIsAirSupport = gc == ProjectDataManagement::GearClass::GearClass_AirSupport; ifs->setAirSupportSource(bChargeIsAirSupport); const Core::FunctionReplyObject ret = ifs->createObject(newData); if (ret.error()) { delete ifs; return ret; } INFO_LOG(m_logger) << "IS Central: " << ifs->data().isCentral; if (ifs->data().isCentral) { DEBUG_LOG(m_logger) << "New cen ExplosionCluster"; if(gearClass == ProjectDataManagement::GearClass::GearClass_AirSupport) { if (s_currentAirSupportCount >= s_maxAirSupportCount) { ifs->removeObject(); //Not finally deleted from db after this,Fallback if DB deletion is not working correct ifs->removeObjectFromDb(); delete ifs; return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active air supports.")); } } else if (totalAreasCentral() >= (s_maxActiveAreasCentral[static_cast(AesType::AtExplosionCluster)]) + (s_currentAirSupportCount) && request.effectStart.is_set()) { ifs->removeObject(); //Not finally deleted from db after this,Fallback if DB deletion is not working correct ifs->removeObjectFromDb(); delete ifs; return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active central explosion areas.")); } } else { DEBUG_LOG(m_logger) << "New dec ExplosionCluster: " << totalAreas() << " Max: " << s_maxActiveAreas[static_cast(AesType::AtExplosionCluster)] << " Is Set: " << request.effectStart.is_set(); if (totalAreas() >= (s_maxActiveAreas[static_cast(AesType::AtExplosionCluster)]) && request.effectStart.is_set()) { ifs->removeObject(); //Not finally deleted from db after this,Fallback if DB deletion is not working correct ifs->removeObjectFromDb(); delete ifs; return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active explosion areas.")); } } if (ifs->data().isCentral) { ++m_areaCountCentral; DEBUG_LOG(m_logger) << "m_areaCountCentral " << m_areaCountCentral; } else if (ifs->isObjectInTrainingArea()) { ++m_areaCount; DEBUG_LOG(m_logger) << "m_areaCount = " << m_areaCount; } else { DEBUG_LOG(m_logger) << "Counting of [AesType::AtExplosionCluster] not affected"; } m_objectMap.insert(ifs->id(), ifs); connect(ifs, &ObjectExplosionCluster::newAiv, this, &HandlerExplosionCluster::newAiv); connect(ifs, &ObjectExplosionCluster::removeAiv, this, &HandlerExplosionCluster::removeAiv); return ret; } Core::FunctionReplyObject HandlerExplosionCluster::explosionClusterModifyRequest(const rti::core::SampleIdentity &cookie, const ExplosionClusterModifyRequest &request ) { // // externalId maybe set be HLA interface: // // from external (externalIdValue>0) -> no partyId required // // from internal (externalIdValue==0) -> partyId required // const int externalIdValue = request.externalId.is_set() ? request.externalId.get() : 0; // if (externalIdValue == 0 && !request.partyId.is_set()) // return Core::FunctionReplyObject(tr_lts("dds", "Explosion areas need a party id.")); DEBUG_LOG(m_logger) << "request.effectStart :" << request.effectStart << ", effectDuration :" << request.effectDuration << ", flightDuration :" << request.flightDuration << ", tapTime :" << request.tapTime << ", properties: " << request.properties; Core::FunctionReplyObject ret; if (request.id == 0 || ((request.id < 0) && !getObjectFromMap(m_objectMap, std::abs(request.id), ret))) return explosionClusterCreateRequest(request); ObjectExplosionCluster *ifs = getObjectFromMap(m_objectMap, std::abs(request.id), ret); if (!ifs) return ret; ifs->setCookie(cookie); AreaEffectSimulation::Database::AesExplosionCluster aea(ifs->data()); fillData(request, aea, m_mainHandler); // Context NASAT: check via chargeTypeId: const ProjectDataManagement::GearClass gc = m_mainHandler->dds()->pdmDtc()->gearClassFromChargeTypeId(request.chargeStruct.chargeTypeId); const bool bChargeIsAirSupport = (gc == ProjectDataManagement::GearClass::GearClass_AirSupport); ifs->setAirSupportSource(bChargeIsAirSupport); // For counting, only Elements being at least prepared are important: if (request.effectStart.is_set() && ifs->isObjectModifiable()) // ToDo: check { // Calculate new polygon here. Not nice, though auto poly = Polygons::explosionClusterArea(aea); std::vector _form; ObjectBase::ddsVecFromPoly(poly, _form); bool isCentral = ifs->checkIsCentral(_form); bool wasCentral = ifs->data().isCentral; DEBUG_LOG(m_logger) << "isCentral: " << isCentral; DEBUG_LOG(m_logger) << "wasCentral: " << wasCentral; if (isCentral) { if (bChargeIsAirSupport) { if (s_currentAirSupportCount >= s_maxAirSupportCount) { return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active air supports.")); } } else { // case 1: war zentral && effectStart war nicht gesetzt // case 2: war dezentral && effectStart ist gesetzt. if (totalAreasCentral() >= (s_maxActiveAreasCentral[static_cast(AesType::AtExplosionCluster)] + (s_currentAirSupportCount)) && request.effectStart.is_set() && ((wasCentral && !ifs->isActivationTimeSet()) || !wasCentral)) { return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active central explosion clusters.")); } } } else { // case 1: war dezentral && effectStart war nicht gesetzt // case 2: war zentral && effectStart ist gesetzt. if (totalAreas() >= (s_maxActiveAreas[static_cast(AesType::AtExplosionCluster)]) && request.effectStart.is_set() && (( !wasCentral && !ifs->isActivationTimeSet()) || wasCentral)) { return Core::FunctionReplyObject(1, tr_lts("dds", "Too many active explosion clusters.")); } } // For counting, only Elements being at least prepared are important: if (request.effectStart.is_set() && ifs->isObjectModifiable()) { DEBUG_LOG(m_logger) << "isCentral: " << isCentral; DEBUG_LOG(m_logger) << "wasCentral: " << wasCentral; // only change if element changed from central to training area or vice versa if ((isCentral != wasCentral)) { // Change from central to training area if (wasCentral) { if (totalAreas() >= (s_maxActiveAreas[static_cast(AesType::AtExplosionCluster)])) return Core::FunctionReplyObject(request.id, tr_lts("dds", "Too many active explosion clusters.")); m_areaCount++; m_areaCountCentral--; DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtExplosionCluster] = " << m_areaCount; DEBUG_LOG(m_logger) << "s_areaCountCentral[AesType::AtExplosionCluster] = " << m_areaCountCentral; } else // Change from training area to central { if (totalAreasCentral() >= (s_maxActiveAreasCentral[static_cast(AesType::AtExplosionCluster)])) return Core::FunctionReplyObject(request.id, tr_lts("dds", "Too many active central explosion clusters.")); m_areaCount--; m_areaCountCentral++; DEBUG_LOG(m_logger) << "s_areaCount[AesType::AtExplosionCluster] = " << m_areaCount; DEBUG_LOG(m_logger) << "s_areaCountCentral[AesType::AtExplosionCluster] = " << m_areaCountCentral; } } } } if (request.id < 0 && checkStateForSfm(ifs)) { DEBUG_LOG(m_logger) << "Overwrite Effect State for OC"; aea.effectStateId = AesEffectState::EsPrepared; } DEBUG_LOG(m_logger) << "request.properties()" << request.properties << " aea.properties=" << aea.properties; return ifs->updateObject(aea); } // unused /* Core::FunctionReplyObject HandlerExplosionCluster::explosionClusterModifyGeometryRequest(const ExplosionClusterModifyRequest &request) { // WARNING: request.area.cornerBottomLeft() contains center point! Core::FunctionReplyObject ret; ObjectExplosionCluster *ifs = getObjectFromMap(m_objectMap, request.id(), ret); if (!ifs) 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::AtExplosionArea] + s_maxActiveAreas[AesType::AtExplosionSingle]) && request.effectStart.is_set() && !ifs->isObjectModifiable()) return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Too many active explosion areas.")); // Todo: IsObjectModifiable() ?!? AreaEffectSimulation::Database::AesExplosionCluster aea(ifs->data()); aea.impactPosition = Polygons::centerPoint2BottomLeft(QPointF(request.area().cornerBottomLeft().lon(), request.area().cornerBottomLeft().lat()), ifs->data().impactWidth, ifs->data().impactLength, request.area().rotation()); aea.rotationAngle = request.area().rotation(); return ifs->updateObject(aea); } */ /* Core::FunctionReplyObject HandlerExplosionCluster::modifyPartyParticipant(qint32 itemId, qint32 partyId, qint32 participantId) { ObjectExplosionCluster *ifs = m_objectMap.value(itemId); if (!ifs) return Core::FunctionReplyObject(itemId, tr_lts("dds", "Explosion Cluster with id %1 not found.")).arg(itemId); AreaEffectSimulation::Database::AesExplosionCluster aea(ifs->data()); aea.partyId = partyId; aea.participantId= participantId; return ifs->updateObject(aea); } */ void HandlerExplosionCluster::recountActiveAreas() { s_currentAirSupportCount = 0; for (const auto *area : qAsConst(m_objectMap)) { if (area->isObjectInTrainingArea()) // meanwhile an ugly name, means EsPrepared, EsActivated, EsPaused { if (m_mainHandler->gearClassOfChargeTypeId(area->data().chargeTypeId) == ProjectDataManagement::GearClass::GearClass_AirSupport) ++s_currentAirSupportCount; } } HandlerBaseTmpl::recountActiveAreas(); DEBUG_LOG(m_logger) << "m_areaCount after Recount = " << m_areaCount; DEBUG_LOG(m_logger) << "m_areaCountCentral after Recount = " << m_areaCountCentral; DEBUG_LOG(m_logger) << "m_areaCount s_currentAirSupportCount after Recount = " << s_currentAirSupportCount; } void HandlerExplosionCluster::onExplosionClusterRemoveRequest(const rti::core::SampleIdentity &cookie, const Core::RemoveElementRequest &request) { DEBUG_LOG(m_logger) << "************************************ onExplosionClusterRemoveRequest: " << request; m_mainHandler->dds()->fts()->explosionClusterRemoveReply(cookie, removeReply(&DatabaseInterface::removeAesExplosionCluster, request)); } void HandlerExplosionCluster::onExplosionClusterPauseResumeRequest(const rti::core::SampleIdentity &cookie, const ExplosionClusterPauseResumeRequest &request) { DEBUG_LOG(m_logger) << "onExplosionClusterPauseResumeRequest" << request; Core::FunctionReplyObject ret; ObjectExplosionCluster *ifs = getObjectFromMap(m_objectMap, request.id, ret); if (!ifs) { m_mainHandler->dds()->fts()->explosionClusterPauseResumeReply(cookie, ret); return; } ret = ifs->resumePause(request); if (ret.error()) ERROR_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->explosionClusterPauseResumeReply(cookie, ret); } void HandlerExplosionCluster::onExplosionClusterReleaseReceivedRequest(const rti::core::SampleIdentity &cookie, const ExplosionClusterReleaseReceivedRequest &request) { DEBUG_LOG(m_logger) << "onExplosionClusterReleaseReceivedRequest" << request; Core::FunctionReplyObject ret(request.id); ObjectExplosionCluster *ifs = getObjectFromMap(m_objectMap, request.id, ret); if (!ifs) { ERROR_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->explosionClusterReleaseReceivedReply(cookie, ret); return; } if (!ifs->isUsingEffectStateReceived()) { ret = ret.setStr(tr_lts("dds", "ExplosionCluster with id %1 is not using EffectState Received")).arg(request.id); ERROR_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->explosionClusterReleaseReceivedReply(cookie, ret); return; } ifs->setUseEffectStateReceived(false); ifs->checkEnterNewState(); if (ret.error()) ERROR_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->explosionClusterReleaseReceivedReply(cookie, ret); } void HandlerExplosionCluster::onTargetPositionsModifyRequest(const rti::core::SampleIdentity &cookie, const TargetPositionsModifyRequest &request) { DEBUG_LOG(m_logger) << "onTargetPositionsModifyRequest" << request; Core::FunctionReplyObject ret; ObjectExplosionCluster *ifs = getObjectFromMap(m_objectMap, request.aesItemId, ret); if (!ifs) { m_mainHandler->dds()->fts()->targetPositionsModifyReply(cookie, ret); return; } ret = ifs->targetPositionsModify(request); if (ret.error()) ERROR_LOG(m_logger) << ret(); m_mainHandler->dds()->fts()->targetPositionsModifyReply(cookie, ret); } } // Namespace AreaEffectSimulation