From c5685ebe2c5e2fedbde4a38ea82d513a7c488211 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 24 Jun 2020 10:59:08 +0200 Subject: QLogicAspect: use QAspectJob::postFrame to drive FrameAction updates Change-Id: I0707d1f971084fc6671aeb4bd1264c77f6406061 Reviewed-by: Mike Krus (cherry picked from commit 7c2badb56eb564327b073fa706fb9c4f809c411a) --- src/logic/callbackjob.cpp | 22 +++++++++++++++++++--- src/logic/callbackjob_p.h | 17 +++++++++++++++++ src/logic/executor.cpp | 32 +++----------------------------- src/logic/executor_p.h | 22 +--------------------- src/logic/manager.cpp | 8 ++------ src/logic/qlogicaspect.cpp | 3 --- 6 files changed, 42 insertions(+), 62 deletions(-) diff --git a/src/logic/callbackjob.cpp b/src/logic/callbackjob.cpp index 5dfc74f02..b2a92e356 100644 --- a/src/logic/callbackjob.cpp +++ b/src/logic/callbackjob.cpp @@ -48,7 +48,7 @@ namespace Qt3DLogic { namespace Logic { CallbackJob::CallbackJob() - : QAspectJob() + : QAspectJob(*new CallbackJobPrivate(this)) , m_logicManager(nullptr) { SET_JOB_RUN_STAT_TYPE(this, JobTypes::Callback, 0) @@ -61,8 +61,24 @@ void CallbackJob::setManager(Manager *manager) void CallbackJob::run() { - Q_ASSERT(m_logicManager); - m_logicManager->triggerLogicFrameUpdates(); +} + +CallbackJobPrivate::CallbackJobPrivate(CallbackJob *q) + : q_ptr(q) +{ +} + +bool CallbackJobPrivate::isRequired() const +{ + return false; +} + +void CallbackJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) +{ + Q_UNUSED(manager) + Q_Q(CallbackJob); + Q_ASSERT(q->m_logicManager); + q->m_logicManager->triggerLogicFrameUpdates(); } } // namespace Logic diff --git a/src/logic/callbackjob_p.h b/src/logic/callbackjob_p.h index 2dabc77f7..033a6e26d 100644 --- a/src/logic/callbackjob_p.h +++ b/src/logic/callbackjob_p.h @@ -52,6 +52,7 @@ // #include +#include QT_BEGIN_NAMESPACE @@ -60,6 +61,21 @@ namespace Logic { class Manager; +class CallbackJob; + +class CallbackJobPrivate : public Qt3DCore::QAspectJobPrivate +{ +public: + explicit CallbackJobPrivate(CallbackJob *q); + + bool isRequired() const override; + void postFrame(Qt3DCore::QAspectManager *manager) override; + + Q_DECLARE_PUBLIC(CallbackJob) +private: + CallbackJob *q_ptr; +}; + class CallbackJob : public Qt3DCore::QAspectJob { public: @@ -70,6 +86,7 @@ public: private: Manager *m_logicManager; + Q_DECLARE_PRIVATE(CallbackJob) }; } // namespace Logic diff --git a/src/logic/executor.cpp b/src/logic/executor.cpp index 41d2f2e31..5a2f2dc51 100644 --- a/src/logic/executor.cpp +++ b/src/logic/executor.cpp @@ -58,41 +58,15 @@ Executor::Executor(QObject *parent) { } -void Executor::clearQueueAndProceed() -{ - // Clear the queue of nodes to process frame updates for (throw the work away). - // If the semaphore is acquired, release it to allow the logic job and hence the - // manager and frame to complete and shutdown to continue. - m_nodeIds.clear(); -} - -void Executor::enqueueLogicFrameUpdates(const QVector &nodeIds) -{ - m_nodeIds = nodeIds; -} - -bool Executor::event(QEvent *e) -{ - if (e->type() == QEvent::User) { - FrameUpdateEvent *ev = static_cast(e); - processLogicFrameUpdates(ev->deltaTime()); - e->setAccepted(true); - return true; - } - return false; -} - /*! - \internal - Called from context of main thread */ -void Executor::processLogicFrameUpdates(float dt) +void Executor::processLogicFrameUpdates(const QVector &nodeIds, float dt) { - if (!m_scene || m_nodeIds.isEmpty()) + if (!m_scene || nodeIds.isEmpty()) return; - const QVector nodes = m_scene->lookupNodes(m_nodeIds); + const QVector nodes = m_scene->lookupNodes(nodeIds); for (QNode *node : nodes) { QFrameAction *frameAction = qobject_cast(node); if (frameAction && frameAction->isEnabled()) diff --git a/src/logic/executor_p.h b/src/logic/executor_p.h index f68f0f93c..1e9e0fa8d 100644 --- a/src/logic/executor_p.h +++ b/src/logic/executor_p.h @@ -66,20 +66,6 @@ class QScene; namespace Qt3DLogic { namespace Logic { -class FrameUpdateEvent : public QEvent -{ -public: - FrameUpdateEvent(float dt) - : QEvent(QEvent::User) - , m_dt(dt) - {} - - float deltaTime() const { return m_dt; } - -private: - float m_dt; -}; - class Executor : public QObject { Q_OBJECT @@ -87,17 +73,11 @@ public: explicit Executor(QObject *parent = 0); void setScene(Qt3DCore::QScene *scene) { m_scene = scene; } - void clearQueueAndProceed(); public Q_SLOTS: - void enqueueLogicFrameUpdates(const QVector &nodeIds); - -protected: - bool event(QEvent *e) override; - void processLogicFrameUpdates(float dt); + void processLogicFrameUpdates(const QVector &nodeIds, float dt); private: - QVector m_nodeIds; Qt3DCore::QScene *m_scene; }; diff --git a/src/logic/manager.cpp b/src/logic/manager.cpp index db90e6ad9..183c965c3 100644 --- a/src/logic/manager.cpp +++ b/src/logic/manager.cpp @@ -91,7 +91,7 @@ bool Manager::hasFrameActions() const return m_logicHandlers.count() > 0; } -// Called from Job Thread +// Called from Job postFrame (main thread) void Manager::triggerLogicFrameUpdates() { Q_ASSERT(m_executor); @@ -101,11 +101,7 @@ void Manager::triggerLogicFrameUpdates() if (Qt3DCore::QAbstractAspectPrivate::get(m_logicAspect)->m_aspectManager->isShuttingDown()) return; - // Trigger the main thread to process logic frame updates for each - // logic component and then wait until done. The Executor will - // release the semaphore when it has completed its work. - m_executor->enqueueLogicFrameUpdates(m_logicComponentIds); - qApp->postEvent(m_executor, new FrameUpdateEvent(m_dt)); + m_executor->processLogicFrameUpdates(m_logicComponentIds, m_dt); } } // namespace Logic diff --git a/src/logic/qlogicaspect.cpp b/src/logic/qlogicaspect.cpp index c4459a84d..30a46886d 100644 --- a/src/logic/qlogicaspect.cpp +++ b/src/logic/qlogicaspect.cpp @@ -81,9 +81,6 @@ QLogicAspectPrivate::QLogicAspectPrivate() void QLogicAspectPrivate::onEngineAboutToShutdown() { - // Throw away any pending work that may deadlock during the shutdown procedure - // when the main thread waits for any queued jobs to finish. - m_executor->clearQueueAndProceed(); m_executor->setScene(nullptr); } -- cgit v1.2.3