Grindstone Game Engine v0.2.0
An open source game engine and toolkit.
Loading...
Searching...
No Matches
PoolAllocator.hpp
1#pragma once
2
3#include <stdint.h>
4#include <utility>
5#include <functional>
6#include <memory>
7
8#include "../SmartPointers.hpp"
9
10
12 class BasePoolAllocator {
13 public:
14
15 void Clear();
16 void ClearAndZero();
17 void Destroy();
18
19 bool IsEmpty() const;
20 size_t GetUsedCount() const;
21
22 struct FreeLink {
23 FreeLink* next;
24 };
25
26 protected:
27 BasePoolAllocator() = default;
28
29 inline void* AllocateImpl();
30 inline void SetupLinkedList();
31
32 void DeallocateImpl(size_t index);
33 void DeallocateImpl(void* ptr);
34
35 // Total Memory size is used in case we are passed owned memory that is bigger than totalChunkCount * chunkSize
36 size_t totalMemorySize = 0;
37 size_t chunkSize = 0;
38 size_t usedChunkCount = 0;
39 size_t totalChunkCount = 0;
40
41 FreeLink* headFreePtr = nullptr;
42 void* memory = nullptr;
43 bool hasAllocatedOwnMemory = false;
44 std::function<void(void*)> deleteFn;
45 };
46
54 class GenericPoolAllocator : public BasePoolAllocator {
55 public:
56 GenericPoolAllocator() = default;
57 ~GenericPoolAllocator();
58
59 void Initialize(void* ownedMemory, size_t totalSize, size_t sizePerChunk);
60 bool Initialize(size_t sizePerChunk, size_t maxChunkCount);
61 void* Allocate();
62 void Deallocate(size_t index);
63 void Deallocate(void* ptr);
64
65 };
66
74 template <typename T>
75 class PoolAllocator : public BasePoolAllocator {
76 public:
77 PoolAllocator() = default;
78
79 bool Initialize(void* ownedMemory, size_t totalSize) {
80 memory = ownedMemory;
81 totalMemorySize = totalSize;
82 chunkSize = sizeof(T);
83 usedChunkCount = 0;
84 totalChunkCount = totalSize / chunkSize;
85 hasAllocatedOwnMemory = false;
86
87 deleteFn = [this](void* ptr) -> void {
88 DeallocateImpl(ptr);
89 };
90
91 SetupLinkedList();
92 }
93
94 bool Initialize(size_t maxChunkCount) {
95 chunkSize = sizeof(T);
96 totalMemorySize = chunkSize * maxChunkCount;
97 usedChunkCount = 0;
98 totalChunkCount = maxChunkCount;
99
100 memory = malloc(totalMemorySize);
101 hasAllocatedOwnMemory = true;
102
103 SetupLinkedList();
104
105 deleteFn = [this](void* ptr) -> void {
106 DeallocateImpl(ptr);
107 };
108
109 return memory != nullptr;
110 }
111
112 template<typename... Args>
113 SharedPtr<T> AllocateShared(Args&&... params) {
114 static_assert(std::is_constructible_v<T, Args...>, "Type T must be constructible with given arguments.");
115
116 T* ptr = static_cast<T*>(AllocateImpl());
117 if (ptr != nullptr) {
118 // Call the constructor on the newly allocated memory
119 new (ptr) T(std::forward<Args>(params)...);
120 }
121
122 return SharedPtr<T>(ptr, deleteFn);
123 }
124
125 template<typename... Args>
126 UniquePtr<T> AllocateUnique(Args&&... params) {
127 static_assert(std::is_constructible_v<T, Args...>, "Type T must be constructible with given arguments.");
128
129 T* ptr = static_cast<T*>(AllocateImpl());
130 if (ptr != nullptr) {
131 // Call the constructor on the newly allocated memory
132 new (ptr) T(std::forward<Args>(params)...);
133 }
134
135 return UniquePtr<T>(ptr, deleteFn);
136 }
137
138 template<typename... Args>
139 T* Allocate(Args&&... params) {
140 static_assert(std::is_constructible_v<T, Args...>, "Type T must be constructible with given arguments.");
141
142 T* ptr = static_cast<T*>(AllocateImpl());
143 if (ptr != nullptr) {
144 // Call the constructor on the newly allocated memory
145 new (ptr) T(std::forward<Args>(params)...);
146 }
147
148 return ptr;
149 }
150
151 T* AllocateWithoutConstructor() {
152 return static_cast<T*>(AllocateImpl());
153 }
154
155 void Deallocate(size_t index) {
156 size_t chunkOffset = index * chunkSize;
157 void* ptr = reinterpret_cast<char*>(memory) + chunkOffset;
158 reinterpret_cast<T*>(ptr)->~T();
159 DeallocateImpl(ptr);
160 }
161
162 void Deallocate(void* ptr) {
163 reinterpret_cast<T*>(ptr)->~T();
164 DeallocateImpl(ptr);
165 }
166
167 void DeallocateWithoutDestructor(size_t index) {
168 size_t chunkOffset = index * chunkSize;
169 void* ptr = reinterpret_cast<char*>(memory) + chunkOffset;
170 DeallocateImpl(ptr);
171 }
172
173 void DeallocateWithoutDestructor(void* ptr) {
174 DeallocateImpl(ptr);
175 }
176 };
177}
Definition SharedPtr.hpp:7
Definition UniquePtr.hpp:7
Definition AllocatorConcept.hpp:11