Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+313
@@ -0,0 +1,313 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AvaControl
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Fröbel, SLSE, 2017-06-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "iava_command_done_observer.h"
|
||||
#include "avm_export.h"
|
||||
#include "ava_types.h"
|
||||
#include "rt_state.h"
|
||||
#include "avs_command_queue.h"
|
||||
#include "logger.h"
|
||||
#include <LtsUtilsCore/connection.h>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <QObject>
|
||||
#include <chrono>
|
||||
|
||||
class QStringList;
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class IAvaComm;
|
||||
class ICommand;
|
||||
class StreamNameMapping;
|
||||
|
||||
namespace AvaCommands
|
||||
{
|
||||
|
||||
class ChooseStream;
|
||||
class GetStreamList;
|
||||
class QueryTimeline;
|
||||
class GetElokaList;
|
||||
class QueryEloka;
|
||||
class SetAnnouncementProfile;
|
||||
class SetVideoProfile;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 considered 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 AvaComm
|
||||
* @see AvaSession
|
||||
* @see ICommand
|
||||
* @author Christian Fröbel
|
||||
*/
|
||||
class AVM_COMMON_EXPORT AvaControl : public QObject, public IAvaCommandDoneObserver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AvaControl(IAvaComm *comm, StreamNameMapping *streamNameMapping, std::chrono::milliseconds commandTimeout);
|
||||
|
||||
void switchContext(int exerciseId);
|
||||
void setUserProfile(const QString &userName, const QString &langCode, AvaAudioPrio, AvaGuiStyle);
|
||||
void setTimezone(QChar tz);
|
||||
void setVideoDialogProfile(const QString &dialogId, AvaVisibility);
|
||||
void setVideoDialogGeometry(const QString &dialogId, const QRect &geometry);
|
||||
template<class Target, class Slot>
|
||||
void setVideoProfile(const QString &dialogId, const QString &menuDef, Target *target, Slot Target:: *slot);
|
||||
void setVideoProfile(const QString &dialogId, const QString &menuDef);
|
||||
template<class Target, class Slot>
|
||||
void setRtProfile(RtState *rtState, const QVector<RtState::RadioCircuit> &radioCircuits, Target *target, Slot Target:: *slot);
|
||||
void setRtProfile(RtState *rtState, const QVector<RtState::RadioCircuit> &radioCircuits);
|
||||
template<class Target, class Slot>
|
||||
void changeRtProfileCircuitName(RtState *rtState, const RtState::RadioCircuit &radioCircuit, Target *target, Slot Target:: *slot);
|
||||
void changeRtProfileCircuitName(RtState *rtState, const RtState::RadioCircuit &radioCircuit);
|
||||
template<class Target, class Slot>
|
||||
void setAnnouncementProfile(RtState *rtState, const QString &menuDef, const QString &identityList, const QString &stateList, Target *target, Slot Target:: *slot);
|
||||
void setAnnouncementProfile(RtState *rtState, const QString &menuDef, const QString &identityList, const QString &stateList);
|
||||
void chooseImport(const QString &dialogId, const QString &path, int mode);
|
||||
void releaseImport(const QString &dialogId);
|
||||
|
||||
|
||||
/**
|
||||
* @param slot must be a pointer to a method of Target and must be compatible with
|
||||
* the getStreamListResponse()-signal.
|
||||
*/
|
||||
template<class Target, class Slot>
|
||||
void getStreamList(AvaStreamType, AvaStreamSource, Target *target, Slot Target:: *slot);
|
||||
void getStreamList(AvaStreamType, AvaStreamSource);
|
||||
|
||||
void chooseStream(const QString &dialogId, const QString &streamName);
|
||||
void chooseStreamOverview(const QString &dialogId, const QStringList &streamNames);
|
||||
void releaseStream(const QString &dialogId, const QString &streamName);
|
||||
|
||||
/**
|
||||
* @param slot must be a pointer to a method of Target and must be compatible with
|
||||
* the queryTimelineResponse()-signal.
|
||||
*/
|
||||
template<class Target, class Slot>
|
||||
void queryTimeline(const QString &streamName, Target *target, Slot Target:: *slot, const boost::optional<AvaTimePoint> &start = {}, const boost::optional<AvaTimePoint> &end = {});
|
||||
void queryTimeline(const QString &streamName, const boost::optional<AvaTimePoint> &start = {}, const boost::optional<AvaTimePoint> &end = {});
|
||||
|
||||
void setVolume(int db);
|
||||
|
||||
/** streamControl */
|
||||
///@{
|
||||
void startStream(const QString &dialogId, const QString &streamName, AvaSpeed);
|
||||
void stopStream(const QString &dialogId, const QString &streamName);
|
||||
void pauseStream(const QString &dialogId, const QString &streamName);
|
||||
void setStreamSpeed(const QString &dialogId, const QString &streamName, AvaSpeed);
|
||||
void setAbsPosition(const QString &dialogId, const QString &streamName, AvaTimePoint pos);
|
||||
void positionUpdate(const QString &dialogId, const QString &streamName, std::chrono::milliseconds updateInterval);
|
||||
void setPint(const QString &dialogId, const QString &streamName, bool doSkip);
|
||||
///@}
|
||||
|
||||
/** ELOKA */
|
||||
///@{
|
||||
/**
|
||||
* @param slot must be a pointer to a method of Target and must be compatible with
|
||||
* the getElokaListResponse()-signal.
|
||||
*/
|
||||
template<class Target, class Slot>
|
||||
void getElokaList(const QString &streamName, Target *target, Slot Target:: *slot);
|
||||
void getElokaList(const QString &streamName);
|
||||
void chooseEloka(const QString &streamName, const QString &signalName, AvaElokaMode mode);
|
||||
void releaseEloka(const QString &streamName);
|
||||
template<class Target, class Slot>
|
||||
void queryEloka(AvaQueryElokaMode mode, Target *target, Slot Target:: *slot);
|
||||
void queryEloka(AvaQueryElokaMode mode);
|
||||
///@}
|
||||
|
||||
/** SCRIPT */
|
||||
///@{
|
||||
void setScript(const QString &dialogId, const QString &scriptName, AvaScriptSource,
|
||||
const QVector<AvaScriptEntry> &streams, LtsUtils::IConnection *connection = nullptr);
|
||||
void startScript(const QString &dialogId, const QString &scriptName, LtsUtils::IConnection *connection = nullptr);
|
||||
void releaseScript(const QString &dialogId, const QString &scriptName);
|
||||
///@}
|
||||
|
||||
/** scriptControl */
|
||||
///@{
|
||||
void stopScript(const QString &dialogId, const QString &scriptName);
|
||||
void pauseScript(const QString &dialogId, const QString &scriptName);
|
||||
void setAbsPositionScript(const QString &dialogId, const QString &scriptName, AvaTimePoint pos);
|
||||
///@}
|
||||
|
||||
/** StreamNameMapping */
|
||||
///@{
|
||||
void defineStreamNameMapping(const QString &internalName, const QString &displayName);
|
||||
void resetStreamNameMapping();
|
||||
///@}
|
||||
|
||||
void keepAlive();
|
||||
|
||||
/**
|
||||
* These overloaded done() methods will be called by the specific
|
||||
* commands themselves upon completion.
|
||||
*/
|
||||
///@{
|
||||
void done(ICommand *cmd) override;
|
||||
void done(AvaCommands::ChooseStream *cmd) override;
|
||||
void done(AvaCommands::GetStreamList *cmd) override;
|
||||
void done(AvaCommands::QueryTimeline *cmd) override;
|
||||
void done(AvaCommands::GetElokaList *cmd) override;
|
||||
void done(AvaCommands::QueryEloka *cmd) override;
|
||||
void done(AvaCommands::SetRtProfileBase *cmd) override;
|
||||
void done(AvaCommands::SetAnnouncementProfile *cmd) override;
|
||||
void done(AvaCommands::SetVideoProfile *cmd) override;
|
||||
void done(AvaCommands::SetScript *cmd) override;
|
||||
void done(AvaCommands::StartScript *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(AvaCommands::SetScript *cmd);
|
||||
void failed(ICommand *cmd) override;
|
||||
///@}
|
||||
|
||||
void alive(ICommand *cmd) override;
|
||||
|
||||
/**
|
||||
* Access to the underlying AvaComm-instance.
|
||||
* @return never nullptr
|
||||
*/
|
||||
IAvaComm *comm() { return m_comm; }
|
||||
|
||||
bool isEmpty() const { return m_queue.isEmpty(); }
|
||||
|
||||
signals:
|
||||
void chooseStreamResponse(const AvaStreamInfo &streamInfo, AvaStreamState);
|
||||
void getStreamListResponse(const QVector<AvaStream> &streams);
|
||||
void queryTimelineResponse(const AvaTimeline &timeline);
|
||||
void getElokaListResponse(const QVector<QString> &elokaSignals);
|
||||
void queryElokaResponse(const QVector<AvaEloka> &eloka);
|
||||
void setRtProfileResponse(const QVector<QString> &invalidNameList);
|
||||
void setAnnouncementProfileResponse(const QVector<QString> &invalidNameList);
|
||||
void setVideoProfileResponse(const QVector<QString> &invalidNameList);
|
||||
void setScriptResponse(const AvaStreamInfo &scriptInfo, AvaStreamState ScriptState);
|
||||
void startScriptResponse( AvaStreamState ScriptState);
|
||||
|
||||
/**
|
||||
* 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 getStreamList(AvaStreamType, AvaStreamSource, LtsUtils::IConnection *connection);
|
||||
void queryTimeline(const QString &streamName, LtsUtils::IConnection *connection, const boost::optional<AvaTimePoint> &start = {}, const boost::optional<AvaTimePoint> &end = {});
|
||||
void getElokaList(const QString &streamName, LtsUtils::IConnection *connection);
|
||||
void queryEloka(AvaQueryElokaMode mode, LtsUtils::IConnection *connection);
|
||||
void setRtProfile(RtState *rtState, const QVector<RtState::RadioCircuit> &radioCircuits, LtsUtils::IConnection *connection);
|
||||
void changeRtProfileCircuitName(RtState *rtState, const RtState::RadioCircuit &radioCircuit, LtsUtils::IConnection *connection);
|
||||
void setAnnouncementProfile(RtState *rtState, const QString &menuDef, const QString &identityList,
|
||||
const QString &stateList, LtsUtils::IConnection *connection);
|
||||
void setVideoProfile(const QString &dialogId, const QString &menuDef, LtsUtils::IConnection *connection);
|
||||
|
||||
|
||||
void queue(ICommand *cmd, LtsUtils::IConnection *connection = nullptr);
|
||||
|
||||
IAvaComm *m_comm;
|
||||
StreamNameMapping *m_streamNameMapping;
|
||||
bool m_connected{false};
|
||||
AvsCommandQueue m_queue;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
template<class Target, class Slot>
|
||||
void AvaControl::getStreamList(AvaStreamType streamType, AvaStreamSource streamSource, Target *target, Slot Target:: *slot)
|
||||
{
|
||||
getStreamList(streamType, streamSource, LtsUtils::createConnection(this, &AvaControl::getStreamListResponse, target, slot));
|
||||
}
|
||||
|
||||
template<class Target, class Slot>
|
||||
void AvaControl::queryTimeline(const QString &streamName, Target *target, Slot Target:: *slot, const boost::optional<AvaTimePoint> &start, const boost::optional<AvaTimePoint> &end)
|
||||
{
|
||||
queryTimeline(streamName, LtsUtils::createConnection(this, &AvaControl::queryTimelineResponse, target, slot), start, end);
|
||||
}
|
||||
|
||||
template<class Target, class Slot>
|
||||
void AvaControl::getElokaList(const QString &streamName, Target *target, Slot Target:: *slot)
|
||||
{
|
||||
getElokaList(streamName, LtsUtils::createConnection(this, &AvaControl::getElokaListResponse, target, slot));
|
||||
}
|
||||
|
||||
template<class Target, class Slot>
|
||||
void AvaControl::queryEloka(AvaQueryElokaMode mode, Target *target, Slot Target:: *slot)
|
||||
{
|
||||
Q_ASSERT(mode != AvaQueryElokaMode::Stop);
|
||||
queryEloka(mode, LtsUtils::createConnection(this, &AvaControl::queryElokaResponse, target, slot));
|
||||
}
|
||||
|
||||
template<class Target, class Slot>
|
||||
void AvaControl::setVideoProfile(const QString &dialogId, const QString &menuDef, Target *target, Slot Target:: *slot)
|
||||
{
|
||||
setVideoProfile(dialogId, menuDef, LtsUtils::createConnection(this, &AvaControl::setVideoProfileResponse, target, slot));
|
||||
}
|
||||
|
||||
template<class Target, class Slot>
|
||||
void AvaControl::setRtProfile(RtState *rtState, const QVector<RtState::RadioCircuit> &radioCircuits, Target *target, Slot Target:: *slot)
|
||||
{
|
||||
setRtProfile(rtState, radioCircuits, LtsUtils::createConnection(this, &AvaControl::setRtProfileResponse, target, slot));
|
||||
}
|
||||
|
||||
template<class Target, class Slot>
|
||||
void AvaControl::changeRtProfileCircuitName(RtState *rtState, const RtState::RadioCircuit &radioCircuit, Target *target, Slot Target:: *slot)
|
||||
{
|
||||
changeRtProfileCircuitName(rtState, radioCircuit, LtsUtils::createConnection(this, &AvaControl::setRtProfileResponse, target, slot));
|
||||
}
|
||||
|
||||
template<class Target, class Slot>
|
||||
void AvaControl::setAnnouncementProfile(RtState *rtState, const QString &menuDef, const QString &identityList, const QString &stateList, Target *target, Slot Target:: *slot)
|
||||
{
|
||||
setAnnouncementProfile(rtState, menuDef, identityList, stateList, LtsUtils::createConnection(this, &AvaControl::setAnnouncementProfileResponse, target, slot));
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
Reference in new issue
Block a user