Add fetching the current value of an Assignable to the interface

This commit is contained in:
Jussi Kuokkanen 2022-04-17 16:27:42 +03:00
parent b82b9263df
commit e0d3ac4191
5 changed files with 69 additions and 8 deletions

View File

@ -44,17 +44,22 @@ using AssignableInfo = std::variant<RangeInfo, std::vector<Enumeration>>;
class Assignable { class Assignable {
public: public:
Assignable(const std::function<std::optional<AssignmentError>(AssignmentArgument)> assignmentFunc, Assignable(const std::function<std::optional<AssignmentError>(AssignmentArgument)> assignmentFunc,
AssignableInfo info) { AssignableInfo info,
const std::function<std::optional<AssignmentArgument>()> currentValueFunc) {
m_assignmentFunc = assignmentFunc; m_assignmentFunc = assignmentFunc;
m_assignableInfo = info; m_assignableInfo = info;
m_currentValueFunc = currentValueFunc;
} }
std::optional<AssignmentError> assign(AssignmentArgument arg) { std::optional<AssignmentError> assign(AssignmentArgument arg) {
return m_assignmentFunc(arg); return m_assignmentFunc(arg);
} }
// What the Assignable is currently set to
std::optional<AssignmentArgument> currentValue() {return m_currentValueFunc();}
AssignableInfo assignableInfo() {return m_assignableInfo;} AssignableInfo assignableInfo() {return m_assignableInfo;}
private: private:
AssignableInfo m_assignableInfo; AssignableInfo m_assignableInfo;
std::function<std::optional<AssignmentError>(AssignmentArgument)> m_assignmentFunc; std::function<std::optional<AssignmentError>(AssignmentArgument)> m_assignmentFunc;
std::function<std::optional<AssignmentArgument>()> m_currentValueFunc;
}; };
class DynamicReadable { class DynamicReadable {
@ -88,6 +93,14 @@ private:
std::optional<std::string> m_unit; std::optional<std::string> m_unit;
}; };
// Either a function to reset an Assignable or its default value
using ResetInfo = std::variant<std::function<void()>, AssignmentArgument>;
class Resettable {
private:
};
/* DeviceNode has a name, and optionally implements one of /* DeviceNode has a name, and optionally implements one of
[Assignable, DynamicReadable, StaticReadable] */ [Assignable, DynamicReadable, StaticReadable] */
using DeviceInterface = std::variant<Assignable, DynamicReadable, StaticReadable>; using DeviceInterface = std::variant<Assignable, DynamicReadable, StaticReadable>;

View File

@ -13,7 +13,7 @@ std::string Plugin::pluginPath() {
std::optional<std::vector<boost::shared_ptr<DevicePlugin>>> DevicePlugin::loadPlugins() { std::optional<std::vector<boost::shared_ptr<DevicePlugin>>> DevicePlugin::loadPlugins() {
std::vector<boost::shared_ptr<DevicePlugin>> retval; std::vector<boost::shared_ptr<DevicePlugin>> retval;
//std::cout << pluginPath();
for (const fs::directory_entry &entry : fs::directory_iterator(Plugin::pluginPath())) { for (const fs::directory_entry &entry : fs::directory_iterator(Plugin::pluginPath())) {
// Bleh, have to catch this unless I do more manual checks // Bleh, have to catch this unless I do more manual checks
try { try {

View File

@ -89,6 +89,7 @@ struct UnspecializedAssignable {
// Method to get the AssignableInfo since they differ per GPU. // Method to get the AssignableInfo since they differ per GPU.
std::function<std::optional<AssignableInfo>(T)> assignableInfo; std::function<std::optional<AssignableInfo>(T)> assignableInfo;
std::function<std::optional<AssignmentError>(T, AssignableInfo, AssignmentArgument)> func; std::function<std::optional<AssignmentError>(T, AssignableInfo, AssignmentArgument)> func;
std::function<std::optional<AssignmentArgument>(T)> currentValueFunc;
std::optional<std::string> unit; std::optional<std::string> unit;
std::string nodeName; std::string nodeName;
std::function<std::string(std::string, T)> hash; std::function<std::string(std::string, T)> hash;
@ -99,9 +100,14 @@ struct UnspecializedAssignable {
std::vector<DeviceNode> retval; std::vector<DeviceNode> retval;
for (auto &rawNode : rawNodes) { for (auto &rawNode : rawNodes) {
if_let(pattern(some(arg)) = rawNode.assignableInfo(devData)) = [&](auto info) { if_let(pattern(some(arg)) = rawNode.assignableInfo(devData)) = [&](auto info) {
// Create an individual Assignable from a generalized Assignable
auto assignable = Assignable([=](auto arg) { auto assignable = Assignable([=](auto arg) {
return rawNode.func(devData, info, arg); return rawNode.func(devData, info, arg);
}, info); },
info,
[=]() {
return rawNode.currentValueFunc(devData);
});
auto node = DeviceNode { auto node = DeviceNode {
.name = rawNode.nodeName, .name = rawNode.nodeName,
.interface = assignable, .interface = assignable,
@ -412,6 +418,12 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
}; };
return retval; return retval;
}, },
[](nvmlDevice_t dev) -> AssignmentArgument {
uint limit = 0;
nvmlDeviceGetPowerManagementLimit(dev, &limit);
// In correspondace with Range<double>
return static_cast<double>(limit) / 1000;
},
"W", "W",
"Power Limit", "Power Limit",
[](std::string uuid, nvmlDevice_t) { [](std::string uuid, nvmlDevice_t) {
@ -424,7 +436,7 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
uint maxState; uint maxState;
uint index; uint index;
}; };
/*
std::vector<UnspecializedAssignable<NVClockInfo>> rawNVCTRLClockAssignables = { std::vector<UnspecializedAssignable<NVClockInfo>> rawNVCTRLClockAssignables = {
{ {
[=](NVClockInfo info) -> std::optional<AssignableInfo> { [=](NVClockInfo info) -> std::optional<AssignableInfo> {
@ -501,6 +513,7 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
} }
} }
}; };
*/
struct NVMLFanInfo { struct NVMLFanInfo {
nvmlDevice_t dev; nvmlDevice_t dev;
@ -571,7 +584,7 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
int fanIndex; int fanIndex;
}; };
std::vector<UnspecializedAssignable<NVCtrlFanInfo>> rawNVCTRLFanAssignables = { /*std::vector<UnspecializedAssignable<NVCtrlFanInfo>> rawNVCTRLFanAssignables = {
{ {
[=](NVCtrlFanInfo info) -> std::optional<AssignableInfo> { [=](NVCtrlFanInfo info) -> std::optional<AssignableInfo> {
NVCTRLAttributeValidValuesRec values; NVCTRLAttributeValidValuesRec values;
@ -602,7 +615,7 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
return md5(uuid + "Fan Speed Write" + std::to_string(info.fanIndex)); return md5(uuid + "Fan Speed Write" + std::to_string(info.fanIndex));
} }
} }
}; };*/
struct NvidiaGPUDataOpt { struct NvidiaGPUDataOpt {
std::string uuid; std::string uuid;
@ -744,7 +757,7 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
gpuRoot.appendChild(node); gpuRoot.appendChild(node);
auto clockInfo = NVClockInfo{nvctrlPerfModes(index), index}; auto clockInfo = NVClockInfo{nvctrlPerfModes(index), index};
for (auto &node : UnspecializedAssignable<NVClockInfo>::toDeviceNodes( /*for (auto &node : UnspecializedAssignable<NVClockInfo>::toDeviceNodes(
rawNVCTRLClockAssignables, clockInfo, nvOpt.uuid)) rawNVCTRLClockAssignables, clockInfo, nvOpt.uuid))
gpuRoot.appendChild(node); gpuRoot.appendChild(node);
@ -757,7 +770,7 @@ NvidiaPlugin::NvidiaPlugin() : m_dpy() {
for (auto &node : UnspecializedAssignable<NVCtrlFanInfo>::toDeviceNodes( for (auto &node : UnspecializedAssignable<NVCtrlFanInfo>::toDeviceNodes(
rawNVCTRLFanAssignables, info, nvOpt.uuid)) rawNVCTRLFanAssignables, info, nvOpt.uuid))
nvctrlFanNodes.push_back(node); nvctrlFanNodes.push_back(node);
} }*/
for (auto &node : UnspecializedReadable<uint>::toDeviceNodes( for (auto &node : UnspecializedReadable<uint>::toDeviceNodes(
rawNVCTRLUtilNodes, index, nvOpt.uuid)) rawNVCTRLUtilNodes, index, nvOpt.uuid))
utilRoot.appendChild(node); utilRoot.appendChild(node);

View File

@ -74,6 +74,8 @@ private:
Q_DECLARE_METATYPE(TCDBus::Range) Q_DECLARE_METATYPE(TCDBus::Range)
Q_DECLARE_METATYPE(TCDBus::Enumeration) Q_DECLARE_METATYPE(TCDBus::Enumeration)
Q_DECLARE_METATYPE(TCDBus::Result<int>) Q_DECLARE_METATYPE(TCDBus::Result<int>)
Q_DECLARE_METATYPE(TCDBus::Result<double>)
Q_DECLARE_METATYPE(TCDBus::Result<uint>)
class AssignableAdaptor : public QDBusAbstractAdaptor { class AssignableAdaptor : public QDBusAbstractAdaptor {
public: public:
@ -83,6 +85,8 @@ public:
qDBusRegisterMetaType<TCDBus::Enumeration>(); qDBusRegisterMetaType<TCDBus::Enumeration>();
qDBusRegisterMetaType<QVector<TCDBus::Enumeration>>(); qDBusRegisterMetaType<QVector<TCDBus::Enumeration>>();
qDBusRegisterMetaType<TCDBus::Result<int>>(); qDBusRegisterMetaType<TCDBus::Result<int>>();
qDBusRegisterMetaType<TCDBus::Result<double>>();
qDBusRegisterMetaType<TCDBus::Result<uint>>();
QVariant a_info; QVariant a_info;
// Unwrap AssignableInfo :( // Unwrap AssignableInfo :(
match(a.assignableInfo()) match(a.assignableInfo())
@ -115,6 +119,36 @@ public:
QDBusVariant assignableInfo_() {return m_dbusAssignableInfo;} QDBusVariant assignableInfo_() {return m_dbusAssignableInfo;}
//QString unit_() {return m_assignable.uni} //QString unit_() {return m_assignable.uni}
public Q_SLOTS: public Q_SLOTS:
QDBusVariant currentValue() {
QDBusVariant retval;
// Indicate error by default
TCDBus::Result<int> defResult {
.error = true,
.value = 0
};
QVariant result;
result.setValue(defResult);
match(m_assignable.currentValue())
(pattern(some(arg)) = [&](auto aa) {
match(aa)
(pattern(as<double>(arg)) = [&](auto d) {
TCDBus::Result<double> r{false, d};
result.setValue(r);
},
pattern(as<int>(arg)) = [&](auto i) {
TCDBus::Result<int> r{false, i};
result.setValue(r);
},
pattern(as<uint>(arg)) = [&](auto u) {
TCDBus::Result<uint> r{false, u};
result.setValue(r);
}
);
}
);
retval.setVariant(result);
return retval;
}
TCDBus::Result<int> assign(QDBusVariant arg_) { TCDBus::Result<int> assign(QDBusVariant arg_) {
auto v = arg_.variant(); auto v = arg_.variant();

View File

@ -87,6 +87,7 @@ int main(int argc, char **argv) {
if (!connection.registerService("org.tuxclocker")) { if (!connection.registerService("org.tuxclocker")) {
qDebug() << "unable to register:" << connection.lastError().message(); qDebug() << "unable to register:" << connection.lastError().message();
qDebug() << "errcode" << connection.lastError().type();
} }
return a.exec(); return a.exec();