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+
140151namespace bindable_p {
141152
142153template <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
154171template <
172+ typename T,
155173 auto offset,
156174 auto bindablePtr,
157175 auto updatedPtr,
@@ -160,10 +178,13 @@ template <
160178 bool required>
161179class 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
168189public:
169190 explicit DBusBindableProperty () { this ->group ()->attachProperty (this ); }
@@ -183,20 +204,33 @@ class DBusBindableProperty: public DBusPropertyCore {
183204
184205protected:
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
201235private:
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 )
0 commit comments