Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
helios::memory::NFrameAllocator< N > Class Template Referencefinal

N-buffered frame allocator. More...

#include <n_frame_allocator.hpp>

Public Member Functions

 NFrameAllocator (size_t capacity_per_buffer)
 Constructs an N-frame allocator with specified capacity per buffer.
 
 NFrameAllocator (const NFrameAllocator &)=delete
 
 NFrameAllocator (NFrameAllocator &&other) noexcept
 
 ~NFrameAllocator () noexcept=default
 
NFrameAllocatoroperator= (const NFrameAllocator &)=delete
 
NFrameAllocatoroperator= (NFrameAllocator &&other) noexcept
 
AllocationResult Allocate (size_t size, size_t alignment=kDefaultAlignment) noexcept
 Allocates memory from the current frame buffer.
 
template<typename T >
requires (N > 0)
T * Allocate () noexcept
 Allocates memory for a single object of type T.
 
template<typename T >
requires (N > 0)
T * Allocate (size_t count) noexcept
 Allocates memory for an array of objects of type T.
 
template<typename T , typename... Args>
requires std::constructible_from<T, Args...>
T * AllocateAndConstruct (Args &&... args) noexcept(std::is_nothrow_constructible_v< T, Args... >)
 Allocates and constructs a single object of type T.
 
template<typename T >
requires std::default_initializable<T>
T * AllocateAndConstructArray (size_t count) noexcept(std::is_nothrow_default_constructible_v< T >)
 Allocates and default-constructs an array of objects of type T.
 
void NextFrame () noexcept
 Advances to the next frame, cycling through buffers.
 
void Reset () noexcept
 Resets all buffers.
 
AllocatorStats Stats () const noexcept
 Gets combined statistics for all buffers.
 
AllocatorStats CurrentFrameStats () const noexcept
 Gets statistics for the current frame buffer.
 
AllocatorStats BufferStats (size_t buffer_index) const noexcept
 Gets statistics for a specific buffer.
 
size_t Capacity () const noexcept
 Gets the total capacity across all buffers.
 
size_t CurrentBufferIndex () const noexcept
 Gets the current frame buffer index.
 
size_t FreeSpace () const noexcept
 Gets free space in current buffer.
 

Static Public Member Functions

static constexpr size_t BufferCount () noexcept
 Gets the number of buffers.
 

Static Public Attributes

static constexpr size_t kBufferCount = N
 

Detailed Description

template<size_t N>
requires (N > 0)
class helios::memory::NFrameAllocator< N >

N-buffered frame allocator.

Maintains N frame buffers, allowing memory from the previous N-1 frames to remain valid. Useful for pipelined operations (e.g., CPU-GPU synchronization with multiple frames in flight).

The allocator cycles through N buffers, ensuring that data from the previous N-1 frames remains accessible while allocating for the current frame.

Note
Thread-safe. Previous N-1 frames' data remains valid until the buffer cycles back.
Template Parameters
NNumber of frame buffers (must be > 0)

Definition at line 35 of file n_frame_allocator.hpp.

Constructor & Destructor Documentation

◆ NFrameAllocator() [1/3]

template<size_t N>
helios::memory::NFrameAllocator< N >::NFrameAllocator ( size_t  capacity_per_buffer)
inlineexplicit

Constructs an N-frame allocator with specified capacity per buffer.

Warning
Triggers assertion if capacity_per_buffer is 0.
Parameters
capacity_per_bufferSize of each buffer in bytes

Definition at line 44 of file n_frame_allocator.hpp.

44: allocators_(CreateAllocators(capacity_per_buffer)) {}

◆ NFrameAllocator() [2/3]

template<size_t N>
helios::memory::NFrameAllocator< N >::NFrameAllocator ( const NFrameAllocator< N > &  )
delete

◆ NFrameAllocator() [3/3]

template<size_t N>
requires (N > 0)
helios::memory::NFrameAllocator< N >::NFrameAllocator ( NFrameAllocator< N > &&  other)
inlinenoexcept

Definition at line 183 of file n_frame_allocator.hpp.

184 : allocators_(std::move(other.allocators_)),
185 current_buffer_(other.current_buffer_.load(std::memory_order_acquire)) {
186 other.current_buffer_.store(0, std::memory_order_release);
187}

◆ ~NFrameAllocator()

template<size_t N>
helios::memory::NFrameAllocator< N >::~NFrameAllocator ( )
defaultnoexcept

Member Function Documentation

◆ Allocate() [1/3]

template<size_t N>
requires (N > 0)
template<typename T >
requires (N > 0)
T * helios::memory::NFrameAllocator< N >::Allocate ( )
inlinenoexcept

Allocates memory for a single object of type T.

Convenience function that calculates size and alignment from the type. The returned memory is uninitialized - use placement new to construct the object.

Template Parameters
TType to allocate memory for
Returns
Pointer to allocated memory, or nullptr on failure

