/** * @RDE_HEADER@ * VdControl * $Id$ * $HeadURL$ * $Author$ * Created by Astrid Müller, SGAS, 2018-02-22 */ #pragma once #include "ivd_command_done_observer.h" #include "avm_export.h" #include "ava_types.h" #include "avs_command_queue.h" #include "logger.h" #include #include #include #include #include #include class QStringList; namespace AudioVideoManagement { class IVdComm; /** * AvaControl sits ontop of AvaComm. * For the communication with the AVS that must be exactly one AvaComm * and one AvaControl instance. * AvaControl uses a command queue and ensures that each command is sent after * the previous command finished. * The definition of when a command is finished is defined by the command itself. * Most of the commands are SimpleCommands which only wait for the OK-response. * * For those commands that have a data-response -- such as getStreamList -- * a signal is provided that will be emitted when the command finished. * * Commands being sent while no connection is established will be dropped. * When the connection gets lost, all Commands still in the queue will be dropped. * When a command fails, all remaining commands will be dropped and the connection * to the AVS will be closed and established again. * * A command must complete within a defined time frame. If it does not, * the command is conside red failed with the implications described above. * * There are two ways to get responses that contain data -- such as the result of * getStreamList or queryTimeline: * 1. Connect to the corresponding signals in the usual way. The problem with this * approach arises when there are several clients using the AvaControl-instance * at the same time. Then you receive all responses no matter who * initiated the corresponding command. * 2. You can specify an optional slot when issuing the command. * This slot will be called when the command is finished. This way you only receive * responses that correspond to the command you initiated. * * @see VdComm * @see VdSession * @see ICommand * @author Astrid Müller, Christian Fröbel */ class AVM_COMMON_EXPORT VdControl : public QObject, public IVdCommandDoneObserver { Q_OBJECT public: VdControl(IVdComm *comm, std::chrono::milliseconds commandTimeout); void switchContext(int exerciseId); /** SCRIPT */ ///@{ template void vdSetScript(const QString &scriptName, AvaStreamType typ, int fileSplitting, const QVector &streams, const QString &exportedDirBaseName, const QString &absolutePath, Target *target, Slot Target:: *slot); void vdSetScript(const QString &scriptName, AvaStreamType typ, int fileSplitting, const QVector &streams, const QString &exportedDirBaseName, const QString &absolutePath); void vdReleaseScript(const QString &scriptName); ///@} void keepAlive(); /** * These overloaded done() methods will be called by the specific * commands themselves upon completion. */ ///@{ void done(ICommand *cmd) override; void done(AvaCommands::VdSetScript *cmd) override; /** * Called whenever a command fails due error response or other unexpected responses. * All queued commands will be dropped and the connection to AVS will * be disconnected and re-established. */ void failed(ICommand *cmd) override; void alive(ICommand *cmd) override; ///@} /** Access to the underlying VdComm-instance. */ IVdComm *comm() { return m_comm; } signals: void vdScriptFinished(const QString &dir, AvaStreamType streamType, bool success); /** * Signalled whenever the command queue is empty again. This can have several reasons: * - The last command finished successfully. * - A command failed and the command queue was flushed. * - This instance is deleted with a non-empty command queue which gets flushed then. */ void commandQueueEmpty(); private slots: void onConnected(); void onDisconnected(); void onTimeout(); private: void vdSetScript(const QString &scriptName, AvaStreamType typ, int fileSplitting, const QVector &streams, const QString &exportedDirBaseName, const QString &absolutePath, LtsUtils::IConnection *connection); void queue(ICommand *cmd, LtsUtils::IConnection *connection = nullptr); IVdComm *m_comm; bool m_connected{false}; AvsCommandQueue m_queue; LOGGER_T m_logger; }; template void VdControl::vdSetScript(const QString &scriptName, AvaStreamType typ, int fileSplitting, const QVector &streams, const QString &exportedDirBaseName, const QString &absolutePath, Target *target, Slot Target::*slot) { vdSetScript(scriptName, typ, fileSplitting, streams, exportedDirBaseName, absolutePath, LtsUtils::createConnection(this, &VdControl::vdScriptFinished, target, slot)); } } // namespace AudioVideoManagement