82 auto &
d =
ptr->d_ref();
109 m_placeHolder.next =
next;
112 next->prev = &m_placeHolder.next;
113 m_placeHolder.prev = &observer->next;
153 explicit operator bool()
const {
return ptr !=
nullptr; }
161 ptr->next->prev =
ptr->prev;
163 ptr->prev.setPointer(
ptr->next.data());
221 using ObserverArray = std::array<QPropertyObserver, 4>;
226 bool updating =
false;
227 bool hasStaticObserver =
false;
228 bool pendingNotify =
false;
229 bool hasBindingWrapper:1;
231 bool isQQmlPropertyBinding:1;
244 ObserverArray inlineDependencyObservers;
274 constexpr
auto align =
alignof (std::max_align_t) - 1;
276 static_assert (sizeEnsuringAlignment %
alignof (std::max_align_t) == 0,
277 "Required for placement new'ing the function behind it.");
278 return sizeEnsuringAlignment;
283 size_t dependencyObserverCount = 0;
292 : hasBindingWrapper(
false)
293 , isQQmlPropertyBinding(isQQmlPropertyBinding)
305 Q_ASSERT(!(callback && bindingWrapper));
307 hasStaticObserver =
true;
308 hasBindingWrapper =
false;
309 staticObserverCallback = callback;
310 }
else if (bindingWrapper) {
311 hasStaticObserver =
false;
312 hasBindingWrapper =
true;
313 staticBindingWrapper = bindingWrapper;
315 hasStaticObserver =
false;
316 hasBindingWrapper =
false;
317 staticObserverCallback =
nullptr;
323 firstObserver = observer;
328 auto observers = firstObserver;
329 firstObserver.
ptr =
nullptr;
334 for (
size_t i = 0;
i < qMin(dependencyObserverCount, inlineDependencyObservers.size()); ++
i) {
339 heapObservers->clear();
340 dependencyObserverCount = 0;
344 if (dependencyObserverCount < inlineDependencyObservers.size()) {
345 ++dependencyObserverCount;
346 return {&inlineDependencyObservers[dependencyObserverCount - 1]};
348 return allocateDependencyObserver_slow();
353 ++dependencyObserverCount;
355 heapObservers.
reset(
new std::vector<QPropertyObserver>());
356 return {&heapObservers->emplace_back()};
361 if (!hasCustomVTable())
364 constexpr
auto msg =
"Custom location";
371 void unlinkAndDeref();
374 void Q_ALWAYS_INLINE evaluateRecursive_inline(
QBindingStatus *status);
376 void notifyRecursive();
386 hasStaticObserver =
false;
387 hasBindingWrapper =
false;
388 propertyDataPtr =
nullptr;
389 clearDependencyObservers();
396 return vtable->
size == 0;
406 delete[]
reinterpret_cast<std::byte *
>(priv);
414 b->firstObserver.ptr = observer;
417 auto &
d =
ptr->d_ref();
418 d =
reinterpret_cast<quintptr>(observer);
423 auto &
d =
ptr->d_ref();
441 return b->firstObserver;
458 template<
typename Class,
typename T,
auto Offset,
auto Setter,
auto Signal =
nullptr,
459 auto Getter =
nullptr>
462 template<
typename Property,
typename>
466 using SignalTakesValue = std::is_invocable<decltype(Signal),
Class,
T>;
469 char *that =
reinterpret_cast<char *
>(
this);
472 const Class *owner()
const
474 char *that =
const_cast<char *
>(
reinterpret_cast<const char *
>(
this));
480 auto *thisData =
static_cast<ThisType *
>(dataPtr);
483 if constexpr (QTypeTraits::has_operator_equal_v<T>)
494 return storage->bindingStatus->currentCompatProperty
499 auto prop =
static_cast<const ThisType *
>(
d);
500 if constexpr (std::is_null_pointer_v<decltype(Getter)>)
503 return (prop->owner()->*Getter)();
519 if (
storage->bindingStatus->currentlyEvaluatingBinding && !inBindingWrapper(
storage))
520 storage->registerDependency_helper(
this);
526 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
528 }
else if constexpr (std::is_pointer_v<T>) {
549 if (
auto *bd =
storage->bindingData(
this)) {
551 if (bd->hasBinding() && !inBindingWrapper(
storage))
552 bd->removeBinding_helper();
580 template <
typename Functor>
583 std::enable_if_t<std::is_invocable_v<Functor>> * =
nullptr)
588 template <
typename Functor>
594 return bd && bd->
binding() !=
nullptr;
600 if (
auto *bd =
storage->bindingData(
this)) {
602 if (bd->hasBinding() && !inBindingWrapper(
storage))
603 bd->removeBinding_helper();
610 if (
auto bd =
storage->bindingData(
this,
false)) {
614 if (!bd->isNotificationDelayed()) {
617 if (!inBindingWrapper(
storage)) {
618 if (bd->notifyObserver_helper(
this, observer,
storage)
619 == QtPrivate::QPropertyBindingData::Evaluated) {
622 observer.notify(
this);
628 if constexpr (!std::is_null_pointer_v<decltype(Signal)>) {
630 (owner()->*Signal)(getPropertyValue(
this));
632 (owner()->*Signal)();
647 template<
typename Functor>
650 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
654 template<
typename Functor>
657 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
662 template<
typename Functor>
665 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
677 template<
typename Class,
typename Ty, auto Offset, auto Setter, auto Signal, auto Getter>
686 { *
static_cast<T*
>(
value) = Property::getPropertyValue(
d); },
689 (
static_cast<Property *
>(
d)->owner()->*Setter)(*
static_cast<const T*
>(
value));
699 []() {
return QMetaType::fromType<T>(); }
704 #define QT_OBJECT_COMPAT_PROPERTY_4(Class, Type, name, setter) \
705 static constexpr size_t _qt_property_##name##_offset() { \
706 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
707 return offsetof(Class, name); \
710 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter> name;
712 #define QT_OBJECT_COMPAT_PROPERTY_5(Class, Type, name, setter, signal) \
713 static constexpr size_t _qt_property_##name##_offset() { \
714 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
715 return offsetof(Class, name); \
718 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, signal> name;
720 #define Q_OBJECT_COMPAT_PROPERTY(...) \
721 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
722 QT_OVERLOADED_MACRO(QT_OBJECT_COMPAT_PROPERTY, __VA_ARGS__) \
725 #define QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS_5(Class, Type, name, setter, value) \
726 static constexpr size_t _qt_property_##name##_offset() { \
727 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
728 return offsetof(Class, name); \
731 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter> name = \
732 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter>( \
735 #define QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS_6(Class, Type, name, setter, signal, value) \
736 static constexpr size_t _qt_property_##name##_offset() { \
737 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
738 return offsetof(Class, name); \
741 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, signal> name = \
742 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, \
745 #define QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS_7(Class, Type, name, setter, signal, getter, value) \
746 static constexpr size_t _qt_property_##name##_offset() { \
747 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
748 return offsetof(Class, name); \
751 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, signal, getter>\
752 name = QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, \
753 signal, getter>(value);
755 #define Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(...) \
756 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
757 QT_OVERLOADED_MACRO(QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS, __VA_ARGS__) \
770 return bindable.
iface;
775 return bindable.
data;
783 if (isQQmlPropertyBinding)
802 auto bindingFunctor =
reinterpret_cast<std::byte *
>(
this) +
804 bool changed =
false;
805 if (hasBindingWrapper) {
806 changed = staticBindingWrapper(metaType, propertyDataPtr,
807 {vtable, bindingFunctor});
809 changed = vtable->call(metaType, propertyDataPtr, bindingFunctor);
813 pendingNotify = pendingNotify || changed;
814 if (!changed || !firstObserver)
817 firstObserver.noSelfDependencies(
this);
818 firstObserver.evaluateBindings(status);
846 auto handlerToCall = observer->changeHandler;
849 observer =
next->next.data();
854 handlerToCall(observer, propertyDataPtr);
860 auto bindingToNotify = observer->binding;
862 bindingToNotify->notifyRecursive();
small capitals from c petite p scientific i
[1]
QtPrivate::QPropertyBindingData * bindingData(const QUntypedPropertyData *data) const
Declares a \l QObjectBindableProperty inside containingClass of type type with name name....
QPropertyBinding< T > takeBinding()
QPropertyBinding< T > setBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor >> *=nullptr)
QPropertyBinding< T > binding() const
QPropertyChangeHandler< Functor > subscribe(Functor f)
typename QPropertyData< T >::parameter_type parameter_type
parameter_type value() const
QObjectCompatProperty & operator=(parameter_type newValue)
void setValue(parameter_type t)
void removeBindingUnlessInWrapper()
bool setBinding(const QUntypedPropertyBinding &newBinding)
QtPrivate::QPropertyBindingData & bindingData() const
arrow_operator_result operator->() const
QObjectCompatProperty(T &&initialValue)
QPropertyNotifier addNotifier(Functor f)
parameter_type operator*() const
QPropertyChangeHandler< Functor > onValueChanged(Functor f)
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &newBinding)
void detachFromProperty()
QPropertyBindingError bindingError() const
QMetaType valueMetaType() const
Q_NEVER_INLINE QPropertyObserverPointer allocateDependencyObserver_slow()
void setStaticObserver(QtPrivate::QPropertyObserverCallback callback, QtPrivate::QPropertyBindingWrapper bindingWrapper)
~QPropertyBindingPrivate()
QPropertyBindingSourceLocation sourceLocation() const
QPropertyBindingSourceLocation location
void clearDependencyObservers()
QPropertyObserverPointer takeObservers()
void setSticky(bool keep=true)
static constexpr size_t getSizeEnsuringAlignment()
void setProperty(QUntypedPropertyData *propertyPtr)
QPropertyBindingPrivate(QMetaType metaType, const QtPrivate::BindingFunctionVTable *vtable, const QPropertyBindingSourceLocation &location, bool isQQmlPropertyBinding=false)
static void destroyAndFreeMemory(QPropertyBindingPrivate *priv)
Q_ALWAYS_INLINE QPropertyObserverPointer allocateDependencyObserver()
bool hasCustomVTable() const
void setError(QPropertyBindingError &&e)
void(*)(QPropertyBindingPrivate *) DeclarativeErrorCallback
void Q_ALWAYS_INLINE evaluateRecursive_inline(QBindingStatus *status)
DeclarativeErrorCallback errorCallBack
QtPrivate::QPropertyBindingWrapper staticBindingWrapper
static QPropertyBindingPrivate * get(const QUntypedPropertyBinding &binding)
void prependObserver(QPropertyObserverPointer observer)
T * data() const noexcept
The QPropertyChangeHandler class controls the lifecycle of change callback installed on a QProperty.
The QPropertyData class is a helper class for properties with automatic property bindings.
std::conditional_t< UseReferences, const T &, T > parameter_type
std::conditional_t< std::is_pointer_v< T >, const T &, std::conditional_t< QTypeTraits::is_dereferenceable_v< T >, const T &, void > > arrow_operator_result
parameter_type valueBypassingBindings() const
The QProperty class is a template class that enables automatic property bindings.
The QPropertyNotifier class controls the lifecycle of change callback installed on a QProperty.
@ ObserverNotifiesBinding
@ ObserverNotifiesChangeHandler
QUntypedPropertyData * aliasData
void(*)(QPropertyObserver *, QUntypedPropertyData *) ChangeHandler
The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon dest...
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
The QScopedValueRollback class resets a variable to its previous value on destruction.
The QSharedData class is a base class for shared data objects. \reentrant.
The QString class provides a Unicode character string.
QUntypedBindable is a uniform interface over bindable properties like QProperty<T> and QObjectBindabl...
const QtPrivate::QBindableInterface * iface
QUntypedPropertyData * data
QMetaType valueMetaType() const
QUntypedPropertyBinding setBinding(const QUntypedPropertyBinding &newBinding, QUntypedPropertyData *propertyDataPtr, QPropertyObserverCallback staticObserverCallback=nullptr, QPropertyBindingWrapper bindingWrapper=nullptr)
bool isNotificationDelayed() const
QPropertyBindingPrivate * binding() const
static constexpr quintptr BindingBit
auto it unsigned count const
typename C::value_type value_type
auto makePropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor >> *=nullptr)
constexpr size_t getOffset(size_t o)
bool(*)(QMetaType, QUntypedPropertyData *dataPtr, QPropertyBindingFunction) QPropertyBindingWrapper
bool isAnyBindingEvaluating()
void initBindingStatusThreadId()
BindingEvaluationState * suspendCurrentBindingStatus()
bool isPropertyInBindingWrapper(const QUntypedPropertyData *property)
void(*)(QUntypedPropertyData *) QPropertyObserverCallback
void restoreBindingStatus(BindingEvaluationState *status)
EGLOutputLayerEXT EGLint EGLAttrib value
#define Q_DISABLE_COPY_MOVE(Class)
const QBindingStorage * qGetBindingStorage(const QObject *o)
GLboolean GLboolean GLboolean b
GLenum GLenum GLsizei count
#define QT_PROPERTY_DEFAULT_BINDING_LOCATION
QPropertyBindingPrivate * binding() const
static void fixupAfterMove(QtPrivate::QPropertyBindingData *ptr)
void Q_ALWAYS_INLINE addObserver(QPropertyObserver *observer)
const QtPrivate::QPropertyBindingData * ptr
int observerCount() const
static QPropertyBindingDataPointer get(QProperty< T > &property)
void setObservers(QPropertyObserver *observer)
QPropertyObserverPointer firstObserver() const
void setFirstObserver(QPropertyObserver *observer)
~QPropertyObserverNodeProtector()
QPropertyObserver * next() const
void noSelfDependencies(QPropertyBindingPrivate *binding)
void notify(QUntypedPropertyData *propertyDataPtr)
void observeProperty(QPropertyBindingDataPointer property)
QPropertyObserverPointer nextObserver() const
void setBindingToNotify_unsafe(QPropertyBindingPrivate *binding)
void setChangeHandler(QPropertyObserver::ChangeHandler changeHandler)
void setBindingToNotify(QPropertyBindingPrivate *binding)
void evaluateBindings(QBindingStatus *status)
const QtPrivate::QPropertyBindingData * originalBindingData
static QtPrivate::QBindableInterface const * getInterface(const QUntypedBindable &bindable)
static QUntypedPropertyData * getPropertyData(const QUntypedBindable &bindable)
QPropertyBindingPrivate * binding
BindingEvaluationState(QPropertyBindingPrivate *binding, QBindingStatus *status)
BindingEvaluationState * previousState
~BindingEvaluationState()
BindingEvaluationState ** currentState
QtPrivate::BindingEvaluationState ** currentlyEvaluatingBindingList
CompatPropertySafePoint * previousState
CompatPropertySafePoint ** currentState
~CompatPropertySafePoint()
QUntypedPropertyData * property
QtPrivate::BindingEvaluationState * bindingState
Q_CORE_EXPORT CompatPropertySafePoint(QBindingStatus *status, QUntypedPropertyData *property)