fix:TextInput support hot update;feat:add zero color and update
algorithm
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "backend.h"
|
||||
#include "data_backend.h"
|
||||
#include "serial/serial_backend.h"
|
||||
#include <qcolor.h>
|
||||
#include <qnumeric.h>
|
||||
|
||||
AppBackend::AppBackend(QObject* parent)
|
||||
@@ -51,6 +52,13 @@ void AppBackend::setShowGrid(bool on) {
|
||||
emit showGridChanged(on);
|
||||
}
|
||||
|
||||
void AppBackend::setUseHeatmap(bool on) {
|
||||
if (m_useHeatmap == on)
|
||||
return;
|
||||
m_useHeatmap = on;
|
||||
emit useHeatmapChanged(on);
|
||||
}
|
||||
|
||||
void AppBackend::setSensorCol(int c) {
|
||||
if (m_serial->connected()) {
|
||||
return;
|
||||
@@ -93,6 +101,13 @@ void AppBackend::setRangeMax(int v) {
|
||||
emit rangeChanged(m_rangeMin, m_rangeMax);
|
||||
}
|
||||
|
||||
void AppBackend::setColorZero(const QColor& color) {
|
||||
if (m_colorZero == color)
|
||||
return;
|
||||
m_colorZero = color;
|
||||
emit colorZeroChanged(m_colorZero);
|
||||
}
|
||||
|
||||
void AppBackend::setColorLow(const QColor& color) {
|
||||
if (m_colorLow == color)
|
||||
return;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QColor>
|
||||
#include <qcolor.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
#include "data_backend.h"
|
||||
@@ -18,12 +19,14 @@ class AppBackend : public QObject {
|
||||
Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged)
|
||||
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
|
||||
Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid NOTIFY showGridChanged);
|
||||
Q_PROPERTY(bool useHeatmap READ useHeatmap WRITE setUseHeatmap NOTIFY useHeatmapChanged);
|
||||
Q_PROPERTY(SerialBackend* serial READ serial CONSTANT)
|
||||
Q_PROPERTY(DataBackend* data READ data CONSTANT)
|
||||
Q_PROPERTY(int sensorCol READ sensorCol WRITE setSensorCol NOTIFY sensorColChanged);
|
||||
Q_PROPERTY(int sensorRow READ sensorRow WRITE setSensorRow NOTIFY sensorRowChanged);
|
||||
Q_PROPERTY(int rangeMin READ rangeMin WRITE setRangeMin NOTIFY rangeMinChanged);
|
||||
Q_PROPERTY(int rangeMax READ rangeMax WRITE setRangeMax NOTIFY rangeMaxChanged);
|
||||
Q_PROPERTY(QColor colorZero READ colorZero WRITE setColorZero NOTIFY colorZeroChanged);
|
||||
Q_PROPERTY(QColor colorLow READ colorLow WRITE setColorLow NOTIFY colorLowChanged);
|
||||
Q_PROPERTY(QColor colorMid READ colorMid WRITE setColorMid NOTIFY colorMidChanged);
|
||||
Q_PROPERTY(QColor colorHigh READ colorHigh WRITE setColorHigh NOTIFY colorHighChanged);
|
||||
@@ -43,6 +46,8 @@ public:
|
||||
|
||||
bool showGrid() const { return m_showGrid; }
|
||||
void setShowGrid(bool on);
|
||||
bool useHeatmap() const { return m_useHeatmap; }
|
||||
void setUseHeatmap(bool on);
|
||||
int sensorCol() const { qInfo() << "col:" << m_sensorCol; return m_sensorCol; }
|
||||
int sensorRow() const { qInfo() << "row:" << m_sensorRow; return m_sensorRow; }
|
||||
void setSensorRow(int r);
|
||||
@@ -51,9 +56,11 @@ public:
|
||||
int rangeMax() const { return m_rangeMax; }
|
||||
void setRangeMin(int v);
|
||||
void setRangeMax(int v);
|
||||
QColor colorZero() const { return m_colorZero; }
|
||||
QColor colorLow() const { return m_colorLow; }
|
||||
QColor colorMid() const { return m_colorMid; }
|
||||
QColor colorHigh() const { return m_colorHigh; }
|
||||
void setColorZero(const QColor& color);
|
||||
void setColorLow(const QColor& color);
|
||||
void setColorMid(const QColor& color);
|
||||
void setColorHigh(const QColor& color);
|
||||
@@ -63,11 +70,13 @@ signals:
|
||||
void languageChanged();
|
||||
void connectedChanged();
|
||||
void showGridChanged(bool on);
|
||||
void useHeatmapChanged(bool on);
|
||||
void sensorColChanged(int c);
|
||||
void sensorRowChanged(int r);
|
||||
void rangeMinChanged(int v);
|
||||
void rangeMaxChanged(int v);
|
||||
void rangeChanged(int minV, int maxV);
|
||||
void colorZeroChanged(const QColor& color);
|
||||
void colorLowChanged(const QColor& color);
|
||||
void colorMidChanged(const QColor& color);
|
||||
void colorHighChanged(const QColor& color);
|
||||
@@ -78,10 +87,12 @@ private:
|
||||
QString m_language = QStringLiteral("zh_CN");
|
||||
|
||||
bool m_showGrid = true;
|
||||
bool m_useHeatmap = false;
|
||||
int m_sensorRow = 12;
|
||||
int m_sensorCol = 7;
|
||||
int m_rangeMin = 0;
|
||||
int m_rangeMax = 1000;
|
||||
QColor m_colorZero = QColor::fromRgbF(0.10, 0.75, 1.00);
|
||||
QColor m_colorLow = QColor::fromRgbF(0.10, 0.75, 1.00);
|
||||
QColor m_colorMid = QColor::fromRgbF(0.10, 0.95, 0.35);
|
||||
QColor m_colorHigh = QColor::fromRgbF(1.00, 0.22, 0.10);
|
||||
|
||||
@@ -127,6 +127,8 @@ bool DataBackend::importXlsx(const QString& path) {
|
||||
cells[r][c] = v;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DataBackend::startPlayback(int intervalMs) {
|
||||
|
||||
@@ -5,48 +5,217 @@
|
||||
#ifndef TACTILEIPC3D_GLOBALHELPER_H
|
||||
#define TACTILEIPC3D_GLOBALHELPER_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <algorithm>
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <qset.h>
|
||||
#include <qsettings.h>
|
||||
|
||||
const QString APP_VERSION = "0.4.0";
|
||||
|
||||
class GlobalHelper {
|
||||
public:
|
||||
const std::string fuck = "fuck you lsp!!!";
|
||||
static GlobalHelper* Instance() {
|
||||
|
||||
public :
|
||||
static GlobalHelper *Instance() {
|
||||
static GlobalHelper ins;
|
||||
return &ins;
|
||||
}
|
||||
|
||||
static void transToMultiMatrix(const cv::Mat& raw_data, float min_threshold,
|
||||
float max_range, cv::Size display_res, cv::Mat& out_matrix) {
|
||||
static void transToMultiMatrix(const cv::Mat &raw_data, float min_threshold,
|
||||
float max_range, cv::Size display_res,
|
||||
cv::Mat &out_matrix) {
|
||||
CV_Assert(raw_data.type() == CV_32F);
|
||||
|
||||
const float safe_max = std::max(max_range, 1e-6f);
|
||||
const float safe_span = std::max(safe_max - min_threshold, 1e-6f);
|
||||
|
||||
cv::Mat saturate_mask_u8;
|
||||
cv::compare(raw_data, max_range, saturate_mask_u8, cv::CMP_GE);
|
||||
cv::Mat zero_mask_u8;
|
||||
cv::compare(raw_data, 0.0f, zero_mask_u8, cv::CMP_LE);
|
||||
|
||||
cv::Mat raw = raw_data.clone();
|
||||
raw.setTo(0.0f, raw < min_threshold);
|
||||
cv::min(raw, safe_max, raw);
|
||||
|
||||
double maxVal = 0.0;
|
||||
cv::minMaxLoc(raw, nullptr, &maxVal);
|
||||
if (maxVal > 0.0) {
|
||||
cv::GaussianBlur(raw, raw, cv::Size(3, 3), 0.8, 0.8, cv::BORDER_DEFAULT);
|
||||
}
|
||||
cv::Mat peak_norm = (raw - min_threshold) / safe_span;
|
||||
cv::max(peak_norm, 0.0f, peak_norm);
|
||||
cv::min(peak_norm, 1.0f, peak_norm);
|
||||
|
||||
const float safe_range = std::max(max_range, 1e-6f);
|
||||
cv::Mat norm_data = raw / safe_range;
|
||||
cv::min(norm_data, 1.0f, norm_data);
|
||||
cv::medianBlur(raw, raw, 3);
|
||||
cv::GaussianBlur(raw, raw, cv::Size(5, 5), 1.2, 1.2, cv::BORDER_DEFAULT);
|
||||
|
||||
cv::Mat norm_data = (raw - min_threshold) / safe_span;
|
||||
cv::max(norm_data, 0.0f, norm_data);
|
||||
cv::min(norm_data, 1.0f, norm_data);
|
||||
|
||||
cv::pow(norm_data, 0.7, norm_data);
|
||||
cv::pow(norm_data, 1.4, norm_data);
|
||||
|
||||
cv::Mat smoothed;
|
||||
cv::resize(norm_data, smoothed, display_res, 0.0, 0.0, cv::INTER_CUBIC);
|
||||
cv::max(smoothed, 0.0f, smoothed);
|
||||
cv::min(smoothed, 1.0f, smoothed);
|
||||
|
||||
cv::GaussianBlur(smoothed, smoothed, cv::Size(31, 31), 0.0, 0.0, cv::BORDER_DEFAULT);
|
||||
const int min_dim =
|
||||
std::max(1, std::min(display_res.width, display_res.height));
|
||||
const double sigma = std::max(1.0, 0.02 * min_dim);
|
||||
int ksize = std::max(3, (static_cast<int>(std::ceil(sigma * 6)) | 1));
|
||||
cv::GaussianBlur(smoothed, smoothed, cv::Size(ksize, ksize), sigma, sigma,
|
||||
cv::BORDER_DEFAULT);
|
||||
cv::max(smoothed, 0.0f, smoothed);
|
||||
cv::min(smoothed, 1.0f, smoothed);
|
||||
|
||||
smoothed *= safe_range;
|
||||
cv::Mat peak_resized;
|
||||
cv::resize(peak_norm, peak_resized, display_res, 0.0, 0.0,
|
||||
cv::INTER_CUBIC);
|
||||
cv::max(smoothed, peak_resized, smoothed);
|
||||
|
||||
if (!saturate_mask_u8.empty()) {
|
||||
cv::Mat mask_f;
|
||||
saturate_mask_u8.convertTo(mask_f, CV_32F, 1.0 / 255.0);
|
||||
cv::Mat mask_resized;
|
||||
cv::resize(mask_f, mask_resized, display_res, 0.0, 0.0,
|
||||
cv::INTER_CUBIC);
|
||||
// Soften the threshold to avoid blocky plateaus.
|
||||
const double mask_sigma = std::max(0.5, 0.008 * min_dim);
|
||||
int mask_ksize =
|
||||
std::max(3, (static_cast<int>(std::ceil(mask_sigma * 6)) | 1));
|
||||
cv::GaussianBlur(mask_resized, mask_resized,
|
||||
cv::Size(mask_ksize, mask_ksize), mask_sigma,
|
||||
mask_sigma, cv::BORDER_DEFAULT);
|
||||
cv::max(mask_resized, 0.0f, mask_resized);
|
||||
cv::min(mask_resized, 1.0f, mask_resized);
|
||||
smoothed = cv::max(smoothed, mask_resized);
|
||||
}
|
||||
|
||||
if (!zero_mask_u8.empty()) {
|
||||
cv::Mat zero_f;
|
||||
zero_mask_u8.convertTo(zero_f, CV_32F, 1.0 / 255.0);
|
||||
cv::Mat zero_resized;
|
||||
cv::resize(zero_f, zero_resized, display_res, 0.0, 0.0,
|
||||
cv::INTER_CUBIC);
|
||||
const double zero_sigma = std::max(0.5, 0.006 * min_dim);
|
||||
int zero_ksize =
|
||||
std::max(3, (static_cast<int>(std::ceil(zero_sigma * 6)) | 1));
|
||||
cv::GaussianBlur(zero_resized, zero_resized,
|
||||
cv::Size(zero_ksize, zero_ksize), zero_sigma,
|
||||
zero_sigma, cv::BORDER_DEFAULT);
|
||||
cv::max(zero_resized, 0.0f, zero_resized);
|
||||
cv::min(zero_resized, 1.0f, zero_resized);
|
||||
cv::Mat zero_bin;
|
||||
cv::threshold(zero_resized, zero_bin, 0.5, 255.0,
|
||||
cv::THRESH_BINARY);
|
||||
zero_bin.convertTo(zero_bin, CV_8U);
|
||||
smoothed.setTo(0.0f, zero_bin);
|
||||
}
|
||||
|
||||
smoothed *= safe_max;
|
||||
out_matrix = smoothed;
|
||||
}
|
||||
|
||||
static void SaveGridConfig(bool b) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
settings.setValue("display/grid", b);
|
||||
}
|
||||
|
||||
static void SaveAxisConfig(bool b) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
settings.setValue("display/axis", b);
|
||||
}
|
||||
|
||||
static void SaveSurfaceConfig(bool b) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
settings.setValue("display/surface", b);
|
||||
}
|
||||
|
||||
static void GetGridConfig(bool& b) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
b = settings.value("display/grid", b).toBool();
|
||||
}
|
||||
|
||||
static void GetAxisConfig(bool& b) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
b = settings.value("display/axis", b).toBool();
|
||||
}
|
||||
|
||||
static void GetSurfaceConfig(bool b) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
b = settings.value("display/surface", b).toBool();
|
||||
}
|
||||
|
||||
static void SaveLastRow(int value) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
settings.setValue("spec/row", value);
|
||||
}
|
||||
|
||||
static void GetLastRow(int& value) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
value = settings.value("spec/row", value).toInt();
|
||||
}
|
||||
|
||||
static void GetLastCol(int value) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
settings.setValue("spec/col", value);
|
||||
}
|
||||
|
||||
static void GetLastCol(int& value) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
value = settings.value("spec/col", value).toInt();
|
||||
}
|
||||
|
||||
static void SaveZeroColor(QString color) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
settings.setValue("color/zero", color);
|
||||
}
|
||||
|
||||
static void GetZeroColor(QString& color) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
color = settings.value("color/zero", color).toString();
|
||||
}
|
||||
|
||||
static void SaveLowColor(QString color) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
settings.setValue("color/low", color);
|
||||
}
|
||||
|
||||
static void GetLowColor(QString& color) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
color = settings.value("color/low", color).toString();
|
||||
}
|
||||
|
||||
static void SaveMidColor(QString color) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
settings.setValue("color/mid", color);
|
||||
}
|
||||
|
||||
static void GetMidColor(QString& color) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
color = settings.value("color/mid", color).toString();
|
||||
}
|
||||
|
||||
static void SaveHighColor(QString color) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
settings.setValue("color/high", color);
|
||||
}
|
||||
|
||||
static void GetHighColor(QString& color) {
|
||||
QSettings settings(GlobalHelper::GetConfigFilePath(), QSettings::IniFormat);
|
||||
color = settings.value("color/high", color).toString();
|
||||
}
|
||||
|
||||
static QString GetConfigFilePath() {
|
||||
return QCoreApplication::applicationDirPath() + QDir::separator() + "conf.ini";
|
||||
}
|
||||
|
||||
static QString GetAppVersion() {
|
||||
return APP_VERSION;
|
||||
}
|
||||
|
||||
private:
|
||||
GlobalHelper() {}
|
||||
GlobalHelper() {
|
||||
}
|
||||
};
|
||||
|
||||
#endif //TACTILEIPC3D_GLOBALHELPER_H
|
||||
#endif // TACTILEIPC3D_GLOBALHELPER_H
|
||||
|
||||
2827
src/glwidget.cpp
2827
src/glwidget.cpp
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,11 @@
|
||||
#include "serial_backend.h"
|
||||
|
||||
#include "piezoresistive_a_protocol.h"
|
||||
#include "serial_qt_transport.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QStringList>
|
||||
#include <QMetaObject>
|
||||
#include <QtGlobal>
|
||||
#include <qcontainerfwd.h>
|
||||
@@ -14,13 +16,20 @@ SerialBackend::SerialBackend(QObject *parent)
|
||||
: QObject(parent), m_packetQueue(2048), m_frameQueue(2048), m_readThread(&m_packetQueue), m_decodeThread(&m_packetQueue, &m_frameQueue)
|
||||
{
|
||||
m_request.dataLength = 24;
|
||||
m_spec.model = QStringLiteral("PZR-A");
|
||||
|
||||
auto codec = std::make_shared<PiezoresistiveACodec>();
|
||||
auto decoder = std::make_shared<PiezoresistiveADecoder>();
|
||||
auto format = std::make_shared<PiezoresistiveAFormat>();
|
||||
m_manager.registerProtocol(codec->name(), {codec, decoder, format});
|
||||
m_manager.setActiveProtocol(codec->name());
|
||||
const QString pluginDir = QDir(QCoreApplication::applicationDirPath())
|
||||
.filePath(QStringLiteral("plugins/decoders"));
|
||||
QStringList errors;
|
||||
const QStringList loaded = m_manager.loadPlugins(pluginDir, &errors);
|
||||
for (const QString& err : errors) {
|
||||
qWarning().noquote() << err;
|
||||
}
|
||||
if (!loaded.isEmpty()) {
|
||||
m_spec.model = m_manager.activeProtocol();
|
||||
} else {
|
||||
qWarning() << "No protocol plugins loaded.";
|
||||
m_spec.model = QStringLiteral("UNKNOWN");
|
||||
}
|
||||
|
||||
m_sendWorker = new SerialSendWorker();
|
||||
m_sendWorker->moveToThread(&m_sendThread);
|
||||
@@ -175,6 +184,10 @@ void SerialBackend::setProtocol(const QString &name)
|
||||
if (!m_manager.setActiveProtocol(name))
|
||||
return;
|
||||
updateProtocolBindings_();
|
||||
if (m_spec.model != name) {
|
||||
m_spec.model = name;
|
||||
emit sensorModelChanged();
|
||||
}
|
||||
emit protocolChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
#include "serial_manager.h"
|
||||
#include "protocol_plugin.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QPluginLoader>
|
||||
|
||||
void SerialManager::registerProtocol(const QString& name, const ProtocolBundle& bundle) {
|
||||
if (name.isEmpty())
|
||||
@@ -15,8 +19,76 @@ bool SerialManager::setActiveProtocol(const QString& name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SerialManager::ProtocolBundle SerialManager::activeBundle() const {
|
||||
ProtocolBundle SerialManager::activeBundle() const {
|
||||
if (!m_protocols.contains(m_activeName))
|
||||
return {};
|
||||
return m_protocols.value(m_activeName);
|
||||
}
|
||||
|
||||
QStringList SerialManager::loadPlugins(const QString& dirPath, QStringList* errors) {
|
||||
QStringList loaded;
|
||||
if (!m_pluginLoaders.empty()) {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
QDir dir(dirPath);
|
||||
if (!dir.exists()) {
|
||||
if (errors)
|
||||
errors->append(QStringLiteral("Plugin dir not found: %1").arg(dirPath));
|
||||
return loaded;
|
||||
}
|
||||
|
||||
QStringList filters;
|
||||
#if defined(Q_OS_WIN)
|
||||
filters << QStringLiteral("*.dll");
|
||||
#elif defined(Q_OS_MAC)
|
||||
filters << QStringLiteral("*.dylib");
|
||||
#else
|
||||
filters << QStringLiteral("*.so");
|
||||
#endif
|
||||
|
||||
const QStringList entries = dir.entryList(filters, QDir::Files);
|
||||
for (const QString& fileName : entries) {
|
||||
const QString path = dir.absoluteFilePath(fileName);
|
||||
auto loader = std::make_unique<QPluginLoader>(path);
|
||||
QObject* instance = loader->instance();
|
||||
if (!instance) {
|
||||
if (errors)
|
||||
errors->append(QStringLiteral("Load failed: %1 (%2)").arg(path, loader->errorString()));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* plugin = qobject_cast<IProtocolPlugin*>(instance);
|
||||
if (!plugin) {
|
||||
if (errors)
|
||||
errors->append(QStringLiteral("Invalid plugin: %1").arg(path));
|
||||
loader->unload();
|
||||
continue;
|
||||
}
|
||||
if (plugin->apiVersion() != kProtocolPluginApiVersion) {
|
||||
if (errors)
|
||||
errors->append(QStringLiteral("API mismatch: %1").arg(path));
|
||||
loader->unload();
|
||||
continue;
|
||||
}
|
||||
|
||||
const ProtocolBundle bundle = plugin->createBundle();
|
||||
if (!bundle.codec || !bundle.decoder || !bundle.format) {
|
||||
if (errors)
|
||||
errors->append(QStringLiteral("Missing components: %1").arg(path));
|
||||
loader->unload();
|
||||
continue;
|
||||
}
|
||||
|
||||
const QString name = plugin->protocolName();
|
||||
if (!m_protocols.contains(name)) {
|
||||
registerProtocol(name, bundle);
|
||||
loaded.append(name);
|
||||
m_pluginLoaders.push_back(std::move(loader));
|
||||
} else {
|
||||
loader->unload();
|
||||
}
|
||||
}
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
@@ -3,22 +3,18 @@
|
||||
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QPluginLoader>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "serial_codec.h"
|
||||
#include "serial_decoder.h"
|
||||
#include "serial_format.h"
|
||||
#include "protocol_bundle.h"
|
||||
|
||||
class SerialManager {
|
||||
public:
|
||||
struct ProtocolBundle {
|
||||
std::shared_ptr<ISerialCodec> codec;
|
||||
std::shared_ptr<ISerialDecoder> decoder;
|
||||
std::shared_ptr<ISerialFormat> format;
|
||||
};
|
||||
|
||||
void registerProtocol(const QString& name, const ProtocolBundle& bundle);
|
||||
bool setActiveProtocol(const QString& name);
|
||||
QStringList loadPlugins(const QString& dirPath, QStringList* errors = nullptr);
|
||||
|
||||
QString activeProtocol() const { return m_activeName; }
|
||||
ProtocolBundle activeBundle() const;
|
||||
@@ -26,6 +22,7 @@ public:
|
||||
private:
|
||||
QHash<QString, ProtocolBundle> m_protocols;
|
||||
QString m_activeName;
|
||||
std::vector<std::unique_ptr<QPluginLoader>> m_pluginLoaders;
|
||||
};
|
||||
|
||||
#endif // TACTILEIPC3D_SERIAL_MANAGER_H
|
||||
|
||||
Reference in New Issue
Block a user