1// Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qscene_p.h"
5
6#include <Qt3DCore/qnode.h>
7#include <QtCore/QHash>
8#include <QtCore/QReadLocker>
9
10#include <Qt3DCore/private/qnode_p.h>
11#include <Qt3DCore/qaspectengine.h>
12
13QT_BEGIN_NAMESPACE
14
15namespace Qt3DCore {
16
17class QScenePrivate
18{
19public:
20 QScenePrivate(QAspectEngine *engine)
21 : m_engine(engine)
22 , m_arbiter(nullptr)
23 //m_postConstructorInit needs the parent set correctly for QObject::moveToThread() to work correctly
24 , m_postConstructorInit(new NodePostConstructorInit(engine))
25 , m_rootNode(nullptr)
26 {
27 }
28
29 QAspectEngine *m_engine;
30 QHash<QNodeId, QNode *> m_nodeLookupTable;
31 QMultiHash<QNodeId, QNodeId> m_componentToEntities;
32 QChangeArbiter *m_arbiter;
33 QScopedPointer<NodePostConstructorInit, QScopedPointerDeleteLater> m_postConstructorInit;
34 mutable QReadWriteLock m_lock;
35 mutable QReadWriteLock m_nodePropertyTrackModeLock;
36 QNode *m_rootNode;
37 QScene::DirtyNodeSet m_dirtyBits;
38};
39
40
41QScene::QScene(QAspectEngine *engine)
42 : d_ptr(new QScenePrivate(engine))
43{
44}
45
46QScene::~QScene()
47{
48}
49
50QAspectEngine *QScene::engine() const
51{
52 Q_D(const QScene);
53 return d->m_engine;
54}
55
56// Called by main thread only
57void QScene::addObservable(QNode *observable)
58{
59 Q_D(QScene);
60 if (observable != nullptr) {
61 QWriteLocker lock(&d->m_lock);
62 d->m_nodeLookupTable.insert(key: observable->id(), value: observable);
63 if (d->m_arbiter != nullptr)
64 observable->d_func()->setArbiter(d->m_arbiter);
65 }
66}
67
68// Called by main thread
69void QScene::removeObservable(QNode *observable)
70{
71 Q_D(QScene);
72 if (observable != nullptr) {
73 QWriteLocker lock(&d->m_lock);
74 const QNodeId nodeUuid = observable->id();
75 d->m_nodeLookupTable.remove(key: nodeUuid);
76 observable->d_func()->setArbiter(nullptr);
77 }
78}
79
80// Called by any thread
81QNode *QScene::lookupNode(QNodeId id) const
82{
83 Q_D(const QScene);
84 QReadLocker lock(&d->m_lock);
85 return d->m_nodeLookupTable.value(key: id);
86}
87
88QList<QNode *> QScene::lookupNodes(const QList<QNodeId> &ids) const
89{
90 Q_D(const QScene);
91 QReadLocker lock(&d->m_lock);
92 QList<QNode *> nodes;
93 nodes.reserve(asize: ids.size());
94 for (QNodeId id : ids)
95 nodes.push_back(t: d->m_nodeLookupTable.value(key: id));
96 return nodes;
97}
98
99QNode *QScene::rootNode() const
100{
101 Q_D(const QScene);
102 return d->m_rootNode;
103}
104
105void QScene::setArbiter(QChangeArbiter *arbiter)
106{
107 Q_D(QScene);
108 d->m_arbiter = arbiter;
109}
110
111QChangeArbiter *QScene::arbiter() const
112{
113 Q_D(const QScene);
114 return d->m_arbiter;
115}
116
117QList<QNodeId> QScene::entitiesForComponent(QNodeId id) const
118{
119 Q_D(const QScene);
120 QReadLocker lock(&d->m_lock);
121 QList<QNodeId> result;
122 const auto p = d->m_componentToEntities.equal_range(key: id);
123 for (auto it = p.first; it != p.second; ++it)
124 result.push_back(t: *it);
125 return result;
126}
127
128void QScene::addEntityForComponent(QNodeId componentUuid, QNodeId entityUuid)
129{
130 Q_D(QScene);
131 QWriteLocker lock(&d->m_lock);
132 d->m_componentToEntities.insert(key: componentUuid, value: entityUuid);
133}
134
135void QScene::removeEntityForComponent(QNodeId componentUuid, QNodeId entityUuid)
136{
137 Q_D(QScene);
138 QWriteLocker lock(&d->m_lock);
139 d->m_componentToEntities.remove(key: componentUuid, value: entityUuid);
140}
141
142bool QScene::hasEntityForComponent(QNodeId componentUuid, QNodeId entityUuid)
143{
144 Q_D(QScene);
145 QReadLocker lock(&d->m_lock);
146 const auto range = d->m_componentToEntities.equal_range(key: componentUuid);
147 return std::find(first: range.first, last: range.second, val: entityUuid) != range.second;
148}
149
150NodePostConstructorInit *QScene::postConstructorInit() const
151{
152 Q_D(const QScene);
153 return d->m_postConstructorInit.get();
154}
155
156QScene::DirtyNodeSet QScene::dirtyBits()
157{
158 Q_D(QScene);
159 return d->m_dirtyBits;
160}
161
162void QScene::clearDirtyBits()
163{
164 Q_D(QScene);
165 d->m_dirtyBits = {};
166}
167
168void QScene::markDirty(QScene::DirtyNodeSet changes)
169{
170 Q_D(QScene);
171 d->m_dirtyBits |= changes;
172}
173
174void QScene::setRootNode(QNode *root)
175{
176 Q_D(QScene);
177 d->m_rootNode = root;
178}
179
180} // Qt3D
181
182QT_END_NAMESPACE
183

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qt3d/src/core/qscene.cpp