18#include <private/qglobal_p.h>
26#include <QtCore/QVarLengthArray>
73 return ptr->binding();
78 auto &
d =
ptr->d_ref();
88 inline int observerCount()
const;
107 m_placeHolder.next =
next;
110 next->prev = &m_placeHolder.next;
111 m_placeHolder.prev = &observer->next;
128#if QT_DEPRECATED_SINCE(6, 6)
129 if (
ptr->next.tag() == QPropertyObserver::ObserverIsAlias)
130 ptr->aliasData =
nullptr;
136#if QT_DEPRECATED_SINCE(6, 6)
137 Q_ASSERT(
ptr->next.tag() != QPropertyObserver::ObserverIsAlias);
157 explicit operator bool()
const {
return ptr !=
nullptr; }
171 ptr->next->prev =
ptr->prev;
173 ptr->prev.setPointer(
ptr->next.data());
193 *currentState = previousState;
214 *currentState = previousState;
215 *currentlyEvaluatingBindingList = bindingState;
232 using ObserverArray = std::array<QPropertyObserver, 4>;
237 bool updating =
false;
238 bool hasStaticObserver =
false;
239 bool pendingNotify =
false;
240 bool hasBindingWrapper:1;
242 bool isQQmlPropertyBinding:1;
255 ObserverArray inlineDependencyObservers;
285 constexpr auto align =
alignof (std::max_align_t) - 1;
287 static_assert (sizeEnsuringAlignment %
alignof (std::max_align_t) == 0,
288 "Required for placement new'ing the function behind it.");
289 return sizeEnsuringAlignment;
294 size_t dependencyObserverCount = 0;
303 : hasBindingWrapper(
false)
304 , isQQmlPropertyBinding(isQQmlPropertyBinding)
316 Q_ASSERT(!(callback && bindingWrapper));
318 hasStaticObserver =
true;
319 hasBindingWrapper =
false;
320 staticObserverCallback = callback;
321 }
else if (bindingWrapper) {
322 hasStaticObserver =
false;
323 hasBindingWrapper =
true;
324 staticBindingWrapper = bindingWrapper;
326 hasStaticObserver =
false;
327 hasBindingWrapper =
false;
328 staticObserverCallback =
nullptr;
334 firstObserver = observer;
339 auto observers = firstObserver;
340 firstObserver.
ptr =
nullptr;
344 void clearDependencyObservers();
347 if (dependencyObserverCount < inlineDependencyObservers.size()) {
348 ++dependencyObserverCount;
349 return {&inlineDependencyObservers[dependencyObserverCount - 1]};
351 return allocateDependencyObserver_slow();
358 if (!hasCustomVTable())
361 constexpr auto msg =
"Custom location";
368 void unlinkAndDeref();
376 NotificationState notifyNonRecursive();
386 hasStaticObserver =
false;
387 hasBindingWrapper =
false;
388 propertyDataPtr =
nullptr;
389 clearDependencyObservers();
396 return vtable->
size == 0;
400 if (
priv->hasCustomVTable()) {
405 priv->~QPropertyBindingPrivate();
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();
424 if (
ptr->isNotificationDelayed()) {
441 return b->firstObserver;
451 if (!
ptr->isNotificationDelayed())
453 return ptr->proxyData();
459 for (
auto observer = firstObserver(); observer; observer = observer.nextObserver())
466 void Q_CORE_EXPORT initBindingStatusThreadId();
473 template<
typename Property,
typename>
477 using SignalTakesValue = std::is_invocable<
decltype(Signal), Class, T>;
480 char *that =
reinterpret_cast<char *
>(
this);
483 const Class *owner()
const
485 char *that =
const_cast<char *
>(
reinterpret_cast<const char *
>(
this));
491 auto *thisData =
static_cast<ThisType *
>(dataPtr);
494 if constexpr (QTypeTraits::has_operator_equal_v<T>)
495 if (
copy.valueBypassingBindings() == thisData->valueBypassingBindings())
500 (thisData->owner()->*
Setter)(
copy.valueBypassingBindings());
505 return storage->bindingStatus &&
storage->bindingStatus->currentCompatProperty
510 auto prop =
static_cast<const ThisType *
>(
d);
511 if constexpr (std::is_null_pointer_v<
decltype(
Getter)>)
512 return prop->value();
514 return (prop->owner()->*
Getter)();
530 if (
storage->bindingStatus &&
storage->bindingStatus->currentlyEvaluatingBinding && !inBindingWrapper(
storage))
531 storage->registerDependency_helper(
this);
537 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
539 }
else if constexpr (std::is_pointer_v<T>) {
560 if (
auto *bd =
storage->bindingData(
this)) {
562 if (bd->hasBinding() && !inBindingWrapper(
storage))
563 bd->removeBinding_helper();
591 template <
typename Functor>
594 std::enable_if_t<std::is_invocable_v<Functor>> * =
nullptr)
599 template <
typename Functor>
605 return bd && bd->
binding() !=
nullptr;
611 if (
auto *bd =
storage->bindingData(
this)) {
613 if (bd->hasBinding() && !inBindingWrapper(
storage))
614 bd->removeBinding_helper();
621 if (
auto bd =
storage->bindingData(
this,
false)) {
625 if (!bd->isNotificationDelayed()) {
628 if (!inBindingWrapper(
storage)) {
630 if (bd->notifyObserver_helper(
this,
storage, observer, bindingObservers)
631 == QtPrivate::QPropertyBindingData::Evaluated) {
634 observer.notify(
this);
635 for (
auto&& bindingObserver: bindingObservers)
636 bindingObserver.binding()->notifyNonRecursive();
642 if constexpr (!std::is_null_pointer_v<
decltype(Signal)>) {
643 if constexpr (SignalTakesValue::value)
644 (owner()->*Signal)(getPropertyValue(
this));
646 (owner()->*Signal)();
661 template<
typename Functor>
664 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
668 template<
typename Functor>
671 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
673 return onValueChanged(
f);
676 template<
typename Functor>
679 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
691template<
typename Class,
typename Ty, auto Offset, auto Setter, auto Signal, auto Getter>
700 { *
static_cast<T*
>(
value) = Property::getPropertyValue(
d); },
703 (
static_cast<Property *
>(
d)->owner()->*Setter)(*
static_cast<const T*
>(
value));
706 {
return static_cast<const Property *
>(
d)->binding(); },
713 []() {
return QMetaType::fromType<T>(); }
718#define QT_OBJECT_COMPAT_PROPERTY_4(Class, Type, name, setter) \
719 static constexpr size_t _qt_property_##name##_offset() { \
720 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
721 return offsetof(Class, name); \
724 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter> name;
726#define QT_OBJECT_COMPAT_PROPERTY_5(Class, Type, name, setter, signal) \
727 static constexpr size_t _qt_property_##name##_offset() { \
728 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
729 return offsetof(Class, name); \
732 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, signal> name;
734#define Q_OBJECT_COMPAT_PROPERTY(...) \
735 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
736 QT_OVERLOADED_MACRO(QT_OBJECT_COMPAT_PROPERTY, __VA_ARGS__) \
739#define QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS_5(Class, Type, name, setter, value) \
740 static constexpr size_t _qt_property_##name##_offset() { \
741 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
742 return offsetof(Class, name); \
745 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter> name = \
746 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter>( \
749#define QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS_6(Class, Type, name, setter, signal, value) \
750 static constexpr size_t _qt_property_##name##_offset() { \
751 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
752 return offsetof(Class, name); \
755 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, signal> name = \
756 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, \
759#define QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS_7(Class, Type, name, setter, signal, getter, value) \
760 static constexpr size_t _qt_property_##name##_offset() { \
761 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
762 return offsetof(Class, name); \
765 QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, signal, getter>\
766 name = QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, \
767 signal, getter>(value);
769#define Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(...) \
770 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
771 QT_OVERLOADED_MACRO(QT_OBJECT_COMPAT_PROPERTY_WITH_ARGS, __VA_ARGS__) \
776Q_CORE_EXPORT BindingEvaluationState *suspendCurrentBindingStatus();
777Q_CORE_EXPORT
void restoreBindingStatus(BindingEvaluationState *status);
784 return bindable.
iface;
789 return bindable.
data;
797 if (isQQmlPropertyBinding)
816 auto bindingFunctor =
reinterpret_cast<std::byte *
>(
this) +
818 bool changed =
false;
819 if (hasBindingWrapper) {
820 changed = staticBindingWrapper(metaType, propertyDataPtr,
821 {vtable, bindingFunctor});
823 changed = vtable->call(metaType, propertyDataPtr, bindingFunctor);
827 pendingNotify = pendingNotify || changed;
828 if (!changed || !firstObserver)
831 firstObserver.noSelfDependencies(
this);
832 firstObserver.evaluateBindings(bindingObservers, status);
869 auto handlerToCall = observer->changeHandler;
872 observer =
next->next.data();
877 handlerToCall(observer, propertyDataPtr);
886#if QT_DEPRECATED_SINCE(6, 6)
887 case QPropertyObserver::ObserverIsAlias:
890 default: Q_UNREACHABLE();
921#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
932 if (
ptr->isImpl(&QPropertyAdaptorSlotObject::impl)) {
934 if (
p->metaProperty_.propertyIndex() == propertyIndex)
945 friend class QT_PREPEND_NAMESPACE(QUntypedBindable);
QtPrivate::QPropertyBindingData * bindingData(const QUntypedPropertyData *data) const
\macro Q_OBJECT_BINDABLE_PROPERTY(containingClass, type, name, signal)
QPropertyBinding< T > binding() const
typename QPropertyData< T >::value_type value_type
QtPrivate::QPropertyBindingData & bindingData() const
QObjectCompatProperty & operator=(parameter_type newValue)
typename QPropertyData< T >::arrow_operator_result arrow_operator_result
typename QPropertyData< T >::parameter_type parameter_type
parameter_type value() const
QObjectCompatProperty()=default
QPropertyChangeHandler< Functor > onValueChanged(Functor f)
void setValue(parameter_type t)
void removeBindingUnlessInWrapper()
bool setBinding(const QUntypedPropertyBinding &newBinding)
QPropertyBinding< T > setBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor > > *=nullptr)
arrow_operator_result operator->() const
QObjectCompatProperty(T &&initialValue)
QPropertyNotifier addNotifier(Functor f)
parameter_type operator*() const
QObjectCompatProperty(const T &initialValue)
QPropertyBinding< T > takeBinding()
QPropertyChangeHandler< Functor > subscribe(Functor f)
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &newBinding)
Type
This enum specifies which error occurred.
T * data() const noexcept
void detachFromProperty()
QPropertyBindingError bindingError() const
QMetaType valueMetaType() const
void setStaticObserver(QtPrivate::QPropertyObserverCallback callback, QtPrivate::QPropertyBindingWrapper bindingWrapper)
QPropertyBindingSourceLocation sourceLocation() const
QPropertyBindingSourceLocation location
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)
bool Q_ALWAYS_INLINE evaluateRecursive_inline(PendingBindingObserverList &bindingObservers, QBindingStatus *status)
void(*)(QPropertyBindingPrivate *) DeclarativeErrorCallback
static QPropertyBindingPrivate * get(const QUntypedPropertyBinding &binding)
DeclarativeErrorCallback errorCallBack
QtPrivate::QPropertyBindingWrapper staticBindingWrapper
void prependObserver(QPropertyObserverPointer observer)
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
@ ObserverNotifiesBinding
@ ObserverNotifiesChangeHandler
void(*)(QPropertyObserver *, QUntypedPropertyData *) ChangeHandler
\macro QT_RESTRICTED_CAST_FROM_ASCII
const QtPrivate::QBindableInterface * iface
QUntypedPropertyData * data
QMetaType valueMetaType() const
Returns the meta-type of the binding.
bool isNull() const
Returns true if the QUntypedPropertyBinding is null.
QPropertyBindingData & bindingData()
const QMetaProperty & metaProperty() const
static QPropertyAdaptorSlotObject * cast(QSlotObjectBase *ptr, int propertyIndex)
const QPropertyBindingData & bindingData() const
QPropertyBindingPrivate * binding() const
QUntypedPropertyBinding setBinding(const QUntypedPropertyBinding &newBinding, QUntypedPropertyData *propertyDataPtr, QPropertyObserverCallback staticObserverCallback=nullptr, QPropertyBindingWrapper bindingWrapper=nullptr)
static constexpr quintptr BindingBit
Combined button and popup list for selecting options.
bool bindingWrapper(QMetaType type, QUntypedPropertyData *d, QtPrivate::QPropertyBindingFunction binding, QUntypedPropertyData *temp, void *value)
constexpr size_t getOffset(size_t o)
bool(*)(QMetaType, QUntypedPropertyData *dataPtr, QPropertyBindingFunction) QPropertyBindingWrapper
bool isAnyBindingEvaluating()
bool isPropertyInBindingWrapper(const QUntypedPropertyData *property)
void(*)(QUntypedPropertyData *) QPropertyObserverCallback
auto makePropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor > > *=nullptr)
static jboolean copy(JNIEnv *, jobject)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static ControlElement< T > * ptr(QWidget *widget)
const QBindingStorage * qGetBindingStorage(const QObject *o)
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei count
#define QT_PROPERTY_DEFAULT_BINDING_LOCATION
constexpr void qt_ptr_swap(T *&lhs, T *&rhs) noexcept
settings setValue("DataPump/bgcolor", color)
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QBindingObserverPtr)
QBindingObserverPtr(QBindingObserverPtr &&other) noexcept
QBindingObserverPtr()=default
void swap(QBindingObserverPtr &other) noexcept
QPropertyObserver * operator->()
QPropertyBindingPrivate * binding() const noexcept
Q_DISABLE_COPY(QBindingObserverPtr)
static QPropertyProxyBindingData * proxyData(QtPrivate::QPropertyBindingData *ptr)
static void fixupAfterMove(QtPrivate::QPropertyBindingData *ptr)
int observerCount() const
static QPropertyBindingDataPointer get(QProperty< T > &property)
QPropertyBindingPrivate * binding() const
void setObservers(QPropertyObserver *observer)
QPropertyObserverPointer firstObserver() const
void setFirstObserver(QPropertyObserver *observer)
~QPropertyObserverNodeProtector()
QPropertyObserver * next() const
void notify(QUntypedPropertyData *propertyDataPtr)
QPropertyBindingPrivate * binding() const
QPropertyObserverPointer nextObserver() const
static QtPrivate::QBindableInterface const * getInterface(const QUntypedBindable &bindable)
static QUntypedPropertyData * getPropertyData(const QUntypedBindable &bindable)
QPropertyBindingPrivate * binding
QVarLengthArray< const QPropertyBindingData *, 8 > alreadyCaptureProperties
~BindingEvaluationState()
~CompatPropertySafePoint()
QUntypedPropertyData * property
const QtPrivate::BindingFunctionVTable * vtable