Am 01.10.19 um 15:18 schrieb Eike Ziller:
>
>> On 26. Sep 2019, at 17:02, Simon Hausmann <simon.hausm...@qt.io> wrote:
>>
>> Hi,
>>
>> Earlier this year, Olivier, Samuel, Auri and I worked on a project to 
>> re-evaluate how we could bring the declarative Qt Quick approach of doing 
>> user interfaces closer to C++, in order to allow building and running user 
>> interfaces in very memory and processor-power constrained environments. 
>> There were many different outcomes of this. One of them was that we figured 
>> out a way to compile QML binding expressions down to full C++, without any 
>> run-time interpretation. This required building a new way of defining 
>> properties and their relationships, a new property binding system. The 
>> results were so convincing that the plan was born to productize this for Qt 
>> 6 in multiple layers and steps. I'd like to initiate a first step in that 
>> direction by proposing API and functionality for Qt 6 and briefly outline 
>> how we see the building blocks apply to QML and Qt Quick:
>>
>> In QML, today, properties consist of a type, a setter function and a getter 
>> function, and the functions are implemented by the developer. There is also 
>> a change signal that needs to be emitted when the value changes.
>>
>> Binding expressions declared in .qml files are created behind the scenes and 
>> the QML engine makes sure to call the getter functions during the evaluation 
>> and the setter function to write the result. Through a connection to the 
>> change signal, bindings are automatically re-evaluated when properties 
>> change and the new values are passed to the setter functions. It's pretty 
>> magic and it works, but it requires a fair amount of indirection and 
>> side-loading of data structures.
>>
>> I would like to propose an API that replaces the setter and getter functions 
>> on objects with a new property template class that encapsulates the property 
>> value instead, and the ability to tie binding expressions to these 
>> properties for automatic updates. In short, it looks like this:
>>
> Hi,
>
>>      QProperty<QString> surname("John");
>>      QProperty<QString> lastname("Smith");
>>
>>      QProperty<QString> fullname;
>>      fullname.setBinding([&]() { return surname() + " " + lastname(); });
>>
>>      qDebug() << fullname(); // Prints "John Smith"
>>
>>      surname = "Emma"; // Marks binding expression as dirty
>>
>>      qDebug() << fullname(); // Re-evaluates the binding expression and 
>> prints "Emma Smith"
>>
>>
>> You can see a work-in-progress patch for this in Gerrit at
>>
>>      https://codereview.qt-project.org/c/qt/qtbase/+/275352
>>
> I’m all for a more declarative coding style also in C++.
> I’m wondering if we are re-inventing part of Reactive Programing a la 
> ReactiveX with QProperty, though?


I suppose we are. It's not black or white I think :)


> The above looks similar to (sodium-cxx):
>
>      cell_sink<QString> surname("John");
>      cell_sink<QString> lastname("Smith”);
>      cell<QString> fullname = surname.lift(
>          lastname, [](QString s, QString l) { return s + " " + l; });
>
>      qDebug() << fullname.sample();
>      surname.send("Emma");
>      qDebug() << fullname.sample();
>
> or (RxJS):
>
>      var surname = new BehaviorSubject("John");
>      var lastname = new BehaviorSubject("Smith");
>      var fullname = new BehaviorSubject();
>      r.combineLatest(surname, lastname).pipe(map(([s, l]) => { return s + " " 
> + l; })).subscribe(fullname);
>
>      console.log(fullname.getValue());
>      surname.next("Emma”);
>      console.log(fullname.getValue());
>
> What is the relation of QProperty to Reactive Programing, in which ways can 
> we orient QProperty on what is done there, or learn from insights in that 
> field?


That's a good question. If you have any insights please share :)

> E.g. what API do you plan for subscribing to value changes of a property (I 
> didn’t see anything in the patch)?


The patch proposes right now an API like this:


     auto subscription = Qt::onPropertyChanged(property, []() { ... });


The function also returns a (moveable) handle that will unsubscribe when 
it goes out of scope. Right now I'm however leaning more towards making 
this a member function of the property again.


> Do you intent to tackle the “missed first event” issue when choosing one? 
> (https://livebook.manning.com/book/functional-reactive-programming/chapter-1/92)


I did not have a specific solution in mind for this. I agree that it's a 
general problem with observers. The same problem exists with signals & 
slots as well -- connecting to a signal after its initial emission. 
Bindings do not have that problem AFAICS.


Simon

_______________________________________________
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to