[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / src / Bullet3Common / b3ResizablePool.h
1
2 #ifndef B3_RESIZABLE_POOL_H
3 #define B3_RESIZABLE_POOL_H
4
5 #include "Bullet3Common/b3AlignedObjectArray.h"
6
7 enum
8 {
9         B3_POOL_HANDLE_TERMINAL_FREE = -1,
10         B3_POOL_HANDLE_TERMINAL_USED = -2
11 };
12
13 template <typename U>
14 struct b3PoolBodyHandle : public U
15 {
16         B3_DECLARE_ALIGNED_ALLOCATOR();
17
18         int m_nextFreeHandle;
19         void setNextFree(int next)
20         {
21                 m_nextFreeHandle = next;
22         }
23         int getNextFree() const
24         {
25                 return m_nextFreeHandle;
26         }
27 };
28
29 template <typename T>
30 class b3ResizablePool
31 {
32 protected:
33         b3AlignedObjectArray<T> m_bodyHandles;
34         int m_numUsedHandles;   // number of active handles
35         int m_firstFreeHandle;  // free handles list
36
37         T* getHandleInternal(int handle)
38         {
39                 return &m_bodyHandles[handle];
40         }
41         const T* getHandleInternal(int handle) const
42         {
43                 return &m_bodyHandles[handle];
44         }
45
46 public:
47         b3ResizablePool()
48         {
49                 initHandles();
50         }
51
52         virtual ~b3ResizablePool()
53         {
54                 exitHandles();
55         }
56         ///handle management
57
58         int getNumHandles() const
59         {
60                 return m_bodyHandles.size();
61         }
62
63         void getUsedHandles(b3AlignedObjectArray<int>& usedHandles) const
64         {
65                 for (int i = 0; i < m_bodyHandles.size(); i++)
66                 {
67                         if (m_bodyHandles[i].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
68                         {
69                                 usedHandles.push_back(i);
70                         }
71                 }
72         }
73
74         T* getHandle(int handle)
75         {
76                 b3Assert(handle >= 0);
77                 b3Assert(handle < m_bodyHandles.size());
78                 if ((handle < 0) || (handle >= m_bodyHandles.size()))
79                 {
80                         return 0;
81                 }
82
83                 if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
84                 {
85                         return &m_bodyHandles[handle];
86                 }
87                 return 0;
88         }
89         const T* getHandle(int handle) const
90         {
91                 b3Assert(handle >= 0);
92                 b3Assert(handle < m_bodyHandles.size());
93                 if ((handle < 0) || (handle >= m_bodyHandles.size()))
94                 {
95                         return 0;
96                 }
97
98                 if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
99                 {
100                         return &m_bodyHandles[handle];
101                 }
102                 return 0;
103         }
104
105         void increaseHandleCapacity(int extraCapacity)
106         {
107                 int curCapacity = m_bodyHandles.size();
108                 //b3Assert(curCapacity == m_numUsedHandles);
109                 int newCapacity = curCapacity + extraCapacity;
110                 m_bodyHandles.resize(newCapacity);
111
112                 {
113                         for (int i = curCapacity; i < newCapacity; i++)
114                                 m_bodyHandles[i].setNextFree(i + 1);
115
116                         m_bodyHandles[newCapacity - 1].setNextFree(-1);
117                 }
118                 m_firstFreeHandle = curCapacity;
119         }
120         void initHandles()
121         {
122                 m_numUsedHandles = 0;
123                 m_firstFreeHandle = -1;
124
125                 increaseHandleCapacity(1);
126         }
127
128         void exitHandles()
129         {
130                 m_bodyHandles.resize(0);
131                 m_firstFreeHandle = -1;
132                 m_numUsedHandles = 0;
133         }
134
135         int allocHandle()
136         {
137                 b3Assert(m_firstFreeHandle >= 0);
138
139                 int handle = m_firstFreeHandle;
140                 m_firstFreeHandle = getHandleInternal(handle)->getNextFree();
141                 m_numUsedHandles++;
142
143                 if (m_firstFreeHandle < 0)
144                 {
145                         //int curCapacity = m_bodyHandles.size();
146                         int additionalCapacity = m_bodyHandles.size();
147                         increaseHandleCapacity(additionalCapacity);
148
149                         getHandleInternal(handle)->setNextFree(m_firstFreeHandle);
150                 }
151                 getHandleInternal(handle)->setNextFree(B3_POOL_HANDLE_TERMINAL_USED);
152                 getHandleInternal(handle)->clear();
153                 return handle;
154         }
155
156         void freeHandle(int handle)
157         {
158                 b3Assert(handle >= 0);
159
160                 if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
161                 {
162                         getHandleInternal(handle)->clear();
163                         getHandleInternal(handle)->setNextFree(m_firstFreeHandle);
164                         m_firstFreeHandle = handle;
165                         m_numUsedHandles--;
166                 }
167         }
168 };
169 ///end handle management
170
171 #endif  //B3_RESIZABLE_POOL_H