/** * Get notifications about changed AES Explosions/MineAreas * $Id$ * $HeadURL$ * $Author$ */ #include #include "handler_aes_data.h" #include "object_aes_data.h" #include "handler_effect_show_vehicle_status.h" #include "effect_show_mine_area.h" #include "effect_show_explosion_area.h" #include "effect_show_explosion_cluster.h" #include "settings.h" using namespace EffectShowManagement; HandlerAesData::HandlerAesData(Initialization *mainHandler) : QObject() , m_mainHandler(mainHandler) , m_logger(getLogger("HandlerAesData")) { } // end of ctor() //============================================================================= HandlerAesData::~HandlerAesData() { qDeleteAll(m_AesDataObjMap); m_AesDataObjMap.clear(); } // end of dtor() //============================================================================= bool HandlerAesData::init() { DEBUG_LOG(m_logger) << "Begin HandlerAesData"; // create ObjectAesData auto cbAes = [this](const Database::EsmAesData & data) { ObjectAesData *ifs(new ObjectAesData(m_mainHandler, this)); ifs->setData(data); m_AesDataObjMap.insert(data.idAes, ifs); }; if (!m_mainHandler->db()->select(cbAes)) { ERROR_LOG(m_logger) << "Error reading data from database!"; return false; } auto dtcAes = m_mainHandler->dds()->dtcAes(); connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::explosionAreaChanged, this, &HandlerAesData::onExplosionAreaChanged); connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::explosionClusterChanged, this, &HandlerAesData::onExplosionClusterChanged, Qt::UniqueConnection); connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::effectClusterChanged, this, &HandlerAesData::onEffectClusterChanged, Qt::UniqueConnection); connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::explosionSingleChanged, this, &HandlerAesData::onExplosionSingleChanged); connect(dtcAes.get(), &AreaEffectSimulation::Interface::Dtc::mineAreaChanged, this, &HandlerAesData::onMineAreaChanged); // Get current data for all ExplosionArea { auto cb = [this](const AreaEffectSimulation::ExplosionArea & explosionArea) { onExplosionAreaChanged(explosionArea, DataModification::eAdded); }; if (!dtcAes->explosionAreas(cb)) return false; } // Get current data for all ExplosionArea { auto cb = [this](const AreaEffectSimulation::ExplosionSingle & explosionSingle) { onExplosionSingleChanged(explosionSingle, DataModification::eAdded); }; if (!dtcAes->explosionSingles(cb)) return false; } // Get current data for all ExplosionCluster { auto cb = [this](const AreaEffectSimulation::ExplosionCluster & explosionCluster) { onExplosionClusterChanged(explosionCluster, DataModification::eAdded); }; if (!dtcAes->explosionClusters(cb)) return false; } // Get current data for all EffectCluster { auto cb = [this](const AreaEffectSimulation::EffectCluster & effectCluster) { onEffectClusterChanged(effectCluster, DataModification::eAdded); }; if (!dtcAes->effectClusters(cb)) return false; } // Get current data for all MineArea { auto cb = [this](const AreaEffectSimulation::MineArea & mineArea) { onMineAreaChanged(mineArea, DataModification::eAdded); }; if (!dtcAes->mineAreas(cb)) return false; } DEBUG_LOG(m_logger) << "m_AesDataObjMap.size() = " << m_AesDataObjMap.size(); return true; } // end of init() //============================================================================= void HandlerAesData::onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType) { const Core::GeoPosition2D &posLl = data.impactPosition(); AreaEffectSimulation::ExplosionArea areaData; areaData.altitude(data.altitude()); areaData.cannonCount(1); areaData.cannonRounds(1); areaData.chargeStruct().chargeTypeId(data.chargeStruct().chargeTypeId()); areaData.effectDuration(data.effectDuration()); areaData.effectMarkingInTa(data.effectMarkingInTa()); areaData.effectStart(data.effectStart()); areaData.effectStateId(data.effectStateId()); areaData.externalId(data.externalId()); areaData.fireRequestTime(data.fireRequestTime()); areaData.remainExplosionNumber(1); areaData.id(data.id()); areaData.name(data.name()); areaData.isDeleted(data.isDeleted()); areaData.isUsed(data.isUsed()); AreaEffectSimulation::Area area; area.cornerBottomLeft(posLl); area.height(50); area.width(50); areaData.area(area); HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed; if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa()) kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(areaData), modType); ObjectAesData *ifs = m_AesDataObjMap.value(data.id()); if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs) kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData; DEBUG_LOG(m_logger) << "Got ExplosionArea: " << "\n ID: " << data.id() << "\n Name: " << data.name() << "\n Effect status: " << data.effectStateId() << "\n Effect show (y/n): " << data.effectMarkingInTa() << "\n Lower left Pos: " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat()) << "\n Start: " << data.effectStart() << "\n Duration: " << data.effectDuration() << "\n Modification: " << modType << "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification); switch (kindOfModification) { case HandlerEffectShow::KindOfModification_e::Added: { ifs = new ObjectAesData(m_mainHandler); Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(areaData)); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); } else { m_AesDataObjMap.insert(data.id(), ifs); m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(areaData, kindOfModification); } break; } case HandlerEffectShow::KindOfModification_e::ModifiedArea: case HandlerEffectShow::KindOfModification_e::ModifiedData: case HandlerEffectShow::KindOfModification_e::Paused: case HandlerEffectShow::KindOfModification_e::Continued: { if (ifs != nullptr) { const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(areaData)); if (!ret.error()) m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(areaData, kindOfModification); else ERROR_LOG(m_logger) << ret(); } else WARNING_LOG(m_logger) << "Explosion Area not available for modification: " << data.id(); break; } case HandlerEffectShow::KindOfModification_e::Removed: { if (ifs != nullptr) { if (!m_AesDataObjMap.remove(data.id())) ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed."; Core::FunctionReplyObject ret = ifs->removeObject(); if (ret.error()) ERROR_LOG(m_logger) << ret(); } m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(areaData, kindOfModification); break; } case HandlerEffectShow::KindOfModification_e::None: break; } } // onExplosionSingleChanged //============================================================================= //============================================================================= void HandlerAesData::onExplosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType) { HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed; if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa()) kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(data), modType); ObjectAesData *ifs = m_AesDataObjMap.value(data.id()); if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs) kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData; const Core::GeoPosition2D &posLl = data.area().cornerBottomLeft(); DEBUG_LOG(m_logger) << "Got ExplosionArea: " << "\n ID: " << data.id() << "\n Name: " << data.name() << "\n Effect status: " << data.effectStateId() << "\n Effect show (y/n): " << data.effectMarkingInTa() << "\n Lower left Pos: " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat()) << "\n Width: " << data.area().width() << "\n Height: " << data.area().height() << "\n Rotation: " << data.area().rotation() << "\n Start: " << data.effectStart() << "\n Duration: " << data.effectDuration() << "\n Modification: " << modType << "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification); switch (kindOfModification) { case HandlerEffectShow::KindOfModification_e::Added: { ifs = new ObjectAesData(m_mainHandler); Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(data)); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); } else { m_AesDataObjMap.insert(ifs->getId(), ifs); m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(data, kindOfModification); } break; } case HandlerEffectShow::KindOfModification_e::ModifiedArea: case HandlerEffectShow::KindOfModification_e::ModifiedData: case HandlerEffectShow::KindOfModification_e::Paused: case HandlerEffectShow::KindOfModification_e::Continued: { if (ifs != nullptr) { const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(data)); if (!ret.error()) m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(data, kindOfModification); else ERROR_LOG(m_logger) << ret(); } else WARNING_LOG(m_logger) << "Explosion Area not available for modification: " << data.id(); break; } case HandlerEffectShow::KindOfModification_e::Removed: { if (ifs != nullptr) { if (!m_AesDataObjMap.remove(data.id())) ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed."; Core::FunctionReplyObject ret = ifs->removeObject(); if (ret.error()) ERROR_LOG(m_logger) << ret(); } m_mainHandler->handlerEffectShow()->onExplosionAreaChanged(data, kindOfModification); break; } case HandlerEffectShow::KindOfModification_e::None: break; } }// onExplosionAreaChanged //============================================================================= void HandlerAesData::onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, DataModification modType) { HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed; if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa()) kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(data), modType); ObjectAesData *ifs = m_AesDataObjMap.value(data.id()); if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs) kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData; const Core::GeoPosition2D &posLl = data.area().cornerBottomLeft(); DEBUG_LOG(m_logger) << ">>>> Got Cluster: " << "\n ID: " << data.id() << "\n Name: " << data.name() << "\n Effect status: " << data.effectStateId() << "\n Effect show (y/n): " << data.effectMarkingInTa() << "\n Lower left Pos: " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat()) << "\n Width: " << data.area().width() << "\n Height: " << data.area().height() << "\n Rotation: " << data.area().rotation() << "\n Start: " << data.effectStart() << "\n Duration: " << data.effectDuration() << "\n Modification: " << modType << "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification); switch (kindOfModification) { case HandlerEffectShow::KindOfModification_e::Added: { ifs = new ObjectAesData(m_mainHandler); Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(data)); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); } else { m_AesDataObjMap.insert(data.id(), ifs); m_mainHandler->handlerEffectShow()->onExplosionClusterChanged(data, kindOfModification); } break; } case HandlerEffectShow::KindOfModification_e::ModifiedArea: case HandlerEffectShow::KindOfModification_e::ModifiedData: case HandlerEffectShow::KindOfModification_e::Paused: case HandlerEffectShow::KindOfModification_e::Continued: { if (ifs != nullptr) { const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(data)); if (!ret.error()) m_mainHandler->handlerEffectShow()->onExplosionClusterChanged(data, kindOfModification); else ERROR_LOG(m_logger) << ret(); } else WARNING_LOG(m_logger) << "Explosion Area not available for modification: " << data.id(); break; } case HandlerEffectShow::KindOfModification_e::Removed: { if (ifs != nullptr) { if (!m_AesDataObjMap.remove(data.id())) ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed."; Core::FunctionReplyObject ret = ifs->removeObject(); if (ret.error()) ERROR_LOG(m_logger) << ret(); } m_mainHandler->handlerEffectShow()->onExplosionClusterChanged(data, kindOfModification); break; } case HandlerEffectShow::KindOfModification_e::None: break; } } void HandlerAesData::onEffectClusterChanged(const AreaEffectSimulation::EffectCluster &data, DataModification modType) { HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed; if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa()) kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(data), modType); ObjectAesData *ifs = m_AesDataObjMap.value(data.id()); if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs) kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData; const Core::GeoPosition2D &posLl = data.area().cornerBottomLeft(); DEBUG_LOG(m_logger) << ">>>> Got EffectCluster: " << "\n ID: " << data.id() << "\n Name: " << data.name() << "\n Effect status: " << data.effectStateId() << "\n Effect show (y/n): " << data.effectMarkingInTa() << "\n Lower left Pos: " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat()) << "\n Width: " << data.area().width() << "\n Height: " << data.area().height() << "\n Rotation: " << data.area().rotation() << "\n Start: " << data.effectStart() << "\n Duration: " << data.effectDuration() << "\n Modification: " << modType << "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification); switch (kindOfModification) { case HandlerEffectShow::KindOfModification_e::Added: { ifs = new ObjectAesData(m_mainHandler); Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(data)); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); } else { m_AesDataObjMap.insert(data.id(), ifs); m_mainHandler->handlerEffectShow()->onEffectClusterChanged(data, kindOfModification); } break; } case HandlerEffectShow::KindOfModification_e::ModifiedArea: case HandlerEffectShow::KindOfModification_e::ModifiedData: case HandlerEffectShow::KindOfModification_e::Paused: case HandlerEffectShow::KindOfModification_e::Continued: { if (ifs != nullptr) { const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(data)); if (!ret.error()) m_mainHandler->handlerEffectShow()->onEffectClusterChanged(data, kindOfModification); else ERROR_LOG(m_logger) << ret(); } else WARNING_LOG(m_logger) << "Explosion Area not available for modification: " << data.id(); break; } case HandlerEffectShow::KindOfModification_e::Removed: { if (ifs != nullptr) { if (!m_AesDataObjMap.remove(data.id())) ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed."; Core::FunctionReplyObject ret = ifs->removeObject(); if (ret.error()) ERROR_LOG(m_logger) << ret(); } m_mainHandler->handlerEffectShow()->onEffectClusterChanged(data, kindOfModification); break; } case HandlerEffectShow::KindOfModification_e::None: break; } } // onExplosionClusterChanged //============================================================================= void HandlerAesData::onMineAreaChanged(const AreaEffectSimulation::MineArea &data, DataModification modType) { HandlerEffectShow::KindOfModification_e kindOfModification = HandlerEffectShow::KindOfModification_e::Removed; if (takeIntoAccountEffectShow(data.effectStateId()) && data.effectMarkingInTa()) kindOfModification = getKindOfModification(ObjectAesData::asEsmAesData(data), modType); ObjectAesData *ifs = m_AesDataObjMap.value(data.id()); if (kindOfModification == HandlerEffectShow::KindOfModification_e::Added && ifs) kindOfModification = HandlerEffectShow::KindOfModification_e::ModifiedData; if (data.segments().size() == 0) return; const Core::GeoPosition2D &posLl = data.segments().at(data.segments().size() / 2).positionStart(); DEBUG_LOG(m_logger) << "Got MineArea: " << "\n ID: " << data.id() << "\n Name: " << data.name() << "\n Effect status: " << data.effectStateId() << "\n Effect show (y/n): " << data.effectMarkingInTa() << "\n Start Position " << LtsCoordTrans::mgrsFromGeographic(posLl.lon(), posLl.lat()) << "\n Start: " << data.effectStart() << "\n Duration: " << data.effectDuration() << "\n Num of segments: " << data.segments().size() << "\n Modification: " << modType << "\n detected Mod: " << HandlerEffectShow::enumToString(kindOfModification); switch (kindOfModification) { case HandlerEffectShow::KindOfModification_e::Added: { ifs = new ObjectAesData(m_mainHandler); Core::FunctionReplyObject ret = ifs->createObject(ObjectAesData::asEsmAesData(data)); if (ret.error()) { delete ifs; ERROR_LOG(m_logger) << ret(); } else { m_AesDataObjMap.insert(data.id(), ifs); m_mainHandler->handlerEffectShow()->onMineAreaChanged(data, kindOfModification); } break; } case HandlerEffectShow::KindOfModification_e::ModifiedArea: case HandlerEffectShow::KindOfModification_e::ModifiedData: case HandlerEffectShow::KindOfModification_e::Paused: case HandlerEffectShow::KindOfModification_e::Continued: { if (ifs != nullptr) { const auto ret = ifs->updateObject(ObjectAesData::asEsmAesData(data)); if (!ret.error()) m_mainHandler->handlerEffectShow()->onMineAreaChanged(data, kindOfModification); else ERROR_LOG(m_logger) << ret(); } else WARNING_LOG(m_logger) << "Mine Area not available for modification: " << data.id(); break; } case HandlerEffectShow::KindOfModification_e::Removed: { if (ifs != nullptr) { if (!m_AesDataObjMap.remove(data.id())) ERROR_LOG(m_logger) << "Remove of AES data (" << data.id() << ") from map failed."; Core::FunctionReplyObject ret = ifs->removeObject(); if (ret.error()) ERROR_LOG(m_logger) << ret(); } m_mainHandler->handlerEffectShow()->onMineAreaChanged(data, kindOfModification); break; } case HandlerEffectShow::KindOfModification_e::None: break; } } // onMineAreaChanged() //----------------------------------------------------------------------------- bool HandlerAesData::takeIntoAccountEffectShow(const AreaEffectSimulation::AesEffectState &effectStateId) { return ( (effectStateId == AreaEffectSimulation::AesEffectState::EsCreated) || (effectStateId == AreaEffectSimulation::AesEffectState::EsPrepared) || (effectStateId == AreaEffectSimulation::AesEffectState::EsActivated) || (effectStateId == AreaEffectSimulation::AesEffectState::EsFired) || (effectStateId == AreaEffectSimulation::AesEffectState::EsPaused) ); } // takeIntoAccountEffectShow() //----------------------------------------------------------------------------- HandlerEffectShow::KindOfModification_e HandlerAesData::getKindOfModification(const Database::EsmAesData &data, DataModification modType) const { auto it = m_AesDataObjMap.find(data.idAes); DEBUG_LOG(m_logger) << "Check esm " << data.idAes << " modType " << modType; switch (modType) { case DataModification::eAdded: case DataModification::eModified: { DEBUG_LOG(m_logger) << "Case Added Or Modified"; if (it != m_AesDataObjMap.end()) { DEBUG_LOG(m_logger) << "Found data"; if (it.value()->areaChanged(data)) return HandlerEffectShow::KindOfModification_e::ModifiedArea; if (it.value()->dataChanged(data)) return HandlerEffectShow::KindOfModification_e::ModifiedData; if (it.value()->statusPaused(data)) return HandlerEffectShow::KindOfModification_e::Paused; if (it.value()->statusContinued(data)) return HandlerEffectShow::KindOfModification_e::Continued; } return HandlerEffectShow::KindOfModification_e::Added; } case DataModification::eRemoved: { if (it != m_AesDataObjMap.end()) return HandlerEffectShow::KindOfModification_e::Removed; } break; } return HandlerEffectShow::KindOfModification_e::None; } // getKindOfModification() //-----------------------------------------------------------------------------