[Development] QProperty and library coding guide

Volker Hilsheimer volker.hilsheimer at qt.io
Tue Jul 21 17:57:12 CEST 2020


> On 21 Jul 2020, at 16:27, Fabian Kosmale <fabian.kosmale at qt.io> wrote:
> 
> Sacrificing operator= to avoid UB and hacks is probably fine (though I expect  some grumbling about the API). But would you suggest  that "real" (non-pimpled) QProperties and "fake" (pimpled) properties have a different API?


Using

object->setValue<Object::fooProperty>();

works no matter how the property is implemented, and whether the QProperty is a public member of the public class, or a private member, or a pimpl’ed member.

If the design goal was to have property access work the same way no matter how the data member storing the value relates to the public class, then yes, my proposal sacrifices that. Once we have C++ 20 (or 23 or whatever might have what we need), we can bring a uniform access API design back. Until then, the more important problems to solve seem to be binding and lazy evaluation.


> And would you change the the property design to always go through the setter when a binding becomes dirty?


I suppose nothing has to change in that respect from what we have right now. If the macro IMPL takes a setter name as well, then it can expand to declare and implement it, forwarding to the generic setValue<PropertyType> template. Ditto for getter.

If that removes the assumption that a custom setter/getter would be called for updates from bindings, then that’s a good reason not to want to allow custom setters and getters. Wiring up the change and guard callbacks would be done the same as today as well.


Volker


> Am 21.07.20 um 15:16 schrieb Volker Hilsheimer:
>> Taking a step back.
>> 
>> I wonder if we can avoid this problem if we require people to write a bit more code. The idea to operate on the property directly looks nice at first sight, ie
>> 
>> auto oldValue = object->enabled;
>> object->enabled = newValue;
>> 
>> but that seems to be the only reason why we need the maybe-zero-sized members in public classes, and the pointer-arithmetic to get to “this"; I’m not convinced that it's worth it.
>> 
>> Realistically [1] we will have a lot of classes that would be a mix of old and new properties. Especially with that in mind, we do need to make sure that we have API consistency. For example, the property getters for boolean properties have always been called isProperty; never just “property". The new system departs from this. Making it cleverly generate an isProperty getter is just more magic.
>> 
>> Requiring the implementing getter/setter methods explicitly, just today, is fine, I think. We might get something better later, but time is ticking and this shouldn’t stop the show.
>> 
>> To set up bindings, one needs to do something like this with the current desitn (I might miss some variants):
>> 
>> sink->otherProperty.setBinding(source->property);
>> sink->otherProperty = Qt::makePropertyBinding(source->property);
>> sink->otherProperty = Qt::makeBinding([&](){ return source->property; });
>> 
>> If instead we need to make a call on the source object, then it would remove the entire “this” pointer problem. To make the call unique for each property, we just have to declare a type for each property, which is easy.
>> 
>> sink->otherProperty = source->makeBinding<Source::propertyType>();
>> 
>> 
>> I’ve hacked a quick poc up at
>> 
>> https://codereview.qt-project.org/c/qt/qtbase/+/308308
>> 
>> This is obviously not taking a lot of use cases into account, so I might be missing a lot, but the concept should be fairly extensible, for intance for subscribe, setValue, value methods. The only downside I see is that
>> 
>> object->property = newValue;
>> 
>> 
>> is not possible with this, but having to write
>> 
>> object->setProperty(newValue);
>> 
>> like we do today can’t be a blocker for the entire concept of bindable and lazily evaluted properties.
>> 
>> 
>> Volker
>> 
>> 
>> [1] There might be many classes that we can’t port entirely over to the new property system, at least not without subtle changes to behavior that we can’t accept. Qt’s properties are not designed to be orthogonal; changing them frequently has side effects on other properties; getters sometimes apply some additional logic for defaults and overrides; we have virtual setters, etc. This has turned out to be quite complex over the last 10 days of trying, and the resulting code has not always been a step into the direction of maintainability.
>> 
>> _______________________________________________
>> Development mailing list
>> Development at qt-project.org
>> https://lists.qt-project.org/listinfo/development
> 
> -- 
> --
> Fabian Kosmale
> Software Engineer
> 
> The Qt Company GmbH
> Erich-Thilo-Str. 10
> D-12489 Berlin
> fabian.kosmale at qt.io
> http://qt.io
> 
> Geschäftsführer: Mika Pälsi,
> Juha Varelius, Mika Harjuaho
> Sitz der Gesellschaft: Berlin,
> Registergericht: Amtsgericht
> Charlottenburg, HRB 144331 B
> --



More information about the Development mailing list