OpenBarnyard
 
Loading...
Searching...
No Matches
T2ObjectPool.h
Go to the documentation of this file.
1#pragma once
2#include "T2Allocator.h"
3
4#undef GetObject
5
7
9{
10protected:
15
16public:
17 virtual ~T2GenericObjectPool() = default;
18
19protected:
20 virtual void* Malloc( TSIZE a_uiSize, TSIZE a_uiAlignment ) OVERRIDE
21 {
22 return TNULL;
23 }
24
25 virtual void* Malloc( TSIZE a_uiSize ) OVERRIDE
26 {
27 return GetObject();
28 }
29
30 virtual void Free( void* a_pPtr ) OVERRIDE
31 {
33 }
34
35 virtual TBOOL CanAllocate( TSIZE size ) const OVERRIDE
36 {
37 return m_pHead != TNULL;
38 }
39
40 virtual void* TryMalloc( TSIZE size, TSIZE alignment ) OVERRIDE
41 {
42 return TNULL;
43 }
44
45 virtual void* TryMalloc( TSIZE size ) OVERRIDE
46 {
47 if ( m_pHead != TNULL )
48 {
49 return GetObject();
50 }
51
52 return TNULL;
53 }
54
55protected:
56 void Initialise( UnusedObject* a_pObjects, TUINT a_uiMaxNumber, TUINT a_uiObjectSize )
57 {
58 TASSERT( a_uiMaxNumber > 1 );
59 m_pHead = a_pObjects;
60 UnusedObject* pObject = a_pObjects;
61
62 for ( TUINT i = a_uiMaxNumber - 1; i != 0; i-- )
63 {
64 UnusedObject* pNext = TREINTERPRETCAST( UnusedObject*, TREINTERPRETCAST( TUINTPTR, pObject ) + a_uiObjectSize );
65 pObject->pNextObject = pNext;
66 pObject = pNext;
67 }
68
69 pObject->pNextObject = TNULL;
70 }
71
73 {
74 UnusedObject* pNode = m_pHead;
75 m_pHead = m_pHead->pNextObject;
76 return pNode;
77 }
78
79 void ReturnObject( UnusedObject* a_pObject )
80 {
81 a_pObject->pNextObject = m_pHead;
82 m_pHead = a_pObject;
83 }
84
86 {
87 TUINT uiNumber = 0;
88 for ( auto it = m_pHead; it != TNULL; it = it->pNextObject, uiNumber++ )
89 ;
90
91 return uiNumber;
92 }
93
94protected:
96};
97
98template <class T, TUINT MaxNumber, TUINT ObjectSize = sizeof( T ), TUINT Alignment = alignof( T )>
100{
101public:
102 TSTATICASSERT( MaxNumber >= 2 );
104
105public:
107 {
110 MaxNumber,
111 ObjectSize
112 );
113 }
114
115 template <class... Args>
116 T* NewObject( Args&&... args )
117 {
119 T* pValue = new ( Malloc( ObjectSize ) ) T( std::forward<Args>( args )... );
120 return pValue;
121 }
122
124 {
126 return TSTATICCAST( T, Malloc( ObjectSize ) );
127 }
128
129 void FreeObject( T* a_pObject )
130 {
131 TASSERT( TTRUE == IsAddressInPool( a_pObject ) );
132 Free( a_pObject );
133 }
134
135 void DeleteObject( T* a_pObject )
136 {
137 TASSERT( TTRUE == IsAddressInPool( a_pObject ) );
138 a_pObject->~T();
139 Free( a_pObject );
140 }
141
142 virtual TSIZE GetUsedSize() const OVERRIDE
143 {
144 return ( MaxNumber - GetNumFreeObjects() ) * ObjectSize;
145 }
146
147 virtual TSIZE GetCapacity() const OVERRIDE
148 {
149 return MaxNumber * ObjectSize;
150 }
151
152 virtual TBOOL IsAddressInPool( const void* a_pAddress ) const
153 {
154 return ( TREINTERPRETCAST( TUINTPTR, this ) + sizeof( T2GenericObjectPool ) ) <= TREINTERPRETCAST( TUINTPTR, a_pAddress ) &&
155 TREINTERPRETCAST( TUINTPTR, a_pAddress ) < ( TREINTERPRETCAST( TUINTPTR, this ) + sizeof( T2GenericObjectPool ) + ( MaxNumber * ObjectSize ) );
156 }
157
158 TBOOL CanAllocate() const { return T2GenericObjectPool::CanAllocate( ObjectSize ); }
159
160private:
161 T* GetObjects()
162 {
163 return TREINTERPRETCAST( T*, m_aObjects );
164 }
165
166 const T* GetObjects() const
167 {
168 return TREINTERPRETCAST( const T*, m_aObjects );
169 }
170
171private:
172 TBYTE m_aObjects[ MaxNumber * ObjectSize ];
173};
174
175template <class T>
177{
178public:
179 T2DynamicObjectPool( T2Allocator* a_pAllocator, TINT a_iMaxNumber, TSIZE a_uiSize = sizeof( T ), TSIZE a_uiAlignment = alignof( T ) )
180 {
181 TVALIDPTR( a_pAllocator );
182 m_iMaxNumber = a_iMaxNumber;
183 m_pAllocator = a_pAllocator;
184
185 TUINT32 uiClassSize = a_uiSize;
186 TUINT32 uiClassAlignment = a_uiAlignment;
187 m_uiObjectSize = ( uiClassSize - 1 ) + uiClassAlignment & ~( uiClassAlignment - 1U );
188
189 TASSERT( m_uiObjectSize >= a_uiSize && uiClassAlignment > 0 );
190
191 if ( m_iMaxNumber < 1 )
192 {
193 m_pData = TNULL;
194 }
195 else
196 {
197 m_pData = m_pAllocator->Malloc( m_iMaxNumber * m_uiObjectSize, uiClassAlignment );
198 }
199
200 TVALIDPTR( m_pData );
203 m_iMaxNumber,
204 m_uiObjectSize
205 );
206 }
207
209 {
210 m_pAllocator->Free( m_pData );
211 }
212
213 template <class... Args>
214 T* NewObject( Args&&... args )
215 {
216 TASSERT( TTRUE == T2GenericObjectPool::CanAllocate( m_uiObjectSize ) );
217 T* pValue = new ( Malloc( m_uiObjectSize ) ) T( std::forward<Args>( args )... );
218 return pValue;
219 }
220
222 {
223 TASSERT( TTRUE == T2GenericObjectPool::CanAllocate( m_uiObjectSize ) );
224 return TSTATICCAST( T, Malloc( m_uiObjectSize ) );
225 }
226
227 void FreeObject( T* a_pObject )
228 {
229 TASSERT( TTRUE == IsAddressInPool( a_pObject ) );
230 Free( a_pObject );
231 }
232
233 void DeleteObject( T* a_pObject )
234 {
235 TASSERT( TTRUE == IsAddressInPool( a_pObject ) );
236 a_pObject->~T();
237 Free( a_pObject );
238 }
239
240 virtual TSIZE GetUsedSize() const OVERRIDE
241 {
242 return ( m_iMaxNumber - GetNumFreeObjects() ) * m_uiObjectSize;
243 }
244
245 virtual TSIZE GetCapacity() const OVERRIDE
246 {
247 return m_iMaxNumber * m_uiObjectSize;
248 }
249
250 virtual TBOOL IsAddressInPool( const void* a_pAddress ) const
251 {
252 return TREINTERPRETCAST( TUINTPTR, m_pData ) <= TREINTERPRETCAST( TUINTPTR, a_pAddress ) &&
253 TREINTERPRETCAST( TUINTPTR, a_pAddress ) < TREINTERPRETCAST( TUINTPTR, m_pData ) + ( m_iMaxNumber * m_uiObjectSize );
254 }
255
256 TBOOL CanAllocate() const { return T2GenericObjectPool::CanAllocate( m_uiObjectSize ); }
257
258private:
259 T2Allocator* m_pAllocator;
260 TINT m_iMaxNumber;
261 TUINT m_uiObjectSize;
262 void* m_pData;
263};
264
265template <class TClassType>
267{
268public:
269 T2DerivedDynamicObjectPool( T2Allocator* a_pAllocator, TINT a_iMaxNumber )
270 {
271 TVALIDPTR( a_pAllocator );
272 m_iMaxNumber = a_iMaxNumber;
273 m_pAllocator = a_pAllocator;
274
275 TUINT32 uiClassSize = TClassType::GetClassStatic()->GetMaxSizeOfDerivedClasses();
276 TUINT32 uiClassAlignment = TClassType::GetClassStatic()->GetMaxAlignmentOfDerivedClasses();
277 m_uiObjectSize = ( uiClassSize - 1 ) + uiClassAlignment & ~( uiClassAlignment - 1U );
278
279 TASSERT( m_uiObjectSize >= sizeof( TClassType ) && uiClassAlignment > 0 );
280
281 if ( m_iMaxNumber < 1 )
282 {
283 m_pData = TNULL;
284 }
285 else
286 {
287 m_pData = m_pAllocator->Malloc( m_iMaxNumber * m_uiObjectSize, uiClassAlignment );
288 }
289
290 TVALIDPTR( m_pData );
293 m_iMaxNumber,
294 m_uiObjectSize
295 );
296 }
297
299 {
300 m_pAllocator->Free( m_pData );
301 }
302
303 template <class... Args>
304 TClassType* NewObject( Args&&... args )
305 {
306 TASSERT( TTRUE == T2GenericObjectPool::CanAllocate( m_uiObjectSize ) );
307 TClassType* pValue = new ( Malloc( m_uiObjectSize ) ) TClassType( std::forward<Args>( args )... );
308 return pValue;
309 }
310
311 template <class T, class... Args>
312 T* NewDerivedObject( Args&&... args )
313 {
314 TASSERT( TTRUE == T::GetClassStatic()->IsA( TClassType::GetClassStatic() ) );
315 TASSERT( TTRUE == T2GenericObjectPool::CanAllocate( m_uiObjectSize ) );
316 T* pValue = new ( Malloc( m_uiObjectSize ) ) T( std::forward<Args>( args )... );
317 return pValue;
318 }
319
320 TClassType* AllocateObject()
321 {
322 TASSERT( TTRUE == T2GenericObjectPool::CanAllocate( m_uiObjectSize ) );
323 return TSTATICCAST( TClassType, Malloc( m_uiObjectSize ) );
324 }
325
326 void FreeObject( TClassType* a_pObject )
327 {
328 TASSERT( TTRUE == IsAddressInPool( a_pObject ) );
329 Free( a_pObject );
330 }
331
332 void DeleteObject( TClassType* a_pObject )
333 {
334 TASSERT( TTRUE == IsAddressInPool( a_pObject ) );
335 a_pObject->~TClassType();
336 Free( a_pObject );
337 }
338
339 virtual TSIZE GetUsedSize() const OVERRIDE
340 {
341 return ( m_iMaxNumber - GetNumFreeObjects() ) * m_uiObjectSize;
342 }
343
344 virtual TSIZE GetCapacity() const OVERRIDE
345 {
346 return m_iMaxNumber * m_uiObjectSize;
347 }
348
349 virtual TBOOL IsAddressInPool( const void* a_pAddress ) const
350 {
351 return TREINTERPRETCAST( TUINTPTR, m_pData ) <= TREINTERPRETCAST( TUINTPTR, a_pAddress ) &&
352 TREINTERPRETCAST( TUINTPTR, a_pAddress ) < TREINTERPRETCAST( TUINTPTR, m_pData ) + ( m_iMaxNumber * m_uiObjectSize );
353 }
354
355 TBOOL CanAllocate() const { return T2GenericObjectPool::CanAllocate( m_uiObjectSize ); }
356
357private:
358 T2Allocator* m_pAllocator;
359 TINT m_iMaxNumber;
360 TUINT m_uiObjectSize;
361 void* m_pData;
362};
363
#define TASSERT(X,...)
Definition Defines.h:138
#define TSTATICCAST(POINTERTYPE, VALUE)
Definition Defines.h:69
#define TREINTERPRETCAST(TYPE, VALUE)
Definition Defines.h:68
#define TOSHI_API
Definition Defines.h:41
#define OVERRIDE
Definition Defines.h:12
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
#define TVALIDPTR(PTR)
Definition Defines.h:139
unsigned int TUINT
Definition Typedefs.h:8
uintptr_t TUINTPTR
Definition Typedefs.h:18
size_t TSIZE
Definition Typedefs.h:9
#define TNULL
Definition Typedefs.h:23
uint32_t TUINT32
Definition Typedefs.h:13
int TINT
Definition Typedefs.h:7
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
uint8_t TBYTE
Definition Typedefs.h:19
virtual void * TryMalloc(TSIZE size) OVERRIDE
virtual void Free(void *a_pPtr) OVERRIDE
TUINT GetNumFreeObjects() const
void ReturnObject(UnusedObject *a_pObject)
virtual void * TryMalloc(TSIZE size, TSIZE alignment) OVERRIDE
UnusedObject * m_pHead
virtual void * Malloc(TSIZE a_uiSize, TSIZE a_uiAlignment) OVERRIDE
UnusedObject * GetObject()
virtual void * Malloc(TSIZE a_uiSize) OVERRIDE
void Initialise(UnusedObject *a_pObjects, TUINT a_uiMaxNumber, TUINT a_uiObjectSize)
virtual ~T2GenericObjectPool()=default
virtual TBOOL CanAllocate(TSIZE size) const OVERRIDE
T * NewObject(Args &&... args)
TBOOL CanAllocate() const
TSTATICASSERT(MaxNumber >=2)
virtual TBOOL IsAddressInPool(const void *a_pAddress) const
virtual TSIZE GetCapacity() const OVERRIDE
T * AllocateObject()
TSTATICASSERT(sizeof(T) >=sizeof(T2GenericObjectPool::UnusedObject))
void DeleteObject(T *a_pObject)
virtual TSIZE GetUsedSize() const OVERRIDE
void FreeObject(T *a_pObject)
virtual ~T2DynamicObjectPool()
virtual TSIZE GetUsedSize() const OVERRIDE
T * NewObject(Args &&... args)
void DeleteObject(T *a_pObject)
virtual TSIZE GetCapacity() const OVERRIDE
TBOOL CanAllocate() const
void FreeObject(T *a_pObject)
T2DynamicObjectPool(T2Allocator *a_pAllocator, TINT a_iMaxNumber, TSIZE a_uiSize=sizeof(T), TSIZE a_uiAlignment=alignof(T))
virtual TBOOL IsAddressInPool(const void *a_pAddress) const
TClassType * AllocateObject()
virtual TBOOL IsAddressInPool(const void *a_pAddress) const
void FreeObject(TClassType *a_pObject)
virtual TSIZE GetCapacity() const OVERRIDE
void DeleteObject(TClassType *a_pObject)
T2DerivedDynamicObjectPool(T2Allocator *a_pAllocator, TINT a_iMaxNumber)
T * NewDerivedObject(Args &&... args)
virtual TSIZE GetUsedSize() const OVERRIDE
TClassType * NewObject(Args &&... args)