Files
qt5-legatus-legacy/Lts/Services/AudioVideoManagement/vd_control.h
T
2026-08-13 18:33:10 +02:00

146 lines
5.0 KiB
C++
Executable File

/**
* @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 <LtsUtilsCore/connection.h>
#include <QString>
#include <QVector>
#include <QTimer>
#include <QObject>
#include <chrono>
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<class Target, class Slot>
void vdSetScript(const QString &scriptName, AvaStreamType typ, int fileSplitting, const QVector<AvaScriptEntry> &streams,
const QString &exportedDirBaseName, const QString &absolutePath, Target *target, Slot Target:: *slot);
void vdSetScript(const QString &scriptName, AvaStreamType typ, int fileSplitting, const QVector<AvaScriptEntry> &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<AvaScriptEntry> &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<class Target, class Slot>
void VdControl::vdSetScript(const QString &scriptName, AvaStreamType typ, int fileSplitting, const QVector<AvaScriptEntry> &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