-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add extended bindable property classes with convenience functions
- Loading branch information
1 parent
b399b6a
commit 32aa011
Showing
3 changed files
with
382 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
#ifndef QX_PROPERTY_H | ||
#define QX_PROPERTY_H | ||
|
||
// Qt Includes | ||
#include <QProperty> | ||
#include <QList> | ||
|
||
/* Lots of repetition here that could be avoided using a CRTP class | ||
* that the final Qx derived versions inherit from in addition | ||
* to the originals, but that would make the interface documentation | ||
* much more messy | ||
*/ | ||
|
||
/*! @cond */ | ||
#define QX_OBJECT_BINDABLE_PROPERTY_3(Class, Type, name) \ | ||
static constexpr size_t _qx_property_##name##_offset() \ | ||
{ \ | ||
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \ | ||
return offsetof(Class, name); \ | ||
QT_WARNING_POP \ | ||
} \ | ||
Qx::ObjectBindableProperty<Class, Type, Class::_qx_property_##name##_offset, nullptr> name; | ||
|
||
#define QX_OBJECT_BINDABLE_PROPERTY_4(Class, Type, name, Signal) \ | ||
static constexpr size_t _qx_property_##name##_offset() \ | ||
{ \ | ||
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \ | ||
return offsetof(Class, name); \ | ||
QT_WARNING_POP \ | ||
} \ | ||
Qx::ObjectBindableProperty<Class, Type, Class::_qx_property_##name##_offset, Signal> name; | ||
|
||
#define QX_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_4(Class, Type, name, value) \ | ||
static constexpr size_t _qx_property_##name##_offset() \ | ||
{ \ | ||
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \ | ||
return offsetof(Class, name); \ | ||
QT_WARNING_POP \ | ||
} \ | ||
Qx::ObjectBindableProperty<Class, Type, Class::_qx_property_##name##_offset, nullptr> name = \ | ||
Qx::ObjectBindableProperty<Class, Type, Class::_qx_property_##name##_offset, nullptr>( \ | ||
value); | ||
|
||
#define QX_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_5(Class, Type, name, valueignal) \ | ||
static constexpr size_t _qx_property_##name##_offset() \ | ||
{ \ | ||
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \ | ||
return offsetof(Class, name); \ | ||
QT_WARNING_POP \ | ||
} \ | ||
Qx::ObjectBindableProperty<Class, Type, Class::_qx_property_##name##_offset, Signal> name = \ | ||
Qx::ObjectBindableProperty<Class, Type, Class::_qx_property_##name##_offset, Signal>( \ | ||
value); | ||
/*! @endcond */ | ||
|
||
#define QX_Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...) \ | ||
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \ | ||
QT_OVERLOADED_MACRO(QX_OBJECT_BINDABLE_PROPERTY_WITH_ARGS, __VA_ARGS__) \ | ||
QT_WARNING_POP | ||
|
||
#define QX_Q_OBJECT_BINDABLE_PROPERTY(...) \ | ||
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \ | ||
QT_OVERLOADED_MACRO(QX_OBJECT_BINDABLE_PROPERTY, __VA_ARGS__) \ | ||
QT_WARNING_POP | ||
|
||
#define QX_Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...) \ | ||
static constexpr size_t _qx_property_##name##_offset() \ | ||
{ \ | ||
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \ | ||
return offsetof(Class, name); \ | ||
QT_WARNING_POP \ | ||
} \ | ||
Qx::ObjectComputedProperty<Class, Type, Class::_qx_property_##name##_offset, __VA_ARGS__> name; | ||
|
||
namespace Qx | ||
{ | ||
|
||
template<typename T> | ||
class Property : public QProperty<T> | ||
{ | ||
//-Instance Members------------------------------------------------------------------------------------------ | ||
private: | ||
QList<QPropertyNotifier> mManagedNotifiers; | ||
|
||
//-Constructor---------------------------------------------------------------------------------------------- | ||
public: | ||
using QProperty<T>::QProperty; | ||
|
||
//-Instance Functions---------------------------------------------------------------------------------------------- | ||
public: | ||
template<typename Functor> | ||
QPropertyNotifier addSubscription(Functor f) const | ||
{ | ||
f(); | ||
return addNotifier(std::forward<Functor>(f)); | ||
} | ||
|
||
template<typename Functor> | ||
void lifetimeSubscribe(Functor f) const | ||
{ | ||
f(); | ||
mManagedNotifiers.append(addNotifier(std::forward<Functor>(f))); | ||
} | ||
|
||
template<typename Functor> | ||
void lifetimeOnValueChanged(Functor f) const | ||
{ | ||
mManagedNotifiers.append(addNotifier(std::forward<Functor>(f))); | ||
} | ||
}; | ||
|
||
template<typename T> | ||
class Bindable : public QBindable<T> | ||
{ | ||
//-Instance Members------------------------------------------------------------------------------------------ | ||
private: | ||
QList<QPropertyNotifier> mManagedNotifiers; | ||
|
||
//-Constructor---------------------------------------------------------------------------------------------- | ||
public: | ||
using QBindable<T>::QBindable; | ||
|
||
//-Instance Functions---------------------------------------------------------------------------------------------- | ||
public: | ||
template<typename Functor> | ||
QPropertyNotifier addSubscription(Functor f) const | ||
{ | ||
f(); | ||
return addNotifier(std::forward<Functor>(f)); | ||
} | ||
|
||
template<typename Functor> | ||
void lifetimeSubscribe(Functor f) const | ||
{ | ||
f(); | ||
mManagedNotifiers.append(addNotifier(std::forward<Functor>(f))); | ||
} | ||
|
||
template<typename Functor> | ||
void lifetimeOnValueChanged(Functor f) const | ||
{ | ||
mManagedNotifiers.append(addNotifier(std::forward<Functor>(f))); | ||
} | ||
}; | ||
|
||
template<typename Class, typename T, auto Offset, auto Signal = nullptr> | ||
class ObjectBindableProperty : public QObjectBindableProperty<Class, T, Offset, Signal> | ||
{ | ||
//-Instance Members------------------------------------------------------------------------------------------ | ||
private: | ||
QList<QPropertyNotifier> mManagedNotifiers; | ||
|
||
//-Constructor---------------------------------------------------------------------------------------------- | ||
public: | ||
using QObjectBindableProperty<Class, T, Offset, Signal>::QObjectBindableProperty; | ||
|
||
//-Instance Functions---------------------------------------------------------------------------------------------- | ||
public: | ||
template<typename Functor> | ||
QPropertyNotifier addSubscription(Functor f) const | ||
{ | ||
f(); | ||
return addNotifier(std::forward<Functor>(f)); | ||
} | ||
|
||
template<typename Functor> | ||
void lifetimeSubscribe(Functor f) const | ||
{ | ||
f(); | ||
mManagedNotifiers.append(addNotifier(std::forward<Functor>(f))); | ||
} | ||
|
||
template<typename Functor> | ||
void lifetimeOnValueChanged(Functor f) const | ||
{ | ||
mManagedNotifiers.append(addNotifier(std::forward<Functor>(f))); | ||
} | ||
}; | ||
|
||
template<typename Class, typename T, auto Offset, auto Getter> | ||
class ObjectComputedProperty : public QObjectComputedProperty<Class, T, Offset, Getter> | ||
{ | ||
//-Instance Members------------------------------------------------------------------------------------------ | ||
private: | ||
QList<QPropertyNotifier> mManagedNotifiers; | ||
|
||
//-Constructor---------------------------------------------------------------------------------------------- | ||
public: | ||
using QObjectBindableProperty<Class, T, Offset, Getter>::QObjectBindableProperty; | ||
|
||
//-Instance Functions---------------------------------------------------------------------------------------------- | ||
public: | ||
template<typename Functor> | ||
QPropertyNotifier addSubscription(Functor f) const | ||
{ | ||
f(); | ||
return addNotifier(std::forward<Functor>(f)); | ||
} | ||
|
||
template<typename Functor> | ||
void lifetimeSubscribe(Functor f) const | ||
{ | ||
f(); | ||
mManagedNotifiers.append(addNotifier(std::forward<Functor>(f))); | ||
} | ||
|
||
template<typename Functor> | ||
void lifetimeOnValueChanged(Functor f) const | ||
{ | ||
mManagedNotifiers.append(addNotifier(std::forward<Functor>(f))); | ||
} | ||
}; | ||
|
||
} | ||
|
||
#endif // QX_PROPERTY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/*! | ||
* @file qx-property.h | ||
* @ingroup qx-core | ||
* | ||
* @brief The qx-property.h header file provides access to extended bindable property types. | ||
*/ | ||
|
||
//-Macros---------------------------------------------------------------------------------------------------------- | ||
/*! | ||
* @def QX_Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...) | ||
* | ||
* Same as Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS, but uses Qx::ObjectBindableProperty. | ||
*/ | ||
|
||
/*! | ||
* @def QX_Q_OBJECT_BINDABLE_PROPERTY(...) | ||
* | ||
* Same as Q_OBJECT_BINDABLE_PROPERTY, but uses Qx::ObjectBindableProperty. | ||
*/ | ||
|
||
/*! | ||
* @def QX_Q_OBJECT_COMPUTED_PROPERTY(...) | ||
* | ||
* Same as Q_OBJECT_COMPUTED_PROPERTY, but uses Qx::ObjectComputedProperty. | ||
*/ | ||
|
||
namespace Qx | ||
{ | ||
//=============================================================================================================== | ||
// Property | ||
//=============================================================================================================== | ||
|
||
/*! | ||
* @class Property qx/core/qx-property.h | ||
* @ingroup qx-core | ||
* | ||
* @brief The Property class extends QProperty<T> with additional convenience functions. | ||
*/ | ||
|
||
//-Class Functions---------------------------------------------------------------------------------------------- | ||
//Public: | ||
/*! | ||
* @fn template<typename Functor> QPropertyNotifier Property::addSubscription(Functor f) const | ||
* | ||
* Equivalent to calling f(), followed by addNotifier(f). | ||
* | ||
* Returns a QPropertyNotifier, which is easier to store than QPropertyChangeHandler since it isn't a template. | ||
*/ | ||
|
||
/*! | ||
* @fn template<typename Functor> void Property::lifetimeSubscribe(Functor f) const | ||
* | ||
* Same as subscribe(), except that the lifetime of the subscription is tied to the lifetime | ||
* of the property, such that it's canceled when the property is destroyed as does not need to be managed | ||
* by the user. | ||
*/ | ||
|
||
/*! | ||
* @fn template<typename Functor> void Property::lifetimeOnValueChanged(Functor f) const | ||
* | ||
* Same as onValueChanged(), except that the lifetime of the subscription is tied to the lifetime | ||
* of the property, such that it's canceled when the property is destroyed as does not need to be managed | ||
* by the user. | ||
*/ | ||
|
||
//=============================================================================================================== | ||
// Bindable | ||
//=============================================================================================================== | ||
|
||
/*! | ||
* @class Bindable qx/core/qx-property.h | ||
* @ingroup qx-core | ||
* | ||
* @brief The Bindable class extends QBindable<T> with additional convenience functions. | ||
*/ | ||
|
||
//-Class Functions---------------------------------------------------------------------------------------------- | ||
//Public: | ||
/*! | ||
* @fn template<typename Functor> QPropertyNotifier Bindable::addSubscription(Functor f) const | ||
* | ||
* @copydoc Property::addSubscription() | ||
*/ | ||
|
||
/*! | ||
* @fn template<typename Functor> void Bindable::lifetimeSubscribe(Functor f) const | ||
* | ||
* @copydoc Property::lifetimeSubscribe() | ||
*/ | ||
|
||
/*! | ||
* @fn template<typename Functor> void Bindable::lifetimeOnValueChanged(Functor f) const | ||
* | ||
* @copydoc Property::lifetimeOnValueChanged() | ||
*/ | ||
|
||
//=============================================================================================================== | ||
// ObjectBindableProperty | ||
//=============================================================================================================== | ||
|
||
/*! | ||
* @class ObjectBindableProperty qx/core/qx-property.h | ||
* @ingroup qx-core | ||
* | ||
* @brief The ObjectBindableProperty class extends QObjectBindableProperty<T> with additional convenience functions. | ||
* | ||
* @note This class should not be instantiated directly, but instead with QX_Q_OBJECT_BINDABLE_PROPERTY() | ||
* or QX_Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(). | ||
*/ | ||
|
||
//-Class Functions---------------------------------------------------------------------------------------------- | ||
//Public: | ||
/*! | ||
* @fn template<typename Functor> QPropertyNotifier ObjectBindableProperty::addSubscription(Functor f) const | ||
* | ||
* @copydoc Property::addSubscription() | ||
*/ | ||
|
||
/*! | ||
* @fn template<typename Functor> void ObjectBindableProperty::lifetimeSubscribe(Functor f) const | ||
* | ||
* @copydoc Property::lifetimeSubscribe() | ||
*/ | ||
|
||
/*! | ||
* @fn template<typename Functor> void ObjectBindableProperty::lifetimeOnValueChanged(Functor f) const | ||
* | ||
* @copydoc Property::lifetimeOnValueChanged() | ||
*/ | ||
|
||
//=============================================================================================================== | ||
// ObjectComputedProperty | ||
//=============================================================================================================== | ||
|
||
/*! | ||
* @class ObjectComputedProperty qx/core/qx-property.h | ||
* @ingroup qx-core | ||
* | ||
* @brief The ObjectComputedProperty class extends QObjectComputedProperty<T> with additional convenience functions. | ||
* | ||
* @note This class should not be instantiated directly, but instead with QX_Q_OBJECT_COMPUTED_PROPERTY(). | ||
*/ | ||
|
||
//-Class Functions---------------------------------------------------------------------------------------------- | ||
//Public: | ||
/*! | ||
* @fn template<typename Functor> QPropertyNotifier ObjectComputedProperty::addSubscription(Functor f) const | ||
* | ||
* @copydoc Property::addSubscription() | ||
*/ | ||
|
||
/*! | ||
* @fn template<typename Functor> void ObjectComputedProperty::lifetimeSubscribe(Functor f) const | ||
* | ||
* @copydoc Property::lifetimeSubscribe() | ||
*/ | ||
|
||
/*! | ||
* @fn template<typename Functor> void ObjectComputedProperty::lifetimeOnValueChanged(Functor f) const | ||
* | ||
* @copydoc Property::lifetimeOnValueChanged() | ||
*/ | ||
|
||
} |