diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2020-03-23 21:30:21 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2020-03-27 13:29:47 +0100 |
commit | f3ce9e9332820a8b5084fb4d75994e8eb19ddfd3 (patch) | |
tree | 92efbcf85b11d4eb30d91e553b68180551943e9e /src/corelib/kernel/qproperty.cpp | |
parent | 96de3e26dbd14be6e43db7116c3ce815f9fc9d4b (diff) |
Make QPropertyBindingPrivate accessible to QtQml
QtQml needs the private just for one detail which nobody else should
need it for: Tracking additional dependencies and marking the binding as
dirty. Exporting the private requires hiding some variables and
providing accessors, to compile with MSVC - including the removal of
QVarLengthArray usage. Upside: The binding structure shrinks by 8 bytes
and the encapsulation makes it a little easier to change things without
breaking declarative, ... in the unlikely event ;-)
Also remove setDirty() from the public API as it's not needed by QtQml
and using it is dangerous, because it means that there's a risk of
somebody keeping a reference (count) to the untyped binding from within
the binding closure, which introduces a memory leak.
Change-Id: I43bd56f4bdf218efb54fa23e2d627ad3acfafeb5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/kernel/qproperty.cpp')
-rw-r--r-- | src/corelib/kernel/qproperty.cpp | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index 2dbe8b6310..18580fa756 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -53,7 +53,7 @@ QPropertyBase::QPropertyBase(QPropertyBase &&other, void *propertyDataPtr) QPropertyBasePointer d{this}; d.setFirstObserver(nullptr); if (auto binding = d.bindingPtr()) - binding->propertyDataPtr = propertyDataPtr; + binding->setProperty(propertyDataPtr); } void QPropertyBase::moveAssign(QPropertyBase &&other, void *propertyDataPtr) @@ -73,7 +73,7 @@ void QPropertyBase::moveAssign(QPropertyBase &&other, void *propertyDataPtr) std::swap(d_ptr, other.d_ptr); if (auto binding = d.bindingPtr()) - binding->propertyDataPtr = propertyDataPtr; + binding->setProperty(propertyDataPtr); d.setFirstObserver(observer.ptr); @@ -111,10 +111,10 @@ QUntypedPropertyBinding QPropertyBase::setBinding(const QUntypedPropertyBinding newBinding.data()->ref.ref(); d_ptr = (d_ptr & FlagMask) | reinterpret_cast<quintptr>(newBinding.data()); d_ptr |= BindingBit; - newBinding->dirty = true; - newBinding->propertyDataPtr = propertyDataPtr; + newBinding->setDirty(true); + newBinding->setProperty(propertyDataPtr); if (observer) - observer.prependToBinding(newBinding.data()); + newBinding->prependObserver(observer); } else { d_ptr &= ~BindingBit; } @@ -175,11 +175,10 @@ static thread_local BindingEvaluationState *currentBindingEvaluationState = null BindingEvaluationState::BindingEvaluationState(QPropertyBindingPrivate *binding) : binding(binding) - , dependencyObservers(&binding->dependencyObservers) { previousState = currentBindingEvaluationState; currentBindingEvaluationState = this; - dependencyObservers->clear(); + binding->clearDependencyObservers(); } BindingEvaluationState::~BindingEvaluationState() @@ -222,8 +221,7 @@ void QPropertyBase::registerWithCurrentlyEvaluatingBinding() const QPropertyBasePointer d{this}; - currentState->dependencyObservers->append(QPropertyObserver()); - QPropertyObserverPointer dependencyObserver{&(*currentState->dependencyObservers)[currentState->dependencyObservers->size() - 1]}; + QPropertyObserverPointer dependencyObserver = currentState->binding->allocateDependencyObserver(); dependencyObserver.setBindingToMarkDirty(currentState->binding); dependencyObserver.observeProperty(d); } @@ -263,6 +261,8 @@ QPropertyObserver::~QPropertyObserver() d.unlink(); } +QPropertyObserver::QPropertyObserver() = default; + QPropertyObserver::QPropertyObserver(QPropertyObserver &&other) { std::swap(bindingToMarkDirty, other.bindingToMarkDirty); @@ -351,12 +351,6 @@ void QPropertyObserverPointer::observeProperty(QPropertyBasePointer property) property.addObserver(ptr); } -void QPropertyObserverPointer::prependToBinding(QPropertyBindingPrivate *binding) -{ - ptr->prev = const_cast<QPropertyObserver **>(&binding->firstObserver.ptr); - binding->firstObserver = *this; -} - QPropertyBindingError::QPropertyBindingError(Type type) { if (type != NoError) { |