9#include <QtCore/qloggingcategory.h>
11#include <QtCore/qmetaobject.h>
31 auto *old = std::exchange(
d,
ptr);
32 if (old && (--old->ref == 0))
41 observer->prev = &
b->firstObserver.ptr;
42 observer->next =
b->firstObserver.ptr;
44 observer->next->prev = &observer->next;
45 b->firstObserver.ptr = observer;
47 auto &
d =
ptr->d_ref();
53 observer->next->prev = &observer->next;
126 auto *bindingData = delayed->originalBindingData;
130 bindingData->d_ptr = delayed->d_ptr;
132 if (!bindingData->hasBinding()) {
156 if (!delayed->originalBindingData)
158 delayed->originalBindingData =
nullptr;
164 observer.notify(delayed->propertyData);
193 if (!groupUpdateData)
195 ++groupUpdateData->
ref;
214 auto *
data = groupUpdateData;
218 groupUpdateData =
nullptr;
225 data->evaluateBindings(bindingObservers,
i, status);
238 delete std::exchange(
data,
data->next);
279static_assert(std::is_trivially_destructible_v<QPropertyBindingSourceLocation>);
287 vtable->
destroy(
reinterpret_cast<std::byte *
>(
this)
297 heapObservers->clear();
305 heapObservers.
reset(
new std::vector<QPropertyObserver>());
306 return {&heapObservers->emplace_back()};
327 for (
auto &&bindingObserver: bindingObservers) {
328 bindingObserver.binding()->notifyNonRecursive();
336 pendingNotify =
false;
343 if (hasStaticObserver)
414 d = std::move(
other.d);
472 for (
auto observer = d.firstObserver(); observer;) {
473 auto next = observer.nextObserver();
477 if (
auto binding = d.binding())
492 auto &
data = d_ref();
493 if (
auto *existingBinding = d.binding()) {
494 if (existingBinding == newBinding.
data())
496 if (existingBinding->isUpdating()) {
505 observer = d.firstObserver();
515 newBindingRaw->prependObserver(observer);
516 newBindingRaw->setStaticObserver(staticObserverCallback, guardCallback);
519 newBindingRaw->evaluateRecursive(bindingObservers);
520 newBindingRaw->notifyNonRecursive(bindingObservers);
521 }
else if (observer) {
522 d.setObservers(observer.
ptr);
568 return currentState ? currentState->
binding :
nullptr;
576void QPropertyBindingData::removeBinding_helper()
580 auto *existingBinding = d.binding();
582 if (existingBinding->isSticky()) {
586 auto observer = existingBinding->takeObservers();
589 d.setObservers(observer.ptr);
590 existingBinding->unlinkAndDeref();
598 registerWithCurrentlyEvaluatingBinding_helper(currentState);
602void QPropertyBindingData::registerWithCurrentlyEvaluatingBinding_helper(
BindingEvaluationState *currentState)
const
614 d.addObserver(dependencyObserver.
ptr);
630 if (notifyObserver_helper(propertyDataPtr,
storage, observer, bindingObservers) == Evaluated) {
641 observer.notify(propertyDataPtr);
642 for (
auto &&bindingObserver: bindingObservers)
643 bindingObserver.binding()->notifyNonRecursive();
648QPropertyBindingData::NotificationResult QPropertyBindingData::notifyObserver_helper
654#ifdef QT_HAS_FAST_CURRENT_THREAD_ID
663 delay->addProperty(
this, propertyDataPtr);
675 d.setChangeHandler(changeHandler);
678#if QT_DEPRECATED_SINCE(6, 6)
682 next.setTag(ObserverIsAlias);
692 d.observeProperty(propPrivate);
703 binding = std::exchange(
other.binding, {});
705 prev = std::exchange(
other.prev, {});
709 prev.setPointer(
this);
721 binding = std::exchange(
other.binding, {});
723 prev = std::exchange(
other.prev, {});
727 prev.setPointer(
this);
750 ptr->changeHandler = changeHandler;
757 ptr->binding = binding;
768 ptr->binding = binding;
791 if (observer->
binding == binding) {
792 qCritical(
"Property depends on itself!");
796 observer = observer->next.data();
811 auto bindingToEvaluate = observer->
binding;
814 if (bindingToEvaluate->evaluateRecursive_inline(bindingObservers, status))
815 bindingObservers.
push_back(std::move(bindingObserver));
827 property.addObserver(
ptr);
890 d->description = description;
926 d = std::move(
other.d);
2178 static_assert(
alignof(
Pair) ==
alignof(
void *));
2179 static_assert(
alignof(size_t) ==
alignof(
void *));
2186 return reinterpret_cast<Pair *
>(dd + 1);
2192 void *nd = malloc(allocSize);
2193 memset(nd, 0, allocSize);
2195 newData->
size = newSize;
2202 for (
size_t i = 0;
i <
d->
size; ++
i, ++
p) {
2230 return &
p[
index].bindingData;
2251 return &
p[
index].bindingData;
2260 return &
p[
index].bindingData;
2268 for (
size_t i = 0;
i <
d->
size; ++
i) {
2300void QBindingStorage::reinitAfterThreadMove()
2306void QBindingStorage::clear()
2310 bindingStatus =
nullptr;
2319#ifdef QT_HAS_FAST_CURRENT_THREAD_ID
2329 if (!currentBinding)
2334 storage->registerWithCurrentlyEvaluatingBinding(currentBinding);
2345 return bindingStatus;
2391 return current->property ==
property;
2395namespace BindableWarnings {
2402 <<
"The QBindable does not allow interaction with the binding.";
2406 <<
"The QBindable is read-only.";
2411 <<
"The QBindable is invalid.";
2418 qCWarning(lcQPropertyBinding) <<
"setBinding: Could not set binding as the property expects it to be of type"
2420 <<
"but got" <<
expected.name() <<
"instead.";
2431namespace PropertyAdaptorSlotObjectHelpers {
2436 auto mt = adaptor->metaProperty().metaType();
2438 mt.construct(
value, adaptor->metaProperty().read(adaptor->object()).data());
2445 adaptor->metaProperty().write(adaptor->object(),
2461 type.construct(
value, adaptor->metaProperty().read(adaptor->object()).data());
2487#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
2501 if (!
self->bindingData_.hasBinding())
2502 self->bindingData_.notifyObservers(self);
2522 if (!metaProperty.
isValid()) {
2523 qCWarning(lcQPropertyBinding) <<
"QUntypedBindable: Property is not valid";
2534 <<
"QUntypedBindable: Property" << metaProperty.
name() <<
"has no notify signal";
2539 if (metaProperty.
metaType() != metatype) {
2540 qCWarning(lcQPropertyBinding) <<
"QUntypedBindable: Property" << metaProperty.
name()
2542 <<
"does not match requested type" << metatype.name();
2548 qCWarning(lcQPropertyBinding) <<
"QUntypedBindable: Property" << metaProperty.
name()
2549 <<
"does not belong to this object";
2574 auto propertyIndex =
obj->metaObject()->indexOfProperty(
property);
2575 if (propertyIndex < 0) {
2577 <<
"QUntypedBindable: No property named" <<
property;
2580 return obj->metaObject()->property(propertyIndex);
QString toString() const
Returns a deep copy of this string view's data as a QString.
const QBindingStatus * status(QtPrivate::QBindingStatusAccessToken) const
static QObjectPrivate * get(QObject *o)
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
QtPrivate::QPropertyAdaptorSlotObject * getPropertyAdaptorSlotObject(const QMetaProperty &property)
QPropertyBindingError::Type type
~QPropertyBindingError()
Destroys the QPropertyBindingError.
QString description() const
Returns a descriptive error message for the QPropertyBindingError if it has been set.
Type
This enum specifies which error occurred.
QPropertyBindingError & operator=(const QPropertyBindingError &other)
Copies other to this QPropertyBindingError.
Type type() const
Returns the type of the QPropertyBindingError.
QPropertyBindingError()
Default constructs QPropertyBindingError.
Q_CORE_EXPORT void destroyAndFreeMemory()
T * data() const noexcept
void reset(T *ptr=nullptr) noexcept
~QPropertyBindingPrivate()
void clearDependencyObservers()
static QPropertyBindingPrivate * currentlyEvaluatingBinding()
QPropertyObserverPointer allocateDependencyObserver_slow()
static constexpr size_t getSizeEnsuringAlignment()
void setProperty(QUntypedPropertyData *propertyPtr)
bool evaluateRecursive(PendingBindingObserverList &bindingObservers, QBindingStatus *status=nullptr)
static void destroyAndFreeMemory(QPropertyBindingPrivate *priv)
void notifyNonRecursive(const PendingBindingObserverList &bindingObservers)
Q_ALWAYS_INLINE QPropertyObserverPointer allocateDependencyObserver()
bool Q_ALWAYS_INLINE evaluateRecursive_inline(PendingBindingObserverList &bindingObservers, QBindingStatus *status)
QtPrivate::QPropertyObserverCallback staticObserverCallback
size_t dependencyObserverCount
NotificationState notifyNonRecursive()
QUntypedPropertyData * propertyDataPtr
@ ObserverNotifiesBinding
@ ObserverNotifiesChangeHandler
void(*)(QPropertyObserver *, QUntypedPropertyData *) ChangeHandler
void setSource(const Property &property)
QPropertyObserver & operator=(QPropertyObserver &&other) noexcept
constexpr QPropertyObserver()=default
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION
const QtPrivate::QBindableInterface * iface
constexpr QUntypedBindable()=default
Default-constructs a QUntypedBindable.
QMetaType valueMetaType() const
Returns the meta-type of the binding.
QUntypedPropertyBinding()
Constructs a null QUntypedPropertyBinding.
QPropertyBindingError error() const
Returns the error state of the binding.
bool isNull() const
Returns true if the QUntypedPropertyBinding is null.
~QUntypedPropertyBinding()
Destroys the QUntypedPropertyBinding.
friend class QPropertyBindingPrivate
QUntypedPropertyBinding & operator=(const QUntypedPropertyBinding &other)
Copy-assigns other to this QUntypedPropertyBinding.
void push_back(const T &t)
const QMetaProperty & metaProperty() const
const QPropertyBindingData & bindingData() const
void registerWithCurrentlyEvaluatingBinding(QtPrivate::BindingEvaluationState *currentBinding) const
QPropertyBindingPrivate * binding() const
QUntypedPropertyBinding setBinding(const QUntypedPropertyBinding &newBinding, QUntypedPropertyData *propertyDataPtr, QPropertyObserverCallback staticObserverCallback=nullptr, QPropertyBindingWrapper bindingWrapper=nullptr)
static constexpr quintptr DelayedNotificationBit
void evaluateIfDirty(const QUntypedPropertyData *) const
bool isNotificationDelayed() const
void notifyObservers(QUntypedPropertyData *propertyDataPtr) const
QPropertyBindingData()=default
static constexpr quintptr BindingBit
void registerWithCurrentlyEvaluatingBinding() const
Combined button and popup list for selecting options.
void printMetaTypeMismatch(QMetaType actual, QMetaType expected)
void printUnsuitableBindableWarning(QAnyStringView prefix, BindableWarnings::Reason reason)
void getter(const QUntypedPropertyData *d, void *value)
void setObserver(const QUntypedPropertyData *d, QPropertyObserver *observer)
QUntypedPropertyBinding setBinding(QUntypedPropertyData *d, const QUntypedPropertyBinding &binding, QPropertyBindingWrapper wrapper)
void setter(QUntypedPropertyData *d, const void *value)
bool bindingWrapper(QMetaType type, QUntypedPropertyData *d, QtPrivate::QPropertyBindingFunction binding, QUntypedPropertyData *temp, void *value)
QUntypedPropertyBinding getBinding(const QUntypedPropertyData *d)
bool(*)(QMetaType, QUntypedPropertyData *dataPtr, QPropertyBindingFunction) QPropertyBindingWrapper
bool isAnyBindingEvaluating()
void initBindingStatusThreadId()
BindingEvaluationState * suspendCurrentBindingStatus()
bool isPropertyInBindingWrapper(const QUntypedPropertyData *property)
Q_AUTOTEST_EXPORT QBindingStatus * getBindingStatus(QBindingStatusAccessToken)
void(*)(QUntypedPropertyData *) QPropertyObserverCallback
void restoreBindingStatus(BindingEvaluationState *status)
Q_CORE_EXPORT void beginPropertyUpdateGroup()
Q_CORE_EXPORT void endPropertyUpdateGroup()
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
size_t qHash(const QFileSystemWatcherPathKey &key, size_t seed=0)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
static ControlElement< T > * ptr(QWidget *widget)
constexpr const T & qMin(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
static Q_CONSTINIT thread_local QBindingStatus bindingStatus
#define QStringLiteral(str)
QT_END_NAMESPACE typedef QT_PREPEND_NAMESPACE(quintptr) WId
if(qFloatDistance(a, b)<(1<< 7))
[0]
QtPrivate::CompatPropertySafePoint * currentCompatProperty
QPropertyDelayedNotifications * groupUpdateData
QtPrivate::BindingEvaluationState * currentlyEvaluatingBinding
QPropertyBindingData bindingData
QUntypedPropertyData * data
static Pair * pairs(QBindingStorageData *dd)
QBindingStoragePrivate(QBindingStorageData *&_d)
void reallocate(size_t newSize)
QPropertyBindingData * get(QUntypedPropertyData *data, bool create)
QPropertyBindingData * get(const QUntypedPropertyData *data)
static void fixupAfterMove(QtPrivate::QPropertyBindingData *ptr)
void Q_ALWAYS_INLINE addObserver(QPropertyObserver *observer)
const QtPrivate::QPropertyBindingData * ptr
QPropertyBindingPrivate * binding() const
QPropertyObserverPointer firstObserver() const
QPropertyDelayedNotifications * next
static constexpr auto PageSize
void notify(qsizetype index)
void addProperty(const QPropertyBindingData *bindingData, QUntypedPropertyData *propertyData)
QPropertyProxyBindingData delayedProperties[size]
void evaluateBindings(PendingBindingObserverList &bindingObservers, qsizetype index, QBindingStatus *status)
static constexpr qsizetype size
QPropertyObserver * next() const
void noSelfDependencies(QPropertyBindingPrivate *binding)
void notify(QUntypedPropertyData *propertyDataPtr)
QPropertyBindingPrivate * binding() const
void evaluateBindings(PendingBindingObserverList &bindingObservers, QBindingStatus *status)
void observeProperty(QPropertyBindingDataPointer property)
void setBindingToNotify_unsafe(QPropertyBindingPrivate *binding)
void setChangeHandler(QPropertyObserver::ChangeHandler changeHandler)
void setBindingToNotify(QPropertyBindingPrivate *binding)
const QtPrivate::QPropertyBindingData * originalBindingData
QPropertyBindingPrivate * binding
QVarLengthArray< const QPropertyBindingData *, 8 > alreadyCaptureProperties
BindingEvaluationState(QPropertyBindingPrivate *binding, QBindingStatus *status)
BindingEvaluationState * previousState
BindingEvaluationState ** currentState
const MoveCtrFn moveConstruct
QtPrivate::BindingEvaluationState ** currentlyEvaluatingBindingList
CompatPropertySafePoint * previousState
CompatPropertySafePoint ** currentState
QtPrivate::BindingEvaluationState * bindingState
Q_CORE_EXPORT CompatPropertySafePoint(QBindingStatus *status, QUntypedPropertyData *property)
const QtPrivate::BindingFunctionVTable * vtable
virtual HRESULT STDMETHODCALLTYPE Compare(__RPC__in_opt ITextRangeProvider *range, __RPC__out BOOL *pRetVal)=0