Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
63c4d67e3This file is pinned to the selected release. Download the original to open it in your design tool.
#ifndef B3_RESIZABLE_POOL_H
#define B3_RESIZABLE_POOL_H
#include "Bullet3Common/b3AlignedObjectArray.h"
enum
{
B3_POOL_HANDLE_TERMINAL_FREE = -1,
B3_POOL_HANDLE_TERMINAL_USED = -2
};
template <typename U>
struct b3PoolBodyHandle : public U
{
B3_DECLARE_ALIGNED_ALLOCATOR();
int m_nextFreeHandle;
void setNextFree(int next)
{
m_nextFreeHandle = next;
}
int getNextFree() const
{
return m_nextFreeHandle;
}
};
template <typename T>
class b3ResizablePool
{
protected:
b3AlignedObjectArray<T> m_bodyHandles;
int m_numUsedHandles; // number of active handles
int m_firstFreeHandle; // free handles list
T* getHandleInternal(int handle)
{
return &m_bodyHandles[handle];
}
const T* getHandleInternal(int handle) const
{
return &m_bodyHandles[handle];
}
public:
b3ResizablePool()
{
initHandles();
}
virtual ~b3ResizablePool()
{
exitHandles();
}
///handle management
int getNumHandles() const
{
return m_bodyHandles.size();
}
void getUsedHandles(b3AlignedObjectArray<int>& usedHandles) const
{
for (int i = 0; i < m_bodyHandles.size(); i++)
{
if (m_bodyHandles[i].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
{
usedHandles.push_back(i);
}
}
}
T* getHandle(int handle)
{
b3Assert(handle >= 0);
b3Assert(handle < m_bodyHandles.size());
if ((handle < 0) || (handle >= m_bodyHandles.size()))
{
return 0;
}
if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
{
return &m_bodyHandles[handle];
}
return 0;
}
const T* getHandle(int handle) const
{
b3Assert(handle >= 0);
b3Assert(handle < m_bodyHandles.size());
if ((handle < 0) || (handle >= m_bodyHandles.size()))
{
return 0;
}
if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
{
return &m_bodyHandles[handle];
}
return 0;
}
void increaseHandleCapacity(int extraCapacity)
{
int curCapacity = m_bodyHandles.size();
//b3Assert(curCapacity == m_numUsedHandles);
int newCapacity = curCapacity + extraCapacity;
m_bodyHandles.resize(newCapacity);
{
for (int i = curCapacity; i < newCapacity; i++)
m_bodyHandles[i].setNextFree(i + 1);
m_bodyHandles[newCapacity - 1].setNextFree(-1);
}
m_firstFreeHandle = curCapacity;
}
void initHandles()
{
m_numUsedHandles = 0;
m_firstFreeHandle = -1;
increaseHandleCapacity(1);
}
void exitHandles()
{
m_bodyHandles.resize(0);
m_firstFreeHandle = -1;
m_numUsedHandles = 0;
}
int allocHandle()
{
b3Assert(m_firstFreeHandle >= 0);
int handle = m_firstFreeHandle;
m_firstFreeHandle = getHandleInternal(handle)->getNextFree();
m_numUsedHandles++;
if (m_firstFreeHandle < 0)
{
//int curCapacity = m_bodyHandles.size();
int additionalCapacity = m_bodyHandles.size();
increaseHandleCapacity(additionalCapacity);
getHandleInternal(handle)->setNextFree(m_firstFreeHandle);
}
getHandleInternal(handle)->setNextFree(B3_POOL_HANDLE_TERMINAL_USED);
getHandleInternal(handle)->clear();
return handle;
}
void freeHandle(int handle)
{
b3Assert(handle >= 0);
if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
{
getHandleInternal(handle)->clear();
getHandleInternal(handle)->setNextFree(m_firstFreeHandle);
m_firstFreeHandle = handle;
m_numUsedHandles--;
}
}
};
///end handle management
#endif //B3_RESIZABLE_POOL_H