Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
allocator_resources.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <helios/core_pch.hpp>
4
10
11#include <cstddef>
12#include <string_view>
13
14namespace helios::app {
15
16/**
17 * @brief Resource wrapper for a per-World frame allocator.
18 * @details Owns a frame allocator that can be reset per-frame.
19 * Suitable for temporary per-frame allocations within a specific World.
20 *
21 * Uses lock-free operations.
22 *
23 * @note Thread-safe.
24 *
25 * @example
26 * @code
27 * world.AddResource<FrameAllocatorResource>(1024 * 1024); // 1MB
28 *
29 * void Update(SystemContext& ctx) {
30 * auto& resource = ctx.WriteResource<FrameAllocatorResource>();
31 * auto& allocator = resource.Get();
32 * // Use allocator for temporary data
33 * }
34 *
35 * // Reset at frame end
36 * world.WriteResource<FrameAllocatorResource>().Reset();
37 * @endcode
38 */
40public:
41 /**
42 * @brief Constructs resource with a frame allocator.
43 * @param capacity Size of the frame allocator buffer in bytes (default: 16MB)
44 */
45 explicit FrameAllocatorResource(size_t capacity = 16 * 1024 * 1024) : allocator_(capacity) {}
48 ~FrameAllocatorResource() noexcept = default;
49
51 FrameAllocatorResource& operator=(FrameAllocatorResource&&) noexcept = default;
52
53 /**
54 * @brief Resets the frame allocator, freeing all allocations.
55 * @details Should be called at frame boundaries.
56 */
57 void Reset() noexcept { allocator_.Reset(); }
58
59 /**
60 * @brief Checks if the frame allocator is empty.
61 * @return True if no allocations exist
62 */
63 [[nodiscard]] bool Empty() const noexcept { return allocator_.Empty(); }
64
65 /**
66 * @brief Gets reference to the frame allocator.
67 * @return Reference to FrameAllocator
68 */
69 [[nodiscard]] memory::FrameAllocator& Get() noexcept { return allocator_; }
70
71 /**
72 * @brief Gets const reference to the frame allocator.
73 * @return Const reference to FrameAllocator
74 */
75 [[nodiscard]] const memory::FrameAllocator& Get() const noexcept { return allocator_; }
76
77 /**
78 * @brief Gets frame allocator statistics.
79 * @return AllocatorStats with current usage
80 */
81 [[nodiscard]] memory::AllocatorStats Stats() const noexcept { return allocator_.Stats(); }
82
83 /**
84 * @brief Gets the capacity of the frame allocator.
85 * @return Capacity in bytes
86 */
87 [[nodiscard]] size_t Capacity() const noexcept { return allocator_.Capacity(); }
88
89 /**
90 * @brief Gets the resource name for registration.
91 * @return Resource name
92 */
93 [[nodiscard]] static constexpr std::string_view Name() noexcept { return "FrameAllocatorResource"; }
94
95private:
96 memory::FrameAllocator allocator_;
97};
98
99/**
100 * @brief Resource wrapper for a per-World free list allocator.
101 * @details Owns a general-purpose allocator for arbitrary allocation patterns.
102 *
103 * Uses mutex for thread safety.
104 *
105 * @note Thread-safe.
106 *
107 * @example
108 * @code
109 * world.AddResource<FreeListAllocatorResource>(64 * 1024 * 1024); // 64MB
110 *
111 * void Update(SystemContext& ctx) {
112 * auto& resource = ctx.WriteResource<FreeListAllocatorResource>();
113 * auto& allocator = resource.Get();
114 * // Use allocator
115 * }
116 * @endcode
117 */
119public:
120 /**
121 * @brief Constructs resource with a free list allocator.
122 * @param capacity Size of the allocator buffer in bytes (default: 64MB)
123 */
124 explicit FreeListAllocatorResource(size_t capacity = 64 * 1024 * 1024) : allocator_(capacity) {}
127 ~FreeListAllocatorResource() noexcept = default;
128
130 FreeListAllocatorResource& operator=(FreeListAllocatorResource&&) noexcept = default;
131
132 /**
133 * @brief Gets reference to the free list allocator.
134 * @return Reference to FreeListAllocator
135 */
136 [[nodiscard]] memory::FreeListAllocator& Get() noexcept { return allocator_; }
137
138 /**
139 * @brief Gets const reference to the free list allocator.
140 * @return Const reference to FreeListAllocator
141 */
142 [[nodiscard]] const memory::FreeListAllocator& Get() const noexcept { return allocator_; }
143
144 /**
145 * @brief Resets the allocator, freeing all allocations.
146 */
147 void Reset() noexcept { allocator_.Reset(); }
148
149 /**
150 * @brief Checks if the allocator is empty.
151 * @return True if no allocations exist
152 */
153 [[nodiscard]] bool Empty() const noexcept { return allocator_.Empty(); }
154
155 /**
156 * @brief Gets allocator statistics.
157 * @return AllocatorStats with current usage
158 */
159 [[nodiscard]] memory::AllocatorStats Stats() const noexcept { return allocator_.Stats(); }
160
161 /**
162 * @brief Gets the capacity of the allocator.
163 * @return Capacity in bytes
164 */
165 [[nodiscard]] size_t Capacity() const noexcept { return allocator_.Capacity(); }
166
167 /**
168 * @brief Gets the resource name for registration.
169 * @return Resource name
170 */
171 [[nodiscard]] static constexpr std::string_view Name() noexcept { return "FreeListAllocatorResource"; }
172
173private:
174 memory::FreeListAllocator allocator_;
175};
176
177/**
178 * @brief Resource wrapper for a per-World pool allocator.
179 * @details Owns a pool allocator for fixed-size allocations.
180 *
181 * Uses lock-free operations.
182 *
183 * @note Thread-safe.
184 *
185 * @example
186 * @code
187 * // Create pool for Entity-sized allocations
188 * auto pool = PoolAllocatorResource::ForType<Entity>(1000);
189 * world.AddResource<PoolAllocatorResource>(std::move(pool));
190 *
191 * void Update(SystemContext& ctx) {
192 * auto& resource = ctx.WriteResource<PoolAllocatorResource>();
193 * auto& allocator = resource.Get();
194 * }
195 * @endcode
196 */
198public:
199 /**
200 * @brief Creates a pool allocator resource sized for type T.
201 * @tparam T Type to allocate
202 * @param block_count Number of blocks to allocate
203 * @return PoolAllocatorResource configured for type T
204 */
205 template <typename T>
206 [[nodiscard]] static PoolAllocatorResource ForType(size_t block_count) {
207 return PoolAllocatorResource(sizeof(T), block_count, alignof(T));
208 }
209
210 /**
211 * @brief Constructs resource with a pool allocator.
212 * @param block_size Size of each block in bytes
213 * @param block_count Number of blocks to allocate
214 * @param alignment Alignment for each block (must be power of 2)
215 */
216 explicit PoolAllocatorResource(size_t block_size, size_t block_count, size_t alignment = memory::kDefaultAlignment)
217 : allocator_(block_size, block_count, alignment) {}
218
221 ~PoolAllocatorResource() noexcept = default;
222
223 PoolAllocatorResource& operator=(const PoolAllocatorResource&) = delete;
224 PoolAllocatorResource& operator=(PoolAllocatorResource&&) noexcept = default;
225
226 /**
227 * @brief Gets reference to the pool allocator.
228 * @return Reference to PoolAllocator
229 */
230 [[nodiscard]] memory::PoolAllocator& Get() noexcept { return allocator_; }
231
232 /**
233 * @brief Gets const reference to the pool allocator.
234 * @return Const reference to PoolAllocator
235 */
236 [[nodiscard]] const memory::PoolAllocator& Get() const noexcept { return allocator_; }
237
238 /**
239 * @brief Resets the pool, making all blocks available.
240 */
241 void Reset() noexcept { allocator_.Reset(); }
242
243 /**
244 * @brief Checks if the pool allocator is empty.
245 * @return True if all blocks are free
246 */
247 [[nodiscard]] bool Empty() const noexcept { return allocator_.Empty(); }
248
249 /**
250 * @brief Checks if the pool allocator is full.
251 * @return True if all blocks are allocated
252 */
253 [[nodiscard]] bool Full() const noexcept { return allocator_.Full(); }
254
255 /**
256 * @brief Gets pool allocator statistics.
257 * @return AllocatorStats with current usage
258 */
259 [[nodiscard]] memory::AllocatorStats Stats() const noexcept { return allocator_.Stats(); }
260
261 /**
262 * @brief Gets the block size.
263 * @return Block size in bytes
264 */
265 [[nodiscard]] size_t BlockSize() const noexcept { return allocator_.BlockSize(); }
266
267 /**
268 * @brief Gets the block count.
269 * @return Total number of blocks
270 */
271 [[nodiscard]] size_t BlockCount() const noexcept { return allocator_.BlockCount(); }
272
273 /**
274 * @brief Gets the resource name for registration.
275 * @return Resource name
276 */
277 [[nodiscard]] static constexpr std::string_view Name() noexcept { return "PoolAllocatorResource"; }
278
279private:
280 memory::PoolAllocator allocator_;
281};
282
283/**
284 * @brief Resource wrapper for a per-World stack allocator.
285 * @details Owns a stack allocator for LIFO allocation patterns.
286 *
287 * Uses mutex for thread safety.
288 *
289 * @warning Deallocations must follow LIFO order.
290 * @note Thread-safe.
291 *
292 * @example
293 * @code
294 * world.AddResource<StackAllocatorResource>(1024 * 1024); // 1MB
295 *
296 * void Update(SystemContext& ctx) {
297 * auto& resource = ctx.WriteResource<StackAllocatorResource>();
298 * auto& allocator = resource.Get();
299 * }
300 * @endcode
301 */
303public:
304 /**
305 * @brief Constructs resource with a stack allocator.
306 * @param capacity Size of the allocator buffer in bytes (default: 16MB)
307 */
308 explicit StackAllocatorResource(size_t capacity = 16 * 1024 * 1024) : allocator_(capacity) {}
311 ~StackAllocatorResource() noexcept = default;
312
314 StackAllocatorResource& operator=(StackAllocatorResource&&) noexcept = default;
315
316 /**
317 * @brief Gets reference to the stack allocator.
318 * @return Reference to StackAllocator
319 */
320 [[nodiscard]] memory::StackAllocator& Get() noexcept { return allocator_; }
321
322 /**
323 * @brief Gets const reference to the stack allocator.
324 * @return Const reference to StackAllocator
325 */
326 [[nodiscard]] const memory::StackAllocator& Get() const noexcept { return allocator_; }
327
328 /**
329 * @brief Resets the stack allocator, freeing all allocations.
330 */
331 void Reset() noexcept { allocator_.Reset(); }
332
333 /**
334 * @brief Checks if the stack allocator is empty.
335 * @return True if no allocations exist
336 */
337 [[nodiscard]] bool Empty() const noexcept { return allocator_.Empty(); }
338
339 /**
340 * @brief Checks if the stack allocator is full.
341 * @return True if no more allocations can be made without reset
342 */
343 [[nodiscard]] bool Full() const noexcept { return allocator_.Full(); }
344
345 /**
346 * @brief Gets stack allocator statistics.
347 * @return AllocatorStats with current usage
348 */
349 [[nodiscard]] memory::AllocatorStats Stats() const noexcept { return allocator_.Stats(); }
350
351 /**
352 * @brief Gets the capacity of the allocator.
353 * @return Capacity in bytes
354 */
355 [[nodiscard]] size_t Capacity() const noexcept { return allocator_.Capacity(); }
356
357 /**
358 * @brief Gets the resource name for registration.
359 * @return Resource name
360 */
361 [[nodiscard]] static constexpr std::string_view Name() noexcept { return "StackAllocatorResource"; }
362
363private:
364 memory::StackAllocator allocator_;
365};
366
367} // namespace helios::app
memory::AllocatorStats Stats() const noexcept
Gets frame allocator statistics.
FrameAllocatorResource(const FrameAllocatorResource &)=delete
size_t Capacity() const noexcept
Gets the capacity of the frame allocator.
bool Empty() const noexcept
Checks if the frame allocator is empty.
void Reset() noexcept
Resets the frame allocator, freeing all allocations.
const memory::FrameAllocator & Get() const noexcept
Gets const reference to the frame allocator.
FrameAllocatorResource(FrameAllocatorResource &&) noexcept=default
static constexpr std::string_view Name() noexcept
Gets the resource name for registration.
memory::FrameAllocator & Get() noexcept
Gets reference to the frame allocator.
FrameAllocatorResource(size_t capacity=16 *1024 *1024)
Constructs resource with a frame allocator.
FreeListAllocatorResource(size_t capacity=64 *1024 *1024)
Constructs resource with a free list allocator.
FreeListAllocatorResource(const FreeListAllocatorResource &)=delete
static constexpr std::string_view Name() noexcept
Gets the resource name for registration.
memory::AllocatorStats Stats() const noexcept
Gets allocator statistics.
memory::FreeListAllocator & Get() noexcept
Gets reference to the free list allocator.
size_t Capacity() const noexcept
Gets the capacity of the allocator.
bool Empty() const noexcept
Checks if the allocator is empty.
void Reset() noexcept
Resets the allocator, freeing all allocations.
FreeListAllocatorResource(FreeListAllocatorResource &&) noexcept=default
const memory::FreeListAllocator & Get() const noexcept
Gets const reference to the free list allocator.
const memory::PoolAllocator & Get() const noexcept
Gets const reference to the pool allocator.
memory::AllocatorStats Stats() const noexcept
Gets pool allocator statistics.
memory::PoolAllocator & Get() noexcept
Gets reference to the pool allocator.
size_t BlockCount() const noexcept
Gets the block count.
void Reset() noexcept
Resets the pool, making all blocks available.
bool Empty() const noexcept
Checks if the pool allocator is empty.
PoolAllocatorResource(const PoolAllocatorResource &)=delete
PoolAllocatorResource(PoolAllocatorResource &&) noexcept=default
static PoolAllocatorResource ForType(size_t block_count)
Creates a pool allocator resource sized for type T.
bool Full() const noexcept
Checks if the pool allocator is full.
PoolAllocatorResource(size_t block_size, size_t block_count, size_t alignment=memory::kDefaultAlignment)
Constructs resource with a pool allocator.
size_t BlockSize() const noexcept
Gets the block size.
static constexpr std::string_view Name() noexcept
Gets the resource name for registration.
memory::StackAllocator & Get() noexcept
Gets reference to the stack allocator.
static constexpr std::string_view Name() noexcept
Gets the resource name for registration.
StackAllocatorResource(size_t capacity=16 *1024 *1024)
Constructs resource with a stack allocator.
StackAllocatorResource(const StackAllocatorResource &)=delete
bool Empty() const noexcept
Checks if the stack allocator is empty.
const memory::StackAllocator & Get() const noexcept
Gets const reference to the stack allocator.
void Reset() noexcept
Resets the stack allocator, freeing all allocations.
StackAllocatorResource(StackAllocatorResource &&) noexcept=default
memory::AllocatorStats Stats() const noexcept
Gets stack allocator statistics.
size_t Capacity() const noexcept
Gets the capacity of the allocator.
bool Full() const noexcept
Checks if the stack allocator is full.
Linear allocator that clears every frame.
size_t Capacity() const noexcept
Gets the total capacity of the allocator.
void Reset() noexcept
Resets the allocator, freeing all allocations.
AllocatorStats Stats() const noexcept
Gets current allocator statistics.
bool Empty() const noexcept
Checks if the allocator is empty.
Free list allocator with best-fit strategy.
AllocatorStats Stats() const noexcept
Gets current allocator statistics.
size_t Capacity() const noexcept
Gets the total capacity of the allocator.
bool Empty() const noexcept
Checks if the allocator is empty (all memory free).
void Reset() noexcept
Resets the allocator, freeing all allocations.
Pool allocator for fixed-size allocations.
bool Full() const noexcept
Checks if the allocator is full.
void Reset() noexcept
Resets the pool, making all blocks available.
size_t BlockSize() const noexcept
Gets the block size.
size_t BlockCount() const noexcept
Gets the block count.
AllocatorStats Stats() const noexcept
Gets current allocator statistics.
Stack/linear allocator with LIFO deallocation support.
AllocatorStats Stats() const noexcept
Gets current allocator statistics.
void Reset() noexcept
Resets the allocator, freeing all allocations.
bool Empty() const noexcept
Checks if the allocator is empty.
size_t Capacity() const noexcept
Gets the total capacity of the allocator.
bool Full() const noexcept
Checks if the allocator is full.
constexpr size_t kDefaultAlignment
Default alignment for allocations (cache line size for most modern CPUs).
Statistics for tracking allocator usage.