Final cleanup of legacy message pipes. Implements #1154

This commit is contained in:
f4exb 2022-03-29 23:03:54 +02:00
parent 35f1c2aacc
commit 9f54d32945
20 changed files with 16 additions and 686 deletions

View File

@ -25,7 +25,6 @@
#include "dsp/scopevis.h"
#include "util/db.h"
#include "util/stepfunctions.h"
#include "pipes/pipeendpoint.h"
#include "maincore.h"
#include "aisdemod.h"

View File

@ -24,7 +24,6 @@
#include "dsp/dspengine.h"
#include "util/db.h"
#include "util/stepfunctions.h"
#include "pipes/pipeendpoint.h"
#include "maincore.h"
#include "aptdemod.h"

View File

@ -23,7 +23,6 @@
#include "dsp/dspengine.h"
#include "dsp/datafifo.h"
#include "util/db.h"
#include "pipes/pipeendpoint.h"
#include "maincore.h"
#include "dabdemod.h"

View File

@ -24,7 +24,6 @@
#include "dsp/datafifo.h"
#include "util/db.h"
#include "util/stepfunctions.h"
#include "pipes/pipeendpoint.h"
#include "maincore.h"
#include "packetdemod.h"

View File

@ -39,6 +39,7 @@ class QNetworkAccessManager;
class QNetworkReply;
class QThread;
class DeviceAPI;
class Feature;
class RadioAstronomyWorker;
class RadioAstronomy : public BasebandSampleSink, public ChannelAPI {

View File

@ -24,7 +24,6 @@
#include "feature/featuregui.h"
#include "util/messagequeue.h"
#include "pipes/pipeendpoint.h"
#include "settings/rollupstate.h"
#include "antennatoolssettings.h"

View File

@ -30,7 +30,6 @@
#include "feature/featuregui.h"
#include "util/messagequeue.h"
#include "util/azel.h"
#include "pipes/pipeendpoint.h"
#include "settings/rollupstate.h"
#include "SWGMapItem.h"

View File

@ -23,7 +23,6 @@
#include "feature/featuregui.h"
#include "util/messagequeue.h"
#include "pipes/pipeendpoint.h"
#include "settings/rollupstate.h"
#include "pertestersettings.h"

View File

@ -170,13 +170,9 @@ set(sdrbase_SOURCES
pipes/datafifostore.cpp
pipes/datapipes.cpp
pipes/datapipesgcworker.cpp
pipes/messagepipeslegacy.cpp
pipes/messagepipes.cpp
pipes/messagepipeslegacycommon.cpp
pipes/messagepipeslegacygcworker.cpp
pipes/messagepipesgcworker.cpp
pipes/messagequeuestore.cpp
pipes/pipeendpoint.cpp
pipes/objectpipe.cpp
pipes/objectpipesregistrations.cpp
@ -383,13 +379,9 @@ set(sdrbase_HEADERS
pipes/datapipesgcworker.h
pipes/elementpipescommon.h
pipes/elementpipesgc.h
pipes/messagepipeslegacy.h
pipes/messagepipes.h
pipes/messagepipeslegacycommon.h
pipes/messagepipeslegacygcworker.h
pipes/messagepipesgcworker.h
pipes/messagequeuestore.h
pipes/pipeendpoint.h
pipes/objectpipe.h
pipes/objectpipesregistrations.h

View File

@ -28,7 +28,6 @@
#include <stdint.h>
#include "export.h"
#include "pipes/pipeendpoint.h"
#include "util/messagequeue.h"
class DeviceAPI;
@ -40,7 +39,7 @@ namespace SWGSDRangel
class SWGChannelActions;
}
class SDRBASE_API ChannelAPI : public QObject, public PipeEndPoint {
class SDRBASE_API ChannelAPI : public QObject {
Q_OBJECT
public:
enum StreamType //!< This is the same enum as in PluginInterface

View File

@ -25,7 +25,6 @@
#include <QByteArray>
#include "export.h"
#include "pipes/pipeendpoint.h"
#include "util/messagequeue.h"
class WebAPIAdapterInterface;
@ -41,7 +40,7 @@ namespace SWGSDRangel
class SWGChannelSettings;
}
class SDRBASE_API Feature : public QObject, public PipeEndPoint {
class SDRBASE_API Feature : public QObject {
Q_OBJECT
public:
enum FeatureState {
@ -164,7 +163,6 @@ protected:
protected slots:
void handleInputMessages();
void handlePipeMessageQueue(MessageQueue* messageQueue);
friend PipeEndPoint;
private:
QString m_name; //!< Unique identifier in a device set used for sorting may change depending on relative position in device set

View File

@ -29,7 +29,6 @@
#include "export.h"
#include "settings/mainsettings.h"
#include "util/message.h"
#include "pipes/messagepipeslegacy.h"
#include "pipes/messagepipes.h"
#include "pipes/datapipes.h"
#include "channel/channelapi.h"
@ -577,26 +576,26 @@ public:
MESSAGE_CLASS_DECLARATION
public:
const PipeEndPoint *getPipeSource() const { return m_pipeSource; }
const QObject *getPipeSource() const { return m_pipeSource; }
QByteArray getPacket() const { return m_packet; }
QDateTime getDateTime() const { return m_dateTime; }
static MsgPacket* create(const PipeEndPoint *pipeSource, QByteArray packet)
static MsgPacket* create(const QObject *pipeSource, QByteArray packet)
{
return new MsgPacket(pipeSource, packet, QDateTime::currentDateTime());
}
static MsgPacket* create(const PipeEndPoint *pipeSource, QByteArray packet, QDateTime dateTime)
static MsgPacket* create(const QObject *pipeSource, QByteArray packet, QDateTime dateTime)
{
return new MsgPacket(pipeSource, packet, dateTime);
}
private:
const PipeEndPoint *m_pipeSource;
const QObject *m_pipeSource;
QByteArray m_packet;
QDateTime m_dateTime;
MsgPacket(const PipeEndPoint *pipeSource, QByteArray packet, QDateTime dateTime) :
MsgPacket(const QObject *pipeSource, QByteArray packet, QDateTime dateTime) :
Message(),
m_pipeSource(pipeSource),
m_packet(packet),
@ -658,19 +657,19 @@ public:
MESSAGE_CLASS_DECLARATION
public:
const PipeEndPoint *getPipeSource() const { return m_pipeSource; }
const QObject *getPipeSource() const { return m_pipeSource; }
SWGSDRangel::SWGStarTrackerDisplaySettings *getSWGStarTrackerDisplaySettings() const { return m_swgStarTrackerDisplaySettings; }
static MsgStarTrackerDisplaySettings* create(const PipeEndPoint *pipeSource, SWGSDRangel::SWGStarTrackerDisplaySettings *swgStarTrackerDisplaySettings)
static MsgStarTrackerDisplaySettings* create(const QObject *pipeSource, SWGSDRangel::SWGStarTrackerDisplaySettings *swgStarTrackerDisplaySettings)
{
return new MsgStarTrackerDisplaySettings(pipeSource, swgStarTrackerDisplaySettings);
}
private:
const PipeEndPoint *m_pipeSource;
const QObject *m_pipeSource;
SWGSDRangel::SWGStarTrackerDisplaySettings *m_swgStarTrackerDisplaySettings;
MsgStarTrackerDisplaySettings(const PipeEndPoint *pipeSource, SWGSDRangel::SWGStarTrackerDisplaySettings *swgStarTrackerDisplaySettings) :
MsgStarTrackerDisplaySettings(const QObject *pipeSource, SWGSDRangel::SWGStarTrackerDisplaySettings *swgStarTrackerDisplaySettings) :
Message(),
m_pipeSource(pipeSource),
m_swgStarTrackerDisplaySettings(swgStarTrackerDisplaySettings)
@ -681,19 +680,19 @@ public:
MESSAGE_CLASS_DECLARATION
public:
const PipeEndPoint *getPipeSource() const { return m_pipeSource; }
const QObject *getPipeSource() const { return m_pipeSource; }
SWGSDRangel::SWGStarTrackerDisplayLoSSettings *getSWGStarTrackerDisplayLoSSettings() const { return m_swgStarTrackerDisplayLoSSettings; }
static MsgStarTrackerDisplayLoSSettings* create(const PipeEndPoint *pipeSource, SWGSDRangel::SWGStarTrackerDisplayLoSSettings *swgStarTrackerDisplayLoSSettings)
static MsgStarTrackerDisplayLoSSettings* create(const QObject *pipeSource, SWGSDRangel::SWGStarTrackerDisplayLoSSettings *swgStarTrackerDisplayLoSSettings)
{
return new MsgStarTrackerDisplayLoSSettings(pipeSource, swgStarTrackerDisplayLoSSettings);
}
private:
const PipeEndPoint *m_pipeSource;
const QObject *m_pipeSource;
SWGSDRangel::SWGStarTrackerDisplayLoSSettings *m_swgStarTrackerDisplayLoSSettings;
MsgStarTrackerDisplayLoSSettings(const PipeEndPoint *pipeSource, SWGSDRangel::SWGStarTrackerDisplayLoSSettings *swgStarTrackerDisplayLoSSettings) :
MsgStarTrackerDisplayLoSSettings(const QObject *pipeSource, SWGSDRangel::SWGStarTrackerDisplayLoSSettings *swgStarTrackerDisplayLoSSettings) :
Message(),
m_pipeSource(pipeSource),
m_swgStarTrackerDisplayLoSSettings(swgStarTrackerDisplayLoSSettings)
@ -737,7 +736,6 @@ public:
void removeFeatureInstance(Feature *feature);
void clearFeatures(FeatureSet *featureSet);
// pipes
MessagePipesLegacy& getMessagePipesLegacy() { return m_messagePipesLegacy; }
MessagePipes& getMessagePipes() { return m_messagePipes; }
DataPipes& getDataPipes() { return m_dataPipes; }
@ -771,7 +769,6 @@ private:
QMap<ChannelAPI*, DeviceSet*> m_channelsMap; //!< Channel to device set map
QMap<Feature*, FeatureSet*> m_featuresMap; //!< Feature to feature set map
PluginManager* m_pluginManager;
MessagePipesLegacy m_messagePipesLegacy;
MessagePipes m_messagePipes;
DataPipes m_dataPipes;

View File

@ -1,78 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QGlobalStatic>
#include "util/messagequeue.h"
#include "messagepipeslegacygcworker.h"
#include "messagepipeslegacy.h"
#include "pipeendpoint.h"
MessagePipesLegacy::MessagePipesLegacy()
{
m_gcWorker = new MessagePipesLegacyGCWorker();
m_gcWorker->setC2FRegistrations(
m_registrations.getMutex(),
m_registrations.getElements(),
m_registrations.getConsumers()
);
m_gcWorker->moveToThread(&m_gcThread);
startGC();
}
MessagePipesLegacy::~MessagePipesLegacy()
{
if (m_gcWorker->isRunning()) {
stopGC();
}
}
MessageQueue *MessagePipesLegacy::registerChannelToFeature(const PipeEndPoint *source, PipeEndPoint *dest, const QString& type)
{
qDebug("MessagePipesLegacy::registerChannelToFeature: %p %p %s", source, dest, qPrintable(type));
return m_registrations.registerProducerToConsumer(source, dest, type);
}
MessageQueue *MessagePipesLegacy::unregisterChannelToFeature(const PipeEndPoint *source, PipeEndPoint *dest, const QString& type)
{
qDebug("MessagePipesLegacy::unregisterChannelToFeature: %p %p %s", source, dest, qPrintable(type));
MessageQueue *messageQueue = m_registrations.unregisterProducerToConsumer(source, dest, type);
m_gcWorker->addMessageQueueToDelete(messageQueue);
return messageQueue;
}
QList<MessageQueue*>* MessagePipesLegacy::getMessageQueues(const PipeEndPoint *source, const QString& type)
{
//qDebug("MessagePipesLegacy::getMessageQueues: %p %s", source, qPrintable(type));
return m_registrations.getElements(source, type);
}
void MessagePipesLegacy::startGC()
{
qDebug("MessagePipesLegacy::startGC");
m_gcWorker->startWork();
m_gcThread.start();
}
void MessagePipesLegacy::stopGC()
{
qDebug("MessagePipesLegacy::stopGC");
m_gcWorker->stopWork();
m_gcThread.quit();
m_gcThread.wait();
}

View File

@ -1,59 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRBASE_PIPES_MESSAGEPIPESLEGACY_H_
#define SDRBASE_PIPES_MESSAGEPIPESLEGACY_H_
#include <QObject>
#include <QHash>
#include <QMap>
#include <QMutex>
#include <QThread>
#include "export.h"
#include "messagepipeslegacycommon.h"
#include "elementpipesregistrations.h"
class PipeEndPoint;
class MessagePipesLegacyGCWorker;
class MessageQueue;
class SDRBASE_API MessagePipesLegacy : public QObject
{
Q_OBJECT
public:
MessagePipesLegacy();
MessagePipesLegacy(const MessagePipesLegacy&) = delete;
MessagePipesLegacy& operator=(const MessagePipesLegacy&) = delete;
~MessagePipesLegacy();
// FIXME: Names of these functions should probably change, as we now support channel or feature at either end
MessageQueue *registerChannelToFeature(const PipeEndPoint *source, PipeEndPoint *dest, const QString& type);
MessageQueue *unregisterChannelToFeature(const PipeEndPoint *source, PipeEndPoint *dest, const QString& type);
QList<MessageQueue*>* getMessageQueues(const PipeEndPoint *source, const QString& type);
private:
ElementPipesRegistrations<PipeEndPoint, PipeEndPoint, MessageQueue> m_registrations;
QThread m_gcThread; //!< Garbage collector thread
MessagePipesLegacyGCWorker *m_gcWorker; //!< Garbage collector
void startGC(); //!< Start garbage collector
void stopGC(); //!< Stop garbage collector
};
#endif // SDRBASE_PIPES_MESSAGEPIPESLEGACY_H_

View File

@ -1,20 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "messagepipeslegacycommon.h"
MESSAGE_CLASS_DEFINITION(MessagePipesLegacyCommon::MsgReportChannelDeleted, Message)

View File

@ -1,61 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRBASE_PIPES_MESSAGEPIPESLEGACYCOMON_H_
#define SDRBASE_PIPES_MESSAGEPIPESLEGACYCOMON_H_
#include <QHash>
#include <QMap>
#include <QMutex>
#include "export.h"
#include "util/message.h"
#include "elementpipescommon.h"
class PipeEndPoint;
class MessageQueue;
class SDRBASE_API MessagePipesLegacyCommon
{
public:
typedef ElementPipesCommon::RegistrationKey<PipeEndPoint> ChannelRegistrationKey;
/** Send this message to stakeholders when the garbage collector finds that a channel was deleted */
class SDRBASE_API MsgReportChannelDeleted : public Message {
MESSAGE_CLASS_DECLARATION
public:
const MessageQueue *getMessageQueue() const { return m_messageQueue; }
const ChannelRegistrationKey& getChannelRegistrationKey() const { return m_channelRegistrationKey; }
static MsgReportChannelDeleted* create(const MessageQueue *messageQueue, const ChannelRegistrationKey& channelRegistrationKey) {
return new MsgReportChannelDeleted(messageQueue, channelRegistrationKey);
}
private:
const MessageQueue *m_messageQueue;
ChannelRegistrationKey m_channelRegistrationKey;
MsgReportChannelDeleted(const MessageQueue *messageQueue, const ChannelRegistrationKey& channelRegistrationKey) :
Message(),
m_messageQueue(messageQueue),
m_channelRegistrationKey(channelRegistrationKey)
{ }
};
};
#endif // SDRBASE_PIPES_MESSAGEPIPESLEGACYCOMON_H_

View File

@ -1,78 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "channel/channelapi.h"
#include "feature/feature.h"
#include "util/messagequeue.h"
#include "maincore.h"
#include "messagepipeslegacycommon.h"
#include "messagepipeslegacygcworker.h"
bool MessagePipesLegacyGCWorker::MessagePipesGC::existsProducer(const PipeEndPoint *pipeEndPoint)
{
return MainCore::instance()->existsChannel((const ChannelAPI *)pipeEndPoint)
|| MainCore::instance()->existsFeature((const Feature *)pipeEndPoint);
}
bool MessagePipesLegacyGCWorker::MessagePipesGC::existsConsumer(const PipeEndPoint *pipeEndPoint)
{
return MainCore::instance()->existsChannel((const ChannelAPI *)pipeEndPoint)
|| MainCore::instance()->existsFeature((const Feature *)pipeEndPoint);
}
void MessagePipesLegacyGCWorker::MessagePipesGC::sendMessageToConsumer(
const MessageQueue *,
MessagePipesLegacyCommon::ChannelRegistrationKey,
PipeEndPoint *)
{
}
MessagePipesLegacyGCWorker::MessagePipesLegacyGCWorker() :
m_running(false)
{}
MessagePipesLegacyGCWorker::~MessagePipesLegacyGCWorker()
{}
void MessagePipesLegacyGCWorker::startWork()
{
connect(&m_gcTimer, SIGNAL(timeout()), this, SLOT(processGC()));
m_gcTimer.start(10000); // collect garbage every 10s
m_running = true;
}
void MessagePipesLegacyGCWorker::stopWork()
{
m_running = false;
m_gcTimer.stop();
disconnect(&m_gcTimer, SIGNAL(timeout()), this, SLOT(processGC()));
}
void MessagePipesLegacyGCWorker::addMessageQueueToDelete(MessageQueue *messageQueue)
{
if (messageQueue)
{
m_gcTimer.start(10000); // restart GC to make sure deletion is postponed
m_messagePipesGC.addElementToDelete(messageQueue);
}
}
void MessagePipesLegacyGCWorker::processGC()
{
// qDebug("MessagePipesLegacyGCWorker::processGC");
m_messagePipesGC.processGC();
}

View File

@ -1,69 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRBASE_PIPES_MESSAGEPIPESLEGACYGCWORKER_H_
#define SDRBASE_PIPES_MESSAGEPIPESLEGACYGCWORKER_H_
#include <QObject>
#include <QTimer>
#include "export.h"
#include "messagepipeslegacycommon.h"
#include "elementpipesgc.h"
class QMutex;
class SDRBASE_API MessagePipesLegacyGCWorker : public QObject
{
Q_OBJECT
public:
MessagePipesLegacyGCWorker();
~MessagePipesLegacyGCWorker();
void setC2FRegistrations(
QMutex *c2fMutex,
QMap<MessagePipesLegacyCommon::ChannelRegistrationKey, QList<MessageQueue*>> *c2fQueues,
QMap<MessagePipesLegacyCommon::ChannelRegistrationKey, QList<PipeEndPoint*>> *c2fPipeEndPoints
)
{
m_messagePipesGC.setRegistrations(c2fMutex, c2fQueues, c2fPipeEndPoints);
}
void startWork();
void stopWork();
void addMessageQueueToDelete(MessageQueue *messageQueue);
bool isRunning() const { return m_running; }
private:
class MessagePipesGC : public ElementPipesGC<PipeEndPoint, PipeEndPoint, MessageQueue>
{
private:
virtual bool existsProducer(const PipeEndPoint *pipeEndPoint);
virtual bool existsConsumer(const PipeEndPoint *pipeEndPoint);
virtual void sendMessageToConsumer(const MessageQueue *messageQueue, MessagePipesLegacyCommon::ChannelRegistrationKey key, PipeEndPoint *pipeEndPoint);
};
MessagePipesGC m_messagePipesGC;
bool m_running;
QTimer m_gcTimer;
private slots:
void processGC(); //!< Collect garbage
};
#endif // SDRBASE_PIPES_MESSAGEPIPESLEGACYGCWORKER_H_

View File

@ -1,185 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2021 Jon Beniston, M7RCE //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <vector>
#include <QRegExp>
#include <QDebug>
#include "dsp/dspengine.h"
#include "device/deviceset.h"
#include "channel/channelapi.h"
#include "feature/featureset.h"
#include "feature/feature.h"
#include "maincore.h"
#include "pipeendpoint.h"
MESSAGE_CLASS_DEFINITION(PipeEndPoint::MsgReportPipes, Message)
QList<PipeEndPoint::AvailablePipeSource> PipeEndPoint::updateAvailablePipeSources(QString pipeName, QStringList pipeTypes, QStringList pipeURIs, PipeEndPoint *destination)
{
MainCore *mainCore = MainCore::instance();
MessagePipesLegacy& messagePipes = mainCore->getMessagePipesLegacy();
std::vector<DeviceSet*>& deviceSets = mainCore->getDeviceSets();
QHash<PipeEndPoint *, AvailablePipeSource> availablePipes;
// Source is a channel
int deviceIndex = 0;
for (std::vector<DeviceSet*>::const_iterator it = deviceSets.begin(); it != deviceSets.end(); ++it, deviceIndex++)
{
DSPDeviceSourceEngine *deviceSourceEngine = (*it)->m_deviceSourceEngine;
DSPDeviceSinkEngine *deviceSinkEngine = (*it)->m_deviceSinkEngine;
if (deviceSourceEngine || deviceSinkEngine)
{
for (int chi = 0; chi < (*it)->getNumberOfChannels(); chi++)
{
ChannelAPI *channel = (*it)->getChannelAt(chi);
int i = pipeURIs.indexOf(channel->getURI());
if (i >= 0)
{
if (!availablePipes.contains(channel))
{
MessageQueue *messageQueue = messagePipes.registerChannelToFeature(channel, destination, pipeName);
if (MainCore::instance()->existsFeature((const Feature *)destination))
{
// Destination is feature
Feature *featureDest = (Feature *)destination;
QObject::connect(
messageQueue,
&MessageQueue::messageEnqueued,
featureDest,
[=](){ featureDest->handlePipeMessageQueue(messageQueue); },
Qt::QueuedConnection
);
}
else
{
// Destination is a channel
// Can't use Qt::QueuedConnection because ChannelAPI isn't a QObject
ChannelAPI *channelDest = (ChannelAPI *)destination;
QObject::connect(
messageQueue,
&MessageQueue::messageEnqueued,
[=](){ channelDest->handlePipeMessageQueue(messageQueue); }
);
}
}
AvailablePipeSource availablePipe =
AvailablePipeSource{
deviceSinkEngine != nullptr ? AvailablePipeSource::TX : AvailablePipeSource::RX,
deviceIndex,
chi,
channel,
pipeTypes.at(i)
};
availablePipes[channel] = availablePipe;
}
}
}
}
// Source is a feature
std::vector<FeatureSet*>& featureSets = mainCore->getFeatureeSets();
int featureIndex = 0;
for (std::vector<FeatureSet*>::const_iterator it = featureSets.begin(); it != featureSets.end(); ++it, featureIndex++)
{
for (int fi = 0; fi < (*it)->getNumberOfFeatures(); fi++)
{
Feature *feature = (*it)->getFeatureAt(fi);
int i = pipeURIs.indexOf(feature->getURI());
if (i >= 0)
{
if (!availablePipes.contains(feature))
{
MessageQueue *messageQueue = messagePipes.registerChannelToFeature(feature, destination, pipeName);
if (MainCore::instance()->existsFeature((const Feature *)destination))
{
// Destination is feature
Feature *featureDest = (Feature *)destination;
QObject::connect(
messageQueue,
&MessageQueue::messageEnqueued,
featureDest,
[=](){ featureDest->handlePipeMessageQueue(messageQueue); },
Qt::QueuedConnection
);
}
else
{
// Destination is a channel
// Can't use Qt::QueuedConnection because ChannelAPI isn't a QObject
ChannelAPI *channelDest = (ChannelAPI *)destination;
QObject::connect(
messageQueue,
&MessageQueue::messageEnqueued,
[=](){ channelDest->handlePipeMessageQueue(messageQueue); }
);
}
}
AvailablePipeSource availablePipe =
AvailablePipeSource{
AvailablePipeSource::Feature,
featureIndex,
fi,
feature,
pipeTypes.at(i)
};
availablePipes[feature] = availablePipe;
}
}
}
QList<AvailablePipeSource> availablePipeList;
QHash<PipeEndPoint*, AvailablePipeSource>::iterator it = availablePipes.begin();
for (; it != availablePipes.end(); ++it) {
availablePipeList.push_back(*it);
}
return availablePipeList;
}
PipeEndPoint *PipeEndPoint::getPipeEndPoint(const QString name, const QList<AvailablePipeSource> &availablePipeSources)
{
QRegExp re("([TRF])([0-9]+):([0-9]+) ([a-zA-Z0-9]+)");
if (re.exactMatch(name))
{
QString type = re.capturedTexts()[1];
int setIndex = re.capturedTexts()[2].toInt();
int index = re.capturedTexts()[3].toInt();
QString id = re.capturedTexts()[4];
QListIterator<AvailablePipeSource> itr(availablePipeSources);
while (itr.hasNext())
{
AvailablePipeSource p = itr.next();
if ((p.m_setIndex == setIndex) && (p.m_index == index) && (id == p.m_id)) {
return p.m_source;
}
}
}
else
{
qDebug() << "PipeEndPoint::getPipeEndPoint: " << name << " is malformed";
}
return nullptr;
}

View File

@ -1,100 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2021 Jon Beniston, M7RCE //
// //
// Parent for ChannelAPI and Features, where either can be used. //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRBASE_PIPES_PIPEENDPOINT_H_
#define SDRBASE_PIPES_PIPEENDPOINT_H_
#include <QList>
#include <QString>
#include <QStringList>
#include "util/message.h"
#include "export.h"
class Feature;
class SDRBASE_API PipeEndPoint {
public:
// Used by pipe sinks (channels or features) to record details about available pipe sources (channels or features)
struct AvailablePipeSource
{
enum {RX, TX, Feature} m_type;
int m_setIndex;
int m_index;
PipeEndPoint *m_source;
QString m_id;
AvailablePipeSource() = default;
AvailablePipeSource(const AvailablePipeSource&) = default;
AvailablePipeSource& operator=(const AvailablePipeSource&) = default;
friend bool operator==(const AvailablePipeSource &lhs, const AvailablePipeSource &rhs)
{
return (lhs.m_type == rhs.m_type)
&& (lhs.m_setIndex == rhs.m_setIndex)
&& (lhs.m_source == rhs.m_source)
&& (lhs.m_id == rhs.m_id);
}
QString getTypeName() const
{
QStringList typeNames = {"R", "T", "F"};
return typeNames[m_type];
}
// Name for use in GUI combo boxes and WebAPI
QString getName() const
{
QString type;
return QString("%1%2:%3 %4").arg(getTypeName())
.arg(m_setIndex)
.arg(m_index)
.arg(m_id);
}
};
class SDRBASE_API MsgReportPipes : public Message {
MESSAGE_CLASS_DECLARATION
public:
QList<AvailablePipeSource>& getAvailablePipes() { return m_availablePipes; }
static MsgReportPipes* create() {
return new MsgReportPipes();
}
private:
QList<AvailablePipeSource> m_availablePipes;
MsgReportPipes() :
Message()
{}
};
protected:
// Utility functions for pipe sinks to manage list of sources
QList<AvailablePipeSource> updateAvailablePipeSources(QString pipeName, QStringList pipeTypes, QStringList pipeURIs, PipeEndPoint *destination);
PipeEndPoint *getPipeEndPoint(const QString name, const QList<AvailablePipeSource> &availablePipeSources);
};
#endif // SDRBASE_PIPES_PIPEENDPOINT_H_