Definition at line 206 of file n_frame_allocator.hpp.

206 {
207 constexpr size_t size = sizeof(T);
208 constexpr size_t alignment = std::max(alignof(T), kMinAlignment);
209 auto result = Allocate(size, alignment);
210 return static_cast<T*>(result.ptr);
211}
T * Allocate() noexcept
Allocates memory for a single object of type T.
constexpr size_t kMinAlignment
Minimum alignment for any allocation.

◆ Allocate() [2/3]

template<size_t N>
requires (N > 0)
template<typename T >
requires (N > 0)
T * helios::memory::NFrameAllocator< N >::Allocate ( size_t  count)
inlinenoexcept

Allocates memory for an array of objects of type T.

Convenience function that calculates size and alignment from the type. The returned memory is uninitialized - use placement new to construct objects.

Template Parameters
TType to allocate memory for
Parameters
countNumber of objects to allocate space for
Returns
Pointer to allocated memory, or nullptr on failure

Definition at line 216 of file n_frame_allocator.hpp.

216 {
217 if (count == 0) [[unlikely]] {
218 return nullptr;
219 }
220 constexpr size_t alignment = std::max(alignof(T), kMinAlignment);
221 const size_t size = sizeof(T) * count;
222 auto result = Allocate(size, alignment);
223 return static_cast<T*>(result.ptr);
224}

◆ Allocate() [3/3]

template<size_t N>
AllocationResult helios::memory::NFrameAllocator< N >::Allocate ( size_t  size,
size_t  alignment = kDefaultAlignment 
)
inlinenoexcept

Allocates memory from the current frame buffer.

Warning
Triggers assertion in next cases:
  • Alignment is not a power of 2.
  • Alignment is less than kMinAlignment.
Parameters
sizeNumber of bytes to allocate
alignmentAlignment requirement (must be power of 2)
Returns
AllocationResult with pointer and actual allocated size, or {nullptr, 0} on failure

Definition at line 61 of file n_frame_allocator.hpp.

61 {
62 return allocators_[current_buffer_.load(std::memory_order_acquire)].Allocate(size, alignment);
63 }

◆ AllocateAndConstruct()

template<size_t N>
requires std::constructible_from<T, Args...>
template<typename T , typename... Args>
requires std::constructible_from<T, Args...>
T * helios::memory::NFrameAllocator< N >::AllocateAndConstruct ( Args &&...  args)
inlinenoexcept

Allocates and constructs a single object of type T.

Convenience function that allocates memory and constructs the object in-place.

Template Parameters
TType to allocate and construct
ArgsConstructor argument types
Parameters
argsArguments to forward to T's constructor
Returns
Pointer to constructed object, or nullptr on allocation failure

Definition at line 230 of file n_frame_allocator.hpp.

231 {
232 T* ptr = Allocate<T>();
233 if (ptr != nullptr) [[likely]] {
234 std::construct_at(ptr, std::forward<Args>(args)...);
235 }
236 return ptr;
237}

◆ AllocateAndConstructArray()

template<size_t N>
requires std::default_initializable<T>
template<typename T >
requires std::default_initializable<T>
T * helios::memory::NFrameAllocator< N >::AllocateAndConstructArray ( size_t  count)
inlinenoexcept

Allocates and default-constructs an array of objects of type T.

Convenience function that allocates memory and default-constructs objects in-place.

Template Parameters
TType to allocate and construct (must be default constructible)
Parameters
countNumber of objects to allocate and construct
Returns
Pointer to first constructed object, or nullptr on allocation failure

Definition at line 243 of file n_frame_allocator.hpp.

244 {
245 T* ptr = Allocate<T>(count);
246 if (ptr != nullptr) [[likely]] {
247 for (size_t i = 0; i < count; ++i) {
248 std::construct_at(ptr + i);
249 }
250 }
251 return ptr;
252}

◆ BufferCount()

template<size_t N>
static constexpr size_t helios::memory::NFrameAllocator< N >::BufferCount ( )
inlinestaticconstexprnoexcept

Gets the number of buffers.

Returns
Number of buffers (N)

Definition at line 169 of file n_frame_allocator.hpp.

169{ return N; }

◆ BufferStats()

template<size_t N>
requires (N > 0)
AllocatorStats helios::memory::NFrameAllocator< N >::BufferStats ( size_t  buffer_index) const
inlinenoexcept

Gets statistics for a specific buffer.

Warning
Triggers assertion if buffer_index is out of range [0, N).
Parameters
buffer_indexBuffer index (0 to N-1)
Returns
AllocatorStats for specified buffer

Definition at line 296 of file n_frame_allocator.hpp.

296 {
297 HELIOS_ASSERT(buffer_index < N, "Failed to get buffer stats: buffer_index '{}' is out of range [0, {}]!",
298 buffer_index, N);
299 return allocators_[buffer_index].Stats();
300}
#define HELIOS_ASSERT(condition,...)
Assertion macro that aborts execution in debug builds.
Definition assert.hpp:140

◆ Capacity()

template<size_t N>
requires (N > 0)
size_t helios::memory::NFrameAllocator< N >::Capacity ( ) const
inlinenoexcept

Gets the total capacity across all buffers.

Returns
Total capacity in bytes

Definition at line 304 of file n_frame_allocator.hpp.

304 {
305 size_t total = 0;
306 for (const auto& allocator : allocators_) {
307 total += allocator.Capacity();
308 }
309 return total;
310}

◆ CurrentBufferIndex()

template<size_t N>
size_t helios::memory::NFrameAllocator< N >::CurrentBufferIndex ( ) const
inlinenoexcept

Gets the current frame buffer index.

Returns
Current buffer index (0 to N-1)

Definition at line 155 of file n_frame_allocator.hpp.

155{ return current_buffer_.load(std::memory_order_relaxed); }

◆ CurrentFrameStats()

template<size_t N>
AllocatorStats helios::memory::NFrameAllocator< N >::CurrentFrameStats ( ) const
inlinenoexcept

Gets statistics for the current frame buffer.

Returns
AllocatorStats for current buffer

Definition at line 133 of file n_frame_allocator.hpp.

133 {
134 return allocators_[current_buffer_.load(std::memory_order_acquire)].Stats();
135 }

◆ FreeSpace()

template<size_t N>
size_t helios::memory::NFrameAllocator< N >::FreeSpace ( ) const
inlinenoexcept

Gets free space in current buffer.

Returns
Free space in bytes

Definition at line 161 of file n_frame_allocator.hpp.

161 {
162 return allocators_[current_buffer_.load(std::memory_order_acquire)].FreeSpace();
163 }

◆ NextFrame()

template<size_t N>
requires (N > 0)
void helios::memory::NFrameAllocator< N >::NextFrame ( )
inlinenoexcept

Advances to the next frame, cycling through buffers.

Resets the new current buffer and makes previous buffers accessible.

Warning
Not thread-safe with Allocate(). Must be called from a single thread while no other threads are allocating. Typically called once per frame by the main thread.

Definition at line 256 of file n_frame_allocator.hpp.

256 {
257 // Advance to next buffer (wrapping around)
258 const size_t buffer = (current_buffer_.load(std::memory_order_relaxed) + 1) % N;
259
260 // Reset the new current buffer before switching
261 allocators_[buffer].Reset();
262
263 // Switch to new buffer
264 current_buffer_.store(buffer, std::memory_order_release);
265}

◆ operator=() [1/2]

template<size_t N>
NFrameAllocator & helios::memory::NFrameAllocator< N >::operator= ( const NFrameAllocator< N > &  )
delete

◆ operator=() [2/2]

template<size_t N>
requires (N > 0)
auto helios::memory::NFrameAllocator< N >::operator= ( NFrameAllocator< N > &&  other)
inlinenoexcept

Definition at line 191 of file n_frame_allocator.hpp.

191 {
192 if (this == &other) [[unlikely]] {
193 return *this;
194 }
195
196 allocators_ = std::move(other.allocators_);
197 current_buffer_.store(other.current_buffer_.load(std::memory_order_acquire), std::memory_order_release);
198 other.current_buffer_.store(0, std::memory_order_release);
199
200 return *this;
201}

◆ Reset()

template<size_t N>
requires (N > 0)
void helios::memory::NFrameAllocator< N >::Reset ( )
inlinenoexcept

Resets all buffers.

Clears all allocations from all buffers.

Definition at line 269 of file n_frame_allocator.hpp.

269 {
270 for (auto& allocator : allocators_) {
271 allocator.Reset();
272 }
273}

◆ Stats()

template<size_t N>
requires (N > 0)
AllocatorStats helios::memory::NFrameAllocator< N >::Stats ( ) const
inlinenoexcept

Gets combined statistics for all buffers.

Returns
AllocatorStats with combined usage information

Definition at line 277 of file n_frame_allocator.hpp.

277 {
278 AllocatorStats combined{};
279
280 for (const auto& allocator : allocators_) {
281 const auto stats = allocator.Stats();
282 combined.total_allocated += stats.total_allocated;
283 combined.total_freed += stats.total_freed;
284 combined.peak_usage = std::max(combined.peak_usage, stats.peak_usage);
285 combined.allocation_count += stats.allocation_count;
286 combined.total_allocations += stats.total_allocations;
287 combined.total_deallocations += stats.total_deallocations;
288 combined.alignment_waste += stats.alignment_waste;
289 }
290
291 return combined;
292}

Member Data Documentation

◆ kBufferCount

template<size_t N>
constexpr size_t helios::memory::NFrameAllocator< N >::kBufferCount = N
staticconstexpr

Definition at line 37 of file n_frame_allocator.hpp.