mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
Data pipes redesign
This commit is contained in:
parent
22604244a3
commit
4c2ca8fa20
@ -383,14 +383,20 @@ void AISDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,14 +219,20 @@ void AMDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,14 +447,20 @@ void DABDemodSink::processOneAudioSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeCI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeCI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,14 +180,20 @@ void DSDDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,14 +256,20 @@ void NFMDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,14 +249,20 @@ void PacketDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,14 +594,20 @@ void PagerDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,19 +207,25 @@ void SSBDemodSink::processOneSample(Complex &ci)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it)
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
(*it)->write(
|
||||
(quint8*) &m_demodBuffer[0],
|
||||
m_demodBuffer.size() * sizeof(qint16),
|
||||
m_audioBinaual ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||
);
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
fifo->write(
|
||||
(quint8*) &m_demodBuffer[0],
|
||||
m_demodBuffer.size() * sizeof(qint16),
|
||||
m_audioBinaual ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,14 +141,20 @@ void WFMDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,14 +272,20 @@ void AISModSource::modulateSample()
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,14 +112,20 @@ void AMModSource::pullOne(Sample& sample)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,14 +173,20 @@ void NFMModSource::modulateSample()
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,14 +280,20 @@ void PacketModSource::modulateSample()
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,19 +184,25 @@ void SSBModSource::modulateSample()
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it)
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
(*it)->write(
|
||||
(quint8*) &m_demodBuffer[0],
|
||||
m_demodBuffer.size() * sizeof(qint16),
|
||||
m_settings.m_audioBinaural ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||
);
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
fifo->write(
|
||||
(quint8*) &m_demodBuffer[0],
|
||||
m_demodBuffer.size() * sizeof(qint16),
|
||||
m_settings.m_audioBinaural ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,14 +152,20 @@ void WFMModSource::pullOne(Sample& sample)
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataFifos)
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<DataFifo*>::iterator it = dataFifos->begin();
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataFifos->end(); ++it) {
|
||||
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ DemodAnalyzer::DemodAnalyzer(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||
m_spectrumVis(SDR_RX_SCALEF),
|
||||
m_selectedChannel(nullptr),
|
||||
m_dataFifo(nullptr)
|
||||
m_dataPipe(nullptr)
|
||||
{
|
||||
qDebug("DemodAnalyzer::DemodAnalyzer: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||
setObjectName(m_featureId);
|
||||
@ -88,10 +88,15 @@ void DemodAnalyzer::start()
|
||||
= DemodAnalyzerWorker::MsgConfigureDemodAnalyzerWorker::create(m_settings, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
|
||||
if (m_dataFifo)
|
||||
if (m_dataPipe)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(m_dataFifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(fifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,10 +104,15 @@ void DemodAnalyzer::stop()
|
||||
{
|
||||
qDebug("DemodAnalyzer::stop");
|
||||
|
||||
if (m_dataFifo)
|
||||
if (m_dataPipe)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(m_dataFifo, false);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(fifo, false);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
m_worker->stopWork();
|
||||
@ -169,8 +179,13 @@ bool DemodAnalyzer::handleMessage(const Message& cmd)
|
||||
DSPSignalNotification *msg = new DSPSignalNotification(0, m_sampleRate);
|
||||
m_spectrumVis.getInputMessageQueue()->push(msg);
|
||||
|
||||
if (m_dataFifo) {
|
||||
m_dataFifo->setSize(2*m_sampleRate);
|
||||
if (m_dataPipe)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->setSize(2*m_sampleRate);
|
||||
}
|
||||
}
|
||||
|
||||
if (getMessageQueueToGUI())
|
||||
@ -319,7 +334,8 @@ void DemodAnalyzer::setChannel(ChannelAPI *selectedChannel)
|
||||
|
||||
if (m_selectedChannel)
|
||||
{
|
||||
DataFifo *fifo = mainCore->getDataPipes().unregisterChannelToFeature(m_selectedChannel, this, "demod");
|
||||
ObjectPipe *pipe = mainCore->getDataPipes().unregisterProducerToConsumer(m_selectedChannel, this, "demod");
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(pipe->m_element);
|
||||
|
||||
if ((fifo) && m_worker->isRunning())
|
||||
{
|
||||
@ -331,13 +347,18 @@ void DemodAnalyzer::setChannel(ChannelAPI *selectedChannel)
|
||||
disconnect(messageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleChannelMessageQueue(MessageQueue*)));
|
||||
}
|
||||
|
||||
m_dataFifo = mainCore->getDataPipes().registerChannelToFeature(selectedChannel, this, "demod");
|
||||
m_dataFifo->setSize(96000);
|
||||
m_dataPipe = mainCore->getDataPipes().registerProducerToConsumer(selectedChannel, this, "demod");
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>(m_dataPipe->m_element);
|
||||
|
||||
if (m_worker->isRunning())
|
||||
if (fifo)
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(m_dataFifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
fifo->setSize(96000);
|
||||
|
||||
if (m_worker->isRunning())
|
||||
{
|
||||
DemodAnalyzerWorker::MsgConnectFifo *msg = DemodAnalyzerWorker::MsgConnectFifo::create(fifo, true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueue *messageQueue = mainCore->getMessagePipes().registerChannelToFeature(selectedChannel, this, "reportdemod");
|
||||
|
@ -33,7 +33,7 @@ class WebAPIAdapterInterface;
|
||||
class DemodAnalyzerWorker;
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class DataFifo;
|
||||
class ObjectPipe;
|
||||
|
||||
namespace SWGSDRangel {
|
||||
class SWGDeviceState;
|
||||
@ -201,7 +201,7 @@ private:
|
||||
ScopeVis m_scopeVis;
|
||||
QHash<ChannelAPI*, DemodAnalyzerSettings::AvailableChannel> m_availableChannels;
|
||||
ChannelAPI *m_selectedChannel;
|
||||
DataFifo *m_dataFifo;
|
||||
ObjectPipe *m_dataPipe;
|
||||
int m_sampleRate;
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
|
@ -170,10 +170,15 @@ set(sdrbase_SOURCES
|
||||
pipes/datapipes.cpp
|
||||
pipes/datapipescommon.cpp
|
||||
pipes/datapipesgcworker.cpp
|
||||
pipes/datafifostore.cpp
|
||||
pipes/datapipes2.cpp
|
||||
pipes/datapipes2gcworker.cpp
|
||||
pipes/messagepipes.cpp
|
||||
pipes/messagepipescommon.cpp
|
||||
pipes/messagepipesgcworker.cpp
|
||||
pipes/pipeendpoint.cpp
|
||||
pipes/objectpipe.cpp
|
||||
pipes/objectpipesregistrations.cpp
|
||||
|
||||
settings/featuresetpreset.cpp
|
||||
settings/preferences.cpp
|
||||
@ -374,12 +379,17 @@ set(sdrbase_HEADERS
|
||||
pipes/datapipes.h
|
||||
pipes/datapipescommon.h
|
||||
pipes/datapipesgcworker.h
|
||||
pipes/datafifostore.h
|
||||
pipes/datapipes2.h
|
||||
pipes/datapipes2gcworker.h
|
||||
pipes/elementpipescommon.h
|
||||
pipes/elementpipesgc.h
|
||||
pipes/messagepipes.h
|
||||
pipes/messagepipescommon.h
|
||||
pipes/messagepipesgcworker.h
|
||||
pipes/pipeendpoint.h
|
||||
pipes/objectpipe.h
|
||||
pipes/objectpipesregistrations.h
|
||||
|
||||
plugin/plugininterface.h
|
||||
plugin/pluginapi.h
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "settings/mainsettings.h"
|
||||
#include "util/message.h"
|
||||
#include "pipes/messagepipes.h"
|
||||
#include "pipes/datapipes.h"
|
||||
#include "pipes/datapipes2.h"
|
||||
#include "channel/channelapi.h"
|
||||
|
||||
class DeviceSet;
|
||||
@ -731,7 +731,7 @@ public:
|
||||
void clearFeatures(FeatureSet *featureSet);
|
||||
// pipes
|
||||
MessagePipes& getMessagePipes() { return m_messagePipes; }
|
||||
DataPipes& getDataPipes() { return m_dataPipes; }
|
||||
DataPipes2& getDataPipes() { return m_dataPipes; }
|
||||
|
||||
friend class MainServer;
|
||||
friend class MainWindow;
|
||||
@ -751,7 +751,7 @@ private:
|
||||
QMap<Feature*, FeatureSet*> m_featuresMap; //!< Feature to feature set map
|
||||
PluginManager* m_pluginManager;
|
||||
MessagePipes m_messagePipes;
|
||||
DataPipes m_dataPipes;
|
||||
DataPipes2 m_dataPipes;
|
||||
|
||||
void debugMaps();
|
||||
};
|
||||
|
56
sdrbase/pipes/datafifostore.cpp
Normal file
56
sdrbase/pipes/datafifostore.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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 "dsp/datafifo.h"
|
||||
#include "datafifostore.h"
|
||||
|
||||
DataFifoStore::DataFifoStore()
|
||||
{}
|
||||
|
||||
DataFifoStore::~DataFifoStore()
|
||||
{
|
||||
deleteAllElements();
|
||||
}
|
||||
|
||||
QObject *DataFifoStore::createElement()
|
||||
{
|
||||
DataFifo *fifo = new DataFifo();
|
||||
m_dataFifos.push_back(fifo);
|
||||
qDebug("DataFifoStore::createElement: %d added", m_dataFifos.size() - 1);
|
||||
return fifo;
|
||||
}
|
||||
|
||||
void DataFifoStore::deleteElement(QObject *element)
|
||||
{
|
||||
int i = m_dataFifos.indexOf((DataFifo*) element);
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
qDebug("DataFifoStore::deleteElement: delte element at %d", i);
|
||||
delete m_dataFifos[i];
|
||||
m_dataFifos.removeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
void DataFifoStore::deleteAllElements()
|
||||
{
|
||||
for (auto& fifo : m_dataFifos) {
|
||||
delete fifo;
|
||||
}
|
||||
|
||||
m_dataFifos.clear();
|
||||
}
|
42
sdrbase/pipes/datafifostore.h
Normal file
42
sdrbase/pipes/datafifostore.h
Normal file
@ -0,0 +1,42 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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_DATAFIFOSTORE_H_
|
||||
#define SDRBASE_PIPES_DATAFIFOSTORE_H_
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "export.h"
|
||||
#include "objectpipeelementsstore.h"
|
||||
|
||||
class DataFifo;
|
||||
|
||||
class SDRBASE_API DataFifoStore : public ObjectPipeElementsStore
|
||||
{
|
||||
public:
|
||||
DataFifoStore();
|
||||
virtual ~DataFifoStore();
|
||||
|
||||
virtual QObject *createElement();
|
||||
virtual void deleteElement(QObject*);
|
||||
|
||||
private:
|
||||
void deleteAllElements();
|
||||
QList<DataFifo*> m_dataFifos;
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_DATAFIFOSTORE_H_
|
68
sdrbase/pipes/datapipes2.cpp
Normal file
68
sdrbase/pipes/datapipes2.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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 "dsp/datafifo.h"
|
||||
#include "datapipes2.h"
|
||||
#include "datapipes2gcworker.h"
|
||||
|
||||
DataPipes2::DataPipes2() :
|
||||
m_registrations(&m_dataFifoStore)
|
||||
{
|
||||
m_gcWorker = new DataPipes2GCWorker(m_registrations);
|
||||
m_gcWorker->moveToThread(&m_gcThread);
|
||||
startGC();
|
||||
}
|
||||
|
||||
DataPipes2::~DataPipes2()
|
||||
{
|
||||
if (m_gcWorker->isRunning()) {
|
||||
stopGC();
|
||||
}
|
||||
|
||||
m_gcWorker->deleteLater();
|
||||
}
|
||||
|
||||
ObjectPipe *DataPipes2::registerProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type)
|
||||
{
|
||||
return m_registrations.registerProducerToConsumer(producer, consumer, type);
|
||||
}
|
||||
|
||||
ObjectPipe *DataPipes2::unregisterProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type)
|
||||
{
|
||||
return m_registrations.unregisterProducerToConsumer(producer, consumer, type);
|
||||
}
|
||||
|
||||
void DataPipes2::getDataPipes(const QObject *producer, const QString& type, QList<ObjectPipe*>& pipes)
|
||||
{
|
||||
return m_registrations.getPipes(producer, type, pipes);
|
||||
}
|
||||
|
||||
void DataPipes2::startGC()
|
||||
{
|
||||
qDebug("DataPipes2::startGC");
|
||||
|
||||
m_gcWorker->startWork();
|
||||
m_gcThread.start();
|
||||
}
|
||||
|
||||
void DataPipes2::stopGC()
|
||||
{
|
||||
qDebug("DataPipes2::stopGC");
|
||||
m_gcWorker->stopWork();
|
||||
m_gcThread.quit();
|
||||
m_gcThread.wait();
|
||||
}
|
55
sdrbase/pipes/datapipes2.h
Normal file
55
sdrbase/pipes/datapipes2.h
Normal file
@ -0,0 +1,55 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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_DATAPIPES2_H_
|
||||
#define SDRBASE_PIPES_DATAPIPES2_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
|
||||
#include "export.h"
|
||||
#include "objectpipesregistrations.h"
|
||||
#include "datafifostore.h"
|
||||
|
||||
class DataFifo;
|
||||
class DataPipes2GCWorker;
|
||||
|
||||
class SDRBASE_API DataPipes2 : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataPipes2();
|
||||
DataPipes2(const DataPipes2&) = delete;
|
||||
DataPipes2& operator=(const DataPipes2&) = delete;
|
||||
~DataPipes2();
|
||||
|
||||
ObjectPipe *registerProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type);
|
||||
ObjectPipe *unregisterProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type);
|
||||
void getDataPipes(const QObject *producer, const QString& type, QList<ObjectPipe*>& pipes);
|
||||
|
||||
private:
|
||||
DataFifoStore m_dataFifoStore;
|
||||
ObjectPipesRegistrations m_registrations;
|
||||
QThread m_gcThread; //!< Garbage collector thread
|
||||
DataPipes2GCWorker *m_gcWorker; //!< Garbage collector
|
||||
|
||||
void startGC(); //!< Start garbage collector
|
||||
void stopGC(); //!< Stop garbage collector
|
||||
};
|
||||
|
||||
|
||||
#endif // SDRBASE_PIPES_DATAPIPES2_H_
|
46
sdrbase/pipes/datapipes2gcworker.cpp
Normal file
46
sdrbase/pipes/datapipes2gcworker.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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 "dsp/datafifo.h"
|
||||
#include "datapipes2gcworker.h"
|
||||
|
||||
DataPipes2GCWorker::DataPipes2GCWorker(ObjectPipesRegistrations& objectPipesRegistrations) :
|
||||
m_running(false),
|
||||
m_objectPipesRegistrations(objectPipesRegistrations)
|
||||
{}
|
||||
|
||||
DataPipes2GCWorker::~DataPipes2GCWorker()
|
||||
{}
|
||||
|
||||
void DataPipes2GCWorker::startWork()
|
||||
{
|
||||
connect(&m_gcTimer, SIGNAL(timeout()), this, SLOT(processGC()));
|
||||
m_gcTimer.start(10000); // collect garbage every 10s
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
void DataPipes2GCWorker::stopWork()
|
||||
{
|
||||
m_running = false;
|
||||
m_gcTimer.stop();
|
||||
disconnect(&m_gcTimer, SIGNAL(timeout()), this, SLOT(processGC()));
|
||||
}
|
||||
|
||||
void DataPipes2GCWorker::processGC()
|
||||
{
|
||||
m_objectPipesRegistrations.processGC();
|
||||
}
|
49
sdrbase/pipes/datapipes2gcworker.h
Normal file
49
sdrbase/pipes/datapipes2gcworker.h
Normal file
@ -0,0 +1,49 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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_DATAPIPES2GCWORKER_H_
|
||||
#define SDRBASE_PIPES_DATAPIPES2GCWORKER_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
#include "export.h"
|
||||
#include "objectpipesregistrations.h"
|
||||
|
||||
class DataFifo;
|
||||
|
||||
class SDRBASE_API DataPipes2GCWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataPipes2GCWorker(ObjectPipesRegistrations& objectPipesRegistrations);
|
||||
~DataPipes2GCWorker();
|
||||
|
||||
void startWork();
|
||||
void stopWork();
|
||||
bool isRunning() const { return m_running; }
|
||||
|
||||
private:
|
||||
bool m_running;
|
||||
QTimer m_gcTimer;
|
||||
ObjectPipesRegistrations& m_objectPipesRegistrations;
|
||||
|
||||
private slots:
|
||||
void processGC(); //!< Collect garbage
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_DATAPIPES2GCWORKER_H_
|
47
sdrbase/pipes/objectpipe.cpp
Normal file
47
sdrbase/pipes/objectpipe.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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 "objectpipe.h"
|
||||
|
||||
ObjectPipe::ObjectPipe() :
|
||||
m_pipeId(0),
|
||||
m_typeId(0),
|
||||
m_producer(nullptr),
|
||||
m_consumer(nullptr),
|
||||
m_element(nullptr),
|
||||
m_gcCount(0)
|
||||
{}
|
||||
|
||||
void ObjectPipe::setToBeDeleted(int reason)
|
||||
{
|
||||
m_gcCount = 2; // will defer actual deletion by one GC pass
|
||||
emit toBeDeleted(reason);
|
||||
}
|
||||
|
||||
int ObjectPipe::getGCCount() const {
|
||||
return m_gcCount;
|
||||
}
|
||||
|
||||
int ObjectPipe::decreaseGCCount()
|
||||
{
|
||||
if (m_gcCount > 0) {
|
||||
return m_gcCount--;
|
||||
} else {
|
||||
return m_gcCount;
|
||||
}
|
||||
}
|
||||
|
51
sdrbase/pipes/objectpipe.h
Normal file
51
sdrbase/pipes/objectpipe.h
Normal file
@ -0,0 +1,51 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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_OBJECTPIPE_H_
|
||||
#define SDRBASE_PIPES_OBJECTPIPE_H_
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
class SDRBASE_API ObjectPipe : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ObjectPipe();
|
||||
ObjectPipe(const ObjectPipe&) = default;
|
||||
ObjectPipe& operator=(const ObjectPipe&) = default;
|
||||
|
||||
void setToBeDeleted(int reason);
|
||||
int getGCCount() const;
|
||||
int decreaseGCCount();
|
||||
|
||||
unsigned int m_pipeId;
|
||||
int m_typeId;
|
||||
const QObject *m_producer;
|
||||
const QObject *m_consumer;
|
||||
QObject *m_element;
|
||||
|
||||
signals:
|
||||
void toBeDeleted(int reason);
|
||||
|
||||
private:
|
||||
int m_gcCount;
|
||||
};
|
||||
|
||||
|
||||
#endif // SDRBASE_PIPES_OBJECTPIPE_H_
|
30
sdrbase/pipes/objectpipeelementsstore.h
Normal file
30
sdrbase/pipes/objectpipeelementsstore.h
Normal file
@ -0,0 +1,30 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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_OBJECTPIPESELEMENT_H_
|
||||
#define SDRBASE_PIPES_OBJECTPIPESELEMENT_H_
|
||||
|
||||
class QObject;
|
||||
|
||||
class ObjectPipeElementsStore
|
||||
{
|
||||
public:
|
||||
virtual QObject *createElement() = 0;
|
||||
virtual void deleteElement(QObject*) = 0;
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_OBJECTPIPESELEMENT_H_
|
236
sdrbase/pipes/objectpipesregistrations.cpp
Normal file
236
sdrbase/pipes/objectpipesregistrations.cpp
Normal file
@ -0,0 +1,236 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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 "objectpipesregistrations.h"
|
||||
|
||||
ObjectPipesRegistrations::ObjectPipesRegistrations(ObjectPipeElementsStore *objectPipeElementsStore) :
|
||||
m_typeCount(0),
|
||||
m_pipeId(0),
|
||||
m_objectPipeElementsStore(objectPipeElementsStore),
|
||||
m_mutex(QMutex::Recursive)
|
||||
{}
|
||||
|
||||
ObjectPipesRegistrations::~ObjectPipesRegistrations()
|
||||
{}
|
||||
|
||||
ObjectPipe *ObjectPipesRegistrations::registerProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type)
|
||||
{
|
||||
int typeId;
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
if (m_typeIds.contains(type))
|
||||
{
|
||||
typeId = m_typeIds.value(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeId = m_typeCount++;
|
||||
m_typeIds.insert(type, typeId);
|
||||
m_types.insert(typeId, type);
|
||||
}
|
||||
|
||||
for (auto& pipe : m_pipes) // check if pipe exists already - there is a unique pipe per producer, consumer and type
|
||||
{
|
||||
if ((producer == pipe->m_producer) && (consumer == pipe->m_consumer) && (typeId == pipe->m_typeId)) {
|
||||
return pipe;
|
||||
}
|
||||
}
|
||||
|
||||
QObject *element = m_objectPipeElementsStore->createElement();
|
||||
m_pipes.push_back(new ObjectPipe());
|
||||
m_pipes.back()->m_pipeId = ++m_pipeId;
|
||||
m_pipes.back()->m_typeId = typeId;
|
||||
m_pipes.back()->m_producer = producer;
|
||||
m_pipes.back()->m_consumer = consumer;
|
||||
m_pipes.back()->m_element = element;
|
||||
|
||||
m_producerPipes[producer].push_back(m_pipes.back());
|
||||
m_consumerPipes[consumer].push_back(m_pipes.back());
|
||||
m_typeIdPipes[typeId].push_back(m_pipes.back());
|
||||
m_producerAndTypeIdPipes[std::make_tuple(producer, typeId)].push_back(m_pipes.back());
|
||||
m_pipeMap[std::make_tuple(producer, consumer, typeId)] = m_pipes.back();
|
||||
|
||||
connect(producer, SIGNAL(destroyed(QObject*)), this, SLOT(removeProducer(QObject*)));
|
||||
connect(consumer, SIGNAL(destroyed(QObject*)), this, SLOT(removeConsumer(QObject*)));
|
||||
|
||||
return m_pipes.back();
|
||||
}
|
||||
|
||||
ObjectPipe *ObjectPipesRegistrations::unregisterProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type)
|
||||
{
|
||||
ObjectPipe *pipe = nullptr;
|
||||
|
||||
if (m_typeIds.contains(type))
|
||||
{
|
||||
int typeId = m_typeIds.value(type);
|
||||
|
||||
if (m_pipeMap.contains(std::make_tuple(producer, consumer, typeId)))
|
||||
{
|
||||
pipe = m_pipeMap[std::make_tuple(producer, consumer, typeId)];
|
||||
m_producerPipes[producer].removeAll(pipe);
|
||||
m_consumerPipes[consumer].removeAll(pipe);
|
||||
m_typeIdPipes[typeId].removeAll(pipe);
|
||||
m_producerAndTypeIdPipes[std::make_tuple(producer, typeId)].removeAll(pipe);
|
||||
|
||||
if (m_producerPipes[producer].size() == 0) {
|
||||
m_producerPipes.remove(producer);
|
||||
}
|
||||
|
||||
if (m_consumerPipes[consumer].size() == 0) {
|
||||
m_consumerPipes.remove(consumer);
|
||||
}
|
||||
|
||||
if (m_typeIdPipes[typeId].size() == 0) {
|
||||
m_typeIdPipes.remove(typeId);
|
||||
}
|
||||
|
||||
if (m_producerAndTypeIdPipes[std::make_tuple(producer, typeId)].size() == 0) {
|
||||
m_producerAndTypeIdPipes.remove(std::make_tuple(producer, typeId));
|
||||
}
|
||||
|
||||
pipe->setToBeDeleted(PipeDeletionReason::PipeDeleted);
|
||||
}
|
||||
}
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
||||
void ObjectPipesRegistrations::getPipes(const QObject *producer, const QString& type, QList<ObjectPipe*>& pipes)
|
||||
{
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
if (m_typeIds.contains(type))
|
||||
{
|
||||
if (m_producerAndTypeIdPipes.contains(std::make_tuple(producer, m_typeIds[type]))) {
|
||||
pipes = m_producerAndTypeIdPipes[std::make_tuple(producer, m_typeIds[type])];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPipesRegistrations::processGC()
|
||||
{
|
||||
qDebug("ObjectPipesRegistrations::processGC");
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
typename QList<ObjectPipe*>::iterator itPipe = m_pipes.begin();
|
||||
|
||||
while (itPipe != m_pipes.end())
|
||||
{
|
||||
if ((*itPipe)->getGCCount() > 0) // scheduled for deletion
|
||||
{
|
||||
if ((*itPipe)->decreaseGCCount() == 0) // delete on this pass
|
||||
{
|
||||
m_objectPipeElementsStore->deleteElement((*itPipe)->m_element);
|
||||
delete *itPipe;
|
||||
itPipe = m_pipes.erase(itPipe);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itPipe;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPipesRegistrations::removeProducer(QObject *producer)
|
||||
{
|
||||
qDebug("ObjectPipesRegistrations::removeProducer");
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
if (m_producerPipes.contains(producer) && (m_producerPipes[producer].size() != 0))
|
||||
{
|
||||
const QList<ObjectPipe*>& pipeList = m_producerPipes[producer];
|
||||
|
||||
for (auto& pipe : pipeList)
|
||||
{
|
||||
for (const auto& consumer : m_consumerPipes.keys()) {
|
||||
m_consumerPipes[consumer].removeAll(pipe);
|
||||
}
|
||||
|
||||
for (const auto& typeId : m_typeIdPipes.keys()) {
|
||||
m_typeIdPipes[typeId].removeAll(pipe);
|
||||
}
|
||||
|
||||
pipe->setToBeDeleted(PipeDeletionReason::PipeProducerDeleted);
|
||||
}
|
||||
|
||||
m_producerPipes.remove(producer);
|
||||
}
|
||||
|
||||
typename QMap<std::tuple<const QObject*, const QObject*, int>, ObjectPipe*>::iterator itP = m_pipeMap.begin();
|
||||
|
||||
while (itP != m_pipeMap.end())
|
||||
{
|
||||
if (std::get<0>(itP.key())) {
|
||||
itP = m_pipeMap.erase(itP);
|
||||
} else {
|
||||
++itP;
|
||||
}
|
||||
}
|
||||
|
||||
typename QMap<std::tuple<const QObject*, int>, QList<ObjectPipe*>>::iterator itPT = m_producerAndTypeIdPipes.begin();
|
||||
|
||||
while (itPT != m_producerAndTypeIdPipes.end())
|
||||
{
|
||||
if (std::get<0>(itPT.key()) == producer) {
|
||||
itPT = m_producerAndTypeIdPipes.erase(itPT);
|
||||
} else {
|
||||
++itPT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPipesRegistrations::removeConsumer(QObject *consumer)
|
||||
{
|
||||
qDebug("ObjectPipesRegistrations::removeConsumer");
|
||||
QMutexLocker mlock(&m_mutex);
|
||||
|
||||
if (m_consumerPipes.contains(consumer) && (m_consumerPipes[consumer].size() != 0))
|
||||
{
|
||||
QList<ObjectPipe*>& pipeList = m_consumerPipes[consumer];
|
||||
|
||||
for (auto& pipe : pipeList)
|
||||
{
|
||||
for (const auto& producer : m_producerPipes.keys()) {
|
||||
m_producerPipes[producer].removeAll(pipe);
|
||||
}
|
||||
|
||||
for (const auto& typeId : m_typeIdPipes.keys()) {
|
||||
m_typeIdPipes[typeId].removeAll(pipe);
|
||||
}
|
||||
|
||||
for (const auto& producerAndTypeId : m_producerAndTypeIdPipes.keys()) {
|
||||
m_producerAndTypeIdPipes[producerAndTypeId].removeAll(pipe);
|
||||
}
|
||||
|
||||
pipe->setToBeDeleted(PipeDeletionReason::PipeConsumerDeleted);
|
||||
}
|
||||
|
||||
m_consumerPipes.remove(consumer);
|
||||
}
|
||||
|
||||
typename QMap<std::tuple<const QObject*, const QObject*, int>, ObjectPipe*>::iterator it = m_pipeMap.begin();
|
||||
|
||||
while (it != m_pipeMap.end())
|
||||
{
|
||||
if (std::get<1>(it.key()) == consumer) {
|
||||
it = m_pipeMap.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
75
sdrbase/pipes/objectpipesregistrations.h
Normal file
75
sdrbase/pipes/objectpipesregistrations.h
Normal file
@ -0,0 +1,75 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2022 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_OBJECTPIPESREGISTRATION_H_
|
||||
#define SDRBASE_PIPES_OBJECTPIPESREGISTRATION_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QMutex>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include "export.h"
|
||||
#include "objectpipe.h"
|
||||
#include "objectpipeelementsstore.h"
|
||||
|
||||
class SDRBASE_API ObjectPipesRegistrations : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum PipeDeletionReason
|
||||
{
|
||||
PipeProducerDeleted,
|
||||
PipeConsumerDeleted,
|
||||
PipeDeleted
|
||||
};
|
||||
|
||||
ObjectPipesRegistrations(ObjectPipeElementsStore *objectPipeElementsStore);
|
||||
~ObjectPipesRegistrations();
|
||||
|
||||
ObjectPipe *registerProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type);
|
||||
ObjectPipe *unregisterProducerToConsumer(const QObject *producer, const QObject *consumer, const QString& type);
|
||||
void getPipes(const QObject *producer, const QString& type, QList<ObjectPipe*>& pipes);
|
||||
void processGC();
|
||||
|
||||
private slots:
|
||||
void removeProducer(QObject *producer);
|
||||
void removeConsumer(QObject *consumer);
|
||||
|
||||
private:
|
||||
QHash<QString, int> m_typeIds;
|
||||
QMap<int, QString> m_types;
|
||||
int m_typeCount;
|
||||
unsigned int m_pipeId;
|
||||
ObjectPipeElementsStore *m_objectPipeElementsStore;
|
||||
QList<ObjectPipe*> m_pipes;
|
||||
|
||||
QMap<const QObject*, QList<ObjectPipe*>> m_producerPipes;
|
||||
QMap<const QObject*, QList<ObjectPipe*>> m_consumerPipes;
|
||||
QMap<int, QList<ObjectPipe*>> m_typeIdPipes;
|
||||
QMap<std::tuple<const QObject*, int>, QList<ObjectPipe*>> m_producerAndTypeIdPipes;
|
||||
QMap<std::tuple<const QObject*, const QObject*, int>, ObjectPipe*> m_pipeMap;
|
||||
|
||||
QMutex m_mutex;
|
||||
};
|
||||
|
||||
#endif // SDRBASE_PIPES_OBJECTPIPESREGISTRATION_H_
|
Loading…
Reference in New Issue
Block a user