save and load parametrization data

This commit is contained in:
Jussi Kuokkanen 2023-09-16 15:16:47 +03:00
parent 0ade3384d3
commit cf47eca15f
9 changed files with 107 additions and 13 deletions

View File

@ -3,6 +3,7 @@
#include <AssignableProxy.hpp>
#include <DeviceModel.hpp>
#include <DeviceModelDelegate.hpp>
#include <DynamicReadableConnectionData.hpp>
#include <functional>
#include <QDebug>
#include <QSettings>
@ -122,6 +123,12 @@ void writeAssignableDefaults(DeviceModel &model) {
}
void writeAssignableSetting(SettingsData data, AssignableSetting setting) {
qRegisterMetaType<DynamicReadableConnectionData>();
qRegisterMetaTypeStreamOperators<QVector<QPointF>>("QVector<QPointF>");
qRegisterMetaTypeStreamOperators<DynamicReadableConnectionData>(
"DynamicReadableConnectionData");
if (!data.currentProfile.has_value())
return;

View File

@ -84,7 +84,11 @@ void AssignableProxy::apply() {
auto proxy = opt.value();
m_connection = new DynamicReadableConnection<uint>{*proxy, data};
// We use this to save succeeded parametrization data
// to settings, since keeping m_value around would affect the view
m_connectionValue = m_value;
startConnection();
m_signalConnectionSuccess = true;
m_value = QVariant();
return;
}
@ -105,8 +109,13 @@ void AssignableProxy::startConnection() {
auto err = doApply(targetValue);
if (err.has_value())
emit connectionValueChanged(err.value(), text);
else
else {
emit connectionValueChanged(targetValue, text);
if (m_signalConnectionSuccess) {
emit connectionSucceeded(m_connectionValue);
m_signalConnectionSuccess = false;
}
}
});
// Emit started signal in case a connection emits a new value right away
emit connectionStarted();

View File

@ -29,14 +29,17 @@ signals:
void applied(std::optional<TC::Device::AssignmentError>);
void connectionValueChanged(
std::variant<QVariant, TC::Device::AssignmentError>, QString text);
void connectionSucceeded(QVariant);
void connectionStarted();
void connectionStopped();
private:
Q_OBJECT
QVariant m_value;
QVariant m_connectionValue;
QDBusInterface *m_iface;
DynamicReadableConnection<uint> *m_connection;
bool m_signalConnectionSuccess;
// This is a bit of a peril but not sure if we can store interfaces any better...
std::shared_ptr<AssignableConnection> m_assignableConnection;

View File

@ -147,6 +147,17 @@ QStandardItem *DeviceModel::createAssignable(
pattern(_) = [] {});
});
connect(proxy, &AssignableProxy::connectionSucceeded, [=](auto value) {
// Write successful connection value to settings
auto assSetting = AssignableSetting{
.assignablePath = proxy->dbusPath(),
.value = value,
};
auto newSettings =
Settings::setAssignableSetting(Globals::g_settingsData, assSetting);
Utils::writeAssignableSetting(newSettings, assSetting);
});
QVariant pv;
pv.setValue(proxy);
ifaceItem->setData(pv, AssignableProxyRole);

View File

@ -1,6 +1,7 @@
#pragma once
#include "AssignableConnection.hpp"
#include <DynamicReadableConnectionData.hpp>
#include <DynamicReadableProxy.hpp>
#include <fplus/fplus.hpp>
#include <patterns.hpp>
@ -17,23 +18,12 @@ using namespace fplus;
using namespace mpark::patterns;
using namespace TuxClocker::Device;
struct DynamicReadableConnectionData {
// y = f(x)
QVector<QPointF> points;
// DBus path
QString dynamicReadablePath;
RangeInfo rangeInfo;
};
enum class TargetType {
IntType,
DoubleType
};
Q_DECLARE_METATYPE(DynamicReadableConnectionData)
// TODO: make DynamicReadableProxy type parametrized so we can be sure to only get numeric values
// from it Connection of an Assignable with a DynamicReadable
// Connection of an Assignable with a DynamicReadable
template <typename OutType> // Result of linear interpolation
class DynamicReadableConnection : public AssignableConnection {
public:

View File

@ -0,0 +1,49 @@
#include "DynamicReadableConnectionData.hpp"
#include <QDataStream>
enum RangeType {
IntRange,
DoubleRange
};
QDataStream &operator<<(QDataStream &out, const TuxClocker::Device::RangeInfo &info) {
if (std::holds_alternative<TuxClocker::Device::Range<int>>(info)) {
auto intRange = std::get<TuxClocker::Device::Range<int>>(info);
out << IntRange << intRange.max << intRange.min;
return out;
}
if (std::holds_alternative<TuxClocker::Device::Range<double>>(info)) {
auto doubleRange = std::get<TuxClocker::Device::Range<double>>(info);
out << DoubleRange << doubleRange.max << doubleRange.min;
return out;
}
return out;
}
QDataStream &operator>>(QDataStream &in, TuxClocker::Device::RangeInfo &info) {
RangeType type;
in >> type;
if (type == IntRange) {
TuxClocker::Device::Range<int> intRange;
in >> intRange.max >> intRange.min;
return in;
}
if (type == DoubleRange) {
TuxClocker::Device::Range<double> doubleRange;
in >> doubleRange.max >> doubleRange.min;
return in;
}
return in;
}
QDataStream &operator<<(QDataStream &out, const DynamicReadableConnectionData &data) {
out << data.dynamicReadablePath << data.points << data.rangeInfo;
return out;
}
QDataStream &operator>>(QDataStream &in, DynamicReadableConnectionData &data) {
in >> data.dynamicReadablePath >> data.points >> data.rangeInfo;
return in;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <Device.hpp>
#include <QDataStream>
#include <QMetaType>
#include <QPointF>
#include <QString>
#include <QVector>
struct DynamicReadableConnectionData {
// y = f(x)
QVector<QPointF> points;
// DBus path
QString dynamicReadablePath;
TuxClocker::Device::RangeInfo rangeInfo;
friend QDataStream &operator<<(QDataStream &, const DynamicReadableConnectionData &);
friend QDataStream &operator>>(QDataStream &, DynamicReadableConnectionData &);
};
Q_DECLARE_METATYPE(DynamicReadableConnectionData);

View File

@ -24,6 +24,7 @@ sources = ['main.cpp',
'data/DeviceModel.cpp',
'data/DeviceModelDelegate.cpp',
'data/DeviceProxyModel.cpp',
'data/DynamicReadableConnectionData.cpp',
'data/DynamicReadableProxy.cpp',
'widgets/DeviceBrowser.cpp',
'widgets/DeviceTreeView.cpp',

View File

@ -1,5 +1,6 @@
#include "Settings.hpp"
#include <DynamicReadableConnectionData.hpp>
#include <Globals.hpp>
#include <QCheckBox>
#include <QGridLayout>
@ -174,6 +175,9 @@ QVector<AssignableSetting> Settings::readAssignableSettings(QString profile) {
SettingsData Settings::readSettings() {
qRegisterMetaTypeStreamOperators<QVector<QString>>("QVector<QString>>");
qRegisterMetaTypeStreamOperators<QVector<QPointF>>("QVector<QPointF>");
qRegisterMetaTypeStreamOperators<DynamicReadableConnectionData>(
"DynamicReadableConnectionData");
QSettings s{"tuxclocker"};
std::optional<QString> profile;