5#include "qx/core/qx_core_export.h"
8#include "__private/qx-property_detail.h"
54 using ManagerPtr = std::shared_ptr<_QxPrivate::PropertyObserverManager>;
55 using WeakManagerPtr = std::weak_ptr<_QxPrivate::PropertyObserverManager>;
56 using ObserverId = _QxPrivate::PropertyObserverManager::ObserverId;
60 WeakManagerPtr mManager;
87 std::function<T()> mFunctor;
93 template<std::invocable Functor>
95 mFunctor(std::forward<Functor>(f))
100 bool isNull()
const {
return !
static_cast<bool>(mFunctor); }
104 explicit operator bool()
const {
return !
isNull(); }
114 using ObserverManager = _QxPrivate::PropertyObserverManager;
119 std::shared_ptr<ObserverManager> mObserverManager;
145 mObserverManager(new ObserverManager)
152 inline bool valueSame(
const T&
value)
const
161 requires std::same_as<std::remove_cvref_t<U>, T>
162 bool updateIfDifferent(U&& newValue)
164 if(valueSame(newValue))
171 template<
typename Binding>
172 PropertyBinding<T> cycleBinding(Binding&& b)
174 auto oldBinding = std::exchange(mBinding, std::forward<Binding>(b));
176 notifyBindingRemoved();
178 notifyBindingAdded();
183 bool callBinding()
override
186 return updateIfDifferent(mBinding());
189 void notifyObservers()
const override { mObserverManager->invokeAll(); }
213 template<std::invocable Functor>
221 attachToCurrentEval();
228 if(updateIfDifferent(newValue))
229 notifyValueChanged();
235 if(updateIfDifferent(std::move(newValue)))
236 notifyValueChanged();
239 template<std::invocable Functor>
242 auto id = mObserverManager->add(std::forward<Functor>(f));
246 template<std::invocable Functor>
249 template<std::invocable Functor>
256 template<std::invocable Functor>
274 operator const T&()
const {
return value(); }
286 Q_DISABLE_COPY_MOVE(ObjectPropertyAdapter);
296 ObjectPropertyAdapterLiaison mLiaison;
298 bool mBlockPropertyUpdate;
319 mBlockPropertyUpdate(false)
322 auto adaptedMetaType = QMetaType::fromType<T>();
323 auto propertyMetaType =
property.metaType();
324 if(propertyMetaType != adaptedMetaType)
326 qWarning(
"Qx::ObjectPropertyAdapter: The type of property %s, %s, is not the same as the"
327 "adapter type, %s.", property.
name(), propertyMetaType.name(), adaptedMetaType.name());
333 qWarning(
"Qx::ObjectPropertyAdapter: Property %s has no notify signal.", property.
name());
338 if(Q_UNLIKELY(!mLiaison.configure(obj, property)))
341 QObject::connect(&mLiaison, &ObjectPropertyAdapterLiaison::objectDeleted, &mLiaison, [
this]{
349 QObject::connect(&mLiaison, &ObjectPropertyAdapterLiaison::propertyNotified, &mLiaison, [
this]{
350 handleExternalUpdate();
354 mCache = readProperty();
359 ~ObjectPropertyAdapter()
362 ObjectPropertyAdapterRegistry::instance()->remove(mObject, mProperty);
378 qWarning(
"Qx::ObjectPropertyAdapter: Null object provided.");
384 qWarning(
"Qx::ObjectPropertyAdapter: Invalid property provided.");
394 qWarning(
"Qx::ObjectPropertyAdapter: The provided property does not belong to the provided object.");
403 if(!basicInputValidation(obj, property))
406 auto man = ObjectPropertyAdapterRegistry::instance();
407 ObjectPropertyAdapter* adptr =
static_cast<ObjectPropertyAdapter*
>(man->retrieve(obj, property));
410 auto newAdptr =
new ObjectPropertyAdapter(obj, property);
411 if(newAdptr->isValid())
413 man->store(obj, property, newAdptr);
425 bool isValid()
const {
return mObject; }
429 Q_ASSERT(
value.isValid() &&
value.canConvert<T>());
430 return value.value<T>();
433 void writeProperty(
const T&
value)
435 if(mBlockPropertyUpdate)
439 mLiaison.setIgnoreUpdates(
true);
442 mLiaison.setIgnoreUpdates(
false);
445 void handleExternalUpdate()
450 mBlockPropertyUpdate =
true;
452 mBlockPropertyUpdate =
false;
457 void setValueBypassingBindings(T&& v)
override
459 mCache = std::move(v);
460 writeProperty(mCache);
463 const T& valueBypassingBindings()
const override {
return mCache; }
464 bool isPropertyWriteable()
const {
return mProperty.
isWritable(); }
515 auto adptr = _QxPrivate::ObjectPropertyAdapter<T>::get(obj, property);
519 mReadOnly = !adptr->isPropertyWriteable();
527 if (propertyIndex < 0)
529 qWarning(
"Qx::Bindable: No property named %s for QObject bindable (obj = %p).", property, obj);
538 bool mutableCheck()
const
542 qWarning(
"Qx::Bindable: Attempt to write/mutate read-only property through Bindable (%p).",
this);
590 template<std::invocable Functor>
597 return mBindable->
setBinding(std::forward<Functor>(f));
610 const T&
value()
const { Q_ASSERT(mBindable);
return mBindable->
value(); }
627 mBindable->
setValue(std::forward<T>(newValue));
630 template<std::invocable Functor>
634 return mBindable->
addNotifier(std::forward<Functor>(f));
637 template<std::invocable Functor>
640 template<std::invocable Functor>
644 return mBindable->
subscribe(std::forward<Functor>(f));
647 template<std::invocable Functor>
659 return mBindable->operator->();
662 const T&
operator*()
const { Q_ASSERT(mBindable);
return mBindable->operator*(); }
663 operator const T&()
const { Q_ASSERT(mBindable);
return static_cast<const T&
>(*mBindable); }
671 mBindable->
setValue(std::forward<T>(newValue));
702 template<std::invocable Functor>
708 mData(std::forward<T>(initialValue))
728 mData = std::exchange(other.mData, {});
The AbstractBindableProperty class provides the baseline feature for bindable properties of the Qx Bi...
Definition qx-property.h:110
PropertyBinding< T > setBinding(Functor &&f)
Definition qx-property.h:214
void subscribeLifetime(Functor &&f) const
Definition qx-property.h:257
virtual void setValueBypassingBindings(T &&v)=0
void setValue(T &&newValue)
Definition qx-property.h:232
void setValue(const T &newValue)
Definition qx-property.h:225
const T & operator*() const
Definition qx-property.h:273
bool hasBinding() const
Definition qx-property.h:217
const T & value() const
Definition qx-property.h:219
PropertyNotifier addNotifier(Functor &&f) const
Definition qx-property.h:240
PropertyNotifier subscribe(Functor &&f) const
Definition qx-property.h:250
virtual const T & valueBypassingBindings() const =0
PropertyBinding< T > setBinding(const PropertyBinding< T > &binding)
Definition qx-property.h:216
PropertyBinding< T > takeBinding()
Definition qx-property.h:210
AbstractBindableProperty()
Definition qx-property.h:144
void addLifetimeNotifier(Functor &&f) const
Definition qx-property.h:247
void removeBinding()
Definition qx-property.h:211
void setValueBypassingBindings(const T &v)
Definition qx-property.h:205
PropertyBinding< T > binding() const
Definition qx-property.h:209
AbstractBindableProperty & operator=(AbstractBindableProperty &&other) noexcept=default
AbstractBindableProperty(AbstractBindableProperty &&other) noexcept=default
Bindable is a wrapper class around binding-enabled properties that provides uniform access,...
Definition qx-property.h:474
const T & value() const
Definition qx-property.h:610
void setValueBypassingBindings(T &&v)
Definition qx-property.h:560
Bindable(QObject *obj, const QMetaProperty &property)
Definition qx-property.h:511
const T & valueBypassingBindings() const
Definition qx-property.h:569
bool hasBinding() const
Definition qx-property.h:609
Bindable & operator=(const T &newValue) noexcept
Definition qx-property.h:675
PropertyBinding< T > setBinding(const PropertyBinding< T > &binding)
Definition qx-property.h:600
Bindable(AbstractBindableProperty< T > &bp)
Definition qx-property.h:501
Bindable(const AbstractBindableProperty< T > &bp)
Definition qx-property.h:506
Bindable()
Definition qx-property.h:496
void subscribeLifetime(Functor &&f) const
Definition qx-property.h:648
Bindable(QObject *obj, const char *property)
Definition qx-property.h:523
void setValue(const T &newValue)
Definition qx-property.h:612
bool isValid() const
Definition qx-property.h:651
PropertyBinding< T > binding() const
Definition qx-property.h:570
Bindable & operator=(T &&newValue) noexcept
Definition qx-property.h:665
void addLifetimeNotifier(Functor &&f) const
Definition qx-property.h:638
void removeBinding()
Definition qx-property.h:581
void setValueBypassingBindings(const T &v)
Definition qx-property.h:551
PropertyNotifier addNotifier(Functor &&f) const
Definition qx-property.h:631
PropertyBinding< T > takeBinding()
Definition qx-property.h:572
PropertyNotifier subscribe(Functor &&f) const
Definition qx-property.h:641
void setValue(T &&newValue)
Definition qx-property.h:621
bool isReadOnly() const
Definition qx-property.h:652
const T & operator*() const
Definition qx-property.h:662
PropertyBinding< T > setBinding(Functor &&f)
Definition qx-property.h:591
The PropertyBinding class acts as a functor for properties with automatic property bindings.
Definition qx-property.h:81
PropertyBinding()=default
PropertyBinding(Functor &&f)
Definition qx-property.h:94
T operator()() const
Definition qx-property.h:105
bool isNull() const
Definition qx-property.h:100
The PropertyNotifier class controls the lifecycle of a change callback installed on a Property.
Definition qx-property.h:48
The Property class is a template class that enables automatic property bindings.
Definition qx-property.h:688
const T & valueBypassingBindings() const override
Definition qx-property.h:719
Property(const T &initialValue)
Definition qx-property.h:711
Property(T &&initialValue)
Definition qx-property.h:707
Property(const PropertyBinding< T > &binding)
Definition qx-property.h:705
Property & operator=(T &&newValue)
Definition qx-property.h:734
Property(Functor &&f)
Definition qx-property.h:703
Property(Property &&other) noexcept
Definition qx-property.h:700
Property & operator=(Property &&other) noexcept
Definition qx-property.h:723
Property & operator=(const T &newValue)
Definition qx-property.h:735
Property()
Definition qx-property.h:697
void setValueBypassingBindings(T &&v) override
Definition qx-property.h:718
The ScopedPropertyUpdateGroup class starts an update group when constructed and ends it when destroye...
Definition qx-property.h:744
~ScopedPropertyUpdateGroup() noexcept(false)
Definition qx-property.h:748
Q_NODISCARD_CTOR ScopedPropertyUpdateGroup()
Definition qx-property.h:747
Definition qx-helpers.h:54
Specifies that a type defines an equal to operator for itself (with strict return).
Definition qx-concepts.h:404
The Qx namespace is the main namespace through which all non-global functionality of the Qx library i...
Definition qx-abstracterror.cpp:13
container_arrow_result< T > container_arrow_operator(T &data)
Definition qx-helpers.h:57
void beginPropertyUpdateGroup()
Definition qx-property.cpp:1524
void endPropertyUpdateGroup()
Definition qx-property.cpp:1533
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
The qx-concepts header file provides a library of general purpose concepts as an extension of the sta...
The qx-concepts header file provides a set of various convenience functions that are are designed to ...