diff options
Diffstat (limited to 'src/qml/qml/qqmllist.h')
-rw-r--r-- | src/qml/qml/qqmllist.h | 129 |
1 files changed, 101 insertions, 28 deletions
diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h index 90ec57c911..17333ca9e4 100644 --- a/src/qml/qml/qqmllist.h +++ b/src/qml/qml/qqmllist.h @@ -55,22 +55,28 @@ struct QMetaObject; template<typename T> class QQmlListProperty { public: - typedef void (*AppendFunction)(QQmlListProperty<T> *, T*); - typedef int (*CountFunction)(QQmlListProperty<T> *); - typedef T *(*AtFunction)(QQmlListProperty<T> *, int); - typedef void (*ClearFunction)(QQmlListProperty<T> *); - - QQmlListProperty() - : append(nullptr), - count(nullptr), - at(nullptr), - clear(nullptr) - {} + using AppendFunction = void (*)(QQmlListProperty<T> *, T *); + using CountFunction = int (*)(QQmlListProperty<T> *); + using AtFunction = T *(*)(QQmlListProperty<T> *, int); + using ClearFunction = void (*)(QQmlListProperty<T> *); + using ReplaceFunction = void (*)(QQmlListProperty<T> *, int, T *); + using RemoveLastFunction = void (*)(QQmlListProperty<T> *); + + QQmlListProperty() = default; + +#if QT_DEPRECATED_SINCE(5,15) + QT_DEPRECATED_X("Use constructor taking QList pointer, and gain improved performance") QQmlListProperty(QObject *o, QList<T *> &list) : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at), - clear(qlist_clear) + clear(qlist_clear), replace(qslow_replace), removeLast(qslow_removeLast) + {} +#endif + QQmlListProperty(QObject *o, QList<T *> *list) + : object(o), data(list), append(qlist_append), count(qlist_count), at(qlist_at), + clear(qlist_clear), replace(qlist_replace), removeLast(qlist_removeLast) {} + QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t, ClearFunction r ) : object(o), @@ -78,37 +84,47 @@ public: append(a), count(c), at(t), - clear(r) - + clear(r), + replace((a && c && t && r) ? qslow_replace : nullptr), + removeLast((a && c && t && r) ? qslow_removeLast : nullptr) {} - QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction t) + + QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t, + ClearFunction r, ReplaceFunction s, RemoveLastFunction p) : object(o), data(d), - append(nullptr), - count(c), at(t), - clear(nullptr) + append(a), + count(c), + at(t), + clear((!r && p && c) ? qslow_clear : r), + replace((!s && a && c && t && (r || p)) ? qslow_replace : s), + removeLast((!p && a && c && t && r) ? qslow_removeLast : p) + {} + + QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction a) + : object(o), data(d), count(c), at(a) {} + bool operator==(const QQmlListProperty &o) const { return object == o.object && data == o.data && append == o.append && count == o.count && at == o.at && - clear == o.clear; + clear == o.clear && + replace == o.replace && + removeLast == o.removeLast; } QObject *object = nullptr; void *data = nullptr; - AppendFunction append; - - CountFunction count; - AtFunction at; - - ClearFunction clear; - - void *dummy1 = nullptr; - void *dummy2 = nullptr; + AppendFunction append = nullptr; + CountFunction count = nullptr; + AtFunction at = nullptr; + ClearFunction clear = nullptr; + ReplaceFunction replace = nullptr; + RemoveLastFunction removeLast = nullptr; private: static void qlist_append(QQmlListProperty *p, T *v) { @@ -123,6 +139,59 @@ private: static void qlist_clear(QQmlListProperty *p) { return reinterpret_cast<QList<T *> *>(p->data)->clear(); } + static void qlist_replace(QQmlListProperty *p, int idx, T *v) { + return reinterpret_cast<QList<T *> *>(p->data)->replace(idx, v); + } + static void qlist_removeLast(QQmlListProperty *p) { + return reinterpret_cast<QList<T *> *>(p->data)->removeLast(); + } + + static void qslow_replace(QQmlListProperty<T> *list, int idx, T *v) + { + const int length = list->count(list); + if (idx < 0 || idx >= length) + return; + + QVector<T *> stash; + if (list->clear != qslow_clear) { + stash.reserve(length); + for (int i = 0; i < length; ++i) + stash.append(i == idx ? v : list->at(list, i)); + list->clear(list); + for (T *item : qAsConst(stash)) + list->append(list, item); + } else { + stash.reserve(length - idx - 1); + for (int i = length - 1; i > idx; --i) { + stash.append(list->at(list, i)); + list->removeLast(list); + } + list->removeLast(list); + list->append(list, v); + while (!stash.isEmpty()) + list->append(list, stash.takeLast()); + } + } + + static void qslow_clear(QQmlListProperty<T> *list) + { + for (int i = 0, end = list->count(list); i < end; ++i) + list->removeLast(list); + } + + static void qslow_removeLast(QQmlListProperty<T> *list) + { + const int length = list->count(list) - 1; + if (length < 0) + return; + QVector<T *> stash; + stash.reserve(length); + for (int i = 0; i < length; ++i) + stash.append(list->at(list, i)); + list->clear(list); + for (T *item : qAsConst(stash)) + list->append(list, item); + } }; #endif @@ -146,6 +215,8 @@ public: bool canAt() const; bool canClear() const; bool canCount() const; + bool canReplace() const; + bool canRemoveLast() const; bool isManipulable() const; bool isReadable() const; @@ -154,6 +225,8 @@ public: QObject *at(int) const; bool clear() const; int count() const; + bool replace(int, QObject *) const; + bool removeLast() const; private: friend class QQmlListReferencePrivate; |