RavEngine
Loading...
Searching...
No Matches
ExtMultiList.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29
30#ifndef EXT_MULTI_LIST_H
31#define EXT_MULTI_LIST_H
32
33// MM: Multiple linked lists in a common array with a free list
34
35#include "foundation/PxArray.h"
36
37namespace physx
38{
39 namespace Ext
40 {
41
42 //-----------------------------------------------------------------------------
43 template <class T>
44 class MultiList {
45 public:
46 MultiList(PxI32 maxId = 0) {
47 firstFree = -1;
48 if (maxId > 0)
49 first.reserve(maxId + 1);
50 }
51 void reserve(int maxId) {
52 first.reserve(maxId + 1);
53 }
54 void clear();
55 PxI32 add(PxI32 id, const T &item);
56 bool addUnique(PxI32 id, const T &item);
57 bool exists(PxI32 id, const T &item) const;
58 void remove(PxI32 id, const T &item);
59 void removeAll(PxI32 id);
60 PxI32 size(PxI32 id) const;
61 PxI32 getPairNr(PxI32 id, const T &item) const;
62
63 void replace(PxI32 id, const T &before, const T &after);
64
65 void getItems(PxI32 id) const;
66 mutable PxArray<T> queryItems;
67
68 void initIteration(PxI32 id, PxI32& iterator);
69 bool iterate(T& item, PxI32& iterator);
70
71 void getPointers(PxI32 id);
72 mutable PxArray<T*> queryPointers;
73
74 private:
75 PxArray<PxI32> first;
76 PxArray<T> items;
77 PxArray<PxI32> next;
78 PxI32 firstFree;
79 };
80
81 //-----------------------------------------------------------------------------
82 template <class T>
84 {
85 first.clear();
86 next.clear();
87 items.clear();
88 queryItems.clear();
89 queryPointers.clear();
90 firstFree = -1;
91 }
92
93 //-----------------------------------------------------------------------------
94 template <class T>
95 PxI32 MultiList<T>::add(PxI32 id, const T &item)
96 {
97 if (id >= PxI32(first.size()))
98 first.resize(id + 1, -1);
99 PxI32 pos = firstFree;
100 if (pos >= 0)
101 firstFree = next[firstFree];
102 else
103 {
104 pos = PxI32(items.size());
105 items.resize(items.size() + 1);
106 next.resize(items.size() + 1);
107 }
108 next[pos] = first[id];
109 first[id] = pos;
110 items[pos] = item;
111 return pos;
112 }
113
114 //-----------------------------------------------------------------------------
115 template <class T>
116 bool MultiList<T>::addUnique(PxI32 id, const T &item)
117 {
118 if (exists(id, item))
119 return false;
120 add(id, item);
121 return true;
122 }
123
124 //-----------------------------------------------------------------------------
125 template <class T>
126 bool MultiList<T>::exists(PxI32 id, const T &item) const
127 {
128 return getPairNr(id, item) >= 0;
129 }
130
131 //-----------------------------------------------------------------------------
132 template <class T>
133 PxI32 MultiList<T>::size(PxI32 id) const
134 {
135 if (id >= PxI32(first.size()))
136 return 0;
137
138 PxI32 num = 0;
139 PxI32 nr = first[id];
140 while (nr >= 0)
141 {
142 num++;
143 nr = next[nr];
144 }
145 return num;
146 }
147
148 //-----------------------------------------------------------------------------
149 template <class T>
150 PxI32 MultiList<T>::getPairNr(PxI32 id, const T &item) const
151 {
152 if (id < 0 || id >= PxI32(first.size()))
153 return -1;
154 PxI32 nr = first[id];
155 while (nr >= 0)
156 {
157 if (items[nr] == item)
158 return nr;
159 nr = next[nr];
160 }
161 return -1;
162 }
163
164 //-----------------------------------------------------------------------------
165 template <class T>
166 void MultiList<T>::remove(PxI32 id, const T &itemNr)
167 {
168 PxI32 nr = first[id];
169 PxI32 prev = -1;
170 while (nr >= 0 && items[nr] != itemNr)
171 {
172 prev = nr;
173 nr = next[nr];
174 }
175 if (nr < 0)
176 return;
177 if (prev >= 0)
178 next[prev] = next[nr];
179 else
180 first[id] = next[nr];
181 next[nr] = firstFree;
182 firstFree = nr;
183 }
184
185 //-----------------------------------------------------------------------------
186 template <class T>
187 void MultiList<T>::replace(PxI32 id, const T &before, const T &after)
188 {
189 PxI32 nr = first[id];
190 while (nr >= 0)
191 {
192 if (items[nr] == before)
193 items[nr] = after;
194 nr = next[nr];
195 }
196 }
197
198 //-----------------------------------------------------------------------------
199 template <class T>
200 void MultiList<T>::removeAll(PxI32 id)
201 {
202 if (id >= PxI32(first.size()))
203 return;
204
205 PxI32 nr = first[id];
206 if (nr < 0)
207 return;
208
209 PxI32 prev = -1;
210 while (nr >= 0)
211 {
212 prev = nr;
213 nr = next[nr];
214 }
215 next[prev] = firstFree;
216 firstFree = first[id];
217 first[id] = -1;
218 }
219
220 //-----------------------------------------------------------------------------
221 template <class T>
222 void MultiList<T>::getItems(PxI32 id) const
223 {
224 queryItems.clear();
225 if (id >= PxI32(first.size()))
226 return;
227 PxI32 nr = first[id];
228 while (nr >= 0)
229 {
230 queryItems.push_back(items[nr]);
231 nr = next[nr];
232 }
233 }
234
235 //-----------------------------------------------------------------------------
236 template <class T>
237 void MultiList<T>::initIteration(PxI32 id, PxI32& iterator)
238 {
239 if (id >= PxI32(first.size()))
240 iterator = -1;
241 else
242 iterator = first[id];
243 }
244
245 //-----------------------------------------------------------------------------
246 template <class T>
247 bool MultiList<T>::iterate(T& item, PxI32& iterator)
248 {
249 if (iterator >= 0)
250 {
251 item = items[iterator];
252 iterator = next[iterator];
253 return true;
254 }
255 return false;
256 }
257
258 //-----------------------------------------------------------------------------
259 template <class T>
260 void MultiList<T>::getPointers(PxI32 id)
261 {
262 queryPointers.clear();
263 if (id >= PxI32(first.size()))
264 return;
265 PxI32 nr = first[id];
266 while (nr >= 0)
267 {
268 queryPointers.push_back(&items[nr]);
269 nr = next[nr];
270 }
271 }
272
273 }
274}
275
276#endif
Definition ExtMultiList.h:44
Definition PxArray.h:53
PX_INLINE void reserve(const uint32_t capacity)
Definition PxArray.h:486
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39