/** * Handler for player data * $Id$ * $HeadURL$ * $Author$ * Created by gr, SLSE, 2017-02-20 */ #include "handler_simulated_movement.h" #include #include #include #include namespace CentralEffectSimulationBasic { HandlerSimulatedMovement::HandlerSimulatedMovement(const std::shared_ptr &ddsHandler, const std::shared_ptr &participantHandler, const std::shared_ptr &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 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 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 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