470 lines
17 KiB
C++
Executable File
470 lines
17 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* AvaControl
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Christian Fröbel, SLSE, 2017-06-26
|
|
*/
|
|
|
|
#include "ava_control.h"
|
|
#include "iava_comm.h"
|
|
#include "ava_types.h"
|
|
#include "AvsCommands/simple_command.h"
|
|
#include "AvsCommands/choose_stream.h"
|
|
#include "AvsCommands/choose_stream_overview.h"
|
|
#include "AvsCommands/get_stream_list.h"
|
|
#include "AvsCommands/query_timeline.h"
|
|
#include "AvsCommands/get_eloka_list.h"
|
|
#include "AvsCommands/query_eloka.h"
|
|
#include "AvsCommands/set_script.h"
|
|
#include "AvsCommands/start_script.h"
|
|
#include "AvsCommands/set_rt_profile.h"
|
|
#include "AvsCommands/change_rt_profile_circuit_name.h"
|
|
#include "AvsCommands/set_rt_profile_base.h"
|
|
#include "AvsCommands/set_announcement_profile.h"
|
|
#include "AvsCommands/set_video_profile.h"
|
|
#include "AvsCommands/set_abs_position.h"
|
|
#include "AvsCommands/set_volume.h"
|
|
#include "AvsCommands/keep_alive.h"
|
|
#include <LtsUtilsCore/scoped_connection.h>
|
|
#include <QTimer>
|
|
#include <QRect>
|
|
#include <QtGlobal>
|
|
#include <chrono>
|
|
|
|
#include <QDebug>
|
|
|
|
namespace AudioVideoManagement
|
|
{
|
|
|
|
AvaControl::AvaControl(IAvaComm *comm, StreamNameMapping *streamNameMapping, std::chrono::milliseconds commandTimeout)
|
|
: m_comm(comm)
|
|
, m_streamNameMapping(streamNameMapping)
|
|
, m_queue(commandTimeout)
|
|
, m_logger(getLogger("AvaControl"))
|
|
{
|
|
Q_ASSERT(comm);
|
|
Q_ASSERT(streamNameMapping);
|
|
|
|
connect(comm, &IAvaComm::connected, this, &AvaControl::onConnected);
|
|
connect(comm, &IAvaComm::disconnected, this, &AvaControl::onDisconnected);
|
|
connect(&m_queue, &AvsCommandQueue::queueEmpty, this, &AvaControl::commandQueueEmpty); // signal -> signal
|
|
connect(&m_queue, &AvsCommandQueue::timeout, this, &AvaControl::onTimeout);
|
|
}
|
|
|
|
void AvaControl::switchContext(int exerciseId)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("SwitchContext"), m_comm, this, [ = ](IAvaComm * comm) { comm->switchContext(exerciseId); }));
|
|
}
|
|
|
|
void AvaControl::setUserProfile(const QString &userName, const QString &langCode, AvaAudioPrio audioPrio, AvaGuiStyle style)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("SetUserProfile"), m_comm, this, [ = ](IAvaComm * comm) { comm->setUserProfile(userName, langCode, audioPrio, style); }));
|
|
}
|
|
|
|
void AvaControl::setTimezone(QChar tz)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("SetTimezone"), m_comm, this, [ = ](IAvaComm * comm) { comm->setTimezone(tz); }));
|
|
}
|
|
|
|
void AvaControl::setVideoDialogProfile(const QString &dialogId, AvaVisibility visibility)
|
|
{
|
|
const int OK_COUNT = 2;
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("SetVideoDialogProfile"), m_comm, this, [ = ](IAvaComm * comm) { comm->setVideoDialogProfile(dialogId, visibility); }, OK_COUNT));
|
|
}
|
|
|
|
void AvaControl::setVideoDialogGeometry(const QString &dialogId, const QRect &geometry)
|
|
{
|
|
const int OK_COUNT = 2;
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("SetVideoDialogGeometry"), m_comm, this, [ = ](IAvaComm * comm) { comm->setVideoDialogGeometry(dialogId, geometry); }, OK_COUNT));
|
|
}
|
|
|
|
void AvaControl::setVideoProfile(const QString &dialogId, const QString &menuDef)
|
|
{
|
|
setVideoProfile(dialogId, menuDef, new LtsUtils::DummyConnection);
|
|
}
|
|
|
|
void AvaControl::setVideoProfile(const QString &dialogId, const QString &menuDef, LtsUtils::IConnection *connection)
|
|
{
|
|
queue(new AvaCommands::SetVideoProfile(m_comm, this, dialogId, menuDef), connection);
|
|
}
|
|
|
|
void AvaControl::setRtProfile(RtState *rtState, const QVector<RtState::RadioCircuit> &radioCircuits)
|
|
{
|
|
setRtProfile(rtState, radioCircuits, new LtsUtils::DummyConnection);
|
|
}
|
|
|
|
void AvaControl::setRtProfile(RtState *rtState, const QVector<RtState::RadioCircuit> &radioCircuits, LtsUtils::IConnection *connection)
|
|
{
|
|
queue(new AvaCommands::SetRtProfile(m_comm, this, rtState, radioCircuits), connection);
|
|
}
|
|
|
|
void AvaControl::changeRtProfileCircuitName(RtState *rtState, const RtState::RadioCircuit &radioCircuit)
|
|
{
|
|
changeRtProfileCircuitName(rtState, radioCircuit, new LtsUtils::DummyConnection);
|
|
}
|
|
|
|
void AvaControl::changeRtProfileCircuitName(RtState *rtState, const RtState::RadioCircuit &radioCircuit, LtsUtils::IConnection *connection)
|
|
{
|
|
queue(new AvaCommands::ChangeRtProfileCircuitName(m_comm, this, rtState, radioCircuit), connection);
|
|
}
|
|
|
|
void AvaControl::setAnnouncementProfile(RtState *rtState, const QString &menuDef, const QString &identityList, const QString &stateList)
|
|
{
|
|
setAnnouncementProfile(rtState, menuDef, identityList, stateList, new LtsUtils::DummyConnection);
|
|
}
|
|
|
|
void AvaControl::setAnnouncementProfile(RtState *rtState, const QString &menuDef, const QString &identityList, const QString &stateList, LtsUtils::IConnection *connection)
|
|
{
|
|
queue(new AvaCommands::SetAnnouncementProfile(m_comm, this, rtState, menuDef, identityList, stateList), connection);
|
|
}
|
|
|
|
void AvaControl::getStreamList(AvaStreamType streamType, AvaStreamSource streamSource)
|
|
{
|
|
getStreamList(streamType, streamSource, new LtsUtils::DummyConnection);
|
|
}
|
|
|
|
void AvaControl::getStreamList(AvaStreamType streamType, AvaStreamSource streamSource, LtsUtils::IConnection *connection)
|
|
{
|
|
queue(new AvaCommands::GetStreamList(m_comm, this, streamType, streamSource, m_streamNameMapping), connection);
|
|
}
|
|
|
|
void AvaControl::chooseStream(const QString &dialogId, const QString &streamName)
|
|
{
|
|
queue(new AvaCommands::ChooseStream(m_comm, this, dialogId, streamName));
|
|
}
|
|
|
|
void AvaControl::chooseStreamOverview(const QString &dialogId, const QStringList &streamNames)
|
|
{
|
|
const bool notMuted = false;
|
|
queue(new AvaCommands::ChooseStreamOverview(m_comm, this, dialogId, streamNames, notMuted));
|
|
}
|
|
|
|
void AvaControl::releaseStream(const QString &dialogId, const QString &streamName)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("ReleaseStream"), m_comm, this, [ = ](IAvaComm * comm) { comm->releaseStream(dialogId, streamName); }));
|
|
}
|
|
|
|
void AvaControl::queryTimeline(const QString &streamName, const boost::optional<AvaTimePoint> &start, const boost::optional<AvaTimePoint> &end)
|
|
{
|
|
queryTimeline(streamName, new LtsUtils::DummyConnection, start, end);
|
|
}
|
|
|
|
void AvaControl::queryTimeline(const QString &streamName, LtsUtils::IConnection *connection, const boost::optional<AvaTimePoint> &start, const boost::optional<AvaTimePoint> &end)
|
|
{
|
|
queue(new AvaCommands::QueryTimeline(m_comm, this, streamName, start, end), connection);
|
|
}
|
|
|
|
void AvaControl::getElokaList(const QString &streamName, LtsUtils::IConnection *connection)
|
|
{
|
|
queue(new AvaCommands::GetElokaList(m_comm, this, streamName), connection);
|
|
}
|
|
|
|
void AvaControl::setVolume(int db)
|
|
{
|
|
queue(new AvaCommands::SetVolume(m_comm, this, db));
|
|
}
|
|
|
|
void AvaControl::startStream(const QString &dialogId, const QString &streamName, AvaSpeed speed)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("StartStream"), m_comm, this, [ = ](IAvaComm * comm) { comm->startStream(dialogId, streamName, speed); }));
|
|
}
|
|
|
|
void AvaControl::stopStream(const QString &dialogId, const QString &streamName)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("StopStream"), m_comm, this, [ = ](IAvaComm * comm) { comm->stopStream(dialogId, streamName); }));
|
|
}
|
|
|
|
void AvaControl::pauseStream(const QString &dialogId, const QString &streamName)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("PauseStream"), m_comm, this, [ = ](IAvaComm * comm) { comm->pauseStream(dialogId, streamName); }));
|
|
}
|
|
|
|
void AvaControl::setStreamSpeed(const QString &dialogId, const QString &streamName, AvaSpeed speed)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("SetStreamSpeed"), m_comm, this, [ = ](IAvaComm * comm) { comm->setStreamSpeed(dialogId, streamName, speed); }));
|
|
}
|
|
|
|
void AvaControl::setAbsPosition(const QString &dialogId, const QString &streamName, AvaTimePoint pos)
|
|
{
|
|
queue(new AvaCommands::SetAbsPosition(m_comm, this, dialogId, streamName, pos));
|
|
}
|
|
|
|
void AvaControl::positionUpdate(const QString &dialogId, const QString &streamName, std::chrono::milliseconds updateInterval)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("PositionUpdate"), m_comm, this, [ = ](IAvaComm * comm) { comm->positionUpdate(dialogId, streamName, updateInterval); }));
|
|
}
|
|
|
|
void AvaControl::setPint(const QString &dialogId, const QString &streamName, bool doSkip)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("SetPint"), m_comm, this, [ = ](IAvaComm * comm) { comm->setPint(dialogId, streamName, doSkip); }));
|
|
}
|
|
|
|
void AvaControl::getElokaList(const QString &streamName)
|
|
{
|
|
getElokaList(streamName, new LtsUtils::DummyConnection);
|
|
}
|
|
|
|
void AvaControl::chooseEloka(const QString &streamName, const QString &signalName, AvaElokaMode mode)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("ChooseEloka"), m_comm, this, [ = ](IAvaComm * comm) { comm->chooseEloka(streamName, signalName, mode); }));
|
|
}
|
|
|
|
void AvaControl::releaseEloka(const QString &streamName)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("ReleaseEloka"), m_comm, this, [ = ](IAvaComm * comm) { comm->releaseEloka(streamName); }));
|
|
}
|
|
|
|
void AvaControl::queryEloka(AvaQueryElokaMode mode)
|
|
{
|
|
// queryEloka 0 (aka Stop) is a SimpleCommad; there is no QueryElokaList-response then
|
|
if (mode == AvaQueryElokaMode::Stop)
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("QueryEloka"), m_comm, this, [ = ](IAvaComm * comm) { comm->queryEloka(mode); }));
|
|
else
|
|
queryEloka(mode, new LtsUtils::DummyConnection);
|
|
}
|
|
|
|
void AvaControl::queryEloka(AvaQueryElokaMode mode, LtsUtils::IConnection *connection)
|
|
{
|
|
queue(new AvaCommands::QueryEloka(m_comm, this, mode), connection);
|
|
}
|
|
|
|
void AvaControl::chooseImport(const QString &dialogId, const QString &path, int mode)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("ChooseImport"), m_comm, this, [ = ](IAvaComm * comm) { comm->chooseImport(dialogId, path, mode); }));
|
|
}
|
|
|
|
void AvaControl::releaseImport(const QString &dialogId)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("ReleaseImport"), m_comm, this, [ = ](IAvaComm * comm) { comm->releaseImport(dialogId); }));
|
|
}
|
|
|
|
void AvaControl::setScript(const QString &dialogId, const QString &scriptName, AvaScriptSource source,
|
|
const QVector<AvaScriptEntry> &streams, LtsUtils::IConnection *connection)
|
|
{
|
|
queue(new AvaCommands::SetScript(m_comm, this, dialogId, scriptName, source, streams), connection);
|
|
}
|
|
|
|
void AvaControl::releaseScript(const QString &dialogId, const QString &scriptName)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("ReleaseScript"), m_comm, this, [ = ](IAvaComm * comm) { comm->releaseScript(dialogId, scriptName); }));
|
|
}
|
|
|
|
void AvaControl::startScript(const QString &dialogId, const QString &scriptName, LtsUtils::IConnection *connection)
|
|
{
|
|
queue(new AvaCommands::StartScript(m_comm, this, dialogId, scriptName, connection != nullptr), connection);
|
|
}
|
|
|
|
void AvaControl::stopScript(const QString &dialogId, const QString &scriptName)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("StopScript"), m_comm, this, [ = ](IAvaComm * comm) { comm->stopScript(dialogId, scriptName); }));
|
|
}
|
|
|
|
void AvaControl::pauseScript(const QString &dialogId, const QString &scriptName)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("PauseScript"), m_comm, this, [ = ](IAvaComm * comm) { comm->pauseScript(dialogId, scriptName); }));
|
|
}
|
|
|
|
void AvaControl::setAbsPositionScript(const QString &dialogId, const QString &scriptName, AvaTimePoint pos)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("SetAbsPositionScript"), m_comm, this, [dialogId, scriptName, pos](IAvaComm * comm) { comm->setAbsPositionScript(dialogId, scriptName, pos); }));
|
|
}
|
|
|
|
void AvaControl::defineStreamNameMapping(const QString &internalName, const QString &displayName)
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("DefineStreamNameMapping"), m_comm, this, [ = ](IAvaComm * comm) { comm->defineStreamNameMapping(internalName, displayName); }));
|
|
}
|
|
|
|
void AvaControl::resetStreamNameMapping()
|
|
{
|
|
queue(new AvaCommands::SimpleCommand(QLatin1String("ResetStreamNameMapping"), m_comm, this, [ = ](IAvaComm * comm) { comm->resetStreamNameMapping(); }));
|
|
}
|
|
|
|
void AvaControl::keepAlive()
|
|
{
|
|
queue(new AvaCommands::KeepAlive(m_comm, this));
|
|
}
|
|
|
|
void AvaControl::onConnected()
|
|
{
|
|
m_connected = true;
|
|
DEBUG_LOG(m_logger) << "connected";
|
|
}
|
|
|
|
void AvaControl::onDisconnected()
|
|
{
|
|
m_connected = false;
|
|
DEBUG_LOG(m_logger) << "disconnected";
|
|
m_queue.flush();
|
|
}
|
|
|
|
void AvaControl::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 AvaControl::queue(ICommand *cmd, LtsUtils::IConnection *connection)
|
|
{
|
|
std::unique_ptr<ICommand> cmd_(cmd);
|
|
std::unique_ptr<LtsUtils::IConnection> 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 AvaControl::done(ICommand *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::ChooseStream *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
emit chooseStreamResponse(cmd->streamInfo(), cmd->streamState());
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::GetStreamList *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit getStreamListResponse(cmd->streams());
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::QueryTimeline *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit queryTimelineResponse(cmd->timeline());
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::GetElokaList *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit getElokaListResponse(cmd->elokaSignals());
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::QueryEloka *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit queryElokaResponse(cmd->eloka());
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::SetScript *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
if (m_queue.currentHasConnection())
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit setScriptResponse(cmd->scriptInfo(), cmd->scriptState());
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::StartScript *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
if (m_queue.currentHasConnection())
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit startScriptResponse(cmd->scriptState());
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::SetVideoProfile *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit setVideoProfileResponse(cmd->invalidNameList());
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::SetRtProfileBase *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit setRtProfileResponse(cmd->invalidNameList());
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::done(AvaCommands::SetAnnouncementProfile *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit setAnnouncementProfileResponse(cmd->invalidNameList());
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
m_queue.done();
|
|
}
|
|
|
|
void AvaControl::failed(AvaCommands::SetScript *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
if (m_queue.currentHasConnection())
|
|
{
|
|
LtsUtils::ScopedConnection scopedConn(m_queue.currentConnection());
|
|
emit setScriptResponse(AvaStreamInfo(), AvaStreamState::NotPossible);
|
|
} // extra small scope as done() deletes the instance scopedConn is operating on
|
|
}
|
|
|
|
void AvaControl::failed(ICommand *cmd)
|
|
{
|
|
ERROR_LOG(m_logger) << "command '" << cmd->debug() << "' failed";
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
auto cmdSetScript = dynamic_cast<AvaCommands::SetScript*>(cmd);
|
|
if (cmdSetScript)
|
|
failed(cmdSetScript);
|
|
m_queue.flush();
|
|
m_comm->forceDisconnect();
|
|
}
|
|
|
|
void AvaControl::alive(ICommand *cmd)
|
|
{
|
|
Q_ASSERT(cmd == m_queue.currentCommand());
|
|
m_queue.alive();
|
|
}
|
|
|
|
|
|
} // namespace AudioVideoManagement
|