1//
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions
4// are met:
5// * Redistributions of source code must retain the above copyright
6// notice, this list of conditions and the following disclaimer.
7// * Redistributions in binary form must reproduce the above copyright
8// notice, this list of conditions and the following disclaimer in the
9// documentation and/or other materials provided with the distribution.
10// * Neither the name of NVIDIA CORPORATION nor the names of its
11// contributors may be used to endorse or promote products derived
12// from this software without specific prior written permission.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
15// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
27// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
28// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
29
30#ifndef PSFOUNDATION_PSBROADCAST_H
31#define PSFOUNDATION_PSBROADCAST_H
32
33#include "Ps.h"
34#include "PsInlineArray.h"
35
36#include "foundation/PxSimpleTypes.h"
37#include "foundation/PxErrorCallback.h"
38
39namespace physx
40{
41namespace shdfnd
42{
43
44/**
45\brief Abstract listener class that listens to allocation and deallocation events from the
46 foundation memory system.
47
48<b>Threading:</b> All methods of this class should be thread safe as it can be called from the user thread
49or the physics processing thread(s).
50*/
51class AllocationListener
52{
53 public:
54 /**
55 \brief callback when memory is allocated.
56 \param size Size of the allocation in bytes.
57 \param typeName Type this data is being allocated for.
58 \param filename File the allocation came from.
59 \param line the allocation came from.
60 \param allocatedMemory memory that will be returned from the allocation.
61 */
62 virtual void onAllocation(size_t size, const char* typeName, const char* filename, int line,
63 void* allocatedMemory) = 0;
64
65 /**
66 \brief callback when memory is deallocated.
67 \param allocatedMemory memory just before allocation.
68 */
69 virtual void onDeallocation(void* allocatedMemory) = 0;
70
71 protected:
72 virtual ~AllocationListener()
73 {
74 }
75};
76
77/**
78\brief Broadcast class implementation, registering listeners.
79
80<b>Threading:</b> All methods of this class should be thread safe as it can be called from the user thread
81or the physics processing thread(s). There is not internal locking
82*/
83template <class Listener, class Base>
84class Broadcast : public Base
85{
86 public:
87 static const uint32_t MAX_NB_LISTENERS = 16;
88
89 /**
90 \brief The default constructor.
91 */
92 Broadcast()
93 {
94 }
95
96 /**
97 \brief Register new listener.
98
99 \note It is NOT SAFE to register and deregister listeners while allocations may be taking place.
100 moreover, there is no thread safety to registration/deregistration.
101
102 \param listener Listener to register.
103 */
104 void registerListener(Listener& listener)
105 {
106 if(mListeners.size() < MAX_NB_LISTENERS)
107 mListeners.pushBack(&listener);
108 }
109
110 /**
111 \brief Deregister an existing listener.
112
113 \note It is NOT SAFE to register and deregister listeners while allocations may be taking place.
114 moreover, there is no thread safety to registration/deregistration.
115
116 \param listener Listener to deregister.
117 */
118 void deregisterListener(Listener& listener)
119 {
120 mListeners.findAndReplaceWithLast(&listener);
121 }
122
123 /**
124 \brief Get number of registered listeners.
125
126 \return Number of listeners.
127 */
128 uint32_t getNbListeners() const
129 {
130 return mListeners.size();
131 }
132
133 /**
134 \brief Get an existing listener from given index.
135
136 \param index Index of the listener.
137 \return Listener on given index.
138 */
139 Listener& getListener(uint32_t index)
140 {
141 PX_ASSERT(index <= mListeners.size());
142 return *mListeners[index];
143 }
144
145 protected:
146 virtual ~Broadcast()
147 {
148 }
149
150 physx::shdfnd::InlineArray<Listener*, MAX_NB_LISTENERS, physx::shdfnd::NonTrackingAllocator> mListeners;
151};
152
153/**
154\brief Abstract base class for an application defined memory allocator that allows an external listener
155to audit the memory allocations.
156*/
157class BroadcastingAllocator : public Broadcast<AllocationListener, PxAllocatorCallback>
158{
159 PX_NOCOPY(BroadcastingAllocator)
160
161 public:
162 /**
163 \brief The default constructor.
164 */
165 BroadcastingAllocator(PxAllocatorCallback& allocator, PxErrorCallback& error) : mAllocator(allocator), mError(error)
166 {
167 mListeners.clear();
168 }
169
170 /**
171 \brief The default constructor.
172 */
173 virtual ~BroadcastingAllocator()
174 {
175 mListeners.clear();
176 }
177
178 /**
179 \brief Allocates size bytes of memory, which must be 16-byte aligned.
180
181 This method should never return NULL. If you run out of memory, then
182 you should terminate the app or take some other appropriate action.
183
184 <b>Threading:</b> This function should be thread safe as it can be called in the context of the user thread
185 and physics processing thread(s).
186
187 \param size Number of bytes to allocate.
188 \param typeName Name of the datatype that is being allocated
189 \param filename The source file which allocated the memory
190 \param line The source line which allocated the memory
191 \return The allocated block of memory.
192 */
193 void* allocate(size_t size, const char* typeName, const char* filename, int line)
194 {
195 void* mem = mAllocator.allocate(size, typeName, filename, line);
196
197 if(!mem)
198 {
199 mError.reportError(code: PxErrorCode::eABORT, message: "User allocator returned NULL.", __FILE__, __LINE__);
200 return NULL;
201 }
202
203 if((reinterpret_cast<size_t>(mem) & 15))
204 {
205 mError.reportError(code: PxErrorCode::eABORT, message: "Allocations must be 16-byte aligned.", __FILE__, __LINE__);
206 return NULL;
207 }
208
209 for(uint32_t i = 0; i < mListeners.size(); i++)
210 mListeners[i]->onAllocation(size, typeName, filename, line, allocatedMemory: mem);
211
212 return mem;
213 }
214
215 /**
216 \brief Frees memory previously allocated by allocate().
217
218 <b>Threading:</b> This function should be thread safe as it can be called in the context of the user thread
219 and physics processing thread(s).
220
221 \param ptr Memory to free.
222 */
223 void deallocate(void* ptr)
224 {
225 for(uint32_t i = 0; i < mListeners.size(); i++)
226 {
227 mListeners[i]->onDeallocation(allocatedMemory: ptr);
228 }
229 mAllocator.deallocate(ptr);
230 }
231
232 private:
233 PxAllocatorCallback& mAllocator;
234 PxErrorCallback& mError;
235};
236
237/**
238\brief Abstract base class for an application defined error callback that allows an external listener
239to report errors.
240*/
241class BroadcastingErrorCallback : public Broadcast<PxErrorCallback, PxErrorCallback>
242{
243 PX_NOCOPY(BroadcastingErrorCallback)
244 public:
245 /**
246 \brief The default constructor.
247 */
248 BroadcastingErrorCallback(PxErrorCallback& errorCallback)
249 {
250 registerListener(listener&: errorCallback);
251 }
252
253 /**
254 \brief The default destructor.
255 */
256 virtual ~BroadcastingErrorCallback()
257 {
258 mListeners.clear();
259 }
260
261 /**
262 \brief Reports an error code.
263 \param code Error code, see #PxErrorCode
264 \param message Message to display.
265 \param file File error occured in.
266 \param line Line number error occured on.
267 */
268 void reportError(PxErrorCode::Enum code, const char* message, const char* file, int line)
269 {
270 for(uint32_t i = 0; i < mListeners.size(); i++)
271 mListeners[i]->reportError(code, message, file, line);
272 }
273};
274}
275} // namespace physx
276
277#endif // PSFOUNDATION_PXBROADCAST_H
278

source code of qtquick3dphysics/src/3rdparty/PhysX/source/foundation/include/PsBroadcast.h