1 | // Copyright (C) 2017 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QQUICKDEFERREDPOINTER_P_P_H |
5 | #define QQUICKDEFERREDPOINTER_P_P_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <QtCore/qglobal.h> |
19 | #include <QtQml/private/qbipointer_p.h> |
20 | #include <QtQml/private/qqmlcomponent_p.h> |
21 | |
22 | QT_BEGIN_NAMESPACE |
23 | |
24 | class QQuickUntypedDeferredPointer |
25 | { |
26 | Q_DISABLE_COPY_MOVE(QQuickUntypedDeferredPointer) |
27 | public: |
28 | QQmlComponentPrivate::DeferredState *deferredState() const |
29 | { |
30 | return value.isT1() ? nullptr : &value.asT2()->state; |
31 | } |
32 | |
33 | void clearDeferredState() |
34 | { |
35 | if (value.isT1()) |
36 | return; |
37 | value.clearFlag(); |
38 | DeferredState *state = value.asT2(); |
39 | value = state->value; |
40 | delete state; |
41 | } |
42 | |
43 | bool wasExecuted() const { return value.isT1() && value.flag(); } |
44 | void setExecuted() |
45 | { |
46 | Q_ASSERT(value.isT1()); |
47 | value.setFlag(); |
48 | } |
49 | |
50 | bool isExecuting() const { return value.isT2() && value.flag(); } |
51 | bool setExecuting(bool b) |
52 | { |
53 | if (b) { |
54 | if (value.isT2()) { |
55 | // Not our state. Set the flag, but leave it alone. |
56 | value.setFlag(); |
57 | return false; |
58 | } |
59 | |
60 | value = new DeferredState { |
61 | .state: QQmlComponentPrivate::DeferredState(), |
62 | .value: value.asT1() |
63 | }; |
64 | value.setFlag(); |
65 | return true; |
66 | } |
67 | |
68 | if (value.isT2()) { |
69 | value.clearFlag(); |
70 | return true; |
71 | } |
72 | |
73 | return false; |
74 | } |
75 | |
76 | protected: |
77 | QQuickUntypedDeferredPointer() = default; |
78 | QQuickUntypedDeferredPointer(void *v) : value(v) |
79 | { |
80 | Q_ASSERT(value.isT1()); |
81 | Q_ASSERT(!value.flag()); |
82 | } |
83 | |
84 | QQuickUntypedDeferredPointer &operator=(void *v) |
85 | { |
86 | if (value.isT1()) |
87 | value = v; |
88 | else |
89 | value.asT2()->value = v; |
90 | return *this; |
91 | } |
92 | |
93 | ~QQuickUntypedDeferredPointer() |
94 | { |
95 | if (value.isT2()) |
96 | delete value.asT2(); |
97 | } |
98 | |
99 | void *data() const { return value.isT1() ? value.asT1() : value.asT2()->value; } |
100 | |
101 | private: |
102 | struct DeferredState |
103 | { |
104 | QQmlComponentPrivate::DeferredState state; |
105 | void *value = nullptr; |
106 | }; |
107 | |
108 | QBiPointer<void, DeferredState> value; |
109 | }; |
110 | |
111 | template<typename T> |
112 | class QQuickDeferredPointer : public QQuickUntypedDeferredPointer |
113 | { |
114 | Q_DISABLE_COPY_MOVE(QQuickDeferredPointer) |
115 | public: |
116 | Q_NODISCARD_CTOR QQuickDeferredPointer() = default; |
117 | ~QQuickDeferredPointer() = default; |
118 | |
119 | Q_NODISCARD_CTOR QQuickDeferredPointer(T *v) : QQuickUntypedDeferredPointer(v) {} |
120 | QQuickDeferredPointer<T> &operator=(T *o) { |
121 | QQuickUntypedDeferredPointer::operator=(o); |
122 | return *this; |
123 | } |
124 | |
125 | T *data() const { return static_cast<T *>(QQuickUntypedDeferredPointer::data()); } |
126 | operator bool() const { return data() != nullptr; } |
127 | operator T*() const { return data(); } |
128 | T *operator*() const { return data(); } |
129 | T *operator->() const { return data(); } |
130 | }; |
131 | |
132 | QT_END_NAMESPACE |
133 | |
134 | #endif // QQUICKDEFERREDPOINTER_P_P_H |
135 |