mirror of
https://github.com/Lurkki14/tuxclocker.git
synced 2024-11-21 15:57:25 -06:00
parametrize correctly with all types
This commit is contained in:
parent
5dbcc23323
commit
f9a660afee
@ -82,7 +82,7 @@ void AssignableProxy::apply() {
|
||||
|
||||
if (opt.has_value()) {
|
||||
auto proxy = opt.value();
|
||||
m_connection = new DynamicReadableConnection<uint>{*proxy, data.points};
|
||||
m_connection = new DynamicReadableConnection<uint>{*proxy, data};
|
||||
|
||||
startConnection();
|
||||
m_value = QVariant();
|
||||
|
@ -17,12 +17,17 @@ using namespace fplus;
|
||||
using namespace mpark::patterns;
|
||||
using namespace TuxClocker::Device;
|
||||
|
||||
class DynamicReadableConnectionData {
|
||||
public:
|
||||
struct DynamicReadableConnectionData {
|
||||
// y = f(x)
|
||||
QVector<QPointF> points;
|
||||
// DBus path
|
||||
QString dynamicReadablePath;
|
||||
RangeInfo rangeInfo;
|
||||
};
|
||||
|
||||
enum class TargetType {
|
||||
IntType,
|
||||
DoubleType
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(DynamicReadableConnectionData)
|
||||
@ -32,9 +37,14 @@ Q_DECLARE_METATYPE(DynamicReadableConnectionData)
|
||||
template <typename OutType> // Result of linear interpolation
|
||||
class DynamicReadableConnection : public AssignableConnection {
|
||||
public:
|
||||
DynamicReadableConnection(
|
||||
DynamicReadableProxy &proxy, QVector<QPointF> points, QObject *parent = nullptr)
|
||||
: AssignableConnection(parent), m_proxy(proxy), m_points(points) {
|
||||
DynamicReadableConnection(DynamicReadableProxy &proxy, DynamicReadableConnectionData data,
|
||||
QObject *parent = nullptr)
|
||||
: AssignableConnection(parent), m_proxy(proxy), m_points(data.points) {
|
||||
if (std::holds_alternative<Range<int>>(data.rangeInfo))
|
||||
m_targetType = TargetType::IntType;
|
||||
else
|
||||
m_targetType = TargetType::DoubleType;
|
||||
|
||||
auto sorted = sort_by(
|
||||
[](auto point_l, auto point_r) { return point_l.x() < point_r.x(); }, m_points);
|
||||
m_points = sorted;
|
||||
@ -43,23 +53,42 @@ public:
|
||||
virtual void start() override {
|
||||
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) {
|
||||
emitTargetValue(u);
|
||||
});
|
||||
match(rv)(
|
||||
pattern(as<uint>(arg)) = [this](auto u) { emitTargetValue(u); },
|
||||
pattern(as<int>(arg)) = [this](int i) { emitTargetValue(i); },
|
||||
pattern(as<double>(arg)) = [this](
|
||||
auto d) { emitTargetValue(d); });
|
||||
});
|
||||
});
|
||||
}
|
||||
virtual void stop() override { disconnect(&m_proxy, nullptr, nullptr, nullptr); }
|
||||
private:
|
||||
TargetType m_targetType;
|
||||
DynamicReadableProxy &m_proxy;
|
||||
QTimer m_timer;
|
||||
QVector<QPointF> m_points;
|
||||
|
||||
template <typename T> void doEmit(T targetValue) {
|
||||
template <typename T> void doEmit(T targetValue, QString targetText) {
|
||||
QDBusVariant arg{QVariant{targetValue}};
|
||||
QVariant v;
|
||||
v.setValue(arg);
|
||||
emit targetValueChanged(v, QString::number(targetValue));
|
||||
emit targetValueChanged(v, targetText);
|
||||
}
|
||||
|
||||
template <typename T> void emitWithType(T value) {
|
||||
switch (m_targetType) {
|
||||
case TargetType::IntType: {
|
||||
int target = static_cast<int>(value);
|
||||
doEmit(target, QString::number(target));
|
||||
return;
|
||||
}
|
||||
case TargetType::DoubleType: {
|
||||
auto target = static_cast<double>(value);
|
||||
// TODO: don't hardcode precision in different places
|
||||
doEmit(target, QString::number(target, 'f', 2));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U> void emitTargetValue(U reading) {
|
||||
@ -72,15 +101,18 @@ private:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Reading wasn't between points
|
||||
if (reading > m_points.last().y()) {
|
||||
// Use y of rightmost point
|
||||
doEmit((uint) qRound(m_points.last().y()));
|
||||
return;
|
||||
} else if (reading < m_points.last().y()) {
|
||||
// Leftmost
|
||||
doEmit((uint) qRound(m_points.first().y()));
|
||||
return;
|
||||
|
||||
if (!leftIndex.has_value()) {
|
||||
// Reading wasn't between points
|
||||
if (reading > m_points.last().y()) {
|
||||
// Use y of rightmost point
|
||||
emitWithType(m_points.last().y());
|
||||
return;
|
||||
} else if (reading < m_points.last().y()) {
|
||||
// Leftmost
|
||||
emitWithType(m_points.last().y());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (leftIndex == std::nullopt) {
|
||||
@ -93,8 +125,9 @@ private:
|
||||
double dx = m_points[li + 1].x() - m_points[li].x();
|
||||
double dvx = reading - m_points[li].x();
|
||||
double p = dvx / dx;
|
||||
OutType interp_y = lerp(m_points[li].y(), m_points[li + 1].y(), p);
|
||||
doEmit(interp_y);
|
||||
U interp_y = lerp(m_points[li].y(), m_points[li + 1].y(), p);
|
||||
|
||||
emitWithType(interp_y);
|
||||
}
|
||||
|
||||
template <typename T> T lerp(T a, T b, double t) { return a + (t * (b - a)); }
|
||||
|
@ -100,6 +100,7 @@ public:
|
||||
auto data = DynamicReadableConnectionData{
|
||||
.points = points,
|
||||
.dynamicReadablePath = proxy->dbusPath(),
|
||||
.rangeInfo = m_rangeInfo,
|
||||
};
|
||||
emit connectionDataChanged(data);
|
||||
this->close();
|
||||
@ -133,6 +134,7 @@ public:
|
||||
[this](auto ir) { m_dragView->setRange(0, 100, ir.min, ir.max); });
|
||||
|
||||
m_applyButton->setToolTip(disabledReason());
|
||||
m_rangeInfo = rangeInfo;
|
||||
}
|
||||
void setAssignableName(QString name) {
|
||||
m_dependableLabel->setText(QString{"Connecting %1 with:"}.arg(name));
|
||||
@ -147,6 +149,7 @@ signals:
|
||||
private:
|
||||
Q_OBJECT
|
||||
|
||||
RangeInfo m_rangeInfo;
|
||||
DeviceModel &m_model;
|
||||
DeviceProxyModel m_proxyModel;
|
||||
DragChartView *m_dragView;
|
||||
|
Loading…
Reference in New Issue
Block a user