Files
qt5-legatus-legacy/Lts/Proxies/GuezNasat/handler_nasat_aircraft_participant.cpp
T
2026-08-13 18:33:10 +02:00

335 lines
12 KiB
C++
Executable File

/**
* Handle the mapping real aircraft <-> participant in exercise
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2018-08-02
*/
#include "handler_nasat_aircraft_participant.h"
#include "handler_nasat_aircraft.h"
#include "initialization.h"
#include "dds_handler.h"
#include "handler_participant.h"
#include <GuezNasat/gna_db.h>
#include <QTimer>
namespace GuezNasat
{
Database::NasatAircraftParticipant toDb(const NasatAircraftParticipant &dds)
{
Database::NasatAircraftParticipant ret;
ret.id = dds.id();
ret.nasatAircraftId = dds.nasatAircraftId();
ret.exerciseId = dds.exerciseId();
ret.participantId = dds.participantId();
return ret;
}
NasatAircraftParticipant fromDb(const Database::NasatAircraftParticipant &db)
{
NasatAircraftParticipant ret;
ret.id(db.id);
ret.nasatAircraftId(db.nasatAircraftId);
ret.exerciseId(db.exerciseId);
ret.participantId(db.participantId);
return ret;
}
HandlerNasatAircraftParticipant::HandlerNasatAircraftParticipant(Initialization *mainHandler)
: QObject()
, Interface::Fts::ModifyNasatAircraftParticipantRequestHandler(mainHandler->dds()->fts())
, m_mainHandler(mainHandler)
, m_dts(mainHandler->dds()->dts())
, m_fts(mainHandler->dds()->fts())
, m_db(mainHandler->db())
, m_logger(getLogger("HandlerNasatAircraftParticipant"))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
}
HandlerNasatAircraftParticipant::~HandlerNasatAircraftParticipant()
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
for (const auto &data : qAsConst(m_nasatAircraftParticipants))
m_dts->removeNasatAircraftByKey(data.id());
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
}
bool HandlerNasatAircraftParticipant::init()
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
auto cb = [this](const Database::NasatAircraftParticipant & data)
{
const auto dds(fromDb(data));
DEBUG_LOG(m_logger) << "m_nasatAircraftParticipants.insert(" << dds.id() << ")";
m_nasatAircraftParticipants.insert(dds.id(), dds);
m_dts->publish(dds);
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantCreated(dds);
};
m_db->select(cb);
// Most likely, the exercises are empty on normal startup of serviceManagement
// since ExerciseManagement is started later...
auto exmDtc = m_mainHandler->dds()->exmDtc();
connect(exmDtc.get(), &ExerciseManagement::Interface::Dtc::exerciseChanged,
this, &HandlerNasatAircraftParticipant::onExerciseChanged, Qt::UniqueConnection);
exmDtc->exercises([this](const ExerciseManagement::Exercise &exercise) {
onExerciseChanged(exercise, DataModification::eAdded);
});
dumpNasatAircraftParticipants();
dumpExercises();
// exercises are started one by one. So try 30
QTimer::singleShot(30000, this, [this]() { // 30000 -> 30sec
dumpNasatAircraftParticipants();
dumpExercises();
});
DEBUG_LOG(m_logger) << "HandlerNasatAircraftParticipant init done";
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
return true;
}
void HandlerNasatAircraftParticipant::dumpNasatAircraftParticipants()
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, size=" << m_nasatAircraftParticipants.size();
DEBUG_LOG(m_logger) << LOGFUNCTION << " --------------------------------------";
auto it = m_nasatAircraftParticipants.begin();
while (it != m_nasatAircraftParticipants.end())
{
const auto &id = it.key();
const auto &nap = it.value();
DEBUG_LOG(m_logger) << LOGFUNCTION << " id=" << id << " - nap=" << nap;
++it;
}
DEBUG_LOG(m_logger) << LOGFUNCTION << " --------------------------------------";
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, size=" << m_nasatAircraftParticipants.size();
}
void HandlerNasatAircraftParticipant::dumpExercises()
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, size=" << m_exercises.size();
DEBUG_LOG(m_logger) << LOGFUNCTION << " --------------------------------------";
auto it = m_exercises.begin();
while (it != m_exercises.end())
{
const auto &id = it.key();
const auto &nasatAircraftParticipant = it.value();
DEBUG_LOG(m_logger) << LOGFUNCTION << " id=" << id << " - nasatAircraftParticipant=" << nasatAircraftParticipant;
++it;
}
DEBUG_LOG(m_logger) << LOGFUNCTION << " --------------------------------------";
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, size=" << m_exercises.size();
}
void HandlerNasatAircraftParticipant::aircraftRemoved(int nasatAircraftId)
{
auto it = m_nasatAircraftParticipants.begin();
while (it != m_nasatAircraftParticipants.end())
{
const auto &val = it.value();
if (val.nasatAircraftId() == nasatAircraftId)
{
removeNasatAircraftParticipant(val);
it = m_nasatAircraftParticipants.erase(it);
}
else
++it;
}
}
void HandlerNasatAircraftParticipant::participantRemoved(int exerciseId, int participantId)
{
DEBUG_LOG(m_logger) << "participantRemoved: " << exerciseId << ", " << participantId;
auto it = m_nasatAircraftParticipants.begin();
while (it != m_nasatAircraftParticipants.end())
{
const auto &val = it.value();
if (val.participantId() == participantId &&
val.exerciseId() == exerciseId)
{
removeNasatAircraftParticipant(val);
it = m_nasatAircraftParticipants.erase(it);
}
else
++it;
}
}
bool isExerciseStateValid(ExerciseManagement::ExerciseState_def::type state)
{
switch (state)
{
case ExerciseManagement::ExerciseState_def::Created:
case ExerciseManagement::ExerciseState_def::Paused:
case ExerciseManagement::ExerciseState_def::Started:
case ExerciseManagement::ExerciseState_def::Stopped:
return true;
case ExerciseManagement::ExerciseState_def::Unknown:
case ExerciseManagement::ExerciseState_def::Terminated:
return false;
}
return false;
}
void HandlerNasatAircraftParticipant::onExerciseChanged(const ExerciseManagement::Exercise &exercise, DataModification modType)
{
INFO_LOG(m_logger) << LOGFUNCTION << " START" << " , exercise" << exercise << " , modType" << modType;
const int exId = exercise.id();
switch (modType)
{
case DataModification::eAdded:
{
m_exercises[exId] = exercise;
const bool valid = isExerciseStateValid(exercise.state().underlying());
if (!valid)
{
INFO_LOG(m_logger) << LOGFUNCTION << " STATE of exId=" << exId
<< " , state=" << exercise.state();
int cnt = removeNapsOfExercise(exId);
INFO_LOG(m_logger) << LOGFUNCTION << " STATE of exId=" << exId << " not valid : counter of removed naps=" << cnt;
}
}
break;
case DataModification::eModified:
{
const ExerciseManagement::Exercise &exerciseRef = m_exercises[exId];
if (exerciseRef.state() != exercise.state())
{
const bool valid = isExerciseStateValid(exercise.state().underlying());
if (!valid)
{
INFO_LOG(m_logger) << LOGFUNCTION << " STATE change of exId=" << exId
<< " , old state=" << exerciseRef.state()
<< " , new state=" << exercise.state();
int cnt = removeNapsOfExercise(exId);
INFO_LOG(m_logger) << LOGFUNCTION << " STATE change of exId=" << exId << " : counter of removed naps=" << cnt;
}
}
m_exercises[exId] = exercise;
}
break;
case DataModification::eRemoved:
{
int cnt = removeNapsOfExercise(exId);
INFO_LOG(m_logger) << LOGFUNCTION << " STATE change of Exercise, counter of removed naps=" << cnt;
m_exercises.remove(exId);
}
break;
}
INFO_LOG(m_logger) << LOGFUNCTION << " END" << " , exercise" << exercise << " , modType" << modType;
}
void HandlerNasatAircraftParticipant::removeNasatAircraftParticipant(const NasatAircraftParticipant &val)
{
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantRemoved(val);
// empty -> remove
m_db->removeNasatAircraftParticipant(val.id());
m_dts->removeNasatAircraftParticipantByKey(val.id());
}
void HandlerNasatAircraftParticipant::onModifyNasatAircraftParticipantRequest(const rti::core::SampleIdentity &cookie,
const NasatAircraftParticipant &request)
{
DEBUG_LOG(m_logger) << "onModifyNasatAircraftParticipantRequest: " << request;
auto ret = request.id() <= 0 ? createNasatAircraftParticipantRequest(request) : modifyNasatAircraftParticipantRequest(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_fts->modifyNasatAircraftParticipantReply(cookie, ret);
}
Core::FunctionReplyObject HandlerNasatAircraftParticipant::createNasatAircraftParticipantRequest(const NasatAircraftParticipant &request)
{
// create
Database::NasatAircraftParticipant napDb(toDb(request));
napDb.id = 0;
if (!m_db->insert(napDb))
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Can not create Aircraft Participant connection - error inserting values in database"));
// Success, Send Topic to DDS
const auto dds(fromDb(napDb));
m_dts->publish(dds);
m_nasatAircraftParticipants.insert(dds.id(), dds);
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantCreated(request);
return Core::FunctionReplyObject(request.id());
}
Core::FunctionReplyObject HandlerNasatAircraftParticipant::modifyNasatAircraftParticipantRequest(const NasatAircraftParticipant &request)
{
auto it = m_nasatAircraftParticipants.find(request.id());
if (it == m_nasatAircraftParticipants.end())
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Can not modify Aircraft Participant connection - id %1 not found")).arg(request.id());
if (request == *it)
return Core::FunctionReplyObject(request.id());
if ((request.exerciseId() == 0 && request.participantId() == 0) ||
request.nasatAircraftId() == 0)
{
removeNasatAircraftParticipant(it.value());
m_nasatAircraftParticipants.erase(it);
return Core::FunctionReplyObject(request.id());
}
// modify
Database::NasatAircraftParticipant napDb(toDb(request));
if (!m_db->update(napDb))
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Can not modify Aircraft Participant connection - error updating values in database"));
// remove old subscriber
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantRemoved(*it);
const auto dds(fromDb(napDb));
m_dts->publish(dds);
m_nasatAircraftParticipants.insert(dds.id(), dds);
// Success, Send Topic to DDS
m_dts->publish(fromDb(napDb));
// add new subscriber
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantCreated(request);
return Core::FunctionReplyObject(request.id());
}
int HandlerNasatAircraftParticipant::removeNapsOfExercise(int exerciseId)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, exerciseId=" << exerciseId
<< ", m_nasatAircraftParticipants.size()" << m_nasatAircraftParticipants.size();
int count = 0;
QHash<int, NasatAircraftParticipant> napsCopy = m_nasatAircraftParticipants;
for (const NasatAircraftParticipant &nap : qAsConst(napsCopy))
{
if (nap.exerciseId() == exerciseId)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " nap has to be removed: nap=" << nap;
NasatAircraftParticipant napToTriggerRemoving;
napToTriggerRemoving.id(nap.id()); // to trigger removing
napToTriggerRemoving.exerciseId(0); // to trigger removing
napToTriggerRemoving.participantId(0); // to trigger removing
napToTriggerRemoving.nasatAircraftId(0); // to trigger removing
modifyNasatAircraftParticipantRequest(napToTriggerRemoving);
++count;
}
}
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, exerciseId=" << exerciseId
<< ", m_nasatAircraftParticipants.size()" << m_nasatAircraftParticipants.size()
<< ", counter=" << count;
return count;
}
} // namespace GuezNasat