/** * @RDE_HEADER@ * Guez Nasat NineLiner 9Liner * $Id$ * $HeadURL$ * $Author$ */ // Own #include "guez_nasat_9liner.h" #include #include #include #include // for method "getForeignGuiInterface" // Qt #include #include #include #include #include #include namespace SituationMap { int32_t GuezNasat9Liner2SituationMap::getSimId(const Sim2SituationMap::DDS_T &ddsData) const { return ddsData.id(); } GuezNasat9Liner2SituationMap::GuezNasat9Liner2SituationMap(ObjectFactory &objFac, const QString &layername, int drawOrder, const char *loggerName) : BaseClass(objFac, layername, drawOrder, loggerName) , FilterClass(loggerName, this) , m_pluginProvider(nullptr) , m_notifyTimer(new QTimer(this)) { m_notifyTimer->setInterval(500); m_notifyTimer->setSingleShot(true); connect(m_notifyTimer, &QTimer::timeout, this, &GuezNasat9Liner2SituationMap::updateAllItems); } GuezNasat9Liner2SituationMap::~GuezNasat9Liner2SituationMap() { m_notifyTimer->stop(); } bool GuezNasat9Liner2SituationMap::init(PluginProvider *pluginProvider) { if (!pluginProvider) { ERROR_LOG(m_logger) << LOGFUNCTION << " no pluginProvider"; return false; } m_pluginProvider = pluginProvider; m_gnaDtc = pluginProvider->gnaDtc(); if (!m_gnaDtc) { ERROR_LOG(m_logger) << LOGFUNCTION << " no m_gnaDtc"; return false; } m_gnaDtc->enableNasat9Liner(); // m_gnaDtc->waitForHistoricalDataNasat9Liner(); // blocks ??? m_ppmDtc = pluginProvider->ppmDtc(); if (!m_ppmDtc) { ERROR_LOG(m_logger) << LOGFUNCTION << " no m_ppmDtc"; return false; } // FilterManagement: FilterClass::init(m_pluginProvider); // PartitionTime connect(m_pluginProvider, &PluginProvider::partitionTimeChanged, this, &GuezNasat9Liner2SituationMap::onPartitionTimeChanged); return true; } bool GuezNasat9Liner2SituationMap::run() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (!m_gnaDtc) { ERROR_LOG(m_logger) << LOGFUNCTION << " no dtc"; return false; } // PPM { connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged, this, &GuezNasat9Liner2SituationMap::onParticipantChanged, Qt::UniqueConnection); // get: m_ppmDtc->participants([this](const ParticipantManagement::Participant &data) { onParticipantChanged(data, DataModification::eAdded); }); } // GNA { connect(m_gnaDtc.get(), &GuezNasat::Interface::Dtc::nasat9LinerChanged, this, &GuezNasat9Liner2SituationMap::handleChanged, Qt::UniqueConnection); // get: m_gnaDtc->nasat9Liners([this](const GuezNasat::Nasat9Liner & data) { handleChanged(data, DataModification::eAdded); }); } TRACE_LOG(m_logger) << LOGFUNCTION << " END"; return true; } bool GuezNasat9Liner2SituationMap::isElapsed(const GuezNasat::Nasat9Liner &ddsData) const { // true -> hide // false -> show DEBUG_LOG(m_logger) << LOGFUNCTION << " check ddsData=" << ddsData; if (BaseClass::isElapsed(ddsData)) { DEBUG_LOG(m_logger) << LOGFUNCTION << " check ddsData=" << ddsData << " HIDE"; return true; } // GUEZE-1676: Nineliner sollen zeitlich wie Trefferlinien angezeigt werden // replace checkbox by slider, so 'isCurrent' is outdated: DEBUG_LOG(m_logger) << LOGFUNCTION << " check ddsData=" << ddsData << " SHOW"; return false; } bool GuezNasat9Liner2SituationMap::mapObjectsClicked(const QVector &uniqueMapIds) { // if(!m_bldInfoIfc) // return false; const QVector &simIds = uniqueMapIds2SimIds(uniqueMapIds); if (simIds.isEmpty()) return true; // m_bldInfoIfc->showInfoWindow(simIds); return true; } bool GuezNasat9Liner2SituationMap::unifiedMapObjectData(UniqueMapId uniqueMapId, UnifiedMapObjectData &umodOut) const { if (!m_gnaDtc) return false; int32_t simIdOut = -1; if (!this->uniqueMapId2SimId(uniqueMapId, simIdOut)) return false; umodOut = UnifiedMapObjectData(); RefPointer mapObj = this->getMapObjectOfUniqueMapId(uniqueMapId); if (mapObj.valid()) umodOut.m_image = mapObj->previewImage(); umodOut.m_description1 = QString::fromStdString(m_gnaDtc->nasat9Liner(simIdOut).name()); return true; } void GuezNasat9Liner2SituationMap::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType) { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " pId=" << data.id() << " parytIdOld=" << m_participantToPartyId.value(data.id(), -1) << " parytId=" << data.partyId() << ", m_participantToPartyId.size()=" << m_participantToPartyId.size(); const int simId = data.id(); switch (modType) { case DataModification::eAdded: case DataModification::eModified: m_participantToPartyId[simId] = data.partyId(); break; case DataModification::eRemoved: m_ddsDataContainer.remove(simId); break; } // what can change? // - participant moves from one party to another // // schedule slot updateAllItems m_notifyTimer->start(); TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_participantToPartyId.size()=" << m_participantToPartyId.size(); } bool GuezNasat9Liner2SituationMap::handleChanged(const Sim2SituationMap::DDS_T &ddsData, DataModification modType) { m_notifyTimer->start(); updateDdsDataContainer(ddsData, modType); // helpfull for FilterManagement/onSymbolAppearanceSettingsChanged return BaseClass::handleChanged(ddsData, modType); } bool GuezNasat9Liner2SituationMap::updateElementImpl(const Sim2SituationMap::DDS_T &ddsData, RefPointer mapObj) { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " id=" << ddsData.id() << " name=" << ddsData.name() << " isCurrent=" << ddsData.isCurrent() << " initialPoint=" << ddsData.initialPoint() << " targetPosition=" << ddsData.targetPosition() << " participantId=" << ddsData.participantId() << " m_participantToPartyId.size()=" << m_participantToPartyId.size() << " partyId.size()=" << m_participantToPartyId.value(ddsData.participantId(), -1); mapObj->setPickable(false); // show just the ObjectAppearance::Technical mapObj->setVisibility(ObjectAppearance::Tactical, false); // PartyId, if not available yet it will be updated later // (via onParticipantChanged and m_notifyTimer) mapObj->setPartyId(m_participantToPartyId.value(ddsData.participantId(), -1)); TextStyle ts = mapObj->textStyle(); ts.setHorizontalAlignment(HorizontalAlignment::Center); mapObj->setTextStyle(ts); MAP_T::NineLinerData data; data.initialPoint = Point3D(ddsData.initialPoint().lon(), ddsData.initialPoint().lat(), .0); data.targetPosition = Point3D(ddsData.targetPosition().lon(), ddsData.targetPosition().lat(), .0); data.fah = ddsData.finalAttackHeading(); data.fahLow = ddsData.finalAttackHeadingLow(); data.fahHigh = ddsData.finalAttackHeadingHigh(); data.friendliesBearing = ddsData.friendliesBearing(); data.friendliesDistance = ddsData.friendliesDistance(); mapObj->setNineLinerData(data); mapObj->setIdentifier(QString::fromStdString(ddsData.name())); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; return true; } bool GuezNasat9Liner2SituationMap::symbolAppearanceSettingsChangesAreRelevant(const FilterManagement::SymbolAppearanceSettings::Settings &newSas) const { return (m_currentSymbolSettings.symbolSettings.symbolScale != newSas.symbolSettings.symbolScale) || (m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec != newSas.symbolSettings.nasatNineLinerDisplayLengthMSec); } void GuezNasat9Liner2SituationMap::handleSymbolAppearanceSettings() { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_ddsDataContainer.size()=" << m_ddsDataContainer.size(); for (const GuezNasat::Nasat9Liner &nineLiner : qAsConst(m_ddsDataContainer)) { RefPointer mapObj = getMapObjectOfSimId(nineLiner.id()); if (!mapObj.valid()) continue; handleSymbolAppearanceSettings(mapObj, nineLiner); } // for TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_ddsDataContainer.size()=" << m_ddsDataContainer.size(); } void GuezNasat9Liner2SituationMap::handleSymbolAppearanceSettings(RefPointer &mapObj) { if (!mapObj.valid()) return; const int simId = m_uniqueMapId2SimId.value(mapObj->uniqueMapId()); handleSymbolAppearanceSettings(mapObj, m_ddsDataContainer.value(simId)); // Since svc GNA updates sample_time for outdated nineLiner(isCurrent==false), // (see handler_nasat_nine_liner.cpp) following workaround is obsolete: // bool bIsRealCurrent = true; // int32_t simIdOut = -1; // if (uniqueMapId2SimId(mapObj->uniqueMapId(), simIdOut)) // { // const DDS_T ddsData = m_ddsDataContainer[simIdOut]; // qint64 youngestSampleTime = getYoungestSampleTimeOfCurrentForParticipant(ddsData.participantId()); // if (youngestSampleTime == ddsData.sampleTime()) // { // DEBUG_LOG(m_logger) << LOGFUNCTION << " IS YOUNGEST ITEM " << simIdOut; // bIsRealCurrent = true; // } else { // DEBUG_LOG(m_logger) << LOGFUNCTION << " IS NOT YOUNGEST ITEM " << simIdOut; // bIsRealCurrent = false; // } // } } void GuezNasat9Liner2SituationMap::handleSymbolAppearanceSettings(RefPointer mapObj, const Sim2SituationMap::DDS_T &ddsData) { mapObj->setScale(m_currentSymbolSettings.symbolSettings.symbolScale); const bool isVisi = visibleByDisplayLength(m_pluginProvider->partitionTime(), ddsData.sampleTime()); if (mapObj->visibility() != isVisi) { mapObj->setVisibility(isVisi); if (!mapObj->updateView()) WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed," << " mapObj = " << mapObj->debugInfo(); } } bool GuezNasat9Liner2SituationMap::visibleByDisplayLength(const qint64 newPartitionTime, const qint64 stateTime) const { DEBUG_LOG(m_logger) << LOGFUNCTION << " newPartitionTime = " << newPartitionTime << " stateTime = " << stateTime << " age = " << (newPartitionTime - stateTime) << " nasatNineLinerDisplayLengthMSec = " << m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec; if (m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec < 0) return true; return (newPartitionTime - stateTime) <= m_currentSymbolSettings.symbolSettings.nasatNineLinerDisplayLengthMSec; // all msec } void GuezNasat9Liner2SituationMap::onPartitionTimeChanged() { handleSymbolAppearanceSettings(); } void GuezNasat9Liner2SituationMap::updateAllItems() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, m_ddsDataContainer.size()=" << m_ddsDataContainer.size(); for (const DDS_T &ddsData : qAsConst(m_ddsDataContainer)) { RefPointer mapObj = getMapObjectOfSimId(ddsData.id()); if (!mapObj.valid()) continue; updateElementImpl(ddsData, mapObj); handleSymbolAppearanceSettings(mapObj); if (!mapObj->updateView()) WARNING_LOG(m_logger) << LOGFUNCTION << " updateView failed for "<< mapObj->debugInfo(); } // for TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_ddsDataContainer.size()=" << m_ddsDataContainer.size(); } }