414 lines
16 KiB
C++
Executable File
414 lines
16 KiB
C++
Executable File
/**
|
|
* Handler for player data
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by hjl, SLSE, 2017-02-20
|
|
*/
|
|
|
|
#include "handler_building_ownership.h"
|
|
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
#include <ngldb/dbtransaction.h>
|
|
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
|
|
|
|
namespace CesBuildings
|
|
{
|
|
|
|
HandlerBuildingOwnership::HandlerBuildingOwnership(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
|
|
const std::shared_ptr<CentralEffectSimulation::HandlerParticipant> &participantHandler,
|
|
const std::shared_ptr<CentralEffectSimulation::HandlerBuildingData> &buildingDataHandler,
|
|
const std::shared_ptr<CentralEffectSimulation::DatabaseInterface> &db,
|
|
QObject *parent)
|
|
: QObject(parent)
|
|
, SetOwnershipRequestHandler(ddsHandler->ftsCes())
|
|
, m_ddsHandler(ddsHandler)
|
|
, m_handlerParticipant(participantHandler)
|
|
, m_handlerBuildingData(buildingDataHandler)
|
|
, m_db(db)
|
|
, m_logger(CentralEffectSimulation::getLogger("Plugin.Buildings.HandlerBuildingOwnership"))
|
|
{
|
|
INFO_LOG(m_logger) << "HandlerBuildingOwnership::HandlerBuildingOwnership";
|
|
} // end of ctor()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
HandlerBuildingOwnership::~HandlerBuildingOwnership()
|
|
{
|
|
} // end of dtor()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool HandlerBuildingOwnership::init()
|
|
{
|
|
INFO_LOG(m_logger) << "HandlerBuildingOwnership::init";
|
|
auto dtcIsm = m_ddsHandler->dtcIsm();
|
|
|
|
DEBUG_LOG(m_logger) << "init";
|
|
loadOwnershipsFromDb();
|
|
|
|
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::newOutdoorPosition,
|
|
this, &HandlerBuildingOwnership::onParticipantPositionChanged);
|
|
|
|
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::newIndoorPosition,
|
|
this, &HandlerBuildingOwnership::onParticipantPositionChanged);
|
|
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::newNotfightMode,
|
|
this, &HandlerBuildingOwnership::onParticipantPositionChanged);
|
|
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::participantLeavesBuilding,
|
|
this, &HandlerBuildingOwnership::onParticipantLeavesBuilding);
|
|
connect(m_handlerParticipant.get(), &CentralEffectSimulation::HandlerParticipant::newParticipantState,
|
|
this, &HandlerBuildingOwnership::onParticipantPositionChanged);
|
|
|
|
dtcIsm->waitForHistoricalDataMainStructureElement(1000);
|
|
connect(dtcIsm.get(), &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged,
|
|
this, &HandlerBuildingOwnership::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()
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// ///////////////////////////////////
|
|
// B L D (Buildings)
|
|
// ///////////////////////////////////
|
|
|
|
void HandlerBuildingOwnership::onSetOwnershipRequest(const rti::core::SampleIdentity &cookie,
|
|
const CentralEffectSimulation::SetOwnershipRequest &request)
|
|
{
|
|
INFO_LOG(m_logger) << "onSetOwnershipRequest: " << request;
|
|
|
|
// remove Ownership, if partyId == 0
|
|
if (request.partyId() == 0)
|
|
removeFromDbBuildingId(request.buildingId());
|
|
|
|
const QVector<int> floors = m_handlerBuildingData->getFloorsFromBuilding(request.buildingId());
|
|
for (int floorId : floors)
|
|
saveBuildingOwnership(floorId, request.partyId(), request.buildingId());
|
|
|
|
if (!floors.isEmpty())
|
|
sendBuildingOwnership(request.buildingId());
|
|
|
|
m_ddsHandler->ftsCes()->setOwnershipReply(cookie, Core::FunctionReplyObject(request.buildingId()));
|
|
}
|
|
|
|
void HandlerBuildingOwnership::onParticipantPositionChanged(const CentralEffectSimulation::HandlerParticipant::CesParticipantData &partPos)
|
|
{
|
|
|
|
const int participantId = partPos.participantId();
|
|
INFO_LOG(m_logger) << "BuildingOwnership onParticipantPositionChanged participantId=" << participantId
|
|
<< " vulnerabilityState=" << partPos.vulnerabilityState
|
|
<< " buildingId=" << partPos.buildingId()
|
|
<< " notfightMode=" << partPos.notfightMode;
|
|
|
|
// [GUEZE-2256] 3D Wirksim - Funktionsraum Nicht Kampffaehig
|
|
// Teilnehmer, die den Status Nicht Kampffaehig haben, düfen nicht bei der Berechnung des Gebaeudebesitzes beruecksichtigt werden.
|
|
if (partPos.notfightMode)
|
|
return;
|
|
|
|
int floorId = m_handlerBuildingData->getFloorIdFromRoomId(partPos.roomId());
|
|
if (partPos.vulnerabilityState == ProjectDataManagement::VulnerabilityState_def::CatastrophicKill)
|
|
m_participantFloor.remove(participantId);
|
|
else
|
|
m_participantFloor.insert(participantId, floorId);
|
|
|
|
int newOwnership = calculateOwnershipByParticipantId(participantId);
|
|
checkAndSendOwnership(newOwnership, floorId);
|
|
INFO_LOG(m_logger) << "END BuildingOwnership onParticipantPositionChanged participantId=" << participantId
|
|
<< " vulnerabilityState=" << partPos.vulnerabilityState;
|
|
} // end of onParticipantPositionChanged()
|
|
|
|
|
|
// ///////////////////////////////////
|
|
// I S M (InfrastructureManagement)
|
|
// ///////////////////////////////////
|
|
void HandlerBuildingOwnership::onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data, DataModification modType)
|
|
{
|
|
INFO_LOG(m_logger) << "onMainStructureElementChanged id=" << data.id()
|
|
<< " modelId =" << data.modelId();
|
|
if (modType == DataModification::eRemoved || data.modelId() <= 0)
|
|
{
|
|
m_buildingOwnership.remove(data.id());
|
|
return;
|
|
}
|
|
|
|
QJsonArray jsonArray = QJsonDocument::fromJson(QByteArray::fromStdString(data.properties())).object().value(QLatin1String("available_in_exercise")).toArray();
|
|
DEBUG_LOG(m_logger) << "available_in_exercise jsonDocument.size()=" << jsonArray.size();
|
|
QVector<int> result;
|
|
result.reserve(jsonArray.size());
|
|
|
|
// Check if present in the current exercise and remove
|
|
if (m_buildingOwnership.contains(data.id()))
|
|
{
|
|
int id = data.id();
|
|
m_buildingOwnership.remove(id);
|
|
m_ddsHandler->dtsCes()->removeBuildingOwnershipByKey(id);
|
|
}
|
|
|
|
for (auto it = jsonArray.constBegin(); it != jsonArray.constEnd(); ++it)
|
|
{
|
|
DEBUG_LOG(m_logger) << "available_in_exercise jsonDocument=" << it->toInt();
|
|
if (m_ddsHandler->getExerciseId() != it->toInt())
|
|
continue;
|
|
|
|
DEBUG_LOG(m_logger) << "Got MainStructureElement"
|
|
<< " data.id()=" << data.id()
|
|
<< " data.modelId=" << data.modelId();
|
|
if (!m_buildingOwnership.contains(data.id()))
|
|
{
|
|
// insert in m_buildingOwnership and publish to dds
|
|
CentralEffectSimulation::BuildingOwnership bo;
|
|
bo.buildingId(data.id());
|
|
bo.sampleTime(QDateTime::currentMSecsSinceEpoch());
|
|
updateOwnerships(&bo);
|
|
m_buildingOwnership.insert(data.id(), bo);
|
|
m_ddsHandler->dtsCes()->publish(bo);
|
|
} // if
|
|
} // for
|
|
}
|
|
|
|
void HandlerBuildingOwnership::onParticipantLeavesBuilding(const int participantId)
|
|
{
|
|
INFO_LOG(m_logger) << "BuildingOwnership onParticipantLeavesBuilding participantId=" << participantId;
|
|
auto it = m_participantFloor.find(participantId);
|
|
if (it == m_participantFloor.end())
|
|
return;
|
|
m_participantFloor.erase(it);
|
|
|
|
const int floorId = it.value();
|
|
const int newOwnership = calculateOwnershipByFloorId(floorId);
|
|
DEBUG_LOG(m_logger) << "newOwnership=" << newOwnership;
|
|
if (newOwnership > 0)
|
|
checkAndSendOwnership(newOwnership, floorId);
|
|
} // end of onParticipantLeavesBuilding()
|
|
|
|
int HandlerBuildingOwnership::calculateOwnershipByParticipantId(const int participantId)
|
|
{
|
|
INFO_LOG(m_logger) << "BuildingOwnership calculateOwnershipByParticipantId participantId=" << participantId;
|
|
CentralEffectSimulation::HandlerParticipant::CesParticipantData partPos = m_handlerParticipant->position(participantId);
|
|
return calculateOwnershipByFloorId(m_handlerBuildingData->getFloorIdFromRoomId(partPos.roomId()));
|
|
}
|
|
|
|
int HandlerBuildingOwnership::calculateOwnershipByFloorId(const int floorId)
|
|
{
|
|
INFO_LOG(m_logger) << "BuildingOwnership calculateOwnershipByFloorId floorId=" << floorId;
|
|
int ownership = -1;
|
|
if (floorId == -1)
|
|
return ownership;
|
|
|
|
DEBUG_LOG(m_logger) << "calculateOwnership floorId = " << floorId;
|
|
|
|
QHash <int, int> partyCount; // key = Party, value= Count of Participants;
|
|
// Suche alle Participants in der Etage
|
|
for (auto it = m_participantFloor.cbegin(); it != m_participantFloor.cend(); ++it)
|
|
{
|
|
int iteratorFloor = it.value();
|
|
int iteratorParticipant = it.key();
|
|
if (floorId == iteratorFloor)
|
|
{
|
|
const CentralEffectSimulation::HandlerParticipant::CesParticipantData &localPartPos = m_handlerParticipant->position(iteratorParticipant);
|
|
if (localPartPos.vulnerabilityState == ProjectDataManagement::VulnerabilityState::CatastrophicKill)
|
|
continue; // Don't count participants with catastrophic Kill
|
|
const int partyId = localPartPos.partyId();
|
|
++partyCount[partyId];
|
|
}
|
|
}
|
|
// berechne daraus die Farbe der Partei
|
|
int countParty = 0;
|
|
for (auto it = partyCount.begin(); it != partyCount.end(); ++it)
|
|
{
|
|
if (it.value() > countParty)
|
|
{
|
|
countParty = it.value();
|
|
ownership = it.key();
|
|
}
|
|
}
|
|
return ownership;
|
|
}
|
|
|
|
int HandlerBuildingOwnership::getOwnership(int buildingId, int floorId) const
|
|
{
|
|
INFO_LOG(m_logger) << "BuildingOwnership getOwnership buildingId=" << buildingId
|
|
<< " floorId=" << floorId;
|
|
auto itBldg = m_buildingOwnership.find(buildingId);
|
|
if (itBldg == m_buildingOwnership.end())
|
|
return -1;
|
|
const CentralEffectSimulation::BuildingOwnership &bo = itBldg.value();
|
|
for (const CentralEffectSimulation::Ownership &ownership : bo.ownerships())
|
|
{
|
|
if (ownership.floorId() == floorId)
|
|
return ownership.partyId();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void HandlerBuildingOwnership::checkAndSendOwnership(const int newOwnership, const int floorId)
|
|
{
|
|
INFO_LOG(m_logger) << "BuildingOwnership checkAndSendOwnership";
|
|
if (floorId < 0) // outside building
|
|
return;
|
|
const int buildingId = m_handlerBuildingData->getBuildingIdFromFloorId(floorId);
|
|
if (buildingId < 0)
|
|
{
|
|
WARNING_LOG(m_logger) << "Could not find building for floor with id " << floorId << " - ignoring";
|
|
return;
|
|
}
|
|
// prüfe, ob sich die Farbe geändert hat.
|
|
const int oldOwnership = getOwnership(buildingId, floorId);
|
|
DEBUG_LOG(m_logger) << "checkAndSendOwnership buildingId = "
|
|
<< buildingId
|
|
<< " floorId=" << floorId
|
|
<< " oldOwnership=" << oldOwnership
|
|
<< " newOwnership=" << newOwnership;
|
|
if (oldOwnership != newOwnership) // Kriterium zum Senden
|
|
{
|
|
// Wenn ja, Eintrag in der Verwaltung
|
|
saveBuildingOwnership(floorId, newOwnership, buildingId);
|
|
// und Meldung verschicken.
|
|
sendBuildingOwnership(buildingId);
|
|
DEBUG_LOG(m_logger) << "new Building Ownership";
|
|
}
|
|
}
|
|
|
|
void HandlerBuildingOwnership::updateOwnerships(CentralEffectSimulation::BuildingOwnership *bo)
|
|
{
|
|
INFO_LOG(m_logger) << "BuildingOwnership updateOwnerships";
|
|
QMap <int, int> ownershipMap;
|
|
|
|
const QVector<int> floors = m_handlerBuildingData->getFloorsFromBuilding(bo->buildingId());
|
|
DEBUG_LOG(m_logger) << "updateOwnerships floors.size= " << floors.size();
|
|
for (const int floorId : floors)
|
|
ownershipMap[floorId] = 0;
|
|
|
|
for (const CentralEffectSimulation::Ownership &ownership : bo->ownerships())
|
|
{
|
|
DEBUG_LOG(m_logger) << "updateOwnerships floorId=" << ownership.floorId() << ": " << ownership.partyId();
|
|
ownershipMap[ownership.floorId()] = ownership.partyId();
|
|
}
|
|
|
|
bo->ownerships().resize(0);
|
|
bo->ownerships().reserve(ownershipMap.size());
|
|
|
|
CentralEffectSimulation::Ownership ownership;
|
|
for (auto it = ownershipMap.cbegin(); it != ownershipMap.cend(); ++it)
|
|
{
|
|
DEBUG_LOG(m_logger) << it.key() << ": " << it.value();
|
|
ownership.floorId(it.key());
|
|
ownership.partyId(it.value());
|
|
bo->ownerships().push_back(ownership);
|
|
}
|
|
|
|
}
|
|
void HandlerBuildingOwnership::saveBuildingOwnership(int floorId, int partyId, int buildingId)
|
|
{
|
|
INFO_LOG(m_logger) << "saveBuildingOwnership floorId: " << floorId
|
|
<< ", partyId: " << partyId
|
|
<< ", buildingId: " << buildingId;
|
|
|
|
// Vorhandenen Eintrag für das Gebäude suchen
|
|
auto it = m_buildingOwnership.find(buildingId);
|
|
if (it != m_buildingOwnership.end())
|
|
{
|
|
CentralEffectSimulation::BuildingOwnership &bo = *it;
|
|
// Vorhanden Eintrag für das Stockwerk suchen:
|
|
for (CentralEffectSimulation::Ownership &ownership : bo.ownerships())
|
|
{
|
|
if (ownership.floorId() == floorId)
|
|
{
|
|
ownership.partyId(partyId);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Neuen Eintrag für das Stockwerk anlegen
|
|
CentralEffectSimulation::Ownership ownership;
|
|
ownership.floorId(floorId);
|
|
ownership.partyId(partyId);
|
|
bo.ownerships().push_back(std::move(ownership));
|
|
m_buildingOwnership.insert(buildingId, bo);
|
|
return;
|
|
}
|
|
|
|
// Neuen Eintrag für das Gebäude anlegen
|
|
CentralEffectSimulation::BuildingOwnership bo;
|
|
CentralEffectSimulation::Ownership ownership;
|
|
|
|
bo.buildingId(buildingId);
|
|
ownership.floorId(floorId);
|
|
ownership.partyId(partyId);
|
|
bo.ownerships().resize(1, ownership);
|
|
m_buildingOwnership.insert(buildingId, bo);
|
|
}
|
|
|
|
void HandlerBuildingOwnership::sendBuildingOwnership(int buildingId)
|
|
{
|
|
INFO_LOG(m_logger) << "sendBuildingOwnership for building: " << buildingId;
|
|
CentralEffectSimulation::BuildingOwnership bo = m_buildingOwnership.value(buildingId);
|
|
bo.buildingId(buildingId);
|
|
bo.sampleTime(QDateTime::currentMSecsSinceEpoch());
|
|
updateOwnerships(&bo);
|
|
m_ddsHandler->dtsCes()->publish(bo);
|
|
insertInDb(bo);
|
|
}
|
|
// ///////////////////////////////////////////////////
|
|
/// \brief HandlerConfigureAlarms::loadOwnershipsFromDb
|
|
/// \return
|
|
///
|
|
bool HandlerBuildingOwnership::loadOwnershipsFromDb()
|
|
{
|
|
INFO_LOG(m_logger) << "HandlerBuildingOwnership::loadOwnershipsFromDb ";
|
|
m_buildingOwnership.clear();
|
|
auto cbBo = [this](const CentralEffectSimulation::Database::CesOwnership & bo)
|
|
{
|
|
saveBuildingOwnership(bo.floorId, bo.partyId, bo.buildingId);
|
|
};
|
|
if (!m_db->select(cbBo))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error reading data from database 'CesOwnership'";
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void HandlerBuildingOwnership::removeFromDbBuildingId(const int buildingId)
|
|
{
|
|
INFO_LOG(m_logger) << "HandlerBuildingOwnership::removeFromDbBuildingId buildingId: " << buildingId;
|
|
m_db->removeCesOwnershipByBuildingId(buildingId);
|
|
}
|
|
|
|
|
|
void HandlerBuildingOwnership::insertInDb(const CentralEffectSimulation::BuildingOwnership &bo)
|
|
{
|
|
DBTransaction trans(m_db->database());
|
|
|
|
removeFromDbBuildingId(bo.buildingId());
|
|
INFO_LOG(m_logger) << "insertInDb buildingId: " << bo.buildingId()
|
|
<< ", bo.ownerships().size(): " << bo.ownerships().size();
|
|
CentralEffectSimulation::Database::CesOwnership newOwnership;
|
|
newOwnership.buildingId = bo.buildingId();
|
|
for (const CentralEffectSimulation::Ownership &ownership : bo.ownerships())
|
|
{
|
|
newOwnership.id = 0;
|
|
newOwnership.floorId = ownership.floorId();
|
|
newOwnership.partyId = ownership.partyId();
|
|
DEBUG_LOG(m_logger) << "ownership: floorId = " << newOwnership.floorId
|
|
<< " partyId = " << newOwnership.partyId;
|
|
if (!m_db->insert(newOwnership))
|
|
ERROR_LOG(m_logger) << "Error adding 'CesOwnership' to database "
|
|
<< " buildingId =" << newOwnership.buildingId
|
|
<< " floorId = " << newOwnership.floorId
|
|
<< " partyId = " << newOwnership.partyId;
|
|
}
|
|
|
|
trans.commit();
|
|
} // end of insertInDb
|
|
|
|
} // namespace CesBuildings
|