Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquick3dobject_p.h
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QSSGOBJECT_P_H
5#define QSSGOBJECT_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 "qquick3dobject.h"
19
20#include "qtquick3dglobal_p.h"
21
23
25
26#include <private/qobject_p.h>
27#include <private/qquickstate_p.h>
28#include <private/qqmlnotifier_p.h>
29#include <private/qlazilyallocated_p.h>
30#include <private/qssgrendergraphobject_p.h>
31#include <QtQuick3DUtils/private/qquick3dprofiler_p.h>
32
33#include <QtCore/qpointer.h>
34
36
37class QQuick3DItem2D;
38
39class Q_QUICK3D_EXPORT QQuick3DObjectPrivate : public QObjectPrivate
40{
41 Q_DECLARE_PUBLIC(QQuick3DObject)
42public:
44
46 {
48 QObject *context = nullptr;
49 Handle unusable = nullptr;
50 friend bool operator==(const ConnectionKey &a, const ConnectionKey &b) noexcept { return (a.context == b.context) && (a.unusable == b.unusable); }
51 };
52 using ConnectionMap = QHash<ConnectionKey, QMetaObject::Connection>;
53
54 template<typename SceneContext, typename CallContext, typename Setter>
55 static void attachWatcherPriv(SceneContext *sceneContext, CallContext *callContext, Setter setter, QQuick3DObject *newO, QObject *oldO)
56 {
57 static_assert(std::is_base_of_v<QQuick3DObject, SceneContext>, "The scene context must be a QQuick3DObject");
58 static_assert(std::is_member_function_pointer_v<Setter>, "The assumption is that the setter is a member function!");
59 static_assert(sizeof(ConnectionKey::Handle) >= sizeof(Setter), "The handle needs to be able to store the value of the setter");
60 // Sanity check: Make sure we have a valid context. If the sceneContext != callContext and we're here because the
61 // watched object just got destroyed by the parent (QObject dtor) and that parent also is used as the sceneContext
62 // then there's nothing more to do; all involved parties are being destroyed, so just bail out.
63 const bool validContext = static_cast<QObject *>(sceneContext) != static_cast<QObject *>(callContext) ? qobject_cast<QQuick3DObject *>(sceneContext) != nullptr : true;
64 if (validContext) {
65 auto sceneManager = QQuick3DObjectPrivate::get(sceneContext)->sceneManager;
66 auto &connectionMap = QQuick3DObjectPrivate::get(sceneContext)->connectionMap;
67 union
68 {
69 Setter s;
71 }; s = setter;
72 ConnectionKey key{static_cast<QObject *>(callContext), h};
73 // disconnect previous destruction listener
74 if (oldO) {
75 // NOTE: If the old object is inside the QObject's dtor (e.g., QObject::destroyed) we can't
76 // call deref (and there's no point anymore either).
77 if (auto old3dO = qobject_cast<QQuick3DObject *>(oldO))
79
80 auto it = connectionMap.constFind(key);
81 if (it != connectionMap.cend()) {
83 connectionMap.erase(it);
84 }
85 }
86
87 // Watch new object
88 if (newO) {
89 if (sceneManager)
90 QQuick3DObjectPrivate::refSceneManager(newO, *sceneManager);
91 auto connection = QObject::connect(newO, &QObject::destroyed, callContext, [callContext, setter](){ (callContext->*setter)(nullptr); });
92 connectionMap.insert(key, connection);
93 }
94 }
95 }
96
111 template<typename Context, typename Setter, typename Object3D>
112 static void attachWatcher(Context *context, Setter setter, Object3D *newO, Object3D *oldO)
113 {
114 attachWatcherPriv(context, context, setter, newO, oldO);
115 }
116
117 static QQuick3DObjectPrivate *get(QQuick3DObject *item) { return item->d_func(); }
118 static const QQuick3DObjectPrivate *get(const QQuick3DObject *item) { return item->d_func(); }
120
121 explicit QQuick3DObjectPrivate(Type t);
122 ~QQuick3DObjectPrivate() override;
123 void init(QQuick3DObject *parent);
124
125 QQmlListProperty<QObject> data();
126 QQmlListProperty<QObject> resources();
127 QQmlListProperty<QQuick3DObject> children();
128
129 QQmlListProperty<QQuickState> states();
130 QQmlListProperty<QQuickTransition> transitions();
131
132 QString state() const;
133 void setState(const QString &);
134
135 // data property
136 static void data_append(QQmlListProperty<QObject> *, QObject *);
137 static qsizetype data_count(QQmlListProperty<QObject> *);
138 static QObject *data_at(QQmlListProperty<QObject> *, qsizetype);
139 static void data_clear(QQmlListProperty<QObject> *);
140
141 // resources property
142 static QObject *resources_at(QQmlListProperty<QObject> *, qsizetype);
143 static void resources_append(QQmlListProperty<QObject> *, QObject *);
144 static qsizetype resources_count(QQmlListProperty<QObject> *);
145 static void resources_clear(QQmlListProperty<QObject> *);
146
147 // children property
148 static void children_append(QQmlListProperty<QQuick3DObject> *, QQuick3DObject *);
149 static qsizetype children_count(QQmlListProperty<QQuick3DObject> *);
150 static QQuick3DObject *children_at(QQmlListProperty<QQuick3DObject> *, qsizetype);
151 static void children_clear(QQmlListProperty<QQuick3DObject> *);
152
153 void _q_resourceObjectDeleted(QObject *);
154 void _q_cleanupContentItem2D();
155 quint64 _q_createJSWrapper(QQmlV4ExecutionEnginePtr engine);
156
158 Geometry = 0x01,
159 SiblingOrder = 0x02,
160 Visibility = 0x04,
161 Opacity = 0x08,
162 Destroyed = 0x10,
163 Parent = 0x20,
164 Children = 0x40,
165 Rotation = 0x80,
166 ImplicitWidth = 0x100,
167 ImplicitHeight = 0x200,
168 Enabled = 0x400,
169 };
170
171 Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
172
174 {
175 using ChangeTypes = QQuick3DObjectPrivate::ChangeTypes;
176
177 ChangeListener(QQuick3DObjectChangeListener *l = nullptr, ChangeTypes t = {}) : listener(l), types(t) {}
178
179 ChangeListener(QQuick3DObjectChangeListener *l) : listener(l), types(Geometry) {}
180
181 bool operator==(const ChangeListener &other) const
182 {
183 return listener == other.listener && types == other.types;
184 }
185
188 };
189
191 {
192 ExtraData();
193
196
197 };
198 QLazilyAllocated<ExtraData> extra;
199
200 QVector<QQuick3DObjectPrivate::ChangeListener> changeListeners;
201
202 void addItemChangeListener(QQuick3DObjectChangeListener *listener, ChangeTypes types);
203 void updateOrAddItemChangeListener(QQuick3DObjectChangeListener *listener, ChangeTypes types);
204 void removeItemChangeListener(QQuick3DObjectChangeListener *, ChangeTypes types);
205
206 QQuickStateGroup *_states();
208
210 TransformOrigin = 0x00000001,
211 Transform = 0x00000002,
212 BasicTransform = 0x00000004,
213 Position = 0x00000008,
214 Size = 0x00000010,
215
216 ZValue = 0x00000020,
217 Content = 0x00000040,
218 Smooth = 0x00000080,
219 OpacityValue = 0x00000100,
220 ChildrenChanged = 0x00000200,
221 ChildrenStackingChanged = 0x00000400,
222 ParentChanged = 0x00000800,
223
224 Clip = 0x00001000,
225 Window = 0x00002000,
226
227 EffectReference = 0x00008000,
228 Visible = 0x00010000,
229 HideReference = 0x00020000,
230 Antialiasing = 0x00040000,
231
232 InstanceRootChanged = 0x00080000,
233 // When you add an attribute here, don't forget to update
234 // dirtyToString()
235
236 TransformUpdateMask = TransformOrigin | Transform | BasicTransform | Position | Window,
237 ComplexTransformUpdateMask = Transform | Window,
238 ContentUpdateMask = Size | Content | Smooth | Window | Antialiasing,
239 ChildrenUpdateMask = ChildrenChanged | ChildrenStackingChanged | EffectReference | Window
240 };
241
243 QString dirtyToString() const;
244 void dirty(DirtyType);
245 void addToDirtyList();
246 void removeFromDirtyList();
249
250 void setCulled(bool);
251
252 QPointer<QQuick3DSceneManager> sceneManager;
254
256
257 QList<QQuick3DObject *> childItems;
258 void addChild(QQuick3DObject *);
259 void removeChild(QQuick3DObject *);
260 void siblingOrderChanged();
261
262 void refSceneManager(QQuick3DSceneManager &);
263 void derefSceneManager();
264
266 {
267 if (obj)
268 QQuick3DObjectPrivate::get(obj)->refSceneManager(mgr);
269 }
271 {
272 if (obj)
273 QQuick3DObjectPrivate::get(obj)->derefSceneManager();
274 }
275
277 void updateSubFocusItem(QQuick3DObject *scope, bool focus);
278
279 void itemChange(QQuick3DObject::ItemChange, const QQuick3DObject::ItemChangeData &);
280
281 virtual void updatePolish() {}
282
283 QSSGRenderGraphObject *spatialNode = nullptr;
284
285 Type type = Type::Unknown;
286 bool componentComplete = true;
287 bool preSyncNeeded = false;
288 bool culled;
289 bool sharedResource = false;
290 QQuick3DItem2D *contentItem2d = nullptr;
293};
294
295Q_DECLARE_OPERATORS_FOR_FLAGS(QQuick3DObjectPrivate::ChangeTypes)
298
299inline size_t qHash(const QQuick3DObjectPrivate::ConnectionKey &con, size_t seed = 0) noexcept
300{
302}
303
305
306#endif // QSSGOBJECT_P_H
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
QQuick3DObject * parentItem
QList< QQuick3DObject * > childItems
QQuickStateGroup * _stateGroup
static void derefSceneManager(QQuick3DObject *obj)
QPointer< QQuick3DSceneManager > sceneManager
QQuick3DObject ** prevDirtyItem
QQuick3DObject * subFocusItem
static void refSceneManager(QQuick3DObject *obj, QQuick3DSceneManager &mgr)
virtual void updatePolish()
static QSSGRenderGraphObject * updateSpatialNode(QQuick3DObject *o, QSSGRenderGraphObject *n)
QQuick3DObject * nextDirtyItem
void refSceneManager(QQuick3DSceneManager &)
static void attachWatcherPriv(SceneContext *sceneContext, CallContext *callContext, Setter setter, QQuick3DObject *newO, QObject *oldO)
QVector< QQuick3DObjectPrivate::ChangeListener > changeListeners
QLazilyAllocated< ExtraData > extra
static QQuick3DObjectPrivate * get(QQuick3DObject *item)
static void attachWatcher(Context *context, Setter setter, Object3D *newO, Object3D *oldO)
Attach a object-destroyed-watcher to an object that's not owned.
static const QQuick3DObjectPrivate * get(const QQuick3DObject *item)
\qmltype Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DObject \inherits QtObject
const_iterator cend() const noexcept
Definition qset.h:142
const_iterator constFind(const T &value) const
Definition qset.h:161
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
[Window class with invokable method]
Definition window.h:11
bool focus
[0]
QSet< QString >::iterator it
else opt state
[0]
Combined button and popup list for selecting options.
static void * context
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection * connection
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition qflags.h:174
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition qflags.h:194
size_t qHashBits(const void *p, size_t size, size_t seed) noexcept
Definition qhash.cpp:1089
GLboolean GLboolean GLboolean b
GLuint64 key
GLboolean GLboolean GLboolean GLboolean a
[7]
GLsizei GLenum GLenum * types
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLfloat n
GLfloat GLfloat GLfloat GLfloat h
GLhandleARB obj
[2]
GLdouble s
[6]
Definition qopenglext.h:235
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint * states
size_t qHash(const QQuick3DObjectPrivate::ConnectionKey &con, size_t seed=0) noexcept
#define Q_QUICK3D_PROFILE_ID
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:157
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:180
unsigned int quint32
Definition qtypes.h:50
unsigned long long quint64
Definition qtypes.h:61
ptrdiff_t qsizetype
Definition qtypes.h:165
XID Window
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
QJSEngine engine
[0]
QQuick3DObjectChangeListener * listener
bool operator==(const ChangeListener &other) const
QQuick3DObjectPrivate::ChangeTypes ChangeTypes
ChangeListener(QQuick3DObjectChangeListener *l=nullptr, ChangeTypes t={})
ChangeListener(QQuick3DObjectChangeListener *l)
void(QQuick3DObject::*)(QObject *) Handle
friend bool operator==(const ConnectionKey &a, const ConnectionKey &b) noexcept
Definition moc.h:23