diff options
Diffstat (limited to 'src/qml/qml/qqmlcontext_p.h')
-rw-r--r-- | src/qml/qml/qqmlcontext_p.h | 335 |
1 files changed, 33 insertions, 302 deletions
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h index f93393a11b..ca49cbf963 100644 --- a/src/qml/qml/qqmlcontext_p.h +++ b/src/qml/qml/qqmlcontext_p.h @@ -51,342 +51,73 @@ // We mean it. // -#include "qqmlcontext.h" +#include <QtCore/qlist.h> +#include <QtCore/qstring.h> +#include <QtCore/qvariant.h> +#include <QtCore/qpointer.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmllist.h> -#include "qqmldata_p.h" -#include "qqmltypenamecache_p.h" -#include "qqmlnotifier_p.h" -#include "qqmllist.h" - -#include <QtCore/qhash.h> -#include <QtQml/qjsvalue.h> -#include <QtCore/qset.h> - -#include <private/qobject_p.h> -#include <private/qflagpointer_p.h> -#include <private/qqmlguard_p.h> - -#include <private/qv4executablecompilationunit_p.h> -#include <private/qv4identifier_p.h> +#include <QtCore/private/qobject_p.h> +#include <QtQml/private/qqmlrefcount_p.h> QT_BEGIN_NAMESPACE -class QQmlContext; -class QQmlExpression; -class QQmlEngine; -class QQmlExpression; -class QQmlExpressionPrivate; -class QQmlJavaScriptExpression; class QQmlContextData; -class QQmlGuardedContextData; -class QQmlIncubatorPrivate; class QQmlContextPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QQmlContext) public: - QQmlContextPrivate(); - - QQmlContextData *data; - - QList<QVariant> propertyValues; - int notifyIndex; - static QQmlContextPrivate *get(QQmlContext *context) { return static_cast<QQmlContextPrivate *>(QObjectPrivate::get(context)); } + static QQmlContext *get(QQmlContextPrivate *context) { return static_cast<QQmlContext *>(context->q_func()); } - // Only used for debugging - QList<QPointer<QObject> > instances; - static int context_count(QQmlListProperty<QObject> *); static QObject *context_at(QQmlListProperty<QObject> *, int); void dropDestroyedQObject(const QString &name, QObject *destroyed); -}; - -class QQmlComponentAttached; - -class Q_QML_PRIVATE_EXPORT QQmlContextData -{ -public: - QQmlContextData(); - QQmlContextData(QQmlContext *); - void emitDestruction(); - void clearContext(); - void clearContextRecursively(); - void invalidate(); - - inline bool isValid() const { - return engine && (!isInternal || !contextObject || !QObjectPrivate::get(contextObject)->wasDeleted); - } - - // My parent context and engine - QQmlContextData *parent = nullptr; - QQmlEngine *engine; - - void setParent(QQmlContextData *, bool stronglyReferencedByParent = false); - void refreshExpressions(); - - void addObject(QQmlData *data); - - QUrl resolvedUrl(const QUrl &); - - // My containing QQmlContext. If isInternal is true this owns publicContext. - // If internal is false publicContext owns this. - QQmlContext *asQQmlContext(); - QQmlContextPrivate *asQQmlContextPrivate(); - quint32 refCount = 0; - quint32 isInternal:1; - quint32 isJSContext:1; - quint32 isPragmaLibraryContext:1; - quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name - quint32 hasEmittedDestruction:1; - quint32 isRootObjectInCreation:1; - quint32 stronglyReferencedByParent:1; - quint32 hasExtraObject:1; // used in QQmlDelegateModelItem::dataForObject to find the corresponding QQmlDelegateModelItem of an object - quint32 dummy:24; - QQmlContext *publicContext; - union { - // The incubator that is constructing this context if any - QQmlIncubatorPrivate *incubator; - // a pointer to extra data, currently only used in QQmlDelegateModel - QObject *extraObject; - }; + int notifyIndex() const { return m_notifyIndex; } + void setNotifyIndex(int notifyIndex) { m_notifyIndex = notifyIndex; } - // Compilation unit for contexts that belong to a compiled type. - QQmlRefPointer<QV4::ExecutableCompilationUnit> typeCompilationUnit; + int numPropertyValues() const { return m_propertyValues.count(); } + void appendPropertyValue(const QVariant &value) { m_propertyValues.append(value); } + void setPropertyValue(int index, const QVariant &value) { m_propertyValues[index] = value; } + QVariant propertyValue(int index) const { return m_propertyValues[index]; } - // object index in CompiledData::Unit to component that created this context - int componentObjectIndex; - - void initFromTypeCompilationUnit(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &unit, int subComponentIndex); - - // flag indicates whether the context owns the cache (after mutation) or not. - mutable QV4::IdentifierHash propertyNameCache; - const QV4::IdentifierHash &propertyNames() const; - QV4::IdentifierHash &detachedPropertyNames(); - - // Context object - QObject *contextObject; - - // Any script blocks that exist on this context - QV4::PersistentValue importedScripts; // This is a JS Array - - QUrl baseUrl; - QString baseUrlString; - - QUrl url() const; - QString urlString() const; - - // List of imports that apply to this context - QQmlRefPointer<QQmlTypeNameCache> imports; - - // My children - QQmlContextData *childContexts = nullptr; - - // My peers in parent's childContexts list - QQmlContextData *nextChild; - QQmlContextData **prevChild; - - // Expressions that use this context - QQmlJavaScriptExpression *expressions; - - // Doubly-linked list of objects that are owned by this context - QQmlData *contextObjects; - - // Doubly-linked list of context guards (XXX merge with contextObjects) - QQmlGuardedContextData *contextGuards = nullptr; - - // id guards - struct ContextGuard : public QQmlGuard<QObject> + QList<QPointer<QObject>> instances() const { return m_instances; } + void appendInstance(QObject *instance) { m_instances.append(instance); } + void cleanInstances() { - inline ContextGuard(); - inline ContextGuard &operator=(QObject *obj); - inline void objectDestroyed(QObject *) override; - - inline bool wasSet() const; - - QFlagPointer<QQmlContextData> context; - QQmlNotifier bindings; - }; - ContextGuard *idValues; - int idValueCount; - void setIdProperty(int, QObject *); - - // Linked contexts. this owns linkedContext. - QQmlContextDataRef linkedContext; - - // Linked list of uses of the Component attached property in this - // context - QQmlComponentAttached *componentAttached; - - // Return the outermost id for obj, if any. - QString findObjectId(const QObject *obj) const; - - static QQmlContextData *get(QQmlContext *context) { - return QQmlContextPrivate::get(context)->data; + for (auto it = m_instances.begin(); it != m_instances.end(); + it->isNull() ? (it = m_instances.erase(it)) : ++it) {} } -private: - friend class QQmlContextDataRef; - friend class QQmlContext; // needs to do manual refcounting :/ - void refreshExpressionsRecursive(bool isGlobal); - void refreshExpressionsRecursive(QQmlJavaScriptExpression *); - ~QQmlContextData(); - void destroy(); -}; - - -class QQmlGuardedContextData -{ -public: - inline QQmlGuardedContextData() = default; - inline QQmlGuardedContextData(QQmlContextData *data) - { setContextData(data); } - inline ~QQmlGuardedContextData() - { clear(); } - - inline QQmlContextData *contextData() const - { return m_contextData; } - inline void setContextData(QQmlContextData *); - - inline bool isNull() const { return !m_contextData; } - - inline operator QQmlContextData*() const { return m_contextData; } - inline QQmlContextData* operator->() const { return m_contextData; } - inline QQmlGuardedContextData &operator=(QQmlContextData *d) { - setContextData(d); return *this; - } + void emitDestruction(); private: - QQmlGuardedContextData &operator=(const QQmlGuardedContextData &) = delete; - QQmlGuardedContextData(const QQmlGuardedContextData &) = delete; friend class QQmlContextData; - inline void clear(); - - QQmlContextData *m_contextData = nullptr; - QQmlGuardedContextData *m_next = nullptr; - QQmlGuardedContextData **m_prev = nullptr; -}; - - -void QQmlGuardedContextData::setContextData(QQmlContextData *contextData) - { - if (m_contextData == contextData) - return; - clear(); - - if (contextData) { - m_contextData = contextData; - m_next = contextData->contextGuards; - if (m_next) m_next->m_prev = &m_next; - m_prev = &contextData->contextGuards; - contextData->contextGuards = this; - } -} - -void QQmlGuardedContextData::clear() -{ - if (m_prev) { - *m_prev = m_next; - if (m_next) m_next->m_prev = m_prev; - m_contextData = nullptr; - m_next = nullptr; - m_prev = nullptr; - } -} - -QQmlContextDataRef::QQmlContextDataRef() - : m_contextData(nullptr) -{ -} - -QQmlContextDataRef::QQmlContextDataRef(const QQmlContextDataRef &other) - : m_contextData(other.m_contextData) -{ - if (m_contextData) - ++m_contextData->refCount; -} - -QQmlContextDataRef::QQmlContextDataRef(QQmlContextData *data) - : m_contextData(data) -{ - if (m_contextData) - ++m_contextData->refCount; -} - -QQmlContextDataRef::~QQmlContextDataRef() -{ - clear(); -} - -void QQmlContextDataRef::setContextData(QQmlContextData *contextData) -{ - if (m_contextData == contextData) - return; - clear(); - - if (contextData) { - m_contextData = contextData; - ++m_contextData->refCount; - } -} - -QQmlContextData *QQmlContextDataRef::contextData() const -{ - return m_contextData; -} - -void QQmlContextDataRef::clear() -{ - if (m_contextData && !--m_contextData->refCount) - m_contextData->destroy(); - m_contextData = nullptr; -} + QQmlContextPrivate(QQmlContextData *data) : m_data(data) {} + QQmlContextPrivate(QQmlContext *publicContext, QQmlContextData *parent, + QQmlEngine *engine = nullptr); -QQmlContextDataRef & -QQmlContextDataRef::operator=(QQmlContextData *d) -{ - setContextData(d); - return *this; -} - -QQmlContextDataRef & -QQmlContextDataRef::operator=(const QQmlContextDataRef &other) -{ - setContextData(other.m_contextData); - return *this; -} + // Intentionally a bare pointer. QQmlContextData knows whether it owns QQmlContext or vice + // versa. If QQmlContext is the owner, QQmlContextData keeps an extra ref for its publicContext. + // The publicContext ref is released when doing QQmlContextData::setPublicContext(nullptr). + QQmlContextData *m_data; -QQmlContextData::ContextGuard::ContextGuard() -: context(nullptr) -{ -} - -QQmlContextData::ContextGuard &QQmlContextData::ContextGuard::operator=(QObject *obj) -{ - QQmlGuard<QObject>::operator=(obj); - context.setFlag(); - bindings.notify(); // For alias connections - return *this; -} + QList<QVariant> m_propertyValues; + int m_notifyIndex = -1; -void QQmlContextData::ContextGuard::objectDestroyed(QObject *) -{ - if (context->contextObject && !QObjectPrivate::get(context->contextObject)->wasDeleted) - bindings.notify(); -} - -bool QQmlContextData::ContextGuard::wasSet() const -{ - return context.flag(); -} + // Only used for debugging + QList<QPointer<QObject>> m_instances; +}; QT_END_NAMESPACE |