diff --git a/src/tuxclocker-qt/Utils.cpp b/src/tuxclocker-qt/Utils.cpp index fce7bea..81e23b3 100644 --- a/src/tuxclocker-qt/Utils.cpp +++ b/src/tuxclocker-qt/Utils.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -122,6 +123,12 @@ void writeAssignableDefaults(DeviceModel &model) { } void writeAssignableSetting(SettingsData data, AssignableSetting setting) { + qRegisterMetaType(); + + qRegisterMetaTypeStreamOperators>("QVector"); + qRegisterMetaTypeStreamOperators( + "DynamicReadableConnectionData"); + if (!data.currentProfile.has_value()) return; diff --git a/src/tuxclocker-qt/data/AssignableProxy.cpp b/src/tuxclocker-qt/data/AssignableProxy.cpp index 24ac506..1145189 100644 --- a/src/tuxclocker-qt/data/AssignableProxy.cpp +++ b/src/tuxclocker-qt/data/AssignableProxy.cpp @@ -84,7 +84,11 @@ void AssignableProxy::apply() { auto proxy = opt.value(); m_connection = new DynamicReadableConnection{*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(); diff --git a/src/tuxclocker-qt/data/AssignableProxy.hpp b/src/tuxclocker-qt/data/AssignableProxy.hpp index 53b087f..e508826 100644 --- a/src/tuxclocker-qt/data/AssignableProxy.hpp +++ b/src/tuxclocker-qt/data/AssignableProxy.hpp @@ -29,14 +29,17 @@ signals: void applied(std::optional); void connectionValueChanged( std::variant, QString text); + void connectionSucceeded(QVariant); void connectionStarted(); void connectionStopped(); private: Q_OBJECT QVariant m_value; + QVariant m_connectionValue; QDBusInterface *m_iface; DynamicReadableConnection *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 m_assignableConnection; diff --git a/src/tuxclocker-qt/data/DeviceModel.cpp b/src/tuxclocker-qt/data/DeviceModel.cpp index 8ef5d56..0cdbeda 100644 --- a/src/tuxclocker-qt/data/DeviceModel.cpp +++ b/src/tuxclocker-qt/data/DeviceModel.cpp @@ -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); diff --git a/src/tuxclocker-qt/data/DynamicReadableConnection.hpp b/src/tuxclocker-qt/data/DynamicReadableConnection.hpp index 5751c2d..c6261d8 100644 --- a/src/tuxclocker-qt/data/DynamicReadableConnection.hpp +++ b/src/tuxclocker-qt/data/DynamicReadableConnection.hpp @@ -1,6 +1,7 @@ #pragma once #include "AssignableConnection.hpp" +#include #include #include #include @@ -17,23 +18,12 @@ using namespace fplus; using namespace mpark::patterns; using namespace TuxClocker::Device; -struct DynamicReadableConnectionData { - // y = f(x) - QVector 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 // Result of linear interpolation class DynamicReadableConnection : public AssignableConnection { public: diff --git a/src/tuxclocker-qt/data/DynamicReadableConnectionData.cpp b/src/tuxclocker-qt/data/DynamicReadableConnectionData.cpp new file mode 100644 index 0000000..3f65183 --- /dev/null +++ b/src/tuxclocker-qt/data/DynamicReadableConnectionData.cpp @@ -0,0 +1,49 @@ +#include "DynamicReadableConnectionData.hpp" + +#include + +enum RangeType { + IntRange, + DoubleRange +}; + +QDataStream &operator<<(QDataStream &out, const TuxClocker::Device::RangeInfo &info) { + if (std::holds_alternative>(info)) { + auto intRange = std::get>(info); + out << IntRange << intRange.max << intRange.min; + return out; + } + + if (std::holds_alternative>(info)) { + auto doubleRange = std::get>(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 intRange; + in >> intRange.max >> intRange.min; + return in; + } + + if (type == DoubleRange) { + TuxClocker::Device::Range 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; +} diff --git a/src/tuxclocker-qt/data/DynamicReadableConnectionData.hpp b/src/tuxclocker-qt/data/DynamicReadableConnectionData.hpp new file mode 100644 index 0000000..de23e2e --- /dev/null +++ b/src/tuxclocker-qt/data/DynamicReadableConnectionData.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +struct DynamicReadableConnectionData { + // y = f(x) + QVector points; + // DBus path + QString dynamicReadablePath; + TuxClocker::Device::RangeInfo rangeInfo; + + friend QDataStream &operator<<(QDataStream &, const DynamicReadableConnectionData &); + friend QDataStream &operator>>(QDataStream &, DynamicReadableConnectionData &); +}; +Q_DECLARE_METATYPE(DynamicReadableConnectionData); diff --git a/src/tuxclocker-qt/meson.build b/src/tuxclocker-qt/meson.build index 9dee418..71274dd 100644 --- a/src/tuxclocker-qt/meson.build +++ b/src/tuxclocker-qt/meson.build @@ -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', diff --git a/src/tuxclocker-qt/widgets/Settings.cpp b/src/tuxclocker-qt/widgets/Settings.cpp index 301ec20..f8bc168 100644 --- a/src/tuxclocker-qt/widgets/Settings.cpp +++ b/src/tuxclocker-qt/widgets/Settings.cpp @@ -1,5 +1,6 @@ #include "Settings.hpp" +#include #include #include #include @@ -174,6 +175,9 @@ QVector Settings::readAssignableSettings(QString profile) { SettingsData Settings::readSettings() { qRegisterMetaTypeStreamOperators>("QVector>"); + qRegisterMetaTypeStreamOperators>("QVector"); + qRegisterMetaTypeStreamOperators( + "DynamicReadableConnectionData"); QSettings s{"tuxclocker"}; std::optional profile;