-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
iio-widgets/MultiDataStrategy: Implement container for multiple Data …
…Strategies The MultiDataStrategy is a Data Strategy that can be added to an IIOWidget. In this strategy, the user can add multiple DSs that will be aggregated in the MultiDataStrategy. Signed-off-by: Andrei-Fabian-Pop <Andreifabian.Pop@analog.com>
- Loading branch information
1 parent
2f19008
commit d3f1013
Showing
4 changed files
with
310 additions
and
48 deletions.
There are no files selected for viewing
103 changes: 103 additions & 0 deletions
103
iio-widgets/include/iio-widgets/datastrategy/multidatastrategy.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* | ||
* Copyright (c) 2024 Analog Devices Inc. | ||
* | ||
* This file is part of Scopy | ||
* (see https://www.github.com/analogdevicesinc/scopy). | ||
* | ||
* 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, either 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 for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef SCOPY_MULTIDATASTRATEGY_H | ||
#define SCOPY_MULTIDATASTRATEGY_H | ||
|
||
#include <QWidget> | ||
#include <QList> | ||
#include <QSet> | ||
#include <iio.h> | ||
#include "datastrategy/datastrategyinterface.h" | ||
#include "scopy-iio-widgets_export.h" | ||
|
||
namespace scopy { | ||
class SCOPY_IIO_WIDGETS_EXPORT MultiDataStrategy : public QWidget, public DataStrategyInterface | ||
{ | ||
Q_OBJECT | ||
Q_INTERFACES(scopy::DataStrategyInterface) | ||
public: | ||
/** | ||
* @brief MultiDataStrategy This is a class for incorporating multiple Data Strategies in the | ||
* same IIOWidget. All results that are used but the IIOWidget class are aggregated, the ones | ||
* that are related to the status of the operations are not. | ||
* @param strategies A QList of pointers to DataStrategyInterfaces. More Data Strategies can be | ||
* added after creation. | ||
* @param parent QWidget* | ||
*/ | ||
explicit MultiDataStrategy(QList<DataStrategyInterface *> strategies, QWidget *parent = nullptr); | ||
|
||
/** | ||
* @brief addDataStrategy Add and connect a new Data Strategy. | ||
* @param ds | ||
*/ | ||
void addDataStrategy(DataStrategyInterface *ds); | ||
|
||
/** | ||
* @brief removeDataStrategy Remove and disconnect a Data Strategy. | ||
* @param ds | ||
*/ | ||
void removeDataStrategy(DataStrategyInterface *ds); | ||
|
||
/** | ||
* @brief removeDataStrategyByIndex Remove and disconnect a Data Strategy based on its index. | ||
* The index can be found from the dataStrategies() function. | ||
* @param index | ||
*/ | ||
void removeDataStrategyByIndex(int index); | ||
|
||
/** | ||
* @brief dataStrategies Return a list of all Data Strategies, useful when wanting to find a | ||
* specific index. | ||
* @return QList of DataStrategyInterface pointers. | ||
*/ | ||
QList<DataStrategyInterface *> dataStrategies(); | ||
|
||
QString data() override; | ||
QString optionalData() override; | ||
|
||
public Q_SLOTS: | ||
int write(QString data) override; | ||
QPair<QString, QString> read() override; | ||
|
||
void writeAsync(QString data) override; | ||
void readAsync() override; | ||
|
||
void receiveSingleRead(QString data, QString optionalData); | ||
|
||
Q_SIGNALS: | ||
void sendData(QString data, QString dataOptions) override; | ||
void aboutToWrite(QString oldData, QString newData) override; | ||
void emitStatus(QDateTime timestamp, QString oldData, QString newData, int returnCode, bool isReadOp) override; | ||
|
||
private: | ||
QList<DataStrategyInterface *> m_dataStrategies; | ||
QList<QPair<QString, QString>> m_receivedData; | ||
|
||
QSet<QObject *> m_expectedSignals; | ||
QSet<QObject *> m_receivedSignals; | ||
|
||
QString m_data; | ||
QString m_optionalData; | ||
int m_returnCode; | ||
}; | ||
} // namespace scopy | ||
|
||
#endif // SCOPY_MULTIDATASTRATEGY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#include "datastrategy/multidatastrategy.h" | ||
|
||
Q_LOGGING_CATEGORY(CAT_MULTI_DATA_STRATEGY, "MultiDataStrategy") | ||
using namespace scopy; | ||
|
||
MultiDataStrategy::MultiDataStrategy(QList<DataStrategyInterface *> strategies, QWidget *parent) | ||
: QWidget(parent) | ||
, m_dataStrategies(strategies) | ||
, m_data("") | ||
, m_optionalData("") | ||
, m_returnCode(0) | ||
{ | ||
for(DataStrategyInterface *ds : m_dataStrategies) { | ||
QWidget *widgetDS = dynamic_cast<QWidget *>(ds); | ||
if(!widgetDS) { | ||
qWarning(CAT_MULTI_DATA_STRATEGY) << "Data strategy not valid."; | ||
continue; | ||
} | ||
|
||
m_expectedSignals.insert(widgetDS); | ||
connect(widgetDS, SIGNAL(sendData(QString, QString)), this, SLOT(receiveSingleRead(QString, QString))); | ||
|
||
// Forward signals from all DS. Caution: these signals are not aggregated. | ||
connect(widgetDS, SIGNAL(emitStatus(QDateTime, QString, QString, int, bool)), this, | ||
SIGNAL(emitStatus(QDateTime, QString, QString, int, bool))); | ||
connect(widgetDS, SIGNAL(aboutToWrite(QString, QString)), this, SIGNAL(aboutToWrite(QString, QString))); | ||
} | ||
} | ||
|
||
void MultiDataStrategy::addDataStrategy(DataStrategyInterface *ds) | ||
{ | ||
m_dataStrategies.append(ds); | ||
m_expectedSignals.insert(dynamic_cast<QObject *>(ds)); | ||
|
||
connect(dynamic_cast<QWidget *>(ds), SIGNAL(sendData(QString, QString)), this, | ||
SLOT(receiveSingleRead(QString, QString))); | ||
|
||
// Forward signals from all DS. Caution: these signals are not aggregated. | ||
connect(dynamic_cast<QWidget *>(ds), SIGNAL(emitStatus(QDateTime, QString, QString, int, bool)), this, | ||
SIGNAL(emitStatus(QDateTime, QString, QString, int, bool))); | ||
connect(dynamic_cast<QWidget *>(ds), SIGNAL(aboutToWrite(QString, QString)), this, | ||
SIGNAL(aboutToWrite(QString, QString))); | ||
} | ||
|
||
void MultiDataStrategy::removeDataStrategy(DataStrategyInterface *ds) | ||
{ | ||
m_dataStrategies.removeOne(ds); | ||
m_expectedSignals.remove(dynamic_cast<QObject *>(ds)); | ||
disconnect(dynamic_cast<QWidget *>(ds), SIGNAL(sendData(QString, QString)), this, | ||
SLOT(receiveSingleRead(QString, QString))); | ||
disconnect(dynamic_cast<QWidget *>(ds), SIGNAL(emitStatus(QDateTime, QString, QString, int, bool)), this, | ||
SIGNAL(emitStatus(QDateTime, QString, QString, int, bool))); | ||
disconnect(dynamic_cast<QWidget *>(ds), SIGNAL(aboutToWrite(QString, QString)), this, | ||
SIGNAL(aboutToWrite(QString, QString))); | ||
} | ||
|
||
void MultiDataStrategy::removeDataStrategyByIndex(int index) | ||
{ | ||
QWidget *ds = dynamic_cast<QWidget *>(m_dataStrategies.at(index)); | ||
m_expectedSignals.remove(dynamic_cast<QObject *>(m_dataStrategies.at(index))); | ||
m_dataStrategies.removeAt(index); | ||
disconnect(ds, SIGNAL(sendData(QString, QString)), this, SLOT(receiveSingleRead(QString, QString))); | ||
disconnect(ds, SIGNAL(emitStatus(QDateTime, QString, QString, int, bool)), this, | ||
SIGNAL(emitStatus(QDateTime, QString, QString, int, bool))); | ||
disconnect(ds, SIGNAL(aboutToWrite(QString, QString)), this, SIGNAL(aboutToWrite(QString, QString))); | ||
} | ||
|
||
QList<DataStrategyInterface *> MultiDataStrategy::dataStrategies() { return m_dataStrategies; } | ||
|
||
QString MultiDataStrategy::data() { return m_data; } | ||
|
||
QString MultiDataStrategy::optionalData() { return m_optionalData; } | ||
|
||
int MultiDataStrategy::write(QString data) | ||
{ | ||
int res = 0; | ||
for(DataStrategyInterface *ds : m_dataStrategies) { | ||
int currentRet = ds->write(data); | ||
if(currentRet < 0) { | ||
res = currentRet; | ||
} | ||
} | ||
|
||
return res; | ||
} | ||
|
||
QPair<QString, QString> MultiDataStrategy::read() | ||
{ | ||
QPair<QString, QString> initialRead; | ||
for(int i = 0; i < m_dataStrategies.size(); ++i) { | ||
if(i == 0) { | ||
initialRead = m_dataStrategies[i]->read(); | ||
} else { | ||
if(initialRead != m_dataStrategies[i]->read()) { | ||
initialRead = {"DIFFERENT RESULTS", ""}; | ||
} | ||
} | ||
} | ||
|
||
return initialRead; | ||
} | ||
|
||
void MultiDataStrategy::writeAsync(QString data) | ||
{ | ||
for(DataStrategyInterface *ds : m_dataStrategies) { | ||
ds->writeAsync(data); | ||
} | ||
} | ||
|
||
void MultiDataStrategy::readAsync() | ||
{ | ||
for(DataStrategyInterface *ds : m_dataStrategies) { | ||
ds->readAsync(); | ||
} | ||
} | ||
|
||
void MultiDataStrategy::receiveSingleRead(QString data, QString optionalData) | ||
{ | ||
QObject *sender = QObject::sender(); | ||
m_receivedSignals.insert(sender); | ||
m_receivedData.append({data, optionalData}); | ||
|
||
if(m_receivedSignals == m_expectedSignals) { | ||
qWarning(CAT_MULTI_DATA_STRATEGY) << "Received all signals!"; | ||
bool ok = true; | ||
for(QPair<QString, QString> ss : m_receivedData) { | ||
if(ss.first != data || ss.second != optionalData) { | ||
ok = false; | ||
Q_EMIT sendData("DIFFERENT RESULTS", ""); | ||
} | ||
} | ||
if(ok) { | ||
m_data = data; | ||
m_optionalData = optionalData; | ||
Q_EMIT sendData(data, optionalData); | ||
} | ||
m_receivedData.clear(); | ||
m_receivedSignals.clear(); | ||
} | ||
} | ||
|
||
#include "moc_multidatastrategy.cpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters