summaryrefslogtreecommitdiffstats
path: root/src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h')
-rw-r--r--src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h309
1 files changed, 309 insertions, 0 deletions
diff --git a/src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h b/src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h
new file mode 100644
index 00000000..ff36b42a
--- /dev/null
+++ b/src/Runtime/Source/foundation/Qt3DSIndexableLinkedList.h
@@ -0,0 +1,309 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DS_FOUNDATION_INDEXABLE_LINKED_LIST_H
+#define QT3DS_FOUNDATION_INDEXABLE_LINKED_LIST_H
+#include "foundation/Qt3DSPool.h"
+
+namespace qt3ds {
+namespace foundation {
+ // Set of helper functions for manipulation of lists that are
+ // somewhat indexable but also amenable to using a pool structure.
+ template <typename TNodeType, typename TObjType, QT3DSU32 TObjCount>
+ struct IndexableLinkedList
+ {
+ typedef TNodeType SNode;
+
+ typedef Pool<SNode, ForwardingAllocator> TPoolType;
+
+ static TObjType &Create(SNode *&inInitialNode, QT3DSU32 &ioCurrentCount, TPoolType &ioPool)
+ {
+ QT3DSU32 idx = ioCurrentCount;
+ ++ioCurrentCount;
+ QT3DSU32 numGroups = (ioCurrentCount + TObjCount - 1) / TObjCount;
+ QT3DSU32 localIdx = idx % TObjCount;
+
+ SNode *theCurrentNode = inInitialNode;
+ for (QT3DSU32 idx = 0, end = numGroups; idx < end; ++idx) {
+ if (idx == 0) {
+ if (theCurrentNode == NULL)
+ inInitialNode = ioPool.construct(__FILE__, __LINE__);
+
+ theCurrentNode = inInitialNode;
+ } else {
+ if (theCurrentNode->m_NextNode == NULL)
+ theCurrentNode->m_NextNode = ioPool.construct(__FILE__, __LINE__);
+ theCurrentNode = theCurrentNode->m_NextNode;
+ }
+ }
+ return theCurrentNode->m_Data[localIdx];
+ }
+
+ static void CreateAll(SNode *&inInitialNode, QT3DSU32 inCount, TPoolType &ioPool)
+ {
+ QT3DSU32 numGroups = (inCount + TObjCount - 1) / TObjCount;
+ SNode *lastNode = NULL;
+ for (QT3DSU32 idx = 0, end = numGroups; idx < end; ++idx) {
+ SNode *nextNode = ioPool.construct(__FILE__, __LINE__);
+ if (idx == 0)
+ inInitialNode = nextNode;
+ else
+ lastNode->m_NextNode = nextNode;
+ lastNode = nextNode;
+ }
+ }
+
+ static void DeleteList(SNode *&inInitialNode, TPoolType &ioPool)
+ {
+ SNode *theNode = inInitialNode;
+ inInitialNode = NULL;
+ while (theNode) {
+ SNode *theNext = theNode->m_NextNode;
+ theNode->m_NextNode = NULL;
+ ioPool.deallocate(theNode);
+ theNode = theNext;
+ }
+ }
+
+ // Performs no checking, so you need to have already allocated what you need.
+ static const TObjType &GetObjAtIdx(const SNode *inInitialNode, QT3DSU32 inIdx)
+ {
+ QT3DSU32 groupIdx = inIdx / TObjCount;
+ QT3DSU32 localIdx = inIdx % TObjCount;
+ for (QT3DSU32 idx = 0; idx < groupIdx; ++idx)
+ inInitialNode = inInitialNode->m_NextNode;
+ return inInitialNode->m_Data[inIdx];
+ }
+
+ static TObjType &GetObjAtIdx(SNode *inInitialNode, QT3DSU32 inIdx)
+ {
+ QT3DSU32 groupIdx = inIdx / TObjCount;
+ QT3DSU32 localIdx = inIdx % TObjCount;
+ for (QT3DSU32 idx = 0; idx < groupIdx; ++idx)
+ inInitialNode = inInitialNode->m_NextNode;
+ return inInitialNode->m_Data[localIdx];
+ }
+
+ struct SIteratorType
+ {
+ QT3DSU32 m_Idx;
+ QT3DSU32 m_Count;
+ SNode *m_Node;
+
+ SIteratorType()
+ : m_Idx(0)
+ , m_Count(0)
+ , m_Node(NULL)
+ {
+ }
+ SIteratorType(const SIteratorType &iter)
+ : m_Idx(iter.m_Idx)
+ , m_Count(iter.m_Count)
+ , m_Node(iter.m_Node)
+ {
+ }
+ SIteratorType(SNode *inNode, QT3DSU32 inCount, QT3DSU32 inIdx)
+ : m_Idx(inIdx)
+ , m_Count(inCount)
+ , m_Node(inNode)
+ {
+ }
+
+ bool operator==(const SIteratorType &iter) const { return m_Idx == iter.m_Idx; }
+
+ bool operator!=(const SIteratorType &iter) const { return m_Idx != iter.m_Idx; }
+
+ TObjType &operator*()
+ {
+ QT3DSU32 localIdx = m_Idx % TObjCount;
+ return m_Node->m_Data[localIdx];
+ }
+
+ SIteratorType &operator++()
+ {
+ ++m_Idx;
+ if ((m_Idx % TObjCount) == 0)
+ m_Node = m_Node->m_NextNode;
+
+ return *this;
+ }
+ };
+
+ struct SConstIteratorType
+ {
+ QT3DSU32 m_Idx;
+ QT3DSU32 m_Count;
+ const SNode *m_Node;
+
+ SConstIteratorType()
+ : m_Idx(0)
+ , m_Count(0)
+ , m_Node(NULL)
+ {
+ }
+ SConstIteratorType(const SIteratorType &iter)
+ : m_Idx(iter.m_Idx)
+ , m_Count(iter.m_Count)
+ , m_Node(iter.m_Node)
+ {
+ }
+ SConstIteratorType(const SConstIteratorType &iter)
+ : m_Idx(iter.m_Idx)
+ , m_Count(iter.m_Count)
+ , m_Node(iter.m_Node)
+ {
+ }
+ SConstIteratorType(const SNode *inNode, QT3DSU32 inCount, QT3DSU32 inIdx)
+ : m_Idx(inIdx)
+ , m_Count(inCount)
+ , m_Node(inNode)
+ {
+ }
+
+ bool operator==(const SConstIteratorType &iter) const { return m_Idx == iter.m_Idx; }
+
+ bool operator!=(const SConstIteratorType &iter) const { return m_Idx != iter.m_Idx; }
+
+ const TObjType &operator*()
+ {
+ QT3DSU32 localIdx = m_Idx % TObjCount;
+ return m_Node->m_Data[localIdx];
+ }
+
+ SConstIteratorType &operator++()
+ {
+ ++m_Idx;
+ if ((m_Idx % TObjCount) == 0)
+ m_Node = m_Node->m_NextNode;
+
+ return *this;
+ }
+ };
+
+ typedef SIteratorType iterator;
+ typedef SConstIteratorType const_iterator;
+
+ static iterator begin(SNode *inInitialNode, QT3DSU32 inItemCount)
+ {
+ return SIteratorType(inInitialNode, inItemCount, 0);
+ }
+
+ static iterator end(SNode * /*inInitialNode*/, QT3DSU32 inItemCount)
+ {
+ return SIteratorType(NULL, inItemCount, inItemCount);
+ }
+
+ static const_iterator begin(const SNode *inInitialNode, QT3DSU32 inItemCount)
+ {
+ return SConstIteratorType(inInitialNode, inItemCount, 0);
+ }
+
+ static const_iterator end(const SNode * /*inInitialNode*/, QT3DSU32 inItemCount)
+ {
+ return SConstIteratorType(NULL, inItemCount, inItemCount);
+ }
+
+ struct SNodeIteratorType
+ {
+ SNode *m_Node;
+
+ SNodeIteratorType()
+ : m_Node(NULL)
+ {
+ }
+ SNodeIteratorType(const SNodeIteratorType &iter)
+ : m_Node(iter.m_Node)
+ {
+ }
+ SNodeIteratorType(SNode *inNode)
+ : m_Node(inNode)
+ {
+ }
+
+ bool operator==(const SNodeIteratorType &iter) const { return m_Node == iter.m_Node; }
+
+ bool operator!=(const SNodeIteratorType &iter) const { return m_Node != iter.m_Node; }
+
+ TNodeType &operator*() { return *m_Node; }
+
+ SNodeIteratorType &operator++()
+ {
+ if (m_Node)
+ m_Node = m_Node->m_NextNode;
+
+ return *this;
+ }
+ };
+
+ typedef SNodeIteratorType node_iterator;
+ static node_iterator node_begin(SNode *inFirstNode) { return node_iterator(inFirstNode); }
+ static node_iterator node_end(SNode * /*inFirstNode*/) { return node_iterator(NULL); }
+
+ // Iterates through the number of nodes required for a given count of objects
+ struct SCountIteratorType
+ {
+ QT3DSU32 m_Idx;
+ QT3DSU32 m_Count;
+
+ SCountIteratorType()
+ : m_Idx(0)
+ , m_Count(0)
+ {
+ }
+ SCountIteratorType(const SCountIteratorType &iter)
+ : m_Idx(iter.m_Idx)
+ , m_Count(iter.m_Count)
+ {
+ }
+ SCountIteratorType(QT3DSU32 idx, QT3DSU32 count)
+ : m_Idx(idx)
+ , m_Count(count)
+ {
+ }
+
+ bool operator==(const SCountIteratorType &iter) const { return m_Idx == iter.m_Idx; }
+
+ bool operator!=(const SCountIteratorType &iter) const { return m_Idx != iter.m_Idx; }
+
+ SCountIteratorType &operator++()
+ {
+ m_Idx = NVMin(m_Idx + TObjCount, m_Count);
+ return *this;
+ }
+ };
+
+ typedef SCountIteratorType count_iterator;
+ static count_iterator count_begin(QT3DSU32 count) { return SCountIteratorType(0, count); }
+ static count_iterator count_end(QT3DSU32 count) { return SCountIteratorType(count, count); }
+ };
+}
+}
+
+#endif \ No newline at end of file