Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/ExerciseEventManagement/handler_dynamic_participant_data.cpp
T
berrux-dev c3eda18234 Migrates remaining services and plugins to generated rtiddsgen API
Converts accessor calls to plain member access across the residual service set.
2026-09-21 02:47:48 +02:00

608 lines
24 KiB
C++
Executable File

/**
* Handler for infrastructure data
* $Id$
* $HeadURL$
* $Author:
* Created by hjl, SLSE, 2016-09-21
*/
#include "handler_dynamic_participant_data.h"
#include <ExerciseEventManagement/eem_db.h>
#include <ParticipantManagement/ppm.hpp>
#include "web_socket_server.h"
#include "settings.h"
#include <QtCore/QSet>
#include <QtCore/QThread>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
#include <LtsUtilsCore/json_object.h>
#include <QtCore/QTimer>
using namespace ExerciseEventManagement;
//-----------------------------------------------------------------------------
HandlerDynamicParticipantData::HandlerDynamicParticipantData(MainHandler *mainHandler,
const std::shared_ptr<DdsHandler> &ddsHandler,
const std::shared_ptr<DbHandler> &db,
const std::shared_ptr<WebSocketEventServer> &eventServer)
: m_ddsHandler(ddsHandler)
, m_dbHandler(db)
, m_eventServer(eventServer)
, m_mainHandler(mainHandler)
, m_logger(getLogger("HandlerDynamicParticipantData"))
{
} // end of ctor()
//-----------------------------------------------------------------------------
HandlerDynamicParticipantData::~HandlerDynamicParticipantData()
{
} // end of dtor()
//-----------------------------------------------------------------------------
bool HandlerDynamicParticipantData::init()
{
INFO_LOG(m_logger) << "start init() DTC ParticipantManagement ";
// DTC ParticipantManagement
m_ppmDtc = ParticipantManagement::Interface::Dtc::create(m_ddsHandler->ddsConnector());
if (m_ppmDtc == nullptr)
{
ERROR_LOG(m_logger) << "Could not create DTC ParticipantManagement";
return false;
}
// Subscribe for DynamicParticipantData (for analyzing data)
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged,
this, &HandlerDynamicParticipantData::onDynamicParticipantDataChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantGearEventChanged,
this, &HandlerDynamicParticipantData::onParticipantGearEventChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
this, &HandlerDynamicParticipantData::onParticipantChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::biteChanged,
this, &HandlerDynamicParticipantData::onBiteChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantPositionChanged,
this, &HandlerDynamicParticipantData::onParticipantPositionChanged);
if (!m_ppmDtc->enableDynamicParticipantData() ||
!m_ppmDtc->enableParticipantGearEvent() ||
!m_ppmDtc->enableParticipant() ||
!m_ppmDtc->enableBite() ||
!m_ppmDtc->enableParticipantPosition())
{
ERROR_LOG(m_logger) << "init() DTC ParticipantManagement failed";
return false;
}
m_bldDtc = Buildings::Interface::Dtc::create(m_ddsHandler->ddsConnector());
if (m_bldDtc == nullptr)
{
ERROR_LOG(m_logger) << "Could not create DTC Buildings";
return false;
}
connect(m_bldDtc.get(), &Buildings::Interface::Dtc::buildingStateChanged,
this, &HandlerDynamicParticipantData::onBuildingStateChanged);
if (!m_bldDtc->enableBuildingState())
{
ERROR_LOG(m_logger) << "Enable buildingState failed";
return false;
}
m_aesDtc = AreaEffectSimulation::Interface::Dtc::create(m_ddsHandler->ddsConnector());
m_aesDtc->enableAesItemView();
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged,
this, &HandlerDynamicParticipantData::onAesItemViewChanged);
// Infrastructure Management
auto dtcIsm = m_ddsHandler->dtcIsm();
dtcIsm->enableMainStructureElement();
connect(dtcIsm.get(), &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged,
this, &HandlerDynamicParticipantData::onMainStructureElementChanged);
// Get 'static' data for all MainStructureElements
{
auto cb = [this](const InfrastructureManagement::MainStructureElement & mse)
{
onMainStructureElementChanged(mse, DataModification::eAdded);
};
if (!dtcIsm->mainStructureElements(cb))
return false;
}
return true;
} // end of init()
void HandlerDynamicParticipantData::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType)
{
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
m_itemViews.insert(data.aesItemId(), data.aesTypeId());
break;
case DataModification::eRemoved:
m_itemViews.remove(data.aesItemId());
}
}
void HandlerDynamicParticipantData::tryCreateHitEvent(Database::EemEvent eData,
const ParticipantManagement::StateInformation &stateInfo)
{
DEBUG_LOG(m_logger) << "tryCreateHitEvent";
// special values - ignore
const ProjectDataManagement::VulnerabilityState vulnState = stateInfo.vulnerabilityState();
if (vulnState == ProjectDataManagement::VulnerabilityState_def::VulnerabilityBitsChanged ||
vulnState == ProjectDataManagement::VulnerabilityState_def::TemporarySeverance)
return;
// combat ready is no hit
if (vulnState == ProjectDataManagement::VulnerabilityState_def::CombatReady)
return;
// only handle 'real' hit events
switch (stateInfo.originatorType().underlying())
{
case ProjectDataManagement::StateChangeOriginator::AreaEffectSimulation:
case ProjectDataManagement::StateChangeOriginator::ImprovisedExplosiveDevice:
case ProjectDataManagement::StateChangeOriginator::DusMine:
eData.eventTypeId = ProjectDataManagement::PdmEventType::HitEffectSimulation;
break;
case ProjectDataManagement::StateChangeOriginator::Participant:
case ProjectDataManagement::StateChangeOriginator::ObserverController:
case ProjectDataManagement::StateChangeOriginator::ExerciseControl:
eData.eventTypeId = ProjectDataManagement::PdmEventType::Hit;
break;
case ProjectDataManagement::StateChangeOriginator::Sanitation:
eData.eventTypeId = ProjectDataManagement::PdmEventType::Sanitation;
break;
case ProjectDataManagement::StateChangeOriginator::Unknown:
case ProjectDataManagement::StateChangeOriginator::WoundTreatmentDevice:
case ProjectDataManagement::StateChangeOriginator::MaintainanceDevice:
case ProjectDataManagement::StateChangeOriginator::FunctionalArea:
case ProjectDataManagement::StateChangeOriginator::Initialization:
case ProjectDataManagement::StateChangeOriginator::MedicalTimeout:
return;
}
QJsonObject obj;
obj[QStringLiteral("VulnerabilityState")] = vulnState.underlying();
obj[QStringLiteral("OriginatorId")] = stateInfo.originatorId();
obj[QStringLiteral("OriginatorType")] = stateInfo.originatorType().underlying();
obj[QStringLiteral("OriginatorChargeTypeId")] = stateInfo.originatorChargeTypeId();
if (stateInfo.originatorType() == ProjectDataManagement::StateChangeOriginator::Participant)
{
ParticipantManagement::Participant originData = m_partMap.value(stateInfo.originatorId());
if (originData.equipmentNumber.is_set())
obj[QStringLiteral("OriginatorEquipmentNumber")] = originData.equipmentNumber.get();
if (originData.partyId() == eData.partyId)
obj[QStringLiteral("FriendlyFire")] = true;
else
obj[QStringLiteral("FriendlyFire")] = false;
}
if (eData.eventTypeId == ProjectDataManagement::PdmEventType::HitEffectSimulation)
{
DEBUG_LOG(m_logger) << "Event HitEffectSimulation from originatorId = " << stateInfo.originatorId();
obj[QStringLiteral("AesId")] = stateInfo.originatorId();
obj[QStringLiteral("AesType")] = m_itemViews.value(stateInfo.originatorId()).underlying();
AreaEffectSimulation::AesItem aesItem;
if (m_aesDtc->aesItemFromId(stateInfo.originatorId(), aesItem))
obj[QStringLiteral("AesName")] = QJsonValue(QString::fromStdString(aesItem.name()));
}
if (eData.eventTypeId == ProjectDataManagement::PdmEventType::Sanitation)
{
// ignore these events
if (stateInfo.sanitationProceduresTaken() == 0 && stateInfo.originatorChargeTypeId() == 0) //qualification
return;
DEBUG_LOG(m_logger) << "Event sanitation ";
obj[QStringLiteral("Vitality")] = stateInfo.vitality();
obj[QStringLiteral("SanitationResult")] = stateInfo.sanitationResult().underlying();
obj[QStringLiteral("SanitationProceduresTaken")] = stateInfo.sanitationProceduresTaken();
}
eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact));
eData.id = 0;
if (eData.sampleTime <= 0)
eData.sampleTime = stateInfo.stateTime();
if (!m_dbHandler->db()->insert(eData))
ERROR_LOG(m_logger) << "Error while inserting event data for participant: " << eData.participantId;
else
publishData(eData);
}
//-----------------------------------------------------------------------------
void HandlerDynamicParticipantData::onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &data,
DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
DEBUG_LOG(m_logger) << "onDynamicParticipantDataChanged()"
<< ", participantId: " << data.participantId()
<< ", size stateHistory: " << data.stateHistory().size();
auto itLastDynData = m_lastDynData.find(data.participantId());
// the first insert does not trigger any updates
if (itLastDynData == m_lastDynData.end())
{
itLastDynData = m_lastDynData.insert(data.participantId(), data);
return;
}
ParticipantManagement::DynamicParticipantData &lastDynData = itLastDynData.value();
// get corresponding participant data
auto itParticipant = m_partMap.find(data.participantId());
if (itParticipant == m_partMap.end())
{
m_ppmDtc->waitForHistoricalDataParticipant(2000);
itParticipant = m_partMap.find(data.participantId());
if (itParticipant == m_partMap.end())
{
ERROR_LOG(m_logger) << "Participant does not exist: participantId: " << data.participantId();
return;
}
}
static const ParticipantManagement::ParticipantPosition emptyPos;
auto itParticipantPos = m_partPosMap.find(data.participantId());
const ParticipantManagement::ParticipantPosition &pPos = itParticipantPos == m_partPosMap.end() ? emptyPos : itParticipantPos.value();
const ParticipantManagement::Participant &pData = itParticipant.value();
Database::EemEvent eData;
eData.participantId = data.participantId();
eData.equipmentNumber = pData.equipmentNumber.is_set() ? pData.equipmentNumber.get() : -1;
eData.partyId = pData.partyId();
eData.sampleTime = data.sampleTime();
eData.eventTypeId = ProjectDataManagement::PdmEventType_def::Unknown;
eData.position = LtsUtils::QPoint3D(pPos.pos().lon(), pPos.pos().lat(), pPos.pos().z());
if (data.stateHistory() != lastDynData.stateHistory())
{
// we assume that the order of the state information do *not* change (it's current true: january 2020)
for (size_t i = 0; i < data.stateHistory().size(); ++i)
{
if (i < lastDynData.stateHistory().size() &&
data.stateHistory().at(i) == lastDynData.stateHistory().at(i))
continue;
tryCreateHitEvent(eData, data.stateHistory().at(i));
}
}
const auto gearIsKnown = [ &lastDynData](const ParticipantManagement::GearInformation & gi) -> bool
{
return std::any_of(lastDynData.gear().begin(), lastDynData.gear().end(),
[&gi](const ParticipantManagement::GearInformation & other)
{
return gi.gearTypeId() == other.gearTypeId() && gi.gearId() == other.gearId();
});
};
for (const ParticipantManagement::GearInformation &gi : data.gear())
{
if (gearIsKnown(gi))
continue;
DEBUG_LOG(m_logger) << "Found new gear " << gi << " for participant " << data.participantId();
QJsonObject obj;
obj[QStringLiteral("GearId")] = QJsonValue(gi.gearId());
obj[QStringLiteral("GearTypeId")] = QJsonValue(gi.gearTypeId());
obj[QStringLiteral("DryFire")] = QJsonValue(gi.chargeCounting());
eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact));
eData.sampleTime = gi.lastUpdate();
eData.eventTypeId = ProjectDataManagement::PdmEventType_def::WeaponAssignment;
eData.id = 0;
if (!m_dbHandler->db()->insert(eData))
ERROR_LOG(m_logger) << "Error while inserting event data for participant: " << data.participantId();
else
publishData(eData);
}
if (data.manipulation() != lastDynData.manipulation())
{
eData.eventTypeId = ProjectDataManagement::PdmEventType_def::Manipulation;
const auto isOldManipulation = [&lastDynData](const ParticipantManagement::ManipulationInformation & mani) -> bool
{
auto it = std::find(lastDynData.manipulation().begin(), lastDynData.manipulation().end(), mani);
return it != lastDynData.manipulation().end();
};
// we can *not* assume that the old and the new manipulation is in the same order
for (const auto &mani : data.manipulation())
{
if (isOldManipulation(mani))
continue;
const QJsonObject obj({{QStringLiteral("DeviceType"), mani.equipmentFunctionId()}});
eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact));
eData.sampleTime = mani.manipulationTime();
eData.id = 0;
if (!m_dbHandler->db()->insert(eData))
ERROR_LOG(m_logger) << "Error while inserting event data for participant: " << data.participantId();
else
publishData(eData);
}
}
lastDynData = data;
} // end of onDynamicParticipantDataChanged()
//-----------------------------------------------------------------------------
void HandlerDynamicParticipantData::onParticipantGearEventChanged(const ParticipantManagement::ParticipantGearEvent &data,
DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
// get corresponding participant data
auto itParticipant = m_partMap.find(data.participantId());
if (itParticipant == m_partMap.end())
{
m_ppmDtc->waitForHistoricalDataParticipant(2000);
itParticipant = m_partMap.find(data.participantId());
if (itParticipant == m_partMap.end())
{
ERROR_LOG(m_logger) << "Participant does not exist: participantId: " << data.participantId();
return;
}
}
static const ParticipantManagement::ParticipantPosition emptyPos;
auto itParticipantPos = m_partPosMap.find(data.participantId());
const ParticipantManagement::ParticipantPosition &pPos = itParticipantPos == m_partPosMap.end() ? emptyPos : itParticipantPos.value();
const ParticipantManagement::Participant &pData = itParticipant.value();
Database::EemEvent eData;
eData.id = 0;
eData.participantId = data.participantId();
eData.equipmentNumber = pData.equipmentNumber.is_set() ? pData.equipmentNumber.get() : -1;
eData.partyId = pData.partyId();
eData.sampleTime = data.sampleTime();
eData.eventTypeId = ProjectDataManagement::PdmEventType_def::FireEvent;
eData.position = LtsUtils::QPoint3D(pPos.pos().lon(), pPos.pos().lat(), pPos.pos().z());
QJsonObject obj;
obj[QStringLiteral("GearId")] = QJsonValue(data.charge().gearId());
obj[QStringLiteral("GearTypeId")] = QJsonValue(data.charge().gearTypeId());
obj[QStringLiteral("ChargeTypeId")] = QJsonValue(data.charge().chargeTypeId());
obj[QStringLiteral("Amount")] = QJsonValue(data.chargeAmount());
if (data.charge().remain() >= 0)
obj[QStringLiteral("Remain")] = QJsonValue(data.charge().remain());
eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact));
eData.id = 0;
DEBUG_LOG(m_logger) << "create fire event for participant " << data.participantId();
if (!m_dbHandler->db()->insert(eData))
ERROR_LOG(m_logger) << "Error while inserting event data for participant: " << data.participantId();
else
publishData(eData);
}
//-----------------------------------------------------------------------------
void HandlerDynamicParticipantData::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType)
{
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
DEBUG_LOG(m_logger) << "added/modified";
m_partMap.insert(data.id(), data);
DEBUG_LOG(m_logger) << "data.participantId: " << data.id()
<< ", data.partyId: " << data.partyId()
<< ". data.equipmentNumber: " << data.equipmentNumber();
break;
case DataModification::eRemoved:
m_partMap.remove(data.id());
break;
}
}
//-----------------------------------------------------------------------------
void HandlerDynamicParticipantData::onParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &data, DataModification modType)
{
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
m_partPosMap.insert(data.participantId(), data);
DEBUG_LOG(m_logger) << "data.participantId: " << data.participantId()
<< ", position lat: " << data.pos().lat()
<< ", position lon: " << data.pos().lon();
break;
case DataModification::eRemoved:
m_partPosMap.remove(data.participantId());
break;
}
}
//-----------------------------------------------------------------------------
void HandlerDynamicParticipantData::onBiteChanged(const ParticipantManagement::Bite &data, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
Database::EemEvent eData;
eData.id = 0;
eData.eventTypeId = ProjectDataManagement::PdmEventType_def::BiteMessage;
eData.equipmentNumber = data.equipmentNumber();
eData.participantId = data.participantId();
eData.sampleTime = data.sampleTime();
QJsonObject obj;
obj[QStringLiteral("BatteryState")] = QJsonValue(data.batteryState());
obj[QStringLiteral("BiteState")] = QJsonValue(data.biteState());
obj[QStringLiteral("ConfigState")] = QJsonValue(data.configState());
QJsonArray array;
for (const ParticipantManagement::BiteError &be : data.biteErrors())
{
QJsonObject object;
object[QStringLiteral("ErrorNo")] = QJsonValue(be.errorNumber());
object[QStringLiteral("CanDeviceNumber")] = QJsonValue(be.canDeviceNumber());
object[QStringLiteral("SubdeviceNumber")] = QJsonValue(be.subdeviceNumber());
object[QStringLiteral("UniqueId")] = QJsonValue(be.uniqueId());
array.append(object);
}
obj[QStringLiteral("BiteErrors")] = QJsonValue(array);
eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact));
ParticipantManagement::Participant part = m_partMap.value(data.participantId());
if (part.id() > 0)
{
eData.partyId = part.partyId();
ParticipantManagement::ParticipantPosition pPos = m_partPosMap.value(eData.participantId);
eData.position = LtsUtils::QPoint3D(pPos.pos().lon(), pPos.pos().lat(), pPos.pos().z());
}
else
{
eData.participantId = -1;
eData.partyId = -1;
}
if (!m_dbHandler->db()->insert(eData))
ERROR_LOG(m_logger) << "Error while inserting event data for participantId: " << data.participantId();
else
publishData(eData);
}
//-----------------------------------------------------------------------------
void HandlerDynamicParticipantData::onBuildingStateChanged(const Buildings::BuildingState &data, DataModification modType)
{
if (modType == DataModification::eRemoved || data.damagePercent() <= 0) // only add hits
return;
Database::EemEvent eData;
eData.id = 0;
eData.eventTypeId = ProjectDataManagement::PdmEventType_def::HitBuilding;
eData.sampleTime = data.sampleTime();
QJsonObject obj;
obj[QStringLiteral("ChargeTypeId")] = QJsonValue(data.chargeTypeId());
obj[QStringLiteral("damagePercent")] = QJsonValue(data.damagePercent());
obj[QStringLiteral("damagePercentOld")] = QJsonValue(data.damagePercentOld());
// obj[QStringLiteral("Name")] = QJsonValue(data.name());
obj[QStringLiteral("VulnerabilityState")] = QJsonValue(data.vulnerabilityState().underlying());
if (data.originatorType() == ProjectDataManagement::StateChangeOriginator::Participant)
{
ParticipantManagement::Participant originData = m_partMap.value(data.originatorParticipantId());
if (originData.equipmentNumber.is_set())
obj[QStringLiteral("OriginatorEquipmentNumber")] = originData.equipmentNumber.get();
}
if (data.originatorType() == ProjectDataManagement::StateChangeOriginator::AreaEffectSimulation)
{
obj[QStringLiteral("AesId")] = data.aesId();
obj[QStringLiteral("AesType")] = m_itemViews.value(data.aesId()).underlying();
AreaEffectSimulation::AesItem aesItem;
if (m_aesDtc->aesItemFromId(data.aesId(), aesItem))
obj[QStringLiteral("AesName")] = QJsonValue(QString::fromStdString(aesItem.name()));
}
//obj[QStringLiteral("StructureElementId")] = QJsonValue(data.structureElementId());
obj[QStringLiteral("MainStructureElementId")] = QJsonValue(data.id());
QJsonArray contaminationArr;
for (const auto &cs: data.contaminationStates())
{
QJsonArray roomArr;
for (const auto &roomId : qAsConst(cs.rooms()))
roomArr.append(QJsonValue(roomId));
contaminationArr.append(QJsonObject({{QStringLiteral("aesId") , cs.aesId()},
{QStringLiteral("rooms"), roomArr}}));
}
obj[QStringLiteral("contaminationStates")] = contaminationArr;
int mainStructureElementId = data.id();
Core::GeoPosition geoPosition = m_mainStructureElements.value(mainStructureElementId).geoPosition();
LtsUtils::QPoint3D pos3D(geoPosition.lon(), geoPosition.lat(), geoPosition.z());
eData.position = pos3D;
eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact));
if (!m_dbHandler->db()->insert(eData))
ERROR_LOG(m_logger) << "Error while inserting event data for building ";
else
publishData(eData);
}
//-----------------------------------------------------------------------------
void HandlerDynamicParticipantData::publishData(const Database::EemEvent &data)
{
m_eventServer->sendEvent(Database::toJson(data));
ExerciseEventManagement::Event ddsData = toDdsData(data);
if (!m_ddsHandler->dts()->publish(ddsData))
ERROR_LOG(m_logger) << "Error publishing event-data to dds";
// take data from dds-bus after 10s, we need just to make sure the recording service got it
m_mainHandler->addEventIdToRemove(ddsData.id());
}
//-----------------------------------------------------------------------------
ExerciseEventManagement::Event HandlerDynamicParticipantData::toDdsData(const Database::EemEvent &data)
{
ExerciseEventManagement::Event ddsData;
ddsData.id(data.id);
ddsData.sampleTime(data.sampleTime);
ddsData.participantId(data.participantId);
ddsData.partyId(data.partyId);
ddsData.equipmentNumber(data.equipmentNumber);
ddsData.eventTypeId(data.eventTypeId);
ddsData.properties(data.properties.toStdString());
ddsData.position(Core::GeoPosition(data.position.x(), data.position.y(), data.position.z()));
if (data.eventTypeId == ProjectDataManagement::PdmEventType_def::HitBuilding)
{
int mainStructureElementId = LtsUtils::JsonObject::fromJson(ddsData.properties()).valueOr<int>(QStringLiteral("MainStructureElementId"), 0);
DEBUG_LOG(m_logger) << "MainStructureElementId=" << mainStructureElementId;
ddsData.position(m_mainStructureElements.value(mainStructureElementId).geoPosition());
}
return ddsData;
}
// ///////////////////////////////////
// I S M (InfrastructureManagement)
// ///////////////////////////////////
void HandlerDynamicParticipantData::onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data, DataModification modType)
{
DEBUG_LOG(m_logger) << "onMainStructureElementChanged";
if (modType != DataModification::eAdded &&
modType != DataModification::eModified)
{
m_mainStructureElements.remove(data.id());
return;
}
m_mainStructureElements.insert(data.id(), data);
DEBUG_LOG(m_logger) << "Got MainStructureElement: " << data;
}
//-----------------------------------------------------------------------------