/** * @RDE_HEADER@ * Handler for all request journal objects * $Id$ * $HeadURL$ * $Author$ * Created by Hanna E. Rathje, SLSE, 2015-01-13 */ #include "handler_situation_replay.h" #include "object_situation_replay.h" #include "db_reader.h" #include #include #include #include namespace SituationReplay { HandlerSituationReplay::HandlerSituationReplay(const std::shared_ptr &ddsHandler, const std::shared_ptr &db, const std::shared_ptr &dbReader) : Interface::Fts::ChangeReplayStateRequestHandler(ddsHandler->fts()) , m_objSrp(nullptr) , m_ddsHandler(ddsHandler) , m_db(db) , m_dbReader(dbReader) , m_exerciseId(0) , m_partitionId(0) , m_logger(getLogger("HandlerSituationReplay")) {} HandlerSituationReplay::~HandlerSituationReplay() { delete m_objSrp; } bool HandlerSituationReplay::init(int exerciseId, int partitionId) { m_exerciseId = exerciseId; m_partitionId = partitionId; const QString tableName = m_db->schemaName().isEmpty() ? QStringLiteral("exercise") : QStringLiteral("exm.exercise"); const QString stmt(QStringLiteral("SELECT start_time FROM %1 WHERE id = %2").arg(tableName).arg(exerciseId)); NSqlQuery q(m_db->database()); const qint64 exerciseStartTime = (q.execAndFetch(stmt) ? q.value(0).toLongLong() : 0); DEBUG_LOG(m_logger) << "stmt: " << stmt << ", res " << exerciseStartTime; Database::SrpSituationReplay newData; newData.srpStateId = SrpState::Stopped; newData.replayPartitionId = m_partitionId; newData.beginTime = exerciseStartTime; newData.endTime = exerciseStartTime; newData.pace = 0.0; return createObject(newData); } bool HandlerSituationReplay::createObject(const Database::SrpSituationReplay &newData) { delete m_objSrp; m_objSrp = new ObjectSituationReplay(m_ddsHandler, m_db, m_dbReader, m_exerciseId); Core::FunctionReplyObject ret = m_objSrp->createObject(newData); if (ret.error()) { delete m_objSrp; m_objSrp = nullptr; ERROR_LOG(m_logger) << ret(); } return m_objSrp != nullptr; } Core::FunctionReplyObject HandlerSituationReplay::startReplayRequest(const SituationReplay::ChangeReplayStateRequest &request) { DEBUG_LOG(m_logger) << "onStartReplayRequest: " << request; // Start only own replay if (request.replayPartitionId() != m_partitionId) return Core::FunctionReplyObject(request.replayPartitionId(),tr_lts("dds", "Wrong replay partition")); if (m_objSrp && m_objSrp->srpState() != SrpState::Stopped) return Core::FunctionReplyObject(request.replayPartitionId(), tr_lts("dds", "Replay is not yet stopped")); Database::SrpSituationReplay newData; newData.srpStateId = SrpState::Started; newData.replayPartitionId = m_partitionId; newData.beginTime = request.beginTime(); newData.endTime = request.endTime(); newData.pace = request.pace().is_set() ? request.pace().get() : 1; // round to sec newData.beginTime = (newData.beginTime / 1000) * 1000; if (newData.endTime) newData.endTime = ((newData.endTime / 1000) + 1) * 1000; if (!m_objSrp && !createObject(newData)) return Core::FunctionReplyObject(request.replayPartitionId(),tr_lts("dds", "Internal error")); m_objSrp->setSrpData(newData); return Core::FunctionReplyObject(m_objSrp->getId()); } Core::FunctionReplyObject HandlerSituationReplay::stopReplayRequest(const SituationReplay::ChangeReplayStateRequest &request) { DEBUG_LOG(m_logger) << "onStopReplayRequest: " << request; if (m_objSrp == nullptr) return Core::FunctionReplyObject(request.id(), tr_lts("dds", "SituationReplay for replayPartitionId %1 not found")).arg(request.replayPartitionId()); if (m_objSrp && (m_objSrp->getId() != request.id() || m_objSrp->getReplayPartitionId() != request.replayPartitionId())) return Core::FunctionReplyObject(request.id(),tr_lts("dds", "Given request id %1 not equal object id %2")).arg(request.id()).arg(m_objSrp->getId()); Core::FunctionReplyObject ret = m_objSrp->switchToState(SrpState::Stopped); if (!ret.error()) ret = m_objSrp->removeObject(); // remove all old data from DDS-Bus & clear maps m_dbReader->clearData(); return ret; } Core::FunctionReplyObject HandlerSituationReplay::changeReplayStateRequest(const SituationReplay::ChangeReplayStateRequest &request) { if (request.state() != SrpState_def::Started) { if (m_objSrp == nullptr) return Core::FunctionReplyObject(request.id(), tr_lts("dds", "SituationReplay for replayPartitionId %1 not found")).arg(request.replayPartitionId()); if (m_objSrp && (m_objSrp->getId() != request.id() || m_objSrp->getReplayPartitionId() != request.replayPartitionId())) return Core::FunctionReplyObject(request.id(),tr_lts("dds", "Given request id %1 not equal object id %2")).arg(request.id()).arg(m_objSrp->getId()); } if (request.pace().is_set()) m_objSrp->setPace(request.pace().get()); switch (request.state().underlying()) { case SrpState_def::Unknown: if (request.pace().is_set()) return Core::FunctionReplyObject(request.id()); return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Can not handle command 'Unknown' in changeReplayStateRequest")); case SrpState_def::Started: return startReplayRequest(request); case SrpState_def::Resumed: { DEBUG_LOG(m_logger) << "Resume request: " << request.beginTime() << ", cur playback time: " << m_objSrp->currentReplayTime(); if (request.beginTime() != 0 && request.beginTime() != m_objSrp->currentReplayTime()) { stopReplayRequest(request); return startReplayRequest(request); } Q_FALLTHROUGH(); case SrpState_def::Paused: return m_objSrp->switchToState(request.state()); } case SrpState_def::Stopped: return stopReplayRequest(request); } return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Unhandled request state %1")).arg(request.state().underlying()); } void HandlerSituationReplay::onChangeReplayStateRequest(const rti::core::SampleIdentity &cookie, const ChangeReplayStateRequest &request) { DEBUG_LOG(m_logger) << "onChangeReplayStateRequest: " << request; auto ret = changeReplayStateRequest(request); if (ret.error()) WARNING_LOG(m_logger) << ret(); m_ddsHandler->fts()->changeReplayStateReply(cookie, ret); } } // Namespace SituationReplay