summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2014-11-02 16:10:12 +0000
committerSean Harmer <sean.harmer@kdab.com>2014-11-02 19:17:49 +0100
commita56aaeed5f09bfa5d32fa7b40ec8782414998daa (patch)
treed9658dfe6d9b6ff4c1df5c0c5800d73e90ed5101
parent8bd7ea0ec2f67679d046d35af5785d99b31620a3 (diff)
QAspectEngine owns the root of the scene
The scene root is now also enforced to be a QEntity as that is what we were checking for in the backend anyway as it is impossible to create a plain QNode. This is another step towards solving the shutdown crashing bug. Change-Id: I8508afa80ec9e99954ab867be1ed28bc35405e79 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--examples/bigscene-cpp/main.cpp2
-rw-r--r--examples/cpp_example/main.cpp3
-rw-r--r--examples/cylinder-cpp/main.cpp3
-rw-r--r--examples/deferred-renderer-cpp/main.cpp3
-rw-r--r--examples/simple-cpp/main.cpp2
-rw-r--r--examples/torus-cpp/main.cpp3
-rw-r--r--src/core/aspects/qaspectengine.cpp38
-rw-r--r--src/core/aspects/qaspectengine.h7
-rw-r--r--src/core/aspects/qaspectengine_p.h6
-rw-r--r--src/core/aspects/qaspectmanager.cpp7
-rw-r--r--src/core/aspects/qaspectmanager_p.h2
-rw-r--r--src/core/window.cpp12
-rw-r--r--src/core/window.h12
-rw-r--r--src/quick3d/quick3d/quickwindow.cpp19
14 files changed, 66 insertions, 53 deletions
diff --git a/examples/bigscene-cpp/main.cpp b/examples/bigscene-cpp/main.cpp
index b7b6561bc..6d252c459 100644
--- a/examples/bigscene-cpp/main.cpp
+++ b/examples/bigscene-cpp/main.cpp
@@ -136,7 +136,7 @@ int main(int ac, char **av)
e->setParent(root);
}
- view.setRootObject(root);
+ view.setRootEntity(root);
view.show();
return app.exec();
}
diff --git a/examples/cpp_example/main.cpp b/examples/cpp_example/main.cpp
index d6d590955..22c1218b9 100644
--- a/examples/cpp_example/main.cpp
+++ b/examples/cpp_example/main.cpp
@@ -148,8 +148,7 @@ int main(int ac, char **av)
rootEntity->addComponent(frameGraph);
// Set root object of the scene
- view.setRootObject(rootEntity);
- // Show window
+ view.setRootEntity(rootEntity);
view.show();
return app.exec();
diff --git a/examples/cylinder-cpp/main.cpp b/examples/cylinder-cpp/main.cpp
index c11435346..20800f389 100644
--- a/examples/cylinder-cpp/main.cpp
+++ b/examples/cylinder-cpp/main.cpp
@@ -132,8 +132,7 @@ int main(int argc, char **argv)
rootEntity->addComponent(frameGraph);
// Set root object of the scene
- view.setRootObject(rootEntity);
- // Show window
+ view.setRootEntity(rootEntity);
view.show();
return app.exec();
diff --git a/examples/deferred-renderer-cpp/main.cpp b/examples/deferred-renderer-cpp/main.cpp
index d91029a2f..0d0c065b9 100644
--- a/examples/deferred-renderer-cpp/main.cpp
+++ b/examples/deferred-renderer-cpp/main.cpp
@@ -185,8 +185,7 @@ int main(int ac, char **av)
screenQuad->addComponent(planeMesh);
// Set root object of the scene
- view.setRootObject(rootEntity);
- // Show window
+ view.setRootEntity(rootEntity);
view.show();
return app.exec();
diff --git a/examples/simple-cpp/main.cpp b/examples/simple-cpp/main.cpp
index 44313ebca..3bd32f720 100644
--- a/examples/simple-cpp/main.cpp
+++ b/examples/simple-cpp/main.cpp
@@ -165,7 +165,7 @@ int main(int argc, char* argv[])
rootEntity->addComponent(frameGraph);
- view.setRootObject(rootEntity);
+ view.setRootEntity(rootEntity);
view.show();
return app.exec();
diff --git a/examples/torus-cpp/main.cpp b/examples/torus-cpp/main.cpp
index a26a9d581..98b457c78 100644
--- a/examples/torus-cpp/main.cpp
+++ b/examples/torus-cpp/main.cpp
@@ -132,8 +132,7 @@ int main(int argc, char **argv)
rootEntity->addComponent(frameGraph);
// Set root object of the scene
- view.setRootObject(rootEntity);
- // Show window
+ view.setRootEntity(rootEntity);
view.show();
return app.exec();
diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp
index dea6987f3..ad7339b20 100644
--- a/src/core/aspects/qaspectengine.cpp
+++ b/src/core/aspects/qaspectengine.cpp
@@ -69,7 +69,7 @@ QAspectEnginePrivate::QAspectEnginePrivate(QAspectEngine *qq)
m_postman->setScene(m_scene);
qRegisterMetaType<Qt3D::QAbstractAspect *>();
qRegisterMetaType<Qt3D::QObserverInterface *>();
- qRegisterMetaType<Qt3D::QNode *>();
+ qRegisterMetaType<Qt3D::QEntity *>();
qRegisterMetaType<Qt3D::QSceneInterface *>();
}
@@ -157,18 +157,44 @@ void QAspectEngine::registerAspect(QAbstractAspect *aspect)
Q_ARG(Qt3D::QAbstractAspect *, aspect));
}
-void QAspectEngine::setRoot(QNode *rootObject)
+void QAspectEngine::setRootEntity(QEntity *root)
{
- Q_D(QAspectEngine);
qCDebug(Aspects) << "Setting scene root on aspect manager";
- initNodeTree(rootObject);
+ Q_D(QAspectEngine);
+ if (d->m_root == root)
+ return;
+
+ // Set the new root object. This will cause the old tree to be deleted
+ // and the deletion of the old frontend tree will cause the backends to
+ // free any related resources
+ d->m_root.reset(root);
+
+ // The aspect engine takes ownership of the scene root. We also set the
+ // parent of the scene root to be the engine
+ d->m_root->setParent(this);
+
+ // Prepare the frontend tree for use by giving each node a pointer to the
+ // scene object and adding each node to the scene
+ // TODO: We probably need a call symmetric to this one above in order to
+ // deregister the nodes from the scene
+ initNodeTree(root);
+
+ // Finally, tell the aspects about the new scene object tree. This is done
+ // in a blocking manner to allow the backends to get synchronized before the
+ // main thread starts triggering potentially more notifications
QMetaObject::invokeMethod(d->m_aspectThread->aspectManager(),
- "setRoot",
+ "setRootEntity",
Qt::BlockingQueuedConnection,
- Q_ARG(Qt3D::QNode *, rootObject));
+ Q_ARG(Qt3D::QEntity *, root));
qCDebug(Aspects) << "Done setting scene root on aspect manager";
}
+QSharedPointer<QEntity> QAspectEngine::rootEntity() const
+{
+ Q_D(const QAspectEngine);
+ return d->m_root;
+}
+
} // namespace Qt3D
QT_END_NAMESPACE
diff --git a/src/core/aspects/qaspectengine.h b/src/core/aspects/qaspectengine.h
index 96332517e..49d984ef1 100644
--- a/src/core/aspects/qaspectengine.h
+++ b/src/core/aspects/qaspectengine.h
@@ -52,10 +52,11 @@ class QSurface;
namespace Qt3D {
-class QNode;
class QAbstractAspect;
class QAspectThread;
class QAspectEnginePrivate;
+class QEntity;
+class QNode;
class QT3DCORESHARED_EXPORT QAspectEngine : public QObject
{
@@ -66,7 +67,9 @@ public:
void initialize();
void shutdown();
- void setRoot(QNode *rootObject);
+ void setRootEntity(QEntity *root);
+ QSharedPointer<QEntity> rootEntity() const;
+
void setSurface(QSurface *surface);
void registerAspect(QAbstractAspect *aspect);
diff --git a/src/core/aspects/qaspectengine_p.h b/src/core/aspects/qaspectengine_p.h
index a4131ce56..68d0af221 100644
--- a/src/core/aspects/qaspectengine_p.h
+++ b/src/core/aspects/qaspectengine_p.h
@@ -43,14 +43,13 @@
#define QT3D_QASPECTENGINE_P_H
#include <private/qobject_p.h>
-#include <QMutex>
-#include <QWaitCondition>
-#include <QHash>
+#include <QtCore/qsharedpointer.h>
QT_BEGIN_NAMESPACE
namespace Qt3D {
+class QEntity;
class QNode;
class QAspectEngine;
class QAspectThread;
@@ -67,6 +66,7 @@ public:
QAspectThread *m_aspectThread;
QPostman *m_postman;
QSceneInterface *m_scene;
+ QSharedPointer<QEntity> m_root;
};
} // Qt3D
diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp
index d6a6d4c21..0e7da01f6 100644
--- a/src/core/aspects/qaspectmanager.cpp
+++ b/src/core/aspects/qaspectmanager.cpp
@@ -101,15 +101,10 @@ void QAspectManager::shutdown()
qDeleteAll(m_aspects);
}
-void QAspectManager::setRoot(QNode *rootObject)
+void QAspectManager::setRootEntity(Qt3D::QEntity *root)
{
qCDebug(Aspects) << Q_FUNC_INFO;
- QEntity *root = qobject_cast<QEntity *>(rootObject);
-
- if (!root)
- qWarning() << "Root object is not an Entity";
-
if (root == m_root)
return;
diff --git a/src/core/aspects/qaspectmanager_p.h b/src/core/aspects/qaspectmanager_p.h
index 9be4423b4..7fccab637 100644
--- a/src/core/aspects/qaspectmanager_p.h
+++ b/src/core/aspects/qaspectmanager_p.h
@@ -72,7 +72,7 @@ public Q_SLOTS:
void initialize();
void shutdown();
- void setRoot(Qt3D::QNode *rootObject);
+ void setRootEntity(Qt3D::QEntity *root);
void setSurface(QSurface *surface);
void registerAspect(Qt3D::QAbstractAspect *aspect);
QSurface *surface() const;
diff --git a/src/core/window.cpp b/src/core/window.cpp
index 5d6ee003a..c09a138d9 100644
--- a/src/core/window.cpp
+++ b/src/core/window.cpp
@@ -105,17 +105,9 @@ void Window::onUpdate()
m_controller->update(1.0 / 60.0);
}
-void Window::setRootObject( QObject* obj )
+void Window::setRootEntity(QEntity *root)
{
- if (m_root == obj)
- return;
-
- if (obj) {
- obj->setParent( this );
- m_root = QSharedPointer<QObject>(obj);
- }
-
- m_aspectEngine->setRoot(qobject_cast<QNode *>(obj));
+ m_aspectEngine->setRootEntity(root);
// Hook up controller input to camera
// TODO: Do this more generically as we may want keyboard ot control an Entity etc
diff --git a/src/core/window.h b/src/core/window.h
index 4fbb0ebf0..9bc12b6f3 100644
--- a/src/core/window.h
+++ b/src/core/window.h
@@ -54,6 +54,7 @@ namespace Qt3D {
class QAbstractAspect;
class QAspectEngine;
class QCamera;
+class QEntity;
// temporary solution to get control over camera
class CameraController;
@@ -65,11 +66,10 @@ public:
explicit Window(QScreen *screen = 0);
~Window();
- void setRootObject( QObject* obj );
+ void setRootEntity(QEntity *root);
- QSharedPointer<QObject> rootObject() { return m_root; }
- void registerAspect(QAbstractAspect *aspect);
- virtual void setCamera(QCamera *camera);
+ void registerAspect(QAbstractAspect *aspect);
+ virtual void setCamera(QCamera *camera);
protected:
virtual void keyPressEvent(QKeyEvent *e);
@@ -85,10 +85,6 @@ private Q_SLOTS:
void onUpdate();
protected:
- QSharedPointer<QObject> m_root;
-
- // The various aspects (subsystems) that will be interested in (parts)
- // of the objects in the object tree.
QAspectEngine *m_aspectEngine;
QCamera* m_camera;
diff --git a/src/quick3d/quick3d/quickwindow.cpp b/src/quick3d/quick3d/quickwindow.cpp
index d19845440..d7c55f111 100644
--- a/src/quick3d/quick3d/quickwindow.cpp
+++ b/src/quick3d/quick3d/quickwindow.cpp
@@ -41,12 +41,14 @@
#include "quickwindow.h"
#include <Qt3DCore/qaspectengine.h>
+#include <Qt3DCore/qentity.h>
+#include <Qt3DCore/cameracontroller.h>
#include <QQmlComponent>
#include <QQmlContext>
+
#include <QDebug>
#include <QTimer>
-#include <Qt3DCore/cameracontroller.h>
QT_BEGIN_NAMESPACE
@@ -88,11 +90,9 @@ void QuickWindow::setSource(const QUrl& source)
return;
}
- if (m_root) {
- m_aspectEngine->shutdown();
- m_aspectEngine->setRoot(0);
- m_root = QSharedPointer<QObject>();
- }
+ // If the engine already has a scene object tree, tidy up first
+ if (m_aspectEngine->rootEntity())
+ m_aspectEngine->setRootEntity(Q_NULLPTR);
if (m_component)
m_component = QSharedPointer<QQmlComponent>();
@@ -156,7 +156,12 @@ void QuickWindow::continueExecute()
return;
}
- setRootObject(obj);
+ QEntity *rootEntity = qobject_cast<QEntity *>(obj);
+ if (rootEntity)
+ setRootEntity(rootEntity);
+ else
+ delete obj;
+
emit statusChanged(status());
}