summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2017-09-12 12:10:03 +0100
committerSean Harmer <sean.harmer@kdab.com>2017-09-12 12:39:05 +0100
commit3f03499bf8a7cf3c3f8d19a020179c1205980bde (patch)
tree518b0ef3fb1b31d3856f43124150ef41acb8c1aa /src/core
parent8a4b9ebadb9e63ae367694f04786c7faf6306f27 (diff)
parentbf5fd7a78c91e29332ce70ad844b756150f32f18 (diff)
Merge branch '5.9' into 5.10
Diffstat (limited to 'src/core')
-rw-r--r--src/core/jobs/dependencyhandler.cpp157
-rw-r--r--src/core/jobs/dependencyhandler_p.h116
-rw-r--r--src/core/jobs/jobs.pri4
-rw-r--r--src/core/jobs/qaspectjobmanager.cpp21
-rw-r--r--src/core/jobs/qaspectjobmanager_p.h1
-rw-r--r--src/core/jobs/qthreadpooler.cpp35
-rw-r--r--src/core/jobs/qthreadpooler_p.h4
-rw-r--r--src/core/jobs/task.cpp24
-rw-r--r--src/core/jobs/task_p.h26
-rw-r--r--src/core/resources/qhandle_p.h27
-rw-r--r--src/core/resources/qhandlemanager_p.h263
-rw-r--r--src/core/resources/qresourcemanager_p.h213
-rw-r--r--src/core/resources/resources.pri1
13 files changed, 136 insertions, 756 deletions
diff --git a/src/core/jobs/dependencyhandler.cpp b/src/core/jobs/dependencyhandler.cpp
deleted file mode 100644
index 6a925d037..000000000
--- a/src/core/jobs/dependencyhandler.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "dependencyhandler_p.h"
-
-#include <iterator>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DCore {
-
-namespace {
- template <template <typename T> class Op>
- struct ByDepender {
- typedef bool result_type;
-
- bool operator()(const RunnableInterface *lhs, const RunnableInterface *rhs) const Q_DECL_NOTHROW
- { return Op<const RunnableInterface *>()(lhs, rhs); }
-
- bool operator()(const RunnableInterface *lhs, const Dependency &rhs) const Q_DECL_NOTHROW
- { return operator()(lhs, rhs.depender); }
-
- bool operator()(const Dependency &lhs, const RunnableInterface *rhs) const Q_DECL_NOTHROW
- { return operator()(lhs.depender, rhs); }
-
- bool operator()(const Dependency &lhs, const Dependency &rhs) const Q_DECL_NOTHROW
- { return operator()(lhs.depender, rhs.depender); }
- };
-
- struct DependeeEquals : std::unary_function<Dependency, bool>
- {
- const RunnableInterface *dependee;
- QVector<RunnableInterface *> *freedList;
- explicit DependeeEquals(const RunnableInterface *dependee, QVector<RunnableInterface *> *freedList)
- : dependee(qMove(dependee)), freedList(qMove(freedList)) {}
- bool operator()(const Dependency &candidate) const
- {
- if (dependee == candidate.dependee) {
- if (!candidate.depender->reserved())
- freedList->append(candidate.depender);
- return true;
- }
- return false;
- }
- };
-
- struct DependerEquals : std::unary_function<Dependency, bool>
- {
- const RunnableInterface *depender;
- explicit DependerEquals(const RunnableInterface *depender)
- : depender(qMove(depender)) {}
- bool operator()(const Dependency &candidate) const
- {
- return depender == candidate.depender;
- }
- };
-
- struct ByDependerThenDependee : std::binary_function<Dependency, Dependency, bool>
- {
- // Defines a lexicographical order (depender first).
- bool operator()(const Dependency &lhs, const Dependency &rhs)
- {
- if (lhs.depender < rhs.depender) return true;
- if (rhs.depender < lhs.depender) return false;
- return lhs.dependee < rhs.dependee;
- }
- };
-}
-
-DependencyHandler::DependencyHandler()
- : m_mutex()
-{
-}
-
-void DependencyHandler::addDependencies(QVector<Dependency> dependencies)
-{
- std::sort(dependencies.begin(), dependencies.end(), ByDependerThenDependee());
-
- const QMutexLocker locker(m_mutex);
-
- QVector<Dependency> newDependencyMap;
- newDependencyMap.reserve(dependencies.size() + m_dependencyMap.size());
- std::set_union(m_dependencyMap.begin(), m_dependencyMap.end(),
- dependencies.begin(), dependencies.end(),
- std::back_inserter(newDependencyMap), ByDependerThenDependee());
- m_dependencyMap.swap(newDependencyMap); // commit
-}
-
-bool DependencyHandler::hasDependency(const RunnableInterface *depender)
-{
- // The caller has to set the mutex, which is QThreadPooler::enqueueTasks
-
- return std::binary_search(m_dependencyMap.begin(), m_dependencyMap.end(),
- depender, ByDepender<std::less>());
-}
-
-/*
- * Removes all the entries on the m_dependencyMap that have given task as a dependee,
- * i.e. entries where the dependency is on the given task.
- */
-QVector<RunnableInterface *> DependencyHandler::freeDependencies(const RunnableInterface *task)
-{
- // The caller has to set the mutex, which is QThreadPooler::taskFinished
-
- m_dependencyMap.erase(std::remove_if(m_dependencyMap.begin(),
- m_dependencyMap.end(),
- DependerEquals(task)),
- m_dependencyMap.end());
-
- QVector<RunnableInterface *> freedList;
- m_dependencyMap.erase(std::remove_if(m_dependencyMap.begin(),
- m_dependencyMap.end(),
- DependeeEquals(task, &freedList)),
- m_dependencyMap.end());
-
- return freedList;
-}
-
-} // namespace Qt3DCore
-
-QT_END_NAMESPACE
diff --git a/src/core/jobs/dependencyhandler_p.h b/src/core/jobs/dependencyhandler_p.h
deleted file mode 100644
index a5a023139..000000000
--- a/src/core/jobs/dependencyhandler_p.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT3DCORE_DEPENDENCYHANDLER_P_H
-#define QT3DCORE_DEPENDENCYHANDLER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/QMutex>
-#include <QtCore/QVector>
-
-#include <Qt3DCore/private/task_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DCore {
-
-struct Dependency
-{
- Dependency()
- : depender(nullptr)
- , dependee(nullptr)
- {}
- Dependency(RunnableInterface *depender, RunnableInterface *dependee)
- : depender(qMove(depender)),
- dependee(qMove(dependee)) {}
-
- RunnableInterface *depender;
- RunnableInterface *dependee;
-};
-
-} // namespace Qt3DCore
-
-template <>
-class QTypeInfo<Qt3DCore::Dependency> : public QTypeInfoMerger<Qt3DCore::Dependency, Qt3DCore::RunnableInterface *> {};
-
-namespace Qt3DCore {
-
-inline bool operator==(const Dependency &left, const Dependency &right)
-{
- return left.depender == right.depender && left.dependee == right.dependee;
-}
-
-inline bool operator!=(const Dependency &left, const Dependency &right)
-{
- return !operator==(left, right);
-}
-
-class DependencyHandler
-{
-public:
- DependencyHandler();
-
- void addDependencies(QVector<Dependency> dependencies);
- bool hasDependency(const RunnableInterface *depender);
- QVector<RunnableInterface *> freeDependencies(const RunnableInterface *task);
- void setMutex(QMutex *mutex) { m_mutex = mutex; }
-
-private:
- Q_DISABLE_COPY(DependencyHandler)
-
- QVector<Dependency> m_dependencyMap;
- QMutex *m_mutex;
-};
-
-} // namespace Qt3DCore
-
-QT_END_NAMESPACE
-
-#endif // QT3DCORE_DEPENDENCYHANDLER_P_H
-
diff --git a/src/core/jobs/jobs.pri b/src/core/jobs/jobs.pri
index d12c42237..5d262f5c7 100644
--- a/src/core/jobs/jobs.pri
+++ b/src/core/jobs/jobs.pri
@@ -4,8 +4,7 @@ SOURCES += \
$$PWD/qaspectjobmanager.cpp \
$$PWD/qabstractaspectjobmanager.cpp \
$$PWD/qthreadpooler.cpp \
- $$PWD/task.cpp \
- $$PWD/dependencyhandler.cpp
+ $$PWD/task.cpp
HEADERS += \
$$PWD/qaspectjob.h \
@@ -13,7 +12,6 @@ HEADERS += \
$$PWD/qaspectjobproviderinterface_p.h \
$$PWD/qaspectjobmanager_p.h \
$$PWD/qabstractaspectjobmanager_p.h \
- $$PWD/dependencyhandler_p.h \
$$PWD/task_p.h \
$$PWD/qthreadpooler_p.h
diff --git a/src/core/jobs/qaspectjobmanager.cpp b/src/core/jobs/qaspectjobmanager.cpp
index e543b60a2..328899433 100644
--- a/src/core/jobs/qaspectjobmanager.cpp
+++ b/src/core/jobs/qaspectjobmanager.cpp
@@ -45,7 +45,6 @@
#include <QtCore/QThread>
#include <QtCore/QFuture>
-#include <Qt3DCore/private/dependencyhandler_p.h>
#include <Qt3DCore/private/qthreadpooler_p.h>
#include <Qt3DCore/private/task_p.h>
@@ -56,9 +55,7 @@ namespace Qt3DCore {
QAspectJobManager::QAspectJobManager(QObject *parent)
: QAbstractAspectJobManager(parent)
, m_threadPooler(new QThreadPooler(this))
- , m_dependencyHandler(new DependencyHandler)
{
- m_threadPooler->setDependencyHandler(m_dependencyHandler.data());
}
QAspectJobManager::~QAspectJobManager()
@@ -84,24 +81,24 @@ void QAspectJobManager::enqueueJobs(const QVector<QAspectJobPtr> &jobQueue)
taskList << task;
}
- // Resolve dependencies
- QVector<Dependency> dependencyList;
-
for (const QSharedPointer<QAspectJob> &job : jobQueue) {
const QVector<QWeakPointer<QAspectJob> > &deps = job->dependencies();
+ AspectTaskRunnable *taskDepender = tasksMap.value(job.data());
+ int dependerCount = 0;
for (const QWeakPointer<QAspectJob> &dep : deps) {
AspectTaskRunnable *taskDependee = tasksMap.value(dep.data());
-
+ // The dependencies here are not hard requirements, i.e., the dependencies
+ // not in the jobQueue should already have their data ready.
if (taskDependee) {
- AspectTaskRunnable *taskDepender = tasksMap.value(job.data());
- dependencyList.append(Dependency(taskDepender, taskDependee));
- taskDepender->setDependencyHandler(m_dependencyHandler.data());
- taskDependee->setDependencyHandler(m_dependencyHandler.data());
+ taskDependee->m_dependers.append(taskDepender);
+ ++dependerCount;
}
}
+
+ taskDepender->m_dependerCount += dependerCount;
}
- m_dependencyHandler->addDependencies(qMove(dependencyList));
+
#if QT_CONFIG(qt3d_profile_jobs)
QThreadPooler::writeFrameJobLogStats();
#endif
diff --git a/src/core/jobs/qaspectjobmanager_p.h b/src/core/jobs/qaspectjobmanager_p.h
index 6fbf03d22..fac71f057 100644
--- a/src/core/jobs/qaspectjobmanager_p.h
+++ b/src/core/jobs/qaspectjobmanager_p.h
@@ -81,7 +81,6 @@ public:
private:
QThreadPooler *m_threadPooler;
- QScopedPointer<DependencyHandler> m_dependencyHandler;
};
} // namespace Qt3DCore
diff --git a/src/core/jobs/qthreadpooler.cpp b/src/core/jobs/qthreadpooler.cpp
index 57a1b09a6..6819faca7 100644
--- a/src/core/jobs/qthreadpooler.cpp
+++ b/src/core/jobs/qthreadpooler.cpp
@@ -48,8 +48,6 @@
#include <QtCore/QCoreApplication>
#endif
-#include <Qt3DCore/private/dependencyhandler_p.h>
-
QT_BEGIN_NAMESPACE
namespace Qt3DCore {
@@ -62,7 +60,6 @@ QThreadPooler::QThreadPooler(QObject *parent)
: QObject(parent)
, m_futureInterface(nullptr)
, m_mutex()
- , m_dependencyHandler(nullptr)
, m_taskCount(0)
{
const QByteArray maxThreadCount = qgetenv("QT3D_MAX_THREAD_COUNT");
@@ -86,12 +83,6 @@ QThreadPooler::~QThreadPooler()
locker.unlock();
}
-void QThreadPooler::setDependencyHandler(DependencyHandler *handler)
-{
- m_dependencyHandler = handler;
- m_dependencyHandler->setMutex(&m_mutex);
-}
-
void QThreadPooler::enqueueTasks(const QVector<RunnableInterface *> &tasks)
{
// The caller have to set the mutex
@@ -99,7 +90,14 @@ void QThreadPooler::enqueueTasks(const QVector<RunnableInterface *> &tasks)
for (QVector<RunnableInterface *>::const_iterator it = tasks.cbegin();
it != end; ++it) {
- if (!m_dependencyHandler->hasDependency((*it)) && !(*it)->reserved()) {
+
+ // Only AspectTaskRunnables are checked for dependencies.
+ static const auto hasDependencies = [](RunnableInterface *task) -> bool {
+ return (task->type() == RunnableInterface::RunnableType::AspectTask)
+ && (static_cast<AspectTaskRunnable *>(task)->m_dependerCount > 0);
+ };
+
+ if (!hasDependencies(*it) && !(*it)->reserved()) {
(*it)->setReserved(true);
(*it)->setPooler(this);
m_threadPool.start((*it));
@@ -113,10 +111,19 @@ void QThreadPooler::taskFinished(RunnableInterface *task)
release();
- if (task->dependencyHandler()) {
- const QVector<RunnableInterface *> freedTasks = m_dependencyHandler->freeDependencies(task);
- if (!freedTasks.empty())
- enqueueTasks(freedTasks);
+ if (task->type() == RunnableInterface::RunnableType::AspectTask) {
+ AspectTaskRunnable *aspectTask = static_cast<AspectTaskRunnable *>(task);
+ const auto &dependers = aspectTask->m_dependers;
+ for (auto it = dependers.begin(); it != dependers.end(); ++it) {
+ aspectTask = static_cast<AspectTaskRunnable *>(*it);
+ if (--aspectTask->m_dependerCount == 0) {
+ if (!aspectTask->reserved()) {
+ aspectTask->setReserved(true);
+ aspectTask->setPooler(this);
+ m_threadPool.start(aspectTask);
+ }
+ }
+ }
}
if (currentCount() == 0) {
diff --git a/src/core/jobs/qthreadpooler_p.h b/src/core/jobs/qthreadpooler_p.h
index 5a2104cdd..00742f8fc 100644
--- a/src/core/jobs/qthreadpooler_p.h
+++ b/src/core/jobs/qthreadpooler_p.h
@@ -57,7 +57,6 @@
#include <QtCore/QSharedPointer>
#include <QtCore/QThreadPool>
-#include <Qt3DCore/private/dependencyhandler_p.h>
#include <Qt3DCore/private/qaspectjob_p.h>
#include <Qt3DCore/private/task_p.h>
@@ -81,8 +80,6 @@ public:
void taskFinished(RunnableInterface *task);
QFuture<void> future();
- void setDependencyHandler(DependencyHandler *handler);
-
int maxThreadCount() const;
#if QT_CONFIG(qt3d_profile_jobs)
static QElapsedTimer m_jobsStatTimer;
@@ -105,7 +102,6 @@ private:
private:
QFutureInterface<void> *m_futureInterface;
QMutex m_mutex;
- DependencyHandler *m_dependencyHandler;
QAtomicInt m_taskCount;
QThreadPool m_threadPool;
};
diff --git a/src/core/jobs/task.cpp b/src/core/jobs/task.cpp
index cbaa993b1..4291a4779 100644
--- a/src/core/jobs/task.cpp
+++ b/src/core/jobs/task.cpp
@@ -43,7 +43,6 @@
#include <QtCore/QElapsedTimer>
#include <QtCore/QMutexLocker>
-#include <Qt3DCore/private/dependencyhandler_p.h>
#include <Qt3DCore/private/qthreadpooler_p.h>
QT_BEGIN_NAMESPACE
@@ -57,8 +56,7 @@ RunnableInterface::~RunnableInterface()
// Aspect task
AspectTaskRunnable::AspectTaskRunnable()
- : m_dependencyHandler(nullptr)
- , m_pooler(nullptr)
+ : m_pooler(nullptr)
, m_reserved(false)
{
}
@@ -94,16 +92,6 @@ void AspectTaskRunnable::run()
m_pooler->taskFinished(this);
}
-void AspectTaskRunnable::setDependencyHandler(DependencyHandler *handler)
-{
- m_dependencyHandler = handler;
-}
-
-DependencyHandler *AspectTaskRunnable::dependencyHandler()
-{
- return m_dependencyHandler;
-}
-
// Synchronized task
SyncTaskRunnable::SyncTaskRunnable(QAbstractAspectJobManager::JobFunction func,
@@ -137,16 +125,6 @@ void SyncTaskRunnable::run()
m_pooler->taskFinished(this);
}
-void SyncTaskRunnable::setDependencyHandler(DependencyHandler *handler)
-{
- Q_UNUSED(handler);
-}
-
-DependencyHandler *SyncTaskRunnable::dependencyHandler()
-{
- return nullptr;
-}
-
} // namespace Qt3DCore {
QT_END_NAMESPACE
diff --git a/src/core/jobs/task_p.h b/src/core/jobs/task_p.h
index 8193abaf6..91e3f5f3d 100644
--- a/src/core/jobs/task_p.h
+++ b/src/core/jobs/task_p.h
@@ -69,13 +69,15 @@ class QThreadPooler;
class RunnableInterface : public QRunnable
{
public:
+ enum class RunnableType {
+ AspectTask,
+ SyncTask
+ };
+
virtual ~RunnableInterface();
virtual void run() = 0;
- virtual void setDependencyHandler(DependencyHandler *) = 0;
- virtual DependencyHandler *dependencyHandler() = 0;
-
virtual int id() = 0;
virtual void setId(int id) = 0;
@@ -83,6 +85,8 @@ public:
virtual bool reserved() = 0;
virtual void setPooler(QThreadPooler *pooler) = 0;
+
+ virtual RunnableType type() const = 0;
};
class AspectTaskRunnable : public RunnableInterface
@@ -93,9 +97,6 @@ public:
void run() Q_DECL_OVERRIDE;
- void setDependencyHandler(DependencyHandler *handler) Q_DECL_OVERRIDE;
- DependencyHandler *dependencyHandler() Q_DECL_OVERRIDE;
-
void setPooler(QThreadPooler *pooler) Q_DECL_OVERRIDE { m_pooler = pooler; }
void setReserved(bool reserved) Q_DECL_OVERRIDE { m_reserved = reserved; }
@@ -104,15 +105,17 @@ public:
int id() Q_DECL_OVERRIDE { return m_id; }
void setId(int id) Q_DECL_OVERRIDE { m_id = id; }
+ RunnableType type() const Q_DECL_OVERRIDE { return RunnableType::AspectTask; }
+
public:
QSharedPointer<QAspectJob> m_job;
+ QVector<AspectTaskRunnable *> m_dependers;
+ int m_dependerCount = 0;
private:
- DependencyHandler *m_dependencyHandler;
QThreadPooler *m_pooler;
- bool m_reserved;
-
int m_id; // For testing purposes for now
+ bool m_reserved;
};
class SyncTaskRunnable : public RunnableInterface
@@ -124,9 +127,6 @@ public:
void run() Q_DECL_OVERRIDE;
- void setDependencyHandler(DependencyHandler *handler) Q_DECL_OVERRIDE;
- DependencyHandler *dependencyHandler() Q_DECL_OVERRIDE;
-
void setPooler(QThreadPooler *pooler) Q_DECL_OVERRIDE { m_pooler = pooler; }
void setReserved(bool reserved) Q_DECL_OVERRIDE { m_reserved = reserved; }
@@ -135,6 +135,8 @@ public:
int id() Q_DECL_OVERRIDE { return m_id; }
void setId(int id) Q_DECL_OVERRIDE { m_id = id; }
+ RunnableType type() const Q_DECL_OVERRIDE { return RunnableType::SyncTask; }
+
private:
QAbstractAspectJobManager::JobFunction m_func;
void *m_arg;
diff --git a/src/core/resources/qhandle_p.h b/src/core/resources/qhandle_p.h
index 94dc7ca45..c4b53ec21 100644
--- a/src/core/resources/qhandle_p.h
+++ b/src/core/resources/qhandle_p.h
@@ -53,6 +53,7 @@
#include <Qt3DCore/qt3dcore_global.h>
#include <QtCore/QDebug>
+#include <limits.h>
class tst_Handle; // needed for friend class declaration below
@@ -60,9 +61,6 @@ QT_BEGIN_NAMESPACE
namespace Qt3DCore {
-template <typename T, uint INDEXBITS>
-class QHandleManager;
-
template <typename T, uint INDEXBITS = 16>
class QHandle
{
@@ -82,18 +80,6 @@ public:
static quint32 maxIndex() { return MaxIndex; }
static quint32 maxCounter() { return MaxCounter; }
-
-private:
- enum {
- // Sizes to use for bit fields
- IndexBits = INDEXBITS,
- CounterBits = 32 - INDEXBITS - 2, // We use 2 bits for book-keeping in QHandleManager
-
- // Sizes to compare against for asserting dereferences
- MaxIndex = (1 << IndexBits) - 1,
- MaxCounter = (1 << CounterBits) - 1
- };
-
QHandle(quint32 i, quint32 count)
{
d.m_index = i;
@@ -103,10 +89,17 @@ private:
Q_ASSERT(count < MaxCounter);
}
+ enum {
+ // Sizes to use for bit fields
+ IndexBits = INDEXBITS,
+ CounterBits = 32 - INDEXBITS - 2, // We use 2 bits for book-keeping in QHandleManager
- friend class QHandleManager<T, INDEXBITS>;
- friend class ::tst_Handle;
+ // Sizes to compare against for asserting dereferences
+ MaxIndex = (1 << IndexBits) - 1,
+ MaxCounter = ((1 << CounterBits) - 1 > SHRT_MAX) ? SHRT_MAX - 1 : (1 << CounterBits) - 1
+ };
+private:
struct Data {
quint32 m_index : IndexBits;
quint32 m_counter : CounterBits;
diff --git a/src/core/resources/qhandlemanager_p.h b/src/core/resources/qhandlemanager_p.h
deleted file mode 100644
index 0c3609bb9..000000000
--- a/src/core/resources/qhandlemanager_p.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT3DCORE_QHANDLEMANAGER_P_H
-#define QT3DCORE_QHANDLEMANAGER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <Qt3DCore/qt3dcore_global.h>
-#include <QtCore/QtGlobal>
-#include <QtCore/QVector>
-
-#include <Qt3DCore/private/qhandle_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DCore {
-
-#ifndef QT_NO_DEBUG_STREAM
-template <typename T, uint INDEXBITS>
-class QHandleManager;
-
-template <typename T, uint INDEXBITS = 16>
-QDebug operator<<(QDebug dbg, const QHandleManager<T, INDEXBITS> &manager);
-#endif
-
-template <typename T, uint INDEXBITS = 16>
-class QHandleManager
-{
-public:
- QHandleManager()
- : m_firstFreeEntry(0)
- , m_activeEntryCount(0)
- , m_entries(1 << INDEXBITS)
- {
- reset();
- }
-
- quint32 activeEntries() const { return m_activeEntryCount; }
-
- void reset();
- QHandle<T, INDEXBITS> acquire(T *d);
- void release(const QHandle<T, INDEXBITS> &handle);
- void update(const QHandle<T, INDEXBITS> &, T *d);
- T *data(const QHandle<T, INDEXBITS> &handle, bool *ok = 0);
- const T *constData(const QHandle<T, INDEXBITS> &handle, bool *ok = 0) const;
- QVector<T *> entries() const;
-
-private:
- Q_DISABLE_COPY(QHandleManager)
-
- friend QDebug operator<< <>(QDebug dbg, const QHandleManager<T, INDEXBITS> &manager);
-
- template <typename U>
- struct HandleEntry
- {
- HandleEntry()
- : m_data(nullptr)
- , m_nextFreeIndex(0)
- , m_counter(0)
- , m_active(false)
- , m_endOfFreeList(false)
- {}
-
- explicit HandleEntry(quint32 nextFreeIndex)
- : m_data(nullptr)
- , m_nextFreeIndex(nextFreeIndex)
- , m_counter(0)
- , m_active(false)
- , m_endOfFreeList(false)
- {}
-
- U *m_data;
- unsigned int m_nextFreeIndex : QHandle<U, INDEXBITS>::IndexBits;
- unsigned int m_counter : QHandle<U, INDEXBITS>::CounterBits;
- unsigned int m_active : 1;
- unsigned int m_endOfFreeList : 1;
- };
-
- quint32 m_firstFreeEntry;
- int m_activeEntryCount;
- QVector<HandleEntry<T> > m_entries;
-};
-
-template <typename T, uint INDEXBITS>
-void QHandleManager<T, INDEXBITS>::reset()
-{
- m_activeEntryCount = 0;
- m_firstFreeEntry = 0;
-
- for (int i = 0; i < QHandle<T, INDEXBITS >::MaxIndex; ++i)
- m_entries[i] = HandleEntry<T>(i + 1);
- m_entries[QHandle<T, INDEXBITS>::MaxIndex] = HandleEntry<T>();
- m_entries[QHandle<T, INDEXBITS>::MaxIndex].m_endOfFreeList = true;
-}
-
-template <typename T, uint INDEXBITS>
-QHandle<T, INDEXBITS> QHandleManager<T, INDEXBITS>::acquire(T *d)
-{
- typedef QHandle<T, INDEXBITS> qHandle;
- Q_ASSERT(m_activeEntryCount < qHandle::MaxIndex);
-
- const quint32 newIndex = m_firstFreeEntry;
- Q_ASSERT(newIndex < qHandle::MaxIndex);
- Q_ASSERT(m_entries[newIndex].m_active == false);
- Q_ASSERT(!m_entries[newIndex].m_endOfFreeList);
-
- m_firstFreeEntry = m_entries[newIndex].m_nextFreeIndex;
- m_entries[newIndex].m_nextFreeIndex = 0;
- ++m_entries[newIndex].m_counter;
- // Check if the counter is about to overflow and reset if necessary
- if (m_entries[newIndex].m_counter == qHandle::MaxCounter)
- m_entries[newIndex].m_counter = 0;
- if (m_entries[newIndex].m_counter == 0)
- m_entries[newIndex].m_counter = 1;
- m_entries[newIndex].m_active = true;
- m_entries[newIndex].m_data = d;
-
- ++m_activeEntryCount;
-
- return qHandle(newIndex, m_entries[newIndex].m_counter);
-}
-
-template <typename T, uint INDEXBITS>
-void QHandleManager<T, INDEXBITS>::release(const QHandle<T, INDEXBITS> &handle)
-{
- const quint32 index = handle.index();
- Q_ASSERT(m_entries[index].m_counter == handle.counter());
- Q_ASSERT(m_entries[index].m_active == true);
-
- m_entries[index].m_nextFreeIndex = m_firstFreeEntry;
- m_entries[index].m_active = false;
- m_firstFreeEntry = index;
-
- --m_activeEntryCount;
-}
-
-// Needed in case the QResourceManager has reordered
-// memory so that the handle still points to valid data
-template <typename T, uint INDEXBITS>
-void QHandleManager<T, INDEXBITS>::update(const QHandle<T, INDEXBITS> &handle, T *d)
-{
- const quint32 index = handle.index();
- Q_ASSERT(m_entries[index].m_counter == handle.counter());
- Q_ASSERT(m_entries[index].m_active == true);
- m_entries[index].m_data = d;
-}
-
-template <typename T, uint INDEXBITS>
-T *QHandleManager<T, INDEXBITS>::data(const QHandle<T, INDEXBITS> &handle, bool *ok)
-{
- const quint32 index = handle.index();
- if (m_entries[index].m_counter != handle.counter() ||
- m_entries[index].m_active == false) {
- if (ok)
- *ok = false;
- return nullptr;
- }
-
- T *d = m_entries[index].m_data;
- if (ok)
- *ok = true;
- return d;
-}
-
-template <typename T, uint INDEXBITS>
-const T *QHandleManager<T, INDEXBITS>::constData(const QHandle<T, INDEXBITS> &handle, bool *ok) const
-{
- const quint32 index = handle.index();
- if (m_entries[index].m_counter != handle.counter() ||
- m_entries[index].m_active == false) {
- if (ok)
- *ok = false;
- return nullptr;
- }
-
- const T *d = m_entries[index].m_data;
- if (ok)
- *ok = true;
- return d;
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-template <typename T, uint INDEXBITS>
-QDebug operator<<(QDebug dbg, const QHandleManager<T, INDEXBITS> &manager)
-{
- QDebugStateSaver saver(dbg);
- dbg << "First free entry =" << manager.m_firstFreeEntry << endl;
-
- const auto end = manager.m_entries.cend();
- const auto max = manager.m_activeEntryCount;
- auto i = 0;
- for (auto it = manager.m_entries.cbegin(); it != end && i < max; ++it) {
- const auto isActive = it->m_active;
- if (isActive) {
- dbg << *(it->m_data);
- ++i;
- }
- }
-
- return dbg;
-}
-#endif
-
-template <typename T, uint INDEXBITS>
-QVector<T *> QHandleManager<T, INDEXBITS>::entries() const
-{
- QVector<T *> entries;
- for (auto handle : qAsConst(m_entries))
- entries.append(handle.m_data);
- return entries;
-}
-
-} // Qt3D
-
-QT_END_NAMESPACE
-
-#endif // QT3DCORE_QHANDLEMANAGER_H
diff --git a/src/core/resources/qresourcemanager_p.h b/src/core/resources/qresourcemanager_p.h
index 8ddc1c0a4..4cb2a38af 100644
--- a/src/core/resources/qresourcemanager_p.h
+++ b/src/core/resources/qresourcemanager_p.h
@@ -57,9 +57,9 @@
#include <QtCore/QReadLocker>
#include <QtCore/QReadWriteLock>
#include <QtCore/QtGlobal>
+#include <limits>
#include <Qt3DCore/private/qhandle_p.h>
-#include <Qt3DCore/private/qhandlemanager_p.h>
// Silence complaints about unreferenced local variables in
// ArrayAllocatingPolicy::deallocateBuckets() when the compiler
@@ -220,15 +220,16 @@ struct Int2Type
};
};
-template <typename T, uint INDEXBITS>
+template <typename T, uint INDEXBITS = 16>
class ArrayAllocatingPolicy
{
public:
+ typedef QHandle<T, INDEXBITS> Handle;
ArrayAllocatingPolicy()
- : m_numBuckets(0)
- , m_numConstructed(0)
{
- reset();
+ m_freeList.resize(MaxSize);
+ for (int i = 0; i < MaxSize; i++)
+ m_freeList[i] = MaxSize - (i + 1);
}
~ArrayAllocatingPolicy()
@@ -236,7 +237,7 @@ public:
deallocateBuckets();
}
- T* allocateResource()
+ Handle allocateResource()
{
Q_ASSERT(!m_freeList.isEmpty());
int idx = m_freeList.takeLast();
@@ -245,9 +246,11 @@ public:
Q_ASSERT(bucketIdx <= m_numBuckets);
if (bucketIdx == m_numBuckets) {
m_bucketDataPtrs[bucketIdx] = static_cast<T*>(malloc(sizeof(T) * BucketSize));
+ m_counters[bucketIdx] = static_cast<short *>(malloc(sizeof(short) * BucketSize));
// ### memset is only needed as long as we also use this for primitive types (see FrameGraphManager)
// ### remove once this is fixed, add a static_assert on T instead
- memset((void*) m_bucketDataPtrs[bucketIdx], 0, sizeof(T) * BucketSize);
+ memset((void *)m_bucketDataPtrs[bucketIdx], 0, sizeof(T) * BucketSize);
+ memset(m_counters[bucketIdx], 0, sizeof(short) * BucketSize);
++m_numBuckets;
}
@@ -256,39 +259,47 @@ public:
new (m_bucketDataPtrs[bucketIdx] + localIdx) T;
++m_numConstructed;
}
-
- return m_bucketDataPtrs[bucketIdx] + localIdx;
+ Q_STATIC_ASSERT(Handle::MaxCounter < USHRT_MAX);
+ Q_ASSERT(m_counters[bucketIdx][localIdx] <= 0);
+ m_counters[bucketIdx][localIdx] *= -1;
+ ++m_counters[bucketIdx][localIdx];
+ if (m_counters[bucketIdx][localIdx] >= Handle::MaxCounter)
+ m_counters[bucketIdx][localIdx] = 1;
+
+ return Handle(idx, m_counters[bucketIdx][localIdx]);
}
- void releaseResource(T *r)
+ void releaseResource(Handle h)
{
- // search linearly over buckets to find the index of the resource
- // and put it into the free list
- for (int bucketIdx = 0; bucketIdx < m_numBuckets; ++bucketIdx) {
- const T* firstItem = m_bucketDataPtrs[bucketIdx];
- if (firstItem > r || r >= firstItem + BucketSize) {
- // resource is not in this bucket when its pointer address
- // is outside the address range spanned by the addresses of
- // the first and last items in a bucket
- continue;
- }
+ int idx = h.index();
+ int bucketIdx = idx / BucketSize;
+ int localIdx = idx % BucketSize;
- // now we found the bucket we can reconstruct the global index
- // and put it back into the free list
- const int localIdx = static_cast<int>(r - firstItem);
- const int idx = bucketIdx * BucketSize + localIdx;
- m_freeList.append(idx);
- performCleanup(r, Int2Type<QResourceInfo<T>::needsCleanup>());
- break;
+ Q_ASSERT(h.counter() == static_cast<quint32>(m_counters[bucketIdx][localIdx]));
+ T *r = m_bucketDataPtrs[bucketIdx] + localIdx;
+
+ m_freeList.append(idx);
+ m_counters[bucketIdx][localIdx] *= -1;
+ performCleanup(r, Int2Type<QResourceInfo<T>::needsCleanup>());
+ }
+
+ T *data(Handle h/*, bool *ok = 0*/) {
+ int bucketIdx = h.index() / BucketSize;
+ int localIdx = h.index() % BucketSize;
+
+ if (h.counter() != static_cast<quint32>(m_counters[bucketIdx][localIdx])) {
+ return nullptr;
}
+ return m_bucketDataPtrs[bucketIdx] + localIdx;
}
- void reset()
- {
- deallocateBuckets();
- m_freeList.resize(MaxSize);
- for (int i = 0; i < MaxSize; i++)
- m_freeList[i] = MaxSize - (i + 1);
+ void for_each(std::function<void(T*)> f) {
+ for (int idx = 0; idx < m_numConstructed; ++idx) {
+ int bucketIdx = idx / BucketSize;
+ int localIdx = idx % BucketSize;
+ T * t = m_bucketDataPtrs[bucketIdx] + localIdx;
+ f(t);
+ }
}
private:
@@ -313,66 +324,15 @@ private:
while (m_numBuckets > 0) {
--m_numBuckets;
free(m_bucketDataPtrs[m_numBuckets]);
+ free(m_counters[m_numBuckets]);
}
}
T* m_bucketDataPtrs[MaxSize / BucketSize];
+ short *m_counters[MaxSize / BucketSize];
QVector<int> m_freeList;
- int m_numBuckets;
- int m_numConstructed;
-
- void performCleanup(T *r, Int2Type<true>)
- {
- r->cleanup();
- }
-
- void performCleanup(T *, Int2Type<false>)
- {}
-
-};
-
-template <typename T, uint INDEXBITS>
-class ArrayPreallocationPolicy
-{
-public:
- ArrayPreallocationPolicy()
- {
- reset();
- }
-
- T* allocateResource()
- {
- Q_ASSERT(!m_freeList.isEmpty());
- int idx = m_freeList.last();
- m_freeList.pop_back();
- return m_bucket.data() + idx;
- }
-
- void releaseResource(T *r)
- {
- Q_ASSERT(m_bucket.data() <= r && r < m_bucket.data() + MaxSize);
- int idx = r - m_bucket.data();
- m_freeList.append(idx);
- performCleanup(r, Int2Type<QResourceInfo<T>::needsCleanup>());
- *r = T();
- }
-
- void reset()
- {
- m_bucket.clear();
- m_bucket.resize(MaxSize);
- m_freeList.resize(MaxSize);
- for (int i = 0; i < MaxSize; i++)
- m_freeList[i] = MaxSize - (i + 1);
- }
-
-private:
- enum {
- MaxSize = 1 << INDEXBITS
- };
-
- QVector<T> m_bucket;
- QVector<int> m_freeList;
+ int m_numBuckets = 0;
+ int m_numConstructed = 0;
void performCleanup(T *r, Int2Type<true>)
{
@@ -386,29 +346,29 @@ private:
#ifndef QT_NO_DEBUG_STREAM
template <typename ValueType, typename KeyType, uint INDEXBITS,
- template <typename, uint> class AllocatingPolicy,
template <class> class LockingPolicy
>
class QResourceManager;
template <typename ValueType, typename KeyType, uint INDEXBITS = 16,
- template <typename, uint> class AllocatingPolicy = ArrayAllocatingPolicy,
template <class> class LockingPolicy = NonLockingPolicy
>
-QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, AllocatingPolicy, LockingPolicy> &manager);
+QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, LockingPolicy> &manager);
#endif
template <typename ValueType, typename KeyType, uint INDEXBITS = 16,
- template <typename, uint> class AllocatingPolicy = ArrayAllocatingPolicy,
template <class> class LockingPolicy = NonLockingPolicy
>
class QResourceManager
- : public AllocatingPolicy<ValueType, INDEXBITS>
- , public LockingPolicy< QResourceManager<ValueType, KeyType, INDEXBITS, AllocatingPolicy, LockingPolicy> >
+ : public ArrayAllocatingPolicy<ValueType, INDEXBITS>
+ , public LockingPolicy< QResourceManager<ValueType, KeyType, INDEXBITS, LockingPolicy> >
{
public:
+ typedef ArrayAllocatingPolicy<ValueType, INDEXBITS> Allocator;
+ typedef QHandle<ValueType, INDEXBITS> Handle;
+
QResourceManager() :
- AllocatingPolicy<ValueType, INDEXBITS>(),
+ Allocator(),
m_maxSize((1 << INDEXBITS) - 1)
{
}
@@ -416,52 +376,43 @@ public:
~QResourceManager()
{}
- QHandle<ValueType, INDEXBITS> acquire()
+ Handle acquire()
{
typename LockingPolicy<QResourceManager>::WriteLocker lock(this);
- QHandle<ValueType, INDEXBITS> handle = m_handleManager.acquire(AllocatingPolicy<ValueType, INDEXBITS>::allocateResource());
+ Handle handle = Allocator::allocateResource();
m_activeHandles.push_back(handle);
return handle;
}
- ValueType* data(const QHandle<ValueType, INDEXBITS> &handle)
+ ValueType* data(const Handle &handle)
{
typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
- ValueType* d = m_handleManager.data(handle);
- return d;
+ return Allocator::data(handle);
}
- void release(const QHandle<ValueType, INDEXBITS> &handle)
+ void release(const Handle &handle)
{
typename LockingPolicy<QResourceManager>::WriteLocker lock(this);
releaseLocked(handle);
}
- void reset()
- {
- typename LockingPolicy<QResourceManager>::WriteLocker lock(this);
- m_handleManager.reset();
- m_activeHandles.clear();
- AllocatingPolicy<ValueType, INDEXBITS>::reset();
- }
-
bool contains(const KeyType &id) const
{
typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
return m_keyToHandleMap.contains(id);
}
- QHandle<ValueType, INDEXBITS> getOrAcquireHandle(const KeyType &id)
+ Handle getOrAcquireHandle(const KeyType &id)
{
typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
- QHandle<ValueType, INDEXBITS> handle = m_keyToHandleMap.value(id);
+ Handle handle = m_keyToHandleMap.value(id);
if (handle.isNull()) {
lock.unlock();
typename LockingPolicy<QResourceManager>::WriteLocker writeLock(this);
// Test that the handle hasn't been set (in the meantime between the read unlock and the write lock)
- QHandle<ValueType, INDEXBITS> &handleToSet = m_keyToHandleMap[id];
+ Handle &handleToSet = m_keyToHandleMap[id];
if (handleToSet.isNull()) {
- handleToSet = m_handleManager.acquire(AllocatingPolicy<ValueType, INDEXBITS>::allocateResource());
+ handleToSet = Allocator::allocateResource();
m_activeHandles.push_back(handleToSet);
}
return handleToSet;
@@ -469,7 +420,7 @@ public:
return handle;
}
- QHandle<ValueType, INDEXBITS> lookupHandle(const KeyType &id)
+ Handle lookupHandle(const KeyType &id)
{
typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
return m_keyToHandleMap.value(id);
@@ -480,58 +431,54 @@ public:
ValueType* ret = nullptr;
{
typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
- QHandle<ValueType, INDEXBITS> handle = m_keyToHandleMap.value(id);
+ Handle handle = m_keyToHandleMap.value(id);
if (!handle.isNull())
- ret = m_handleManager.data(handle);
+ ret = Allocator::data(handle);
}
return ret;
}
ValueType *getOrCreateResource(const KeyType &id)
{
- const QHandle<ValueType, INDEXBITS> handle = getOrAcquireHandle(id);
+ const Handle handle = getOrAcquireHandle(id);
typename LockingPolicy<QResourceManager>::ReadLocker lock(this);
- return m_handleManager.data(handle);
+ return Allocator::data(handle);
}
void releaseResource(const KeyType &id)
{
typename LockingPolicy<QResourceManager>::WriteLocker lock(this);
- QHandle<ValueType, INDEXBITS> handle = m_keyToHandleMap.take(id);
+ Handle handle = m_keyToHandleMap.take(id);
if (!handle.isNull())
releaseLocked(handle);
}
int maximumSize() const { return m_maxSize; }
- int count() const Q_DECL_NOEXCEPT { return m_handleManager.activeEntries(); }
+ int count() const Q_DECL_NOEXCEPT { return m_activeHandles.size(); }
- inline QVector<QHandle<ValueType, INDEXBITS> > activeHandles() const Q_DECL_NOEXCEPT { return m_activeHandles; }
+ inline QVector<Handle > activeHandles() const Q_DECL_NOEXCEPT { return m_activeHandles; }
protected:
- QHandleManager<ValueType, INDEXBITS> m_handleManager;
- QHash<KeyType, QHandle<ValueType, INDEXBITS> > m_keyToHandleMap;
- QVector<QHandle<ValueType, INDEXBITS> > m_activeHandles;
+ QHash<KeyType, Handle > m_keyToHandleMap;
+ QVector<Handle > m_activeHandles;
const int m_maxSize;
private:
- void releaseLocked(const QHandle<ValueType, INDEXBITS> &handle)
+ void releaseLocked(const Handle &handle)
{
- ValueType *val = m_handleManager.data(handle);
- m_handleManager.release(handle);
m_activeHandles.removeOne(handle);
- AllocatingPolicy<ValueType, INDEXBITS>::releaseResource(val);
+ Allocator::releaseResource(handle);
}
- friend QDebug operator<< <>(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, AllocatingPolicy, LockingPolicy> &manager);
+ friend QDebug operator<< <>(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, LockingPolicy> &manager);
};
#ifndef QT_NO_DEBUG_STREAM
template <typename ValueType, typename KeyType, uint INDEXBITS,
- template <typename, uint> class AllocatingPolicy,
template <class> class LockingPolicy
>
-QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, AllocatingPolicy, LockingPolicy> &manager)
+QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBITS, LockingPolicy> &manager)
{
QDebugStateSaver saver(dbg);
dbg << "Contains" << manager.count() << "items" << "of a maximum" << manager.maximumSize() << endl;
@@ -541,8 +488,8 @@ QDebug operator<<(QDebug dbg, const QResourceManager<ValueType, KeyType, INDEXBI
for (auto it = manager.m_keyToHandleMap.cbegin(); it != end; ++it)
dbg << "QNodeId =" << it.key() << "Handle =" << it.value() << endl;
- dbg << "Resources:" << endl;
- dbg << manager.m_handleManager;
+// dbg << "Resources:" << endl;
+// dbg << manager.m_handleManager;
return dbg;
}
#endif
diff --git a/src/core/resources/resources.pri b/src/core/resources/resources.pri
index 855d73b79..96ea21e93 100644
--- a/src/core/resources/resources.pri
+++ b/src/core/resources/resources.pri
@@ -1,5 +1,4 @@
HEADERS += \
- $$PWD/qhandlemanager_p.h \
$$PWD/qresourcemanager_p.h \
$$PWD/qcircularbuffer_p.h \
$$PWD/qboundedcircularbuffer_p.h \