/** * @RDE_HEADER@ * VdControl * $Id$ * $HeadURL$ * $Author$ * Created by Astrid Müller, SGAS, 2018-02-22 */ #include "vd_control.h" #include "ivd_comm.h" #include "ava_types.h" #include "AvsCommands/simple_command.h" #include "AvsCommands/vd_set_script.h" #include "AvsCommands/keep_alive.h" #include #include #include #include #include namespace AudioVideoManagement { VdControl::VdControl(IVdComm *comm, std::chrono::milliseconds commandTimeout) : m_comm(comm) , m_queue(commandTimeout) , m_logger(getLogger("VdControl")) { Q_ASSERT(comm); connect(comm, &IVdComm::connected, this, &VdControl::onConnected); connect(comm, &IVdComm::disconnected, this, &VdControl::onDisconnected); connect(&m_queue, &AvsCommandQueue::queueEmpty, this, &VdControl::commandQueueEmpty); // signal -> signal connect(&m_queue, &AvsCommandQueue::timeout, this, &VdControl::onTimeout); } void VdControl::switchContext(int exerciseId) { queue(new VdCommands::SimpleCommand(QLatin1String("SwitchContext"), m_comm, this, [ = ](IVdComm * comm) { comm->switchContext(exerciseId); })); } void VdControl::vdSetScript(const QString &scriptName, AvaStreamType typ, int fileSplitting, const QVector &streams, const QString &exportedDirBaseName, const QString &absolutePath) { vdSetScript(scriptName, typ, fileSplitting, streams, exportedDirBaseName, absolutePath, new LtsUtils::DummyConnection); } void VdControl::vdReleaseScript(const QString &scriptName) { queue(new VdCommands::SimpleCommand(QLatin1String("vdReleaseScript"), m_comm, this, [ = ](IVdComm * comm) { comm->vdReleaseScript(scriptName); })); } void VdControl::keepAlive() { queue(new VdCommands::KeepAlive(m_comm, this)); } void VdControl::onConnected() { m_connected = true; DEBUG_LOG(m_logger) << "connected"; } void VdControl::onDisconnected() { m_connected = false; DEBUG_LOG(m_logger) << "disconnected"; m_queue.flush(); } void VdControl::onTimeout() { ICommand *cmd = m_queue.currentCommand(); if (cmd->canTimeout()) { INFO_LOG(m_logger) << "command '" << cmd->debug() << "' failed"; m_queue.done(); return; } ERROR_LOG(m_logger) << "command timed out"; failed(cmd); } void VdControl::vdSetScript(const QString &scriptName, AvaStreamType typ, int fileSplitting, const QVector &streams, const QString &exportedDirBaseName, const QString &absolutePath, LtsUtils::IConnection *connection) { queue(new AvaCommands::VdSetScript(m_comm, this, scriptName, typ, fileSplitting, streams, exportedDirBaseName, absolutePath), connection); } void VdControl::queue(ICommand *cmd, LtsUtils::IConnection *connection) { Q_ASSERT(cmd); std::unique_ptr cmd_(cmd); std::unique_ptr connection_(connection); if (!m_connected) { DEBUG_LOG(m_logger) << "not connected -> dropping command"; return; } m_queue.queue(std::move(cmd_), std::move(connection_)); } /** * Default fallback for all commands that don't require special action * upon completion such as emitting a signal. */ void VdControl::done(ICommand *cmd) { Q_ASSERT(cmd == m_queue.currentCommand()); m_queue.done(); } void VdControl::done(AvaCommands::VdSetScript *cmd) { Q_ASSERT(cmd == m_queue.currentCommand()); { LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection()); emit vdScriptFinished(cmd->getAvDir(), cmd->getStreamType(), cmd->wasSuccessful()); } // extra small scope as done() deletes the instance scopedConn is operating on m_queue.done(); } void VdControl::failed(ICommand *cmd) { ERROR_LOG(m_logger) << "command '" << cmd->debug() << "' failed"; Q_ASSERT(cmd == m_queue.currentCommand()); m_queue.flush(); m_comm->forceDisconnect(); } void VdControl::alive(ICommand *cmd) { Q_ASSERT(cmd == m_queue.currentCommand()); m_queue.alive(); } } // namespace AudioVideoManagement