summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qproperty.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QProperty: markDirty should be internalFabian Kosmale2021-03-221-0/+3
| | | | | | Change-Id: If69a6f37c32ce0d7f824794a2a1c52bad82d84cc Reviewed-by: Andreas Buhr <andreas.buhr@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Add documentation for Q_OBJECT_BINDABLE_PROPERTYAndreas Buhr2021-03-071-0/+23
| | | | | | | | | | | | | | | | The duo Q_OBJECT_BINDABLE_PROPERTY and QObjectBindableProperty can only be documented together. The documentation is now with QObjectBindableProperty. This patch adds a documentation entry for Q_OBJECT_BINDABLE_PROPERTY which links the user to QObjectBindableProperty. Task-number: QTBUG-90511 Change-Id: I9af4a99d49f4b02ee9645a2cc9a9a024a6a1a552 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit 89cc39a894dddaa0347ecf08438ea31b4880961c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* Fix some qdoc-warnings for 6.1Friedemann Kleint2021-02-181-1/+3
| | | | | | | | | | | | | | | | | | Fix: qtbase/src/testlib/qtestelementattribute.cpp:89: (qdoc) warning: Undocumented enum item 'LET_Message' in QTest::LogElementType qtbase/src/testlib/qtestelementattribute.cpp:89: (qdoc) warning: No such enum item 'LET_Error' in QTest::LogElementType qtbase/src/testlib/qtestelementattribute.cpp:89: (qdoc) warning: Undocumented enum item 'LET_SystemOutput' in QTest::LogElementType qtbase/src/network/ssl/qsslsocket.cpp:1666: (qdoc) warning: Unknown command '\cl' qtbase/src/corelib/kernel/qproperty.cpp:883: (qdoc) warning: Unknown command '\T' qtbase/src/corelib/kernel/qproperty.cpp:799: (qdoc) warning: Undocumented return value (hint: use 'return' or 'returns' in the text qtbase/src/corelib/kernel/qjnienvironment.cpp:250: (qdoc) warning: Undocumented return value (hint: use 'return' or 'returns' in the text Change-Id: I116f5d8ace2c29ba7b6b93256d5761591e01296a Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Nico Vertriest <nico.vertriest@qt.io> (cherry picked from commit 868242b6e1840fcea491ad86d8b2a7a101c4eeaa) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* Mark QPropertyAlias as internalFabian Kosmale2021-02-161-0/+2
| | | | | | | | | | That class was only really meant for the QML compiler, and it is dubious if event that one needs it. The current implementation is also broken. Change-Id: Ie40d282707f3fabc8079bee9e98f082aeb9d30b3 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> (cherry picked from commit 5481601debd6ce06bb8f0135e3ea4baf8a21cb3d) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QProperty: Treat change listener modifying its source property as a loopFabian Kosmale2021-01-281-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is in line with QML where import QtQuick 2.15 Rectangle { width: 100 height: 100 color: "red" Rectangle { id: inner x: 10 y: x width: 50 height: 50 onYChanged: { console.log("hey"); inner.x = 10} TapHandler { onTapped: inner.x = 20 } } } results in a binding loop warning when the tap handler triggers. While the change handler would only run once, we cannot statically determine if we need to loop once, twice, or if there actually is a diverging loop. Thus we unconditionally warn about the binding loop and stop executing the binding. As a drive-by, verify in the related test that a change handler which overwrites its properties binding itself removes the binding. Change-Id: I5372019c2389ab724c49cd7489ecbd3ebced1c69 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Create bindable property overview documentationAndreas Buhr2021-01-281-54/+5
| | | | | | | | | | | So far, all documentation about bindable properties was in the corresponding classes QProperty and QObjectBindableProperty. This patch creates one documentation page for a general introduction to bindable properties and information concerning all of those classes. Change-Id: Ib718dbeb385c3899fb34cc2ce03bec7a8d43a034 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Q(Untyped)Bindable: add takeBinding methodFabian Kosmale2021-01-271-1/+20
| | | | | | | | | | | We missed takeBinding as a supported operation on Q(Untyped)Bindable. To avoid adding version checks to code dealing with QBindableInterface, we simply synthesize takeBinding as a combination of binding to retrieve the binding and setBinding with a default-constructed QUntypedPropertyBinding. Change-Id: I43803a0dfe210353d0235f0373d2257f75ffe534 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QBindable: add initial documentationFabian Kosmale2021-01-271-0/+72
| | | | | | Change-Id: I43681093c8819289037c76bd9c05b88a6da8311b Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QProperty: Add private isAnyBindingEvaluating functionFabian Kosmale2021-01-211-0/+15
| | | | | | | | | | | | | | | | | To optimize certain operations, it can be useful to know whether we are currently evaluating a binding. For instance, we have properties whose storage is only alloctaed on-demand when they are set. However, we would also allocate them if they are used in a binding context, as we would otherwise not properly track the dependency. Using isAnyBindingEvaluating in the getter, we can detect this situation, and avoid the allocation if it returns false. This API is private for now, as it exposes some internals of the property system and should be used with care. As it needs to access the TLS variable, it also has a non-negligible cost. Change-Id: I373aabee644fe7020b2ffba7d6a0ad9a1e1b4ec0 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QUntypedBindable: Add documentationFabian Kosmale2021-01-181-0/+113
| | | | | | | Task-number: QTBUG-89505 Change-Id: I4428c3c0eb723e996195f6f6f5ac736757cea33e Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Clarify variable names in QPropertyObserverPointer::notifyAndreas Buhr2021-01-111-13/+9
| | | | | | | | | | | | | | In QPropertyObserverPointer::notify and its calling sites, variable names "alreadyKnownToHaveChanged", "knownIfPropertyChanged", "propertyChanged", and at its calling site "knownIfChanged" are used. This is confusing. This patch changes those four to "knownToHaveChanged". For the logic implemented it is not necessary to track whether we have knowledge about having changed and whether it has actually changed (if we have knowledge) separately. Change-Id: I90b86b276ab67b2ed70dba4e456cd90220588870 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QProperty docs: update macro nameAndreas Buhr2021-01-081-4/+5
| | | | | | | | | | Use Q_OBJECT_BINDABLE_PROPERTY instead of non-existing ones. Follow-up to 50e1976437f645e9d6571d4498e9d44388e59c19. Task-number: QTBUG-85520 Pick-to: 6.0 Change-Id: I138f0775d9804029f2ecd6bd3594ab47b247392e Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Doc: Fix \sa statement link errorNico Vertriest2021-01-071-1/+1
| | | | | Change-Id: I19f131a7bcbbed5ec39a7ad79a9d7a46d1320529 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QProperty add markdirtyFabian Kosmale2020-12-181-0/+43
| | | | | | | | | | | This adds functionality for marking properties (QProperty and related classes) manually as dirty. This facilliates the integration of bindable properties with non-binable properties and makes it possible for bindable properties to change due to external events. Fixes: QTBUG-89167 Change-Id: I256cf154d914149dacb6cadaba92b13c88c9d027 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Bindable property with initializationIvan Solovev2020-12-171-2/+16
| | | | | | | | | | Implement Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS and Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS macros. They allow to directly initialize the property member. Task-number: QTBUG-85520 Change-Id: I76541d6785bbbf27976b9f0b865fb45be1e9beee Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QProperty docs: update macro nameIvan Solovev2020-12-151-2/+3
| | | | | | | | | Use Q_OBJECT_BINDABLE_PROPERTY instead of non-existing ones Task-number: QTBUG-85520 Pick-to: 6.0 Change-Id: I47e3ff150f54176b42a478fd3ff639754d90e70a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Move QObjectBindableProperty documentation into snippet fileFabian Kosmale2020-12-151-18/+1
| | | | | | | | | | | The \Q_OBJECT macro has been removed but using Q_OBJECT in the file would erroneously trigger automoc. Avoid the issue by moving the snippet into its own file. Task-number: QTBUG-89505 Pick-to: 6.0 Change-Id: I6630ff4bfcbf33eae348ac3d92aae1878dc573ea Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QProperty: Handle eager binding calling setBindingFabian Kosmale2020-12-091-0/+6
| | | | | | | | | | | | | | | | | When an eager binding triggers a setBinding call, we end up with a special kind of binding loop: setBinding() -> evaluate -> notifyObserver ^ | | / ---------------------------- We now catch set condition, and set the binding status to BindingLoop (with a distinct description). Task-number: QTBUG-87153 Task-number: QTBUG-87733 Pick-to: 6.0 Change-Id: I9f9915797d82eab820fc279baceaf89d7e5a3f4a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QPropertyBindingPrivate: Enable QML engine error handlingFabian Kosmale2020-12-081-0/+4
| | | | | | | | | | | | | | | | | The QPropertyBindingSourceLocation is only useful for C++ bindings; for QML bindings we store the binding location in the V4 function. As the QML binding needs to store some additional information for error handling, we allow that memory to be reused by putting it into a union with an array of byte. Moreover, we use some of the space to store a callback pointer, which gets called when an error occurs during binding evaluation. That callback is only called when we know that the binding actually was set up from the QML engine, in which case a bitflag is set. Task-number: QTBUG-87733 Change-Id: I4387a4bd59d4d1ccfe75756ce81f4608319e0490 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Fix QPropertyAlias example, which did not compileAndreas Buhr2020-12-071-3/+3
| | | | | | | | | The QPropertyAlias example did not compile and comments were out of sync with code. This patch fixes both. Pick-to: 6.0 Change-Id: I5717f8df99f4936d0bcbae8df7d2d17e8086951d Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Fix QProperty example so that comments match implementationAndreas Buhr2020-12-071-1/+1
| | | | | | | | | The comments in the QProperty examples slightly mismatched the implementation. This patch fixes it. Pick-to: 6.0 Change-Id: I03cfb35c024fad8ea4eaa5d5db220e1907f06bc3 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Make the signal argument in Q_OBJECT_BINDABLE_PROPERTY optionalLars Knoll2020-12-071-0/+3
| | | | | | | | | | | The intention was always that you can define properties that do not require a changed signal. But having to explicitly pass a nullptr as signal parameter into the macro is ugly, so use the cool QT_OVERLOADED_MACRO to make it optional. Pick-to: 6.0 Change-Id: I0ce366d043850f983c968d73c544d89933c48df9 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QProperty: Avoid spurious dependencies by suspending binding stateFabian Kosmale2020-12-011-1/+18
| | | | | | | | | | Avoid spurious bindings by resetting the binding state before calling the setter of eager properties. Fixes: QTBUG-88999 Pick-to: 6.0 Change-Id: I1e3b5662307d906598335a21d306be9c606529d4 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Simplify the safeguarding logic in notify()Lars Knoll2020-11-301-90/+53
| | | | | | | | | | | | | | | | | | The logic in notify() was doing quite a bit more work than it needed to. By inserting a dummy node after the current one instead of replacing it, we can avoid half of the data shuffling that has been happening and also don't need a back pointer when executing the notification. Also avoid calling a semi expensive destructor of QPropertyObserver. Reduces the overhead of notify() by ~30%. Change-Id: I7ce16bcf9cd9c4368c18bf875fc959223452fd4f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> (cherry picked from commit e8ef871e3522f340b4efe32382af7e35ef908665) Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Inline the fast path for removeBinding()Lars Knoll2020-11-301-8/+9
| | | | | | | | | | | Save a function call in the common case where we don't have a binding This makes a rather large performance difference for setters that do not have a binding. Change-Id: I140f29790f6fe868721a33b9fad37205e547b8e9 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit c63901c5f3195596eb81e5f5ae5483ca5a0b6d35) Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Smaller cleanup in QBindingStorageLars Knoll2020-11-301-11/+11
| | | | | | | | | Unify code paths and avoid excessive code generation. Change-Id: I4a54234dd322bba380cc45d4f9c97d97a0c93303 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 65759c9867321d978c1f98f5cf66bef11c8f5c15) Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Inline the fast path of a few methodsLars Knoll2020-11-301-14/+13
| | | | | | | | | | No need to do function calls for the case where we return immediately after checking a boolean. Change-Id: I3e449850a10fcf82acb843cce6da6dfd98de32ad Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit e165f416a752398079590161a18255f9a0058a3e) Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Remove ExtraBit and FlagMask from QPropertyBindingDataLars Knoll2020-11-301-4/+5
| | | | | | | | | | They are not needed and removing it can simplify the code in some places and avoid a couple of masking operations. Change-Id: I0e4241a2784026aa89deed35f408b094e89a11a0 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit b1be6e6e6f355bfcb0c3814516f6009c91d2de89) Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Inline the QPropertyBindingPrivatePtr destructorLars Knoll2020-11-301-3/+2
| | | | | | | | | | In many cases, it only derefs and does nothing else. Inline the fast code path. Change-Id: Ib605c385c1683f7833f7189c84d6cf4eb5b0e59e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit eda4c29eb26dab32e22040bdda0b9b9109b1408b) Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Inline access to the QBindingStorageLars Knoll2020-11-301-6/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | And inline the fast checks inside the methods in QBindingStorage. This allows QObjectBindableProperty and friends to inline all the fast checks and almost completely eliminates the overhead for property accesses when no bindings are being used. Read and write times of QObject based properties when no bindings are being used: Read Write Old style property: 3.8ns 7.3ns QObjectBindableProperty (no notification): 4.5ns 4.3ns QObjectBindableProperty (with signal): 4.5ns 7.6ns QObjectBindableProperty (inline accessors): 3.2ns 3.4ns Numbers without this patch: Old style property: 3.8ns 7.9ns QObjectBindableProperty (no notification): 7.2ns 7.7ns QObjectBindableProperty (with signal): 7.2ns 16.0ns QObjectBindableProperty (inline accessors): 6.3ns 6.7ns Change-Id: Ifd1fa3a489c3be8b1468c0b88af547aac397f412 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 98c82fb445acf45cc4c4bc86a5adda43358127bf) Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QProperty: Fix notification logic for eager propertiesFabian Kosmale2020-11-031-2/+5
| | | | | | | | | | | | | This ensurse that we do not do dobule notifications in setValue. Moerover we avoid needless notifications in markDirtyAndNotifyObservers when the value did not change. Lastly, if the value did actually change, we pass that information along to notify, so that we do not evaluate the eager property twice. Fixes a test-case which errorneously relied on the old behavior, and adds a new test which verifies that the fix works. Change-Id: I8ec6fa2fe8611565dfc603ceab3ba5f92999b26c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Remove std::function from QProperty interfaceFabian Kosmale2020-11-031-21/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | std::function as a type is rather unfortunate for us, as its SSO buffer makes it rather large, and we can ensure that the function is never empty. Considering that we do need to allocate memory for QPropertyBindingPrivate anyway, we can get rid of the SSO buffer and instead coalesce the allocations (similar to how std::make_shared works). The memory looks then like [--QPropertyBindingPrivate--][Functor] and QPropertyBindingPrivate can get a pointer to the functor via reinterpret_cast<std::byte>(this)+sizeof(QPropertyBindingPrivate). To actually do anything with the functor, we do however need a "vtable" which describes how we can call, destroy and move the functor. This is done by creating a constexpr struct of function pointers, and storing a pointer to it in QPropertyBindingPrivate. As a consequence of those changes, we cannot use QESDP anymore, as we now have to carefully deallocate the buffer we used for both the QPropertyBindingPrivate and the functor. We introduce a custom refcounting pointer for that. While we're at it, we make the refcount non-atomic, as bindings do not work across threads to begin with. Moreover, we can now make the class non-virtual, as that was only needed to hack around limitations of QESDP in the context of exported symbols. Change-Id: Idc5507e4c120e28df5bd5aea717fe69f15e540dc Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Doc: Fix various documentation issues for Qt CoreTopi Reinio2020-10-311-2/+2
| | | | | | | Task-number: QTBUG-86295 Change-Id: I3bf7d4b1533d4fc81114d353b19beaf4ea9b93b2 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Doc: Fix documentation warnings for QProperty and related classesTopi Reinio2020-10-231-128/+43
| | | | | | Task-number: QTBUG-86295 Change-Id: I547f4cf34d9721f56ba1cd665218f66597ffbb5c Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Remove nodiscard in QPropertyObserverNodeProtector ctorAndrei Golubev2020-10-131-1/+1
| | | | | | | | | Produced error in my GCC 7.5 on Ubuntu 18: error: ‘nodiscard’ attribute applied to ‘QPropertyObserverNodeProtector<<anonymous> >::QPropertyObserverNodeProtector(QPropertyObserver*&)’ with void return type [-Werror=attributes] Q_REQUIRED_RESULT QPropertyObserverNodeProtector(QPropertyObserver *&observer) Change-Id: Ic1f6c4f502bb4d5c764686d5521b92f655592bb2 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Mark the class QPropertyObserverNodeProtector as [[nodiscard]]Lars Knoll2020-10-131-1/+1
| | | | | | | And not its constructor, as GCC at least doesn't like that. Change-Id: I4aada7ca7135dd9c599980640588e7c98d398171 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QPropertyObserver: mark as noexcecptFabian Kosmale2020-10-121-2/+2
| | | | | Change-Id: I2df75b35e42fa923c6cbf71a15569dc37140ee55 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QUntypedPropertyBinding::QUntypedPropertyBinding: use member initializer listFabian Kosmale2020-10-121-1/+1
| | | | | | | No need to default initialize the std::function and source location. Change-Id: I7d840376b16e7257386a4787dd06b7956fe37576 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Handle notifier list modification during iterationFabian Kosmale2020-10-121-22/+120
| | | | | | | | | | | | | | As propertyobservers can execute arbitrarily complex code, they can also modify the obsever list in multiple ways. To protect against list corruption resulting from this, we introduce a protection scheme which makes the list resilient against modification. A detailed description of the scheme can be found as a comment in QPropertyObserverPointer::notify. Task-number: QTBUG-87153 Change-Id: I9bb49e457165ddc1e4c8bbdf3d3c9fbf5ff27e94 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Fix ChangeHandler notification for eager propertiesFabian Kosmale2020-09-301-4/+16
| | | | | | | | | | | | | | ChangeHandler's evaluated the binding to detect if the value actually changed. This is a valid strategy for lazy bindings, but eager bindings were already evaluated at that point, and thus the change would not be detected. Change the binding loop test, so that there isn't a fixpoint in the binding loop, and we can still detect it. Changing the binding loop detection code to deal with this case is left as an exercise for the future. Change-Id: Ia5d9ce2cd98a5780e69c993b5824024eb186c154 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Disable moving of QPropertyLars Knoll2020-09-291-40/+7
| | | | | | | | | The semantics are not very intuitive, and it opens a can of worms with regards to what should happen with observers that observe that property. Change-Id: I6fb00b7693904b968224cc87d098bbd0ea776ba3 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QProperty: fix QBindingStoragePrivate::reallocate related codeFabian Kosmale2020-09-291-1/+2
| | | | | | | | | | In the internal hash map implementation, we have to ensure that the index is in the interval [0, size - 1]. Moreover, in setBinding we have to refetch the binding storage in case a reallocation happened. Change-Id: I11c6264f16537699c8908b647e2355a39ce87648 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Prevent endless markDirtyAndNotifyObservers <-> notify loopFabian Kosmale2020-09-281-0/+8
| | | | | | | | | | | | Before we had the option of eager evaluation, we were able to use the dirty flag to detect whether we are recursing. However, eager properties will lead to a evaluateIfDirtyAndReturnTrueIfValueChanged call, and that in turn will clear the dirty flag. Introduce a new member to detect that situation, and set the bindings error state to BindingLoop if we detect that kind of loop. Change-Id: If40b93221848bd9e9422502318d992fad95b0b74 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Add QObjectCompatPropertyLars Knoll2020-09-021-13/+25
| | | | | | | | | | | | Add a compatibility property class that makes porting to the new property system as simple as possible. Binding evaluation for those compat properties is eager, as we do not control possible side effects of the code in the existing setters. Change-Id: Ic56347abb49e40631ec73e88c6d40d4bdb05ca29 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Pass a pointer to the property data into the method evaluating a bindingLars Knoll2020-09-021-6/+11
| | | | | | | | | Make it possible to evaluate the binding but write the result into a different memory location. This will help support compat properties, where the setter does a lot of additional work. Change-Id: Ib60220eb629e3dcb5c0d7004b693e92290dfabe5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Add support for bindable properties to QObjectLars Knoll2020-09-021-0/+237
| | | | | | | | | | | | | | | | Add Q_OBJECT_BINDABLE_PROPERTY() macro that can be used to define a bindable property inside QObject. The macro and the class behind it creates storage for a property that is bindable inside a QObject or QObjectPrivate. The property only uses as much space as the data contained, ie. it has no storage overhead, as long as no bindings are being used. Bindings are being stored and looked up in the QBindingStorage associated with the owning object. Change-Id: I1dadd7bddbad6fbf10cfa791d6461574b9db82dd Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Cleanup QBindingPrivateLars Knoll2020-09-021-5/+6
| | | | | | | | | | | | Simplify the data structure. We only need one pointer for either the static callback or a bindingWrapper, so don't share it with the dependency observer array. Also ensure we reset the propertyDataPtr and clear the observers when the binding gets removed from a property. Change-Id: I4c1e7ec7823c3ef12c63d6f758b757e7bac60cae Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Add a QBindingStorage classLars Knoll2020-09-021-4/+163
| | | | | | | | | | | | | | | | | | | QBindingStorage is a class that can store a set of binding objects for the properties of a QObject. This will get used to reduce the memory overhead of the property system when adding bindable properties to QObject based classes. The binding storage has a pointer to the TLS entry containing the currently evaluating binding. Like that we avoid repeated TLS lookups and reduce the overhead of the property system to one pointer lookup and one compare for the case that properties aren't being used. Each QObject now owns one binding storage object, that can be used to store binding data for properties that members of the QObject. Change-Id: I27427c03c2ba281f072e074be96147bdbcaac246 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Move QPropertyObserver further up in the header fileLars Knoll2020-09-021-0/+2
| | | | | | | | | | Reorder source code to make the follow-up work easier. Also clean up retrieving the pointer to the aliased property. Make setSource(QPropertyBindingData) public, it'll be needed later on. Change-Id: I784fdceac8722c7df756b2d7c35e08c7ab3a2074 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Introduce a common base class for all QProperty typesLars Knoll2020-09-021-16/+60
| | | | | | | | | | | | | | | | | | Add an empty QUntypedPropertyData class. This allows making a couple of places where the system is currently using a void * more type safe. Also add a QPropertyData<T> as an intermediate class between QUntypedPropertyData and QProperty. This class will get used in a future commit to simplify storing property data separately from the possible binding data. Also simplify the static observer handling a bit by always passing it a pointer to the QUntypedPropertyData instead of some other void * that could point to anything. Change-Id: I1f8144ea717815b1bc6f034d1ac883c13af5aaf8 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>