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

216 lines
6.4 KiB
C++
Executable File

/**
* @RDE_HEADER@
* ListResponseCollector
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Fröbel, NLE, 2018-12-18
*/
#pragma once
#include "iava_comm.h"
#include "ava_types.h"
#include "avm_export.h"
#include <QVector>
#include <QList>
#include <QObject>
#include <functional>
class QString;
class QByteArray;
namespace AudioVideoManagement
{
class StreamNameMapping;
/**
* Internal helper class for ListResponseCollector.
*
* @author Christian Fröbel
*/
template<class ResultContainer, class ElementFactory>
class ListResponseCollectorHelper
{
public:
using DoneCallback = std::function<void(ResultContainer &&)>;
using AliveCallback = std::function<void()>;
ListResponseCollectorHelper(IAvaComm *comm, const DoneCallback &doneCallback, const ElementFactory &elementFactory = {});
/**
* @param aliveCallback may be empty, i.e. no callback given.
*/
ListResponseCollectorHelper(IAvaComm *comm, const DoneCallback &doneCallback, const AliveCallback &aliveCallback, const ElementFactory &elementFactory = {});
/**
* Connect to the signals and start collecting; stop after the list was collected.
* May be called again when the doneCallback was called.
*/
void start();
void reset();
private:
void onListValueReceived(const QVector<QByteArray> &parts);
void onEndOfListReceived();
QObject m_hint; //!< used to control the lifetime of the signal-to-lambda connections
IAvaComm *m_comm;
DoneCallback m_doneCallback;
AliveCallback m_aliveCallback;
ElementFactory m_elementFactory;
bool m_started{false};
ResultContainer m_elements;
unsigned m_elementCount{0};
};
/**
* Template class for collecting the list responses on the RCP_AVA interface to AVS_Workstation.
*
* It works ontop of IAvaComm. It connects to the following three signals:
* - a list-specific signal that marks the begin of the list, e.g. IAvaComm::invalidNameListBeginReceived()
* - IAvaComm::listValueReceived(const QVector<QString> &parts)
* - IAvaComm::endOfListReceived()
* The first list-specific signal must be specified as 2nd template parameter.
* The 3rd template parameter is a factory functor that creates an element of type T
* from the parts as signalled by IAvaComm::listValueReceived().
* As a result a QVector<T> is built where T is the 1st template parameter.
* When the list response is finished the DoneCallback given to the constructor will be called.
*
* The user does not need to specify the template parameters himself.
* There are predefined type aliases for the different types of list responses.
*
* For the list response of QueryTimeline there exists a separate collector-class: TimelineListCollector
*
* @see StreamListCollector
* @see InvalidNameListCollector
* @see ElokaListCollector
* @see QueryElokaListCollector
* @see TimelineListCollector
*
* @author Christian Fröbel
*/
template<class T, void (IAvaComm::*listBeginSignal)(), class ElementFactory>
class ListResponseCollector
{
private:
using Helper = ListResponseCollectorHelper<QVector<T>, ElementFactory>;
public:
using DoneCallback = typename Helper::DoneCallback;
ListResponseCollector(IAvaComm *comm, const DoneCallback &doneCallback, const ElementFactory &elementFactory = ElementFactory{});
/**
* Connect to the signals and start collecting; stop after the list was collected.
* May be called again when the doneCallback was called.
*/
void start();
/**
* Reset the collector.
* Can be useful in case the connection to AVS breaks in the middle of receiving a list.
*/
void reset();
private:
void onBeginOfListReceived();
void onDone(QVector<T> &&result);
QObject m_hint;
IAvaComm *m_comm;
DoneCallback m_doneCallback;
bool m_started{false};
Helper m_helper;
};
struct AVM_COMMON_EXPORT TimelineListElementFactory
{
AvaTimelinePart operator()(const QVector<QByteArray> &parts) const;
};
/**
* A special collector-implementation for the list-reponse of QueryTimeline.
* The reason for this is that the list-begin-signal takes a parameter (IAvaComm::timelineListBegin(const QString&))
* and thus we cannot use the generalized ListCollector.
*
* The result as passed to the DoneCallback is an AvaTimeline.
*
* @author Christian Fröbel
*/
class AVM_COMMON_EXPORT TimelineListCollector
{
private:
using Helper = ListResponseCollectorHelper<AvaTimeline, TimelineListElementFactory>;
public:
using DoneCallback = typename Helper::DoneCallback;
using AliveCallback = typename Helper::AliveCallback;
/**
* @param aliveCallback may be empty, i.e. no callback given.
*/
TimelineListCollector(IAvaComm *comm, const QString &streamName, const DoneCallback &doneCallback, const AliveCallback &aliveCallback);
/**
* Connect to the signals and start collecting; stop after the list was collected.
* May be called again when the doneCallback was called.
*/
void start();
private:
void onBeginOfListReceived(const QString &streamName);
void onDone(AvaTimeline &&timeline);
QObject m_hint;
IAvaComm *m_comm;
const QString m_streamName;
DoneCallback m_doneCallback;
bool m_started{false};
Helper m_helper;
};
class StreamListElementFactory
{
public:
StreamListElementFactory(AvaStreamType streamType, AvaStreamSource streamSource, StreamNameMapping *streamNameMapping);
AvaStream operator()(const QVector<QByteArray> &parts) const;
private:
const AvaStreamType m_streamType;
const AvaStreamSource m_streamSource;
StreamNameMapping *m_streamNameMapping;
};
struct InvalidNameListElementFactory
{
QString operator()(const QVector<QByteArray> &parts) const;
};
using ElokaListElementFactory = InvalidNameListElementFactory;
struct QueryElokaListElementFactory
{
AvaEloka operator()(const QVector<QByteArray> &parts) const;
};
/** @name Concrete collector types. */
///@{
using StreamListCollector = ListResponseCollector<AvaStream, &IAvaComm::streamListBeginReceived, StreamListElementFactory>;
using InvalidNameListCollector = ListResponseCollector<QString, &IAvaComm::invalidNameListBeginReceived, InvalidNameListElementFactory>;
using ElokaListCollector = ListResponseCollector<QString, &IAvaComm::elokaListBeginReceived, ElokaListElementFactory>;
using QueryElokaListCollector = ListResponseCollector<AvaEloka, &IAvaComm::queryElokaListBeginReceived, QueryElokaListElementFactory>;
///@}
} // namespace AudioVideoManagement