Skip to content

Commit d4deb11

Browse files
committed
dbus/properties: support data transformation/validation before store
1 parent a13c9d9 commit d4deb11

File tree

2 files changed

+82
-17
lines changed

2 files changed

+82
-17
lines changed

src/dbus/properties.hpp

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <functional>
4+
#include <type_traits>
45
#include <utility>
56

67
#include <bit>
@@ -43,7 +44,7 @@ class DBusResult {
4344

4445
bool isValid() { return !this->error.isValid(); }
4546

46-
T value;
47+
T value {};
4748
QDBusError error;
4849
};
4950

@@ -137,6 +138,16 @@ public slots:
137138
friend class DBusPropertyGroup;
138139
};
139140

141+
// Default implementation with no transformation
142+
template <typename T>
143+
struct DBusDataTransform {
144+
using Wire = T;
145+
using Data = T;
146+
147+
static DBusResult<Data> fromWire(Wire&& wire) { return DBusResult<T>(std::move(wire)); }
148+
static Wire toWire(const Data& value) { return value; }
149+
};
150+
140151
namespace bindable_p {
141152

142153
template <typename T>
@@ -149,9 +160,16 @@ struct BindableParams<B<C, T, O, S>> {
149160
static constexpr size_t OFFSET = O;
150161
};
151162

163+
template <typename Bindable>
164+
struct BindableType {
165+
using Meta = BindableParams<Bindable>;
166+
using Type = Meta::Type;
167+
};
168+
152169
} // namespace bindable_p
153170

154171
template <
172+
typename T,
155173
auto offset,
156174
auto bindablePtr,
157175
auto updatedPtr,
@@ -160,10 +178,13 @@ template <
160178
bool required>
161179
class DBusBindableProperty: public DBusPropertyCore {
162180
using PtrMeta = MemberPointerTraits<decltype(bindablePtr)>;
163-
using Bindable = PtrMeta::Type;
164181
using Owner = PtrMeta::Class;
165-
using BindableMeta = bindable_p::BindableParams<Bindable>;
166-
using DataType = BindableMeta::Type;
182+
using Bindable = PtrMeta::Type;
183+
using BindableType = bindable_p::BindableType<Bindable>::Type;
184+
using BaseType = std::conditional_t<std::is_void_v<T>, BindableType, T>;
185+
using Transform = DBusDataTransform<BaseType>;
186+
using DataType = Transform::Data;
187+
using WireType = Transform::Wire;
167188

168189
public:
169190
explicit DBusBindableProperty() { this->group()->attachProperty(this); }
@@ -183,20 +204,33 @@ class DBusBindableProperty: public DBusPropertyCore {
183204

184205
protected:
185206
QDBusError store(const QVariant& variant) override {
186-
auto result = demarshallVariant<DataType>(variant);
207+
DBusResult<DataType> result;
208+
209+
if constexpr (std::is_same_v<WireType, BaseType>) {
210+
result = demarshallVariant<DataType>(variant);
211+
} else {
212+
auto wireResult = demarshallVariant<WireType>(variant);
213+
if (!wireResult.isValid()) return wireResult.error;
214+
result = Transform::fromWire(std::move(wireResult.value));
215+
}
187216

188-
if (result.isValid()) {
189-
this->bindable()->setValue(std::move(result.value));
217+
if (!result.isValid()) return result.error;
218+
this->bindable()->setValue(std::move(result.value));
190219

191-
if constexpr (updatedPtr != nullptr) {
192-
(this->owner()->*updatedPtr)();
193-
}
220+
if constexpr (updatedPtr != nullptr) {
221+
(this->owner()->*updatedPtr)();
194222
}
195223

196-
return result.error;
224+
return QDBusError();
197225
}
198226

199-
QVariant serialize() override { return QVariant::fromValue(this->bindable()->value()); }
227+
QVariant serialize() override {
228+
if constexpr (std::is_same_v<WireType, BaseType>) {
229+
return QVariant::fromValue(this->bindable()->value());
230+
} else {
231+
return QVariant::fromValue(Transform::toWire(this->bindable()->value()));
232+
}
233+
}
200234

201235
private:
202236
[[nodiscard]] constexpr Owner* owner() const {
@@ -308,10 +342,20 @@ class DBusProperty: public AbstractDBusProperty {
308342
// NOLINTBEGIN
309343
#define QS_DBUS_BINDABLE_PROPERTY_GROUP(Class, name) qs::dbus::DBusPropertyGroup name {this};
310344

311-
#define QS_DBUS_PROPERTY_BINDING_P(Class, property, bindable, updated, group, name, required) \
345+
#define QS_DBUS_PROPERTY_BINDING_P( \
346+
Class, \
347+
Type, \
348+
property, \
349+
bindable, \
350+
updated, \
351+
group, \
352+
name, \
353+
required \
354+
) \
312355
static constexpr size_t _qs_property_##property##_offset() { return offsetof(Class, property); } \
313356
\
314357
qs::dbus::DBusBindableProperty< \
358+
Type, \
315359
&Class::_qs_property_##property##_offset, \
316360
&Class::bindable, \
317361
updated, \
@@ -320,11 +364,32 @@ class DBusProperty: public AbstractDBusProperty {
320364
required> \
321365
property;
322366

323-
#define QS_DBUS_PROPERTY_BINDING_7(Class, property, bindable, updated, group, name, required) \
324-
QS_DBUS_PROPERTY_BINDING_P(Class, property, bindable, &Class::updated, group, name, required)
367+
#define QS_DBUS_PROPERTY_BINDING_8( \
368+
Class, \
369+
Type, \
370+
property, \
371+
bindable, \
372+
updated, \
373+
group, \
374+
name, \
375+
required \
376+
) \
377+
QS_DBUS_PROPERTY_BINDING_P( \
378+
Class, \
379+
Type, \
380+
property, \
381+
bindable, \
382+
&Class::updated, \
383+
group, \
384+
name, \
385+
required \
386+
)
387+
388+
#define QS_DBUS_PROPERTY_BINDING_7(Class, Type, property, bindable, group, name, required) \
389+
QS_DBUS_PROPERTY_BINDING_P(Class, Type, property, bindable, nullptr, group, name, required)
325390

326391
#define QS_DBUS_PROPERTY_BINDING_6(Class, property, bindable, group, name, required) \
327-
QS_DBUS_PROPERTY_BINDING_P(Class, property, bindable, nullptr, group, name, required)
392+
QS_DBUS_PROPERTY_BINDING_7(Class, void, property, bindable, group, name, required)
328393

329394
#define QS_DBUS_PROPERTY_BINDING_5(Class, property, bindable, group, name) \
330395
QS_DBUS_PROPERTY_BINDING_6(Class, property, bindable, group, name, true)

src/services/mpris/player.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ private slots:
457457
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pCanSeek, bpCanSeek, playerProperties, "CanSeek");
458458
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pCanGoNext, bpCanGoNext, playerProperties, "CanGoNext");
459459
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pCanGoPrevious, bpCanGoPrevious, playerProperties, "CanGoPrevious");
460-
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pPosition, bpPosition, onPositionUpdated, playerProperties, "Position", false);
460+
QS_DBUS_PROPERTY_BINDING(MprisPlayer, qlonglong, pPosition, bpPosition, onPositionUpdated, playerProperties, "Position", false);
461461
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pVolume, bVolume, playerProperties, "Volume", false);
462462
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pMetadata, bpMetadata, playerProperties, "Metadata");
463463
QS_DBUS_PROPERTY_BINDING(MprisPlayer, pPlaybackStatus, bpPlaybackStatus, playerProperties, "PlaybackStatus");

0 commit comments

Comments
 (0)