forked from quickshell/quickshell
dbus/properties: support data transformation/validation before store
This commit is contained in:
parent
a13c9d91b5
commit
d4deb11216
2 changed files with 83 additions and 18 deletions
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
@ -43,7 +44,7 @@ public:
|
||||||
|
|
||||||
bool isValid() { return !this->error.isValid(); }
|
bool isValid() { return !this->error.isValid(); }
|
||||||
|
|
||||||
T value;
|
T value {};
|
||||||
QDBusError error;
|
QDBusError error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -137,6 +138,16 @@ private:
|
||||||
friend class DBusPropertyGroup;
|
friend class DBusPropertyGroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Default implementation with no transformation
|
||||||
|
template <typename T>
|
||||||
|
struct DBusDataTransform {
|
||||||
|
using Wire = T;
|
||||||
|
using Data = T;
|
||||||
|
|
||||||
|
static DBusResult<Data> fromWire(Wire&& wire) { return DBusResult<T>(std::move(wire)); }
|
||||||
|
static Wire toWire(const Data& value) { return value; }
|
||||||
|
};
|
||||||
|
|
||||||
namespace bindable_p {
|
namespace bindable_p {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -149,9 +160,16 @@ struct BindableParams<B<C, T, O, S>> {
|
||||||
static constexpr size_t OFFSET = O;
|
static constexpr size_t OFFSET = O;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Bindable>
|
||||||
|
struct BindableType {
|
||||||
|
using Meta = BindableParams<Bindable>;
|
||||||
|
using Type = Meta::Type;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace bindable_p
|
} // namespace bindable_p
|
||||||
|
|
||||||
template <
|
template <
|
||||||
|
typename T,
|
||||||
auto offset,
|
auto offset,
|
||||||
auto bindablePtr,
|
auto bindablePtr,
|
||||||
auto updatedPtr,
|
auto updatedPtr,
|
||||||
|
@ -160,10 +178,13 @@ template <
|
||||||
bool required>
|
bool required>
|
||||||
class DBusBindableProperty: public DBusPropertyCore {
|
class DBusBindableProperty: public DBusPropertyCore {
|
||||||
using PtrMeta = MemberPointerTraits<decltype(bindablePtr)>;
|
using PtrMeta = MemberPointerTraits<decltype(bindablePtr)>;
|
||||||
using Bindable = PtrMeta::Type;
|
|
||||||
using Owner = PtrMeta::Class;
|
using Owner = PtrMeta::Class;
|
||||||
using BindableMeta = bindable_p::BindableParams<Bindable>;
|
using Bindable = PtrMeta::Type;
|
||||||
using DataType = BindableMeta::Type;
|
using BindableType = bindable_p::BindableType<Bindable>::Type;
|
||||||
|
using BaseType = std::conditional_t<std::is_void_v<T>, BindableType, T>;
|
||||||
|
using Transform = DBusDataTransform<BaseType>;
|
||||||
|
using DataType = Transform::Data;
|
||||||
|
using WireType = Transform::Wire;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DBusBindableProperty() { this->group()->attachProperty(this); }
|
explicit DBusBindableProperty() { this->group()->attachProperty(this); }
|
||||||
|
@ -183,20 +204,33 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QDBusError store(const QVariant& variant) override {
|
QDBusError store(const QVariant& variant) override {
|
||||||
auto result = demarshallVariant<DataType>(variant);
|
DBusResult<DataType> result;
|
||||||
|
|
||||||
if (result.isValid()) {
|
if constexpr (std::is_same_v<WireType, BaseType>) {
|
||||||
this->bindable()->setValue(std::move(result.value));
|
result = demarshallVariant<DataType>(variant);
|
||||||
|
} else {
|
||||||
if constexpr (updatedPtr != nullptr) {
|
auto wireResult = demarshallVariant<WireType>(variant);
|
||||||
(this->owner()->*updatedPtr)();
|
if (!wireResult.isValid()) return wireResult.error;
|
||||||
}
|
result = Transform::fromWire(std::move(wireResult.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.error;
|
if (!result.isValid()) return result.error;
|
||||||
|
this->bindable()->setValue(std::move(result.value));
|
||||||
|
|
||||||
|
if constexpr (updatedPtr != nullptr) {
|
||||||
|
(this->owner()->*updatedPtr)();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QDBusError();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant serialize() override { return QVariant::fromValue(this->bindable()->value()); }
|
QVariant serialize() override {
|
||||||
|
if constexpr (std::is_same_v<WireType, BaseType>) {
|
||||||
|
return QVariant::fromValue(this->bindable()->value());
|
||||||
|
} else {
|
||||||
|
return QVariant::fromValue(Transform::toWire(this->bindable()->value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] constexpr Owner* owner() const {
|
[[nodiscard]] constexpr Owner* owner() const {
|
||||||
|
@ -308,10 +342,20 @@ private:
|
||||||
// NOLINTBEGIN
|
// NOLINTBEGIN
|
||||||
#define QS_DBUS_BINDABLE_PROPERTY_GROUP(Class, name) qs::dbus::DBusPropertyGroup name {this};
|
#define QS_DBUS_BINDABLE_PROPERTY_GROUP(Class, name) qs::dbus::DBusPropertyGroup name {this};
|
||||||
|
|
||||||
#define QS_DBUS_PROPERTY_BINDING_P(Class, property, bindable, updated, group, name, required) \
|
#define QS_DBUS_PROPERTY_BINDING_P( \
|
||||||
|
Class, \
|
||||||
|
Type, \
|
||||||
|
property, \
|
||||||
|
bindable, \
|
||||||
|
updated, \
|
||||||
|
group, \
|
||||||
|
name, \
|
||||||
|
required \
|
||||||
|
) \
|
||||||
static constexpr size_t _qs_property_##property##_offset() { return offsetof(Class, property); } \
|
static constexpr size_t _qs_property_##property##_offset() { return offsetof(Class, property); } \
|
||||||
\
|
\
|
||||||
qs::dbus::DBusBindableProperty< \
|
qs::dbus::DBusBindableProperty< \
|
||||||
|
Type, \
|
||||||
&Class::_qs_property_##property##_offset, \
|
&Class::_qs_property_##property##_offset, \
|
||||||
&Class::bindable, \
|
&Class::bindable, \
|
||||||
updated, \
|
updated, \
|
||||||
|
@ -320,11 +364,32 @@ private:
|
||||||
required> \
|
required> \
|
||||||
property;
|
property;
|
||||||
|
|
||||||
#define QS_DBUS_PROPERTY_BINDING_7(Class, property, bindable, updated, group, name, required) \
|
#define QS_DBUS_PROPERTY_BINDING_8( \
|
||||||
QS_DBUS_PROPERTY_BINDING_P(Class, property, bindable, &Class::updated, group, name, required)
|
Class, \
|
||||||
|
Type, \
|
||||||
|
property, \
|
||||||
|
bindable, \
|
||||||
|
updated, \
|
||||||
|
group, \
|
||||||
|
name, \
|
||||||
|
required \
|
||||||
|
) \
|
||||||
|
QS_DBUS_PROPERTY_BINDING_P( \
|
||||||
|
Class, \
|
||||||
|
Type, \
|
||||||
|
property, \
|
||||||
|
bindable, \
|
||||||
|
&Class::updated, \
|
||||||
|
group, \
|
||||||
|
name, \
|
||||||
|
required \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define QS_DBUS_PROPERTY_BINDING_7(Class, Type, property, bindable, group, name, required) \
|
||||||
|
QS_DBUS_PROPERTY_BINDING_P(Class, Type, property, bindable, nullptr, group, name, required)
|
||||||
|
|
||||||
#define QS_DBUS_PROPERTY_BINDING_6(Class, property, bindable, group, name, required) \
|
#define QS_DBUS_PROPERTY_BINDING_6(Class, property, bindable, group, name, required) \
|
||||||
QS_DBUS_PROPERTY_BINDING_P(Class, property, bindable, nullptr, group, name, required)
|
QS_DBUS_PROPERTY_BINDING_7(Class, void, property, bindable, group, name, required)
|
||||||
|
|
||||||
#define QS_DBUS_PROPERTY_BINDING_5(Class, property, bindable, group, name) \
|
#define QS_DBUS_PROPERTY_BINDING_5(Class, property, bindable, group, name) \
|
||||||
QS_DBUS_PROPERTY_BINDING_6(Class, property, bindable, group, name, true)
|
QS_DBUS_PROPERTY_BINDING_6(Class, property, bindable, group, name, true)
|
||||||
|
|
|
@ -457,7 +457,7 @@ private:
|
||||||
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pCanSeek, bpCanSeek, playerProperties, "CanSeek");
|
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pCanSeek, bpCanSeek, playerProperties, "CanSeek");
|
||||||
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pCanGoNext, bpCanGoNext, playerProperties, "CanGoNext");
|
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pCanGoNext, bpCanGoNext, playerProperties, "CanGoNext");
|
||||||
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pCanGoPrevious, bpCanGoPrevious, playerProperties, "CanGoPrevious");
|
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pCanGoPrevious, bpCanGoPrevious, playerProperties, "CanGoPrevious");
|
||||||
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pPosition, bpPosition, onPositionUpdated, playerProperties, "Position", false);
|
QS_DBUS_PROPERTY_BINDING(MprisPlayer, qlonglong, pPosition, bpPosition, onPositionUpdated, playerProperties, "Position", false);
|
||||||
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pVolume, bVolume, playerProperties, "Volume", false);
|
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pVolume, bVolume, playerProperties, "Volume", false);
|
||||||
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pMetadata, bpMetadata, playerProperties, "Metadata");
|
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pMetadata, bpMetadata, playerProperties, "Metadata");
|
||||||
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pPlaybackStatus, bpPlaybackStatus, playerProperties, "PlaybackStatus");
|
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pPlaybackStatus, bpPlaybackStatus, playerProperties, "PlaybackStatus");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue