mirror of
https://github.com/Lurkki14/tuxclocker.git
synced 2025-02-25 18:55:24 -06:00
apply parametrization through AssignableProxy
Doesn't work as intended yet, see DynamicReadableConnection.cpp:44
This commit is contained in:
parent
9b22f14898
commit
407974c0b9
11
src/tuxclocker-qt/Globals.hpp
Normal file
11
src/tuxclocker-qt/Globals.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
class DeviceModel;
|
||||
|
||||
// Data that (needs) to be accessed globally, eg. main stacked widget
|
||||
namespace Globals {
|
||||
|
||||
// This is used to search nodes by their DBus path to avoid passing pointers through many levels
|
||||
extern DeviceModel *g_deviceModel;
|
||||
|
||||
} // namespace Globals
|
@ -15,6 +15,7 @@
|
||||
#include <QString>
|
||||
#include <QTreeView>
|
||||
#include <QVector>
|
||||
#include <Globals.hpp>
|
||||
#include <Tree.hpp>
|
||||
#include <Utils.hpp>
|
||||
|
||||
@ -25,6 +26,8 @@ using namespace TuxClocker;
|
||||
Q_DECLARE_METATYPE(TCDBus::DeviceNode)
|
||||
Q_DECLARE_METATYPE(TCDBus::FlatTreeNode<TCDBus::DeviceNode>)
|
||||
|
||||
DeviceModel *Globals::g_deviceModel;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
|
||||
qDBusRegisterMetaType<TCDBus::DeviceNode>();
|
||||
qDBusRegisterMetaType<TCDBus::FlatTreeNode<TCDBus::DeviceNode>>();
|
||||
@ -61,6 +64,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
|
||||
auto browser = new DeviceBrowser(*model);
|
||||
setCentralWidget(browser);
|
||||
|
||||
// TODO: make sure this is the only assignment
|
||||
Globals::g_deviceModel = model;
|
||||
|
||||
Utils::writeAssignableDefaults(*model);
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,7 @@ QVariant fromAssignmentArgument(TuxClocker::Device::AssignmentArgument arg) {
|
||||
|
||||
using ModelTraverseCallback = std::function<QModelIndex(QAbstractItemModel *, QModelIndex &, int)>;
|
||||
|
||||
void traverseModel(const ModelTraverseCallback &cb, QAbstractItemModel *model,
|
||||
QModelIndex parent = QModelIndex()) {
|
||||
void traverseModel(const ModelTraverseCallback &cb, QAbstractItemModel *model, QModelIndex parent) {
|
||||
for (int i = 0; i < model->rowCount(parent); i++) {
|
||||
// We get the next index we should traverse, and the funtion does
|
||||
// its thing with the model and index
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
namespace Utils {
|
||||
|
||||
using ModelTraverseCallback = std::function<QModelIndex(QAbstractItemModel *, QModelIndex &, int)>;
|
||||
|
||||
void traverseModel(
|
||||
const ModelTraverseCallback &, QAbstractItemModel *, QModelIndex parent = QModelIndex());
|
||||
void writeAssignableDefaults(DeviceModel &model);
|
||||
|
||||
}
|
||||
} // namespace Utils
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "AssignableProxy.hpp"
|
||||
|
||||
#include <DBusTypes.hpp>
|
||||
#include <DynamicReadableConnection.hpp>
|
||||
#include <Globals.hpp>
|
||||
#include <Utils.hpp>
|
||||
#include <QDBusReply>
|
||||
#include <QDBusMessage>
|
||||
|
||||
@ -19,6 +22,8 @@ AssignableProxy::AssignableProxy(QString path, QDBusConnection conn, QObject *pa
|
||||
qDBusRegisterMetaType<TCD::Result<QDBusVariant>>();
|
||||
m_iface =
|
||||
new QDBusInterface("org.tuxclocker", path, "org.tuxclocker.Assignable", conn, this);
|
||||
|
||||
m_connection = nullptr;
|
||||
}
|
||||
|
||||
std::optional<AssignmentError> AssignableProxy::doApply(const QVariant &v) {
|
||||
@ -34,11 +39,57 @@ std::optional<AssignmentError> AssignableProxy::doApply(const QVariant &v) {
|
||||
return AssignmentError::UnknownError;
|
||||
}
|
||||
|
||||
std::optional<DynamicReadableProxy *> fromPath(QString path) {
|
||||
DynamicReadableProxy *retval = nullptr;
|
||||
|
||||
auto cb = [&](auto model, auto index, int row) {
|
||||
auto ifaceIndex = model->index(row, DeviceModel::InterfaceColumn, index);
|
||||
auto dynProxyV = ifaceIndex.data(DeviceModel::DynamicReadableProxyRole);
|
||||
|
||||
if (dynProxyV.isValid()) {
|
||||
auto dynProxy = qvariant_cast<DynamicReadableProxy *>(dynProxyV);
|
||||
if (dynProxy->dbusPath() == path) {
|
||||
// TODO: stop recursing here
|
||||
retval = dynProxy;
|
||||
}
|
||||
}
|
||||
return model->index(row, DeviceModel::NameColumn, index);
|
||||
};
|
||||
Utils::traverseModel(cb, Globals::g_deviceModel);
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void AssignableProxy::apply() {
|
||||
// A value hasn't been set yet
|
||||
if (m_value.isNull())
|
||||
return;
|
||||
|
||||
// Stop existing parametrization
|
||||
if (m_connection) {
|
||||
disconnect(m_connection, nullptr, nullptr, nullptr);
|
||||
m_connection->stop();
|
||||
delete m_connection;
|
||||
m_connection = nullptr;
|
||||
}
|
||||
|
||||
// Parametrization
|
||||
if (m_value.canConvert<DynamicReadableConnectionData>()) {
|
||||
auto data = m_value.value<DynamicReadableConnectionData>();
|
||||
auto opt = fromPath(data.dynamicReadablePath);
|
||||
|
||||
if (opt.has_value()) {
|
||||
auto proxy = opt.value();
|
||||
m_connection = new DynamicReadableConnection<uint>{*proxy, data.points};
|
||||
|
||||
startConnection();
|
||||
m_value = QVariant();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Use QDBusVariant since otherwise tries to call with the wrong signature
|
||||
QDBusVariant dv(m_value);
|
||||
QVariant v;
|
||||
@ -48,9 +99,8 @@ void AssignableProxy::apply() {
|
||||
m_value = QVariant();
|
||||
}
|
||||
|
||||
void AssignableProxy::startConnection(std::shared_ptr<AssignableConnection> conn) {
|
||||
m_assignableConnection = conn;
|
||||
connect(conn.get(), &AssignableConnection::targetValueChanged,
|
||||
void AssignableProxy::startConnection() {
|
||||
QObject::connect(m_connection, &AssignableConnection::targetValueChanged,
|
||||
[this](auto targetValue, auto text) {
|
||||
auto err = doApply(targetValue);
|
||||
if (err.has_value())
|
||||
@ -60,7 +110,7 @@ void AssignableProxy::startConnection(std::shared_ptr<AssignableConnection> conn
|
||||
});
|
||||
// Emit started signal in case a connection emits a new value right away
|
||||
emit connectionStarted();
|
||||
m_assignableConnection->start();
|
||||
m_connection->start();
|
||||
}
|
||||
|
||||
// DBus type to the more precise C++ type
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <AssignableConnection.hpp>
|
||||
#include <Device.hpp>
|
||||
#include <DynamicReadableConnection.hpp>
|
||||
#include <memory>
|
||||
#include <QDebug>
|
||||
#include <QDBusConnection>
|
||||
@ -17,7 +18,6 @@ class AssignableProxy : public QObject {
|
||||
public:
|
||||
AssignableProxy(QString path, QDBusConnection conn, QObject *parent = nullptr);
|
||||
void apply();
|
||||
void startConnection(std::shared_ptr<AssignableConnection> conn);
|
||||
// Stop connection and clear current connection
|
||||
void stopConnection();
|
||||
void setValue(QVariant v) { m_value = v; }
|
||||
@ -34,8 +34,11 @@ private:
|
||||
|
||||
QVariant m_value;
|
||||
QDBusInterface *m_iface;
|
||||
DynamicReadableConnection<uint> *m_connection;
|
||||
|
||||
// This is a bit of a peril but not sure if we can store interfaces any better...
|
||||
std::shared_ptr<AssignableConnection> m_assignableConnection;
|
||||
|
||||
std::optional<TC::Device::AssignmentError> doApply(const QVariant &v);
|
||||
void startConnection();
|
||||
};
|
||||
|
@ -25,6 +25,8 @@ public:
|
||||
QString dynamicReadablePath;
|
||||
};
|
||||
|
||||
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
|
||||
template <typename OutType> // Result of linear interpolation
|
||||
@ -39,16 +41,7 @@ public:
|
||||
}
|
||||
virtual QVariant connectionData() override { return QVariant(); }
|
||||
virtual void start() override {
|
||||
/*QObject::connect(&m_timer, &QTimer::timeout, [this] {
|
||||
int rand = QRandomGenerator::global()->bounded(0, 10);
|
||||
|
||||
QDBusVariant arg{QVariant{rand}};
|
||||
QVariant v;
|
||||
v.setValue(arg);
|
||||
emit targetValueChanged(v, QString::number(rand));
|
||||
});
|
||||
m_timer.start(1000);*/
|
||||
|
||||
// TODO: Something goes wrong here (not always!!)
|
||||
connect(&m_proxy, &DynamicReadableProxy::valueChanged, [this](auto val) {
|
||||
match(val)(pattern(as<ReadableValue>(arg)) = [this](auto rv) {
|
||||
match(rv)(pattern(as<uint>(arg)) = [this](auto u) {
|
||||
@ -62,7 +55,7 @@ public:
|
||||
v.setValue(arg);
|
||||
emit targetValueChanged(v, "1");*/
|
||||
}
|
||||
virtual void stop() override {}
|
||||
virtual void stop() override { disconnect(&m_proxy, nullptr, nullptr, nullptr); }
|
||||
private:
|
||||
DynamicReadableProxy &m_proxy;
|
||||
QTimer m_timer;
|
||||
|
@ -32,7 +32,6 @@
|
||||
// Delet this
|
||||
namespace p = mpark::patterns;
|
||||
|
||||
Q_DECLARE_METATYPE(DynamicReadableConnectionData)
|
||||
Q_DECLARE_METATYPE(DynamicReadableProxy *)
|
||||
|
||||
// TODO: make constructor of the type data Editor a = Maybe (Range a)
|
||||
|
Loading…
Reference in New Issue
Block a user