handlealloc.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright 2010-2015 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #ifndef BX_HANDLE_ALLOC_H_HEADER_GUARD
  6. #define BX_HANDLE_ALLOC_H_HEADER_GUARD
  7. #include "bx.h"
  8. #include "allocator.h"
  9. namespace bx
  10. {
  11. template <uint16_t MaxHandlesT>
  12. class HandleAllocT
  13. {
  14. public:
  15. static const uint16_t invalid = 0xffff;
  16. HandleAllocT()
  17. : m_numHandles(0)
  18. {
  19. for (uint16_t ii = 0; ii < MaxHandlesT; ++ii)
  20. {
  21. m_handles[ii] = ii;
  22. }
  23. }
  24. ~HandleAllocT()
  25. {
  26. }
  27. const uint16_t* getHandles() const
  28. {
  29. return m_handles;
  30. }
  31. uint16_t getHandleAt(uint16_t _at) const
  32. {
  33. return m_handles[_at];
  34. }
  35. uint16_t getNumHandles() const
  36. {
  37. return m_numHandles;
  38. }
  39. uint16_t getMaxHandles() const
  40. {
  41. return MaxHandlesT;
  42. }
  43. uint16_t alloc()
  44. {
  45. if (m_numHandles < MaxHandlesT)
  46. {
  47. uint16_t index = m_numHandles;
  48. ++m_numHandles;
  49. uint16_t handle = m_handles[index];
  50. uint16_t* sparse = &m_handles[MaxHandlesT];
  51. sparse[handle] = index;
  52. return handle;
  53. }
  54. return invalid;
  55. }
  56. bool isValid(uint16_t _handle)
  57. {
  58. uint16_t* sparse = &m_handles[MaxHandlesT];
  59. uint16_t index = sparse[_handle];
  60. return (index < m_numHandles && m_handles[index] == _handle);
  61. }
  62. void free(uint16_t _handle)
  63. {
  64. BX_CHECK(0 < m_numHandles, "Freeing invalid handle %d.", _handle);
  65. uint16_t* sparse = &m_handles[MaxHandlesT];
  66. uint16_t index = sparse[_handle];
  67. --m_numHandles;
  68. uint16_t temp = m_handles[m_numHandles];
  69. m_handles[m_numHandles] = _handle;
  70. sparse[temp] = index;
  71. m_handles[index] = temp;
  72. }
  73. private:
  74. uint16_t m_handles[MaxHandlesT*2];
  75. uint16_t m_numHandles;
  76. };
  77. class HandleAlloc
  78. {
  79. public:
  80. static const uint16_t invalid = 0xffff;
  81. HandleAlloc(uint16_t _maxHandles, void* _handles)
  82. : m_handles( (uint16_t*)_handles)
  83. , m_numHandles(0)
  84. , m_maxHandles(_maxHandles)
  85. {
  86. for (uint16_t ii = 0; ii < _maxHandles; ++ii)
  87. {
  88. m_handles[ii] = ii;
  89. }
  90. }
  91. ~HandleAlloc()
  92. {
  93. }
  94. const uint16_t* getHandles() const
  95. {
  96. return m_handles;
  97. }
  98. uint16_t getHandleAt(uint16_t _at) const
  99. {
  100. return m_handles[_at];
  101. }
  102. uint16_t getNumHandles() const
  103. {
  104. return m_numHandles;
  105. }
  106. uint16_t getMaxHandles() const
  107. {
  108. return m_maxHandles;
  109. }
  110. uint16_t alloc()
  111. {
  112. if (m_numHandles < m_maxHandles)
  113. {
  114. uint16_t index = m_numHandles;
  115. ++m_numHandles;
  116. uint16_t handle = m_handles[index];
  117. uint16_t* sparse = &m_handles[m_maxHandles];
  118. sparse[handle] = index;
  119. return handle;
  120. }
  121. return invalid;
  122. }
  123. bool isValid(uint16_t _handle)
  124. {
  125. uint16_t* sparse = &m_handles[m_maxHandles];
  126. uint16_t index = sparse[_handle];
  127. return (index < m_numHandles && m_handles[index] == _handle);
  128. }
  129. void free(uint16_t _handle)
  130. {
  131. uint16_t* sparse = &m_handles[m_maxHandles];
  132. uint16_t index = sparse[_handle];
  133. --m_numHandles;
  134. uint16_t temp = m_handles[m_numHandles];
  135. m_handles[m_numHandles] = _handle;
  136. sparse[temp] = index;
  137. m_handles[index] = temp;
  138. }
  139. private:
  140. uint16_t* m_handles;
  141. uint16_t m_numHandles;
  142. uint16_t m_maxHandles;
  143. };
  144. inline HandleAlloc* createHandleAlloc(AllocatorI* _allocator, uint16_t _maxHandles)
  145. {
  146. uint8_t* ptr = (uint8_t*)BX_ALLOC(_allocator, sizeof(HandleAlloc) + 2*_maxHandles*sizeof(uint16_t) );
  147. return ::new (ptr) HandleAlloc(_maxHandles, &ptr[sizeof(HandleAlloc)]);
  148. }
  149. inline void destroyHandleAlloc(AllocatorI* _allocator, HandleAlloc* _handleAlloc)
  150. {
  151. _handleAlloc->~HandleAlloc();
  152. BX_FREE(_allocator, _handleAlloc);
  153. }
  154. } // namespace bx
  155. #endif // BX_HANDLE_ALLOC_H_HEADER_GUARD