| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 | 
#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
 |