/** * @RDE_HEADER@ * ListResponseCollector * $Id$ * $HeadURL$ * $Author$ * Created by Christian Fröbel, NLE, 2018-12-18 */ #include "list_response_collector.h" #include "av_helper.h" #include #include #include namespace AudioVideoManagement { template ListResponseCollectorHelper::ListResponseCollectorHelper(IAvaComm *comm, const DoneCallback &doneCallback, const ElementFactory &elementFactory) : ListResponseCollectorHelper(comm, doneCallback, AliveCallback{}, elementFactory) { } template ListResponseCollectorHelper::ListResponseCollectorHelper(IAvaComm *comm, const DoneCallback &doneCallback, const AliveCallback &aliveCallback, const ElementFactory &elementFactory) : m_comm(comm) , m_doneCallback(doneCallback) , m_aliveCallback(aliveCallback) , m_elementFactory(elementFactory) { Q_ASSERT(comm); Q_ASSERT(doneCallback); } template void ListResponseCollectorHelper::start() { using namespace std::placeholders; Q_ASSERT(!m_started); QObject::connect(m_comm, &IAvaComm::listValueReceived, &m_hint, std::bind(&ListResponseCollectorHelper::onListValueReceived, this, _1)); QObject::connect(m_comm, &IAvaComm::endOfListReceived, &m_hint, std::bind(&ListResponseCollectorHelper::onEndOfListReceived, this)); m_started = true; } template void ListResponseCollectorHelper::reset() { m_comm->disconnect(&m_hint); m_elements.clear(); m_elementCount = 0; m_started = false; } template void ListResponseCollectorHelper::onListValueReceived(const QVector &parts) { m_elements.append(m_elementFactory(parts)); ++m_elementCount; // In case the list reponse is very long, e.g. for queryTimeline, // we tell the issuer that we are still alive. if (m_elementCount % 1000 == 0 && m_aliveCallback) m_aliveCallback(); } template void ListResponseCollectorHelper::onEndOfListReceived() { using std::swap; m_comm->disconnect(&m_hint); ResultContainer result; swap(result, m_elements); m_started = false; m_doneCallback(std::move(result)); } //====================================================================================================================== template ListResponseCollector::ListResponseCollector(IAvaComm *comm, const DoneCallback &doneCallback, const ElementFactory &elementFactory) : m_comm(comm) , m_doneCallback(doneCallback) , m_helper(comm, [this] (QVector &&result) { onDone(std::move(result)); }, elementFactory) { Q_ASSERT(comm); Q_ASSERT(doneCallback); } template void ListResponseCollector::start() { Q_ASSERT(!m_started); QObject::connect(m_comm, listBeginSignal, &m_hint, std::bind(&ListResponseCollector::onBeginOfListReceived, this)); m_started = true; } template void ListResponseCollector::reset() { m_helper.reset(); m_comm->disconnect(&m_hint); m_started = false; } template void ListResponseCollector::onBeginOfListReceived() { m_helper.start(); } template void ListResponseCollector::onDone(QVector &&result) { m_comm->disconnect(&m_hint); m_started = false; m_doneCallback(std::move(result)); } //====================================================================================================================== TimelineListCollector::TimelineListCollector(IAvaComm *comm, const QString &streamName, const TimelineListCollector::DoneCallback &doneCallback, const AliveCallback &aliveCallback) : m_comm(comm) , m_streamName(streamName) , m_doneCallback(doneCallback) , m_helper(comm, [this] (AvaTimeline &&timeline) { onDone(std::move(timeline)); }, aliveCallback) { Q_ASSERT(comm); Q_ASSERT(doneCallback); } void TimelineListCollector::start() { using namespace std::placeholders; Q_ASSERT(!m_started); QObject::connect(m_comm, &IAvaComm::timelineListBeginReceived, &m_hint, std::bind(&TimelineListCollector::onBeginOfListReceived, this, _1)); m_started = true; } void TimelineListCollector::onBeginOfListReceived(const QString &streamName) { Q_ASSERT(streamName == m_streamName); m_helper.start(); } void TimelineListCollector::onDone(AvaTimeline &&timeline) { m_started = false; m_comm->disconnect(&m_hint); m_doneCallback(std::move(timeline)); } //====================================================================================================================== StreamListElementFactory::StreamListElementFactory(AvaStreamType streamType, AvaStreamSource streamSource, StreamNameMapping *streamNameMapping) : m_streamType(streamType) , m_streamSource(streamSource) , m_streamNameMapping(streamNameMapping) { Q_ASSERT(streamNameMapping); } AvaStream StreamListElementFactory::operator()(const QVector &parts) const { Q_ASSERT(parts.size() == 3); bool couldConvert = false; AvaStreamType streamType = static_cast(parts.at(0).toInt(&couldConvert)); Q_ASSERT(couldConvert); Q_ASSERT(streamType == m_streamType); AvaStreamSource streamSource = static_cast(parts.at(1).toInt(&couldConvert)); Q_ASSERT(couldConvert); Q_ASSERT(streamSource == m_streamSource); QString internalName = QString::fromUtf8(parts.at(2)); return AvaStream::create(streamType, streamSource, internalName, m_streamNameMapping); } QString InvalidNameListElementFactory::operator()(const QVector &parts) const { Q_ASSERT(parts.size() == 1); return QString::fromUtf8(parts.at(0)); } AvaEloka QueryElokaListElementFactory::operator()(const QVector &parts) const { Q_ASSERT(parts.size() == 4); AvaEloka eloka; eloka.signal = QString::fromUtf8(parts.at(0)); eloka.stream = QString::fromUtf8(parts.at(1)); eloka.priority = parts.at(2).toInt(); eloka.time = createTimePoint(parts.at(3)); return eloka; } AvaTimelinePart TimelineListElementFactory::operator()(const QVector &parts) const { Q_ASSERT(parts.size() == 1); QList intervalParts = parts.front().split('-'); Q_ASSERT(intervalParts.size() == 2); AvaTimePoint start = createTimePoint(intervalParts.at(0)); AvaTimePoint end = createTimePoint(intervalParts.at(1)); return {start, end}; } /** * Explicit template instantiations. */ ///@{ template class AVM_COMMON_EXPORT ListResponseCollector; template class AVM_COMMON_EXPORT ListResponseCollector; template class AVM_COMMON_EXPORT ListResponseCollector; template class AVM_COMMON_EXPORT ListResponseCollector; ///@} } // namespace AudioVideoManagement