Files
qt5-legatus-legacy/Lts/Services/CentralEffectSimulation/Plugins/Basic/handler_simulated_movement.cpp
T
2026-08-13 18:33:10 +02:00

311 lines
12 KiB
C++
Executable File

/**
* Handler for player data
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2017-02-20
*/
#include "handler_simulated_movement.h"
#include <CentralEffectSimulation/handler_participant.h>
#include <QTimer>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <ngldb/dbtransaction.h>
namespace CentralEffectSimulationBasic
{
HandlerSimulatedMovement::HandlerSimulatedMovement(const std::shared_ptr<CentralEffectSimulation::DdsHandler> &ddsHandler,
const std::shared_ptr<CentralEffectSimulation::HandlerParticipant> &participantHandler,
const std::shared_ptr<CentralEffectSimulation::DatabaseInterface> &db,
QObject *parent)
: QObject(parent)
, SimulatedMovementModifyRequestHandler(ddsHandler->ftsCes())
, SimulatedMovementRemoveRequestHandler(ddsHandler->ftsCes())
, SimulatedMovementRemoveByParticipantIdRequestHandler(ddsHandler->ftsCes())
, m_ddsHandler(ddsHandler)
, m_handlerParticipant(participantHandler)
, m_db(db)
, m_jumpToStart(false)
, m_logger(CentralEffectSimulation::getLogger("Plugin.Basic.HandlerSimulatedMovement"))
{
} // end of ctor()
//-----------------------------------------------------------------------------
HandlerSimulatedMovement::~HandlerSimulatedMovement()
{
qDeleteAll(m_simulationMovements);
} // end of dtor()
//-----------------------------------------------------------------------------
bool HandlerSimulatedMovement::init()
{
if (!loadSimulatedMovementFromDb())
return false;
return true;
} // end of init()
bool HandlerSimulatedMovement::loadSimulatedMovementFromDb()
{
QVector<CentralEffectSimulation::Database::CesSimulatedMovement> simMoveVec;
if (!m_db->select(simMoveVec))
{
ERROR_LOG(m_logger) << "Error reading data from database 'CesSimulatedMovement'";
return false;
}
DEBUG_LOG(m_logger) << "loadSimulatedMovementFromDb size =" << simMoveVec.size();
QVector<CentralEffectSimulation::Database::CesSimulatedMovementSegment> simMoveSegVec;
if (!m_db->select(simMoveSegVec))
{
ERROR_LOG(m_logger) << "Error reading data from database 'CesSimulatedMovementSegment'";
return false;
}
DEBUG_LOG(m_logger) << "loadSimulatedMovementSegmentsFromDb size =" << simMoveSegVec.size();
// add to internal buffer
for (const CentralEffectSimulation::Database::CesSimulatedMovement &data : qAsConst(simMoveVec))
{
CentralEffectSimulation::SimulatedMovement request;
request.id(data.id);
request.name(data.name.toStdString());
request.startTime(data.startTime);
request.participantId(data.participantId);
request.repeat(data.repeat);
request.nextPoint(data.nextpoint);
DEBUG_LOG(m_logger) << "Loading SimulatedMovement: " << request;
QMap <int, CentralEffectSimulation::Database::CesSimulatedMovementSegment> segDbMap; // QMap to get it sorted
for (const CentralEffectSimulation::Database::CesSimulatedMovementSegment &segData : qAsConst(simMoveSegVec))
{
if (segData.simulatedMovementId == data.id)
segDbMap.insert(segData.positionIndex, segData);
}
request.segments().reserve(segDbMap.size());
CentralEffectSimulation::SimulatedMovementSegment seg;
for (const CentralEffectSimulation::Database::CesSimulatedMovementSegment &segDb : qAsConst(segDbMap))
{
seg.delay(segDb.delay);
seg.name(segDb.name.toStdString());
seg.speed(segDb.speed);
seg.position(Core::GeoPosition2D(segDb.position.x(),
segDb.position.y()));
request.segments().push_back(seg);
}
SimulationMovement *sm = new SimulationMovement(m_ddsHandler, m_db, m_handlerParticipant, request);
m_simulationMovements.insert(sm->id(), sm);
publishSimulatedMovement(request);
}
return true;
}
Core::FunctionReplyObject HandlerSimulatedMovement::insertInDb(const CentralEffectSimulation::SimulatedMovement &request)
{
CentralEffectSimulation::Database::CesSimulatedMovement newSimulatedMovement = SimulationMovement::toDb(request);
DBTransaction trans(m_db->database());
if (m_simulationMovements.contains(request.id()))
newSimulatedMovement.nextpoint = m_simulationMovements.value(request.id())->getNextPoint();
else // new Simulation
newSimulatedMovement.nextpoint = 1;
if (!m_db->insert(newSimulatedMovement))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error adding 'CesSimulatedMovement' to database"));
DEBUG_LOG(m_logger) << "newSimulatedMovement.id = " << newSimulatedMovement.id;
CentralEffectSimulation::Database::CesSimulatedMovementSegment newSegment;
newSegment.simulatedMovementId = newSimulatedMovement.id;
for (const CentralEffectSimulation::SimulatedMovementSegment &seg : request.segments())
{
newSegment.id = 0; // insert
newSegment.delay = seg.delay();
newSegment.speed = seg.speed();
newSegment.name = QString::fromStdString(seg.name());
newSegment.position = QPointF(seg.position().lon(), seg.position().lat());
if (!m_db->insert(newSegment))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error adding 'CesSimulatedMovementSegment' to database"));
++newSegment.positionIndex;
}
trans.commit();
DEBUG_LOG(m_logger) << "newSimulatedMovement.id=" << newSimulatedMovement.id << " request.id=" << request.id();
return Core::FunctionReplyObject(newSimulatedMovement.id);
} // end of insertInDb
Core::FunctionReplyObject HandlerSimulatedMovement::updateDb(const CentralEffectSimulation::SimulatedMovement &request)
{
CentralEffectSimulation::Database::CesSimulatedMovement newSimulatedMovement(SimulationMovement::toDb(request));
if (!m_db->update(newSimulatedMovement))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error update 'CesSimulatedMovement' to database"));
DEBUG_LOG(m_logger) << "newSimulatedMovement.id = " << newSimulatedMovement.id;
// First remove all participant-segments
m_db->removeCesSimulatedMovementSegmentBySimulatedMovementId(newSimulatedMovement.id);
// Insert new segments:
CentralEffectSimulation::Database::CesSimulatedMovementSegment newSegment;
newSegment.simulatedMovementId = newSimulatedMovement.id;
for (const CentralEffectSimulation::SimulatedMovementSegment &seg : request.segments())
{
newSegment.id = 0; // insert
newSegment.delay = seg.delay();
newSegment.speed = seg.speed();
newSegment.name = QString::fromStdString(seg.name());
newSegment.position = QPointF(seg.position().lon(), seg.position().lat());
if (!m_db->insert(newSegment))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error adding 'CesSimulatedMovementSegment' to database"));
++newSegment.positionIndex;
}
DEBUG_LOG(m_logger) << "newSimulatedMovement.id=" << newSimulatedMovement.id << " request.id=" << request.id();
return Core::FunctionReplyObject(newSimulatedMovement.id);
} // end of updateDb
Core::FunctionReplyObject HandlerSimulatedMovement::removeFromDb(const int32_t id)
{
DEBUG_LOG(m_logger) << "removeFromDb: id=" << id;
if (!m_db->removeCesSimulatedMovement(id))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error remove 'CesSimulatedMovement' from database"));
return Core::FunctionReplyObject(id);
}
void HandlerSimulatedMovement::publishSimulatedMovement(const CentralEffectSimulation::SimulatedMovement &request)
{
INFO_LOG(m_logger) << "publishSimulatedMovement: " << request;
m_ddsHandler->dtsCes()->publish(request);
}
void HandlerSimulatedMovement::setParticipantAsSimulated(const int &participantId, const bool isSimulated)
{
if (participantId <= 0)
return;
ParticipantManagement::SetAsSimulated req(participantId,isSimulated);
if (!m_ddsHandler->ftcPpm()->setAsSimulatedRequest(req, this))
ERROR_LOG(m_logger) << "Error modify participant data participantId=" << participantId;
}
void HandlerSimulatedMovement::onModifyParticipantDataReply(const Core::FunctionReplyObject &replyObject)
{
if (replyObject.error())
WARNING_LOG(m_logger) << "onModifyParticipantDataReply: " << replyObject();
}
void HandlerSimulatedMovement::onSetAsSimulatedReply(const Core::FunctionReplyObject &replyObject)
{
if (replyObject.error())
WARNING_LOG(m_logger) << "onSetAsSimulatedReply: " << replyObject();
}
void HandlerSimulatedMovement::onSimulatedMovementModifyRequest(const rti::core::SampleIdentity &cookie,
const CentralEffectSimulation::SimulatedMovement &request)
{
DEBUG_LOG(m_logger) << "onSimulatedMovementModifyRequest: " << request;
m_jumpToStart = request.jumpToStart();
// we allow a modify with requestId = 0 and participantId != 0
SimulationMovement *sm = findSimulationMovement(request.id(), request.participantId());
if (sm)
sm->setSimulatedMovementRequest(request);
else
sm = new SimulationMovement(m_ddsHandler, m_db, m_handlerParticipant, request);
// New Route
if (request.jumpToStart())
{
DEBUG_LOG(m_logger) << "sm->setJump(true)";
sm->setJump(true);
}
Core::FunctionReplyObject reply = request.id() > 0
? updateDb(sm->simMovementData())
: insertInDb(sm->simMovementData());
sm->setId(reply.id());
m_simulationMovements[sm->id()] = sm;
publishSimulatedMovement(request);
setParticipantAsSimulated(request.participantId(), true);
DEBUG_LOG(m_logger) << "simulatedMovementModifyReply id=" << reply.id();
m_ddsHandler->ftsCes()->simulatedMovementModifyReply(cookie, reply);
} // end onSimulatedMovementModifyRequest
Core::FunctionReplyObject HandlerSimulatedMovement::removeSimulatedMovement(int32_t ddsId)
{
DEBUG_LOG(m_logger) << "removeSimulatedMovement with id " << ddsId << ", " << m_simulationMovements.size();
if (ddsId <= 0)
return Core::FunctionReplyObject(0, tr_lts("dds", "remove participant simulation "));
auto reply = removeFromDb(ddsId);
if (reply.error())
return reply;
int participantId = -1;
auto it = m_simulationMovements.find(ddsId);
if (it != m_simulationMovements.end())
{
participantId = it.value()->participantId();
delete it.value();
m_simulationMovements.erase(it);
}
if (participantId == -1)
WARNING_LOG(m_logger) << "Could not find movement simulation with id " << ddsId << ", " << m_simulationMovements.size();
setParticipantAsSimulated(participantId, false);
return reply;
}
void HandlerSimulatedMovement::onSimulatedMovementRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request)
{
Core::FunctionReplyObject reply = removeSimulatedMovement(request.id());
if (reply.error())
WARNING_LOG(m_logger) << reply();
m_ddsHandler->ftsCes()->simulatedMovementRemoveReply(cookie, reply);
} // end onSimulatedMovementRemoveRequest
void HandlerSimulatedMovement::onSimulatedMovementRemoveByParticipantIdRequest(const rti::core::SampleIdentity &cookie,
const CentralEffectSimulation::SimulatedMovementRemoveByParticipantId &request)
{
DEBUG_LOG(m_logger) << "onSimulatedMovementRemoveByParticipantIdRequest: " << request;
int id = 0;
for (const SimulationMovement *simMovement : qAsConst(m_simulationMovements))
{
if (simMovement->participantId() == request.participantId())
{
id = simMovement->id();
break;
}
}
Core::FunctionReplyObject reply = removeSimulatedMovement(id);
if (reply.error())
WARNING_LOG(m_logger) << reply();
m_ddsHandler->ftsCes()->simulatedMovementRemoveByParticipantIdReply(cookie, reply);
}
SimulationMovement *HandlerSimulatedMovement::findSimulationMovement(int id, int participantId)
{
if (id)
return m_simulationMovements.value(id);
for (SimulationMovement *s : qAsConst(m_simulationMovements))
{
if (s->participantId() == participantId)
return s;
}
return nullptr;
}
} // namespace CentralEffectSimulationBasic