ObjectAllocator.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Util/Array.h>
  7. namespace anki {
  8. /// @addtogroup util_containers
  9. /// @{
  10. /// A simple allocator for objects of similar types.
  11. /// @tparam kTObjectSize The maximum size of the objects.
  12. /// @tparam kTObjectAlignment The maximum alignment of the objects.
  13. /// @tparam kTObjectsPerChunk How much memory (in objects) will be allocated at once.
  14. /// @tparam TIndexType If kTObjectsPerChunk>0xFF make it U16. If kTObjectsPerChunk>0xFFFF make it U32.
  15. template<PtrSize kTObjectSize, U32 kTObjectAlignment, typename TMemoryPool, U32 kTObjectsPerChunk = 64, typename TIndexType = U8>
  16. class ObjectAllocator
  17. {
  18. public:
  19. static constexpr PtrSize kObjectSize = kTObjectSize;
  20. static constexpr U32 kObjectAlignment = kTObjectAlignment;
  21. static constexpr U32 kObjectsPerChunk = kTObjectsPerChunk;
  22. ObjectAllocator(const TMemoryPool& pool = TMemoryPool())
  23. : m_pool(pool)
  24. {
  25. }
  26. ~ObjectAllocator()
  27. {
  28. ANKI_ASSERT(m_chunksHead == nullptr && m_chunksTail == nullptr && "Forgot to deallocate");
  29. }
  30. /// Allocate and construct a new object instance.
  31. /// @note Not thread-safe.
  32. template<typename T, typename... TArgs>
  33. T* newInstance(TArgs&&... args);
  34. /// Delete an object.
  35. /// @note Not thread-safe.
  36. template<typename T>
  37. void deleteInstance(T* obj);
  38. private:
  39. /// Storage with equal properties as the object.
  40. struct alignas(kObjectAlignment) Object
  41. {
  42. U8 m_storage[kObjectSize];
  43. };
  44. /// A single allocation.
  45. class Chunk
  46. {
  47. public:
  48. Array<Object, kObjectsPerChunk> m_objects;
  49. Array<U32, kObjectsPerChunk> m_unusedStack;
  50. U32 m_unusedCount;
  51. Chunk* m_next = nullptr;
  52. Chunk* m_prev = nullptr;
  53. };
  54. TMemoryPool m_pool;
  55. Chunk* m_chunksHead = nullptr;
  56. Chunk* m_chunksTail = nullptr;
  57. };
  58. /// Convenience wrapper for ObjectAllocator.
  59. template<typename T, typename TMemoryPool, U32 kTObjectsPerChunk = 64, typename TIndexType = U8>
  60. class ObjectAllocatorSameType : public ObjectAllocator<sizeof(T), U32(alignof(T)), TMemoryPool, kTObjectsPerChunk, TIndexType>
  61. {
  62. public:
  63. using Base = ObjectAllocator<sizeof(T), U32(alignof(T)), TMemoryPool, kTObjectsPerChunk, TIndexType>;
  64. /// Allocate and construct a new object instance.
  65. /// @note Not thread-safe.
  66. template<typename... TArgs>
  67. T* newInstance(TArgs&&... args)
  68. {
  69. return Base::template newInstance<T>(std::forward(args)...);
  70. }
  71. /// Delete an object.
  72. /// @note Not thread-safe.
  73. void deleteInstance(T* obj)
  74. {
  75. Base::deleteInstance(obj);
  76. }
  77. };
  78. /// @}
  79. } // end namespace anki
  80. #include <AnKi/Util/ObjectAllocator.inl.h>