Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
system_context.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <helios/core_pch.hpp>
4
24
25#include <array>
26#include <cstddef>
27#include <functional>
28#include <memory>
29#include <ranges>
30#include <string_view>
31#include <variant>
32
33namespace helios::app {
34
35/**
36 * @brief Per-system execution context with validated access.
37 * @details SystemContext wraps ecs::World to provide:
38 * - Validated access to components and resources based on AccessPolicy
39 * - Thread-safe query creation
40 * - Local command buffer access for deferred operations
41 * - Event emission capabilities
42 * - Async execution support (Executor or SubTaskGraph)
43 * - Frame allocator access for temporary allocations
44 *
45 * SystemContext is created once per system per update and holds only references.
46 * All access is validated against the system's declared AccessPolicy.
47 *
48 * Query and command buffer methods use the frame allocator by default for
49 * efficient temporary storage within systems.
50 *
51 * @note Pratially thread-safe.
52 */
54public:
55 /// Allocator type for component type IDs in queries
57
58 /// Allocator type for command pointers in command buffers
60
61 /**
62 * @brief Constructs a system context with Executor for main schedule systems.
63 * @param world Reference to the ECS world
64 * @param system_info Reference to system information
65 * @param executor Reference to async executor
66 * @param local_storage Reference to system local storage
67 */
70 : world_(world), system_info_(system_info), async_context_(std::ref(executor)), local_storage_(local_storage) {}
71
72 /**
73 * @brief Constructs a system context with SubTaskGraph for parallel schedule systems.
74 * @param world Reference to the ECS world
75 * @param system_info Reference to system information
76 * @param sub_graph Reference to async sub task graph
77 * @param local_storage Reference to system local storage
78 */
81 : world_(world), system_info_(system_info), async_context_(std::ref(sub_graph)), local_storage_(local_storage) {}
82
83 SystemContext(const SystemContext&) = delete;
86
89
90 /**
91 * @brief Creates a query builder for component queries (mutable access).
92 * @details Creates a QueryBuilder that can be used to construct queries.
93 * Runtime validation ensures queried components were declared in AccessPolicy.
94 * Allows both const and mutable component access.
95 * Uses the frame allocator for internal storage.
96 * @note Thread-safe.
97 * @return QueryBuilder for the world using frame allocator
98 *
99 * @example
100 * @code
101 * void MySystem(app::SystemContext& ctx) {
102 * auto query = ctx.Query().Get<Position&, const Velocity&>();
103 * query.ForEach([](Position& pos, const Velocity& vel) {
104 * pos.x += vel.dx;
105 * });
106 * }
107 * @endcode
108 */
109 [[nodiscard]] auto Query() noexcept -> ecs::QueryBuilder<QueryAllocator> {
110 return {world_, system_info_.access_policy, QueryAllocator(local_storage_.FrameAllocator())};
111 }
112
113 /**
114 * @brief Creates a read-only query builder for component queries.
115 * @details Creates a QueryBuilder with const World for read-only operations.
116 * Runtime validation ensures queried components were declared in AccessPolicy.
117 * Only allows const component access - mutable access will fail at compile time.
118 * Uses the frame allocator for internal storage.
119 * @note Thread-safe.
120 * @return ReadOnlyQueryBuilder for const world (read-only) using frame allocator
121 *
122 * @example
123 * @code
124 * void ReadOnlySystem(app::SystemContext& ctx) {
125 * auto query = ctx.ReadOnlyQuery().Get<const Position&>(); // OK - const component
126 * // auto query = ctx.ReadOnlyQuery().Get<Position&>(); // ERROR - mutable access from const World
127 * }
128 * @endcode
129 */
130 [[nodiscard]] auto ReadOnlyQuery() const noexcept -> ecs::ReadOnlyQueryBuilder<QueryAllocator> {
131 return {world_, system_info_.access_policy, QueryAllocator(local_storage_.FrameAllocator())};
132 }
133
134 /**
135 * @brief Creates a command buffer for deferred world operations.
136 * @details Command buffer allows queuing operations that will be executed during ecs::World::Update().
137 * This is the thread-safe way to modify the world.
138 * Uses the frame allocator for internal storage.
139 * @note Thread-safe, but keep in mind that world command buffer is not, avoid sharing between threads.
140 * @return WorldCmdBuffer for queuing commands using frame allocator
141 */
142 [[nodiscard]] auto Commands() noexcept -> ecs::WorldCmdBuffer<CommandAllocator> {
143 return ecs::WorldCmdBuffer<CommandAllocator>(local_storage_, CommandAllocator(local_storage_.FrameAllocator()));
144 }
145
146 /**
147 * @brief Creates an entity command buffer for a specific entity.
148 * @details Provides convenient interface for entity-specific operations.
149 * Uses the frame allocator for internal storage.
150 * @note Thread-safe, but keep in mind that entity command buffer is not, avoid sharing between threads.
151 * @param entity Entity to operate on
152 * @return EntityCmdBuffer for the entity using frame allocator
153 */
155 return {entity, local_storage_, CommandAllocator(local_storage_.FrameAllocator())};
156 }
157
158 /**
159 * @brief Reserves an entity ID for deferred creation.
160 * @details The actual entity creation is deferred until ecs::World::Update().
161 * @note Thread-safe.
162 * @return Reserved entity ID
163 */
165
166 /**
167 * @brief Gets mutable reference to a resource.
168 * @note Thread-safe.
169 * @warning Triggers assertion in next cases:
170 * - Resource not declared for write access.
171 * - Resource doesn't exist.
172 * @tparam T Resource type
173 * @return Mutable reference to resource
174 */
175 template <ecs::ResourceTrait T>
176 [[nodiscard]] T& WriteResource();
177
178 /**
179 * @brief Gets const reference to a resource.
180 * @note Thread-safe.
181 * @warning Triggers assertion in next cases:
182 * - Resource not declared for read access.
183 * - Resource doesn't exist.
184 * @tparam T Resource type
185 * @return Const reference to resource
186 */
187 template <ecs::ResourceTrait T>
188 [[nodiscard]] const T& ReadResource() const;
189
190 /**
191 * @brief Tries to get mutable pointer to a resource.
192 * @note Thread-safe.
193 * @warning Triggers assertion if resource not declared for write access.
194 * @tparam T Resource type
195 * @return Pointer to resource, or nullptr if not found
196 */
197 template <ecs::ResourceTrait T>
199
200 /**
201 * @brief Tries to get const pointer to a resource.
202 * @note Thread-safe.
203 * @warning Triggers assertion if resource not declared for read access.
204 * @tparam T Resource type
205 * @return Const pointer to resource, or nullptr if not found
206 */
207 template <ecs::ResourceTrait T>
208 [[nodiscard]] const T* TryReadResource() const;
209
210 /**
211 * @brief Emits an event to the local event queue.
212 * @details Events are stored in system-local storage and flushed after schedule execution.
213 * @note Not thread-safe, only one thread should emit events for a system at a time.
214 * @warning Triggers assertion if event type is not registered.
215 * @tparam T Event type
216 * @param event Event to emit
217 */
218 template <ecs::EventTrait T>
219 void EmitEvent(const T& event);
220
221 /**
222 * @brief Emits multiple events in bulk.
223 * @details More efficient than calling EmitEvent multiple times.
224 * @note Not thread-safe, only one thread should emit events for a system at a time.
225 * @warning Triggers assertion if event type is not registered.
226 * @tparam R Range of events
227 * @param events Range of events to emit
228 */
229 template <std::ranges::sized_range R>
231 void EmitEventBulk(const R& events);
232
233 /**
234 * @brief Gets an event reader for type T.
235 * @details Provides a type-safe, ergonomic API for reading events with
236 * support for iteration, filtering, and searching.
237 * Event must be registered via World::AddEvent<T>() first.
238 * @note Thread-safe.
239 * @warning Triggers assertion if event type is not registered.
240 * @tparam T Event type
241 * @return EventReader for type T
242 */
243 template <ecs::EventTrait T>
244 [[nodiscard]] auto ReadEvents() const noexcept -> ecs::EventReader<T>;
245
246 /**
247 * @brief Checks if entity exists in the world.
248 * @note Thread-safe.
249 * @warning Triggers assertion if entity is invalid.
250 * @param entity Entity to check.
251 * @return True if entity exists, false otherwise.
252 */
253 [[nodiscard]] bool EntityExists(ecs::Entity entity) const;
254
255 /**
256 * @brief Checks if entity has component.
257 * @note Thread-safe.
258 * @warning Triggers assertion in next cases:
259 * 1. Entity is invalid.
260 * 2. World does not own entity.
261 * @tparam T Component type.
262 * @param entity Entity to check.
263 * @return True if entity has component, false otherwise.
264 */
265 template <ecs::ComponentTrait T>
266 [[nodiscard]] bool HasComponent(ecs::Entity entity) const;
267
268 /**
269 * @brief Checks if entity has components.
270 * @note Thread-safe.
271 * @warning Triggers assertion if entity is invalid.
272 * @tparam Ts Components types.
273 * @param entity Entity to check.
274 * @return Array of bools indicating whether entity has each component (true if entity has component,
275 * false otherwise).
276 */
277 template <ecs::ComponentTrait... Ts>
278 requires utils::UniqueTypes<Ts...>
279 [[nodiscard]] auto HasComponents(ecs::Entity entity) const -> std::array<bool, sizeof...(Ts)>;
280
281 /**
282 * @brief Checks if a resource exists.
283 * @note Thread-safe.
284 * @tparam T Resource type
285 * @return True if resource exists, false otherwise
286 */
287 template <ecs::ResourceTrait T>
288 [[nodiscard]] bool HasResource() const {
289 return world_.HasResource<T>();
290 }
291
292 /**
293 * @brief Checks if SubTaskGraph is available in this context.
294 * @note Thread-safe.
295 * @return True if sub task graph is available, false otherwise
296 */
298 return std::holds_alternative<std::reference_wrapper<async::SubTaskGraph>>(async_context_);
299 }
300
301 /**
302 * @brief Checks if Executor is available in this context.
303 * @note Thread-safe.
304 * @return True if executor is available, false otherwise
305 */
307 return std::holds_alternative<std::reference_wrapper<async::Executor>>(async_context_);
308 }
309
310 /**
311 * @brief Gets the number of entities in the world.
312 * @note Thread-safe.
313 * @return Number of entities in the world.
314 */
315 [[nodiscard]] size_t EntityCount() const noexcept { return world_.EntityCount(); }
316
317 /**
318 * @brief Gets frame allocator statistics.
319 * @details Useful for debugging and profiling memory usage within systems.
320 * @note Thread-safe.
321 * @return Allocator statistics with current usage information
322 */
326
327 /**
328 * @brief Gets reference to the per-system frame allocator.
329 * @details Use this allocator for temporary per-frame allocations that don't need individual deallocation.
330 * The allocator is reset at frame boundaries.
331 *
332 * Ideal for:
333 * - Temporary containers used within a single system execution
334 * - Scratch buffers for algorithms
335 * - Short-lived data structures
336 *
337 * @note Thread-safe.
338 * @warning Data allocated with the frame allocator is only valid for the current frame.
339 * All pointers and references to frame-allocated data become invalid after the frame ends.
340 * Do not store frame-allocated data in components, resources, or any persistent storage.
341 * @return Reference to the growable frame allocator
342 */
346
347 /**
348 * @brief Gets const reference to the per-system frame allocator.
349 * @note Thread-safe.
350 * @warning Data allocated with the frame allocator is only valid for the current frame.
351 * @return Const reference to the growable frame allocator
352 */
356
357 /**
358 * @brief Creates an STL allocator adapter for the frame allocator.
359 * @details Convenience method to create an STL-compatible allocator that uses the per-system frame allocator.
360 * Use this with STL containers for zero-overhead temporary allocations.
361 *
362 * The frame allocator is reset at frame boundaries, making it ideal for temporary per-frame data.
363 * Common use cases:
364 * - Temporary containers for query results (via CollectWith())
365 * - Temporary containers for event data (via CollectWith())
366 * - Scratch buffers for algorithms
367 * - Short-lived data structures that don't outlive the current frame
368 *
369 * @note Thread-safe.
370 * @warning Data allocated with the frame allocator is only valid for the current frame.
371 * All pointers and references to frame-allocated data become invalid after the frame ends.
372 * Do not store frame-allocated data in components, resources, or any persistent storage.
373 * @tparam T Type to allocate
374 * @return STL allocator adapter for type T
375 *
376 * @example
377 * @code
378 * void MySystem::Update(app::SystemContext& ctx) {
379 * // Temporary container with frame allocator
380 * auto alloc = ctx.MakeFrameAllocator<int>();
381 * std::vector<int, decltype(alloc)> temp{alloc};
382 * temp.push_back(42);
383 * // Memory automatically reclaimed at frame end
384 *
385 * // Use with query results
386 * auto query = ctx.Query().Get<Position&, Velocity&>();
387 * auto query_alloc = ctx.MakeFrameAllocator<decltype(query)::value_type>();
388 * auto results = query.CollectWith(query_alloc);
389 * // results valid only during this frame
390 * }
391 * @endcode
392 */
393 template <typename T>
394 [[nodiscard]] auto MakeFrameAllocator() noexcept -> memory::STLGrowableAllocator<T, memory::FrameAllocator> {
396 }
397
398 /**
399 * @brief Gets reference to the sub task graph for parallel work.
400 * @note Thread-safe.
401 * @warning Triggers assertion if sub task graph is not available.
402 * @return Reference to the async sub task graph
403 */
405
406 /**
407 * @brief Gets reference to the executor for async work.
408 * @note Thread-safe.
409 * @warning Triggers assertion if executor is not available.
410 * @return Reference to the executor
411 */
412 [[nodiscard]] async::Executor& Executor() noexcept;
413
414 /**
415 * @brief Gets the system information.
416 * @note Thread-safe.
417 * @return Const reference to system info
418 */
419 [[nodiscard]] const details::SystemInfo& GetSystemInfo() const noexcept { return system_info_; }
420
421 /**
422 * @brief Gets the system name.
423 * @note Thread-safe.
424 * @return System name
425 */
426 [[nodiscard]] std::string_view GetSystemName() const noexcept { return system_info_.name; }
427
428private:
429 /**
430 * @brief Validates that a resource was declared for reading.
431 * @tparam T Resource type
432 */
433 template <ecs::ResourceTrait T>
434 void ValidateReadResource() const;
435
436 /**
437 * @brief Validates that a resource was declared for writing.
438 * @tparam T Resource type
439 */
440 template <ecs::ResourceTrait T>
441 void ValidateWriteResource() const;
442
443 ecs::World& world_; ///< Reference to the ECS world
444 const details::SystemInfo& system_info_; ///< Reference to system information
445 std::variant<std::reference_wrapper<async::Executor>, std::reference_wrapper<async::SubTaskGraph>>
446 async_context_; ///< Async execution context (never null)
447 ecs::details::SystemLocalStorage& local_storage_; ///< Reference to system local storage
448};
449
450template <ecs::ResourceTrait T>
453 return world_.WriteResource<T>();
454}
455
456template <ecs::ResourceTrait T>
457inline const T& SystemContext::ReadResource() const {
459 return world_.ReadResource<T>();
460}
461
462template <ecs::ResourceTrait T>
465 return world_.TryWriteResource<T>();
466}
467
468template <ecs::ResourceTrait T>
469inline const T* SystemContext::TryReadResource() const {
471 return world_.TryReadResource<T>();
472}
473
474template <ecs::EventTrait T>
475inline void SystemContext::EmitEvent(const T& event) {
476 HELIOS_ASSERT(world_.HasEvent<T>(),
477 "Failed to emit event of type '{}': Event type not registered in world! "
478 "Add World::AddEvent<{}>() during initialization.",
480 local_storage_.WriteEvent(event);
481}
482
483template <std::ranges::sized_range R>
485inline void SystemContext::EmitEventBulk(const R& events) {
486 using EventType = std::ranges::range_value_t<R>;
488 "Failed to emit events of type '{}': Event type not registered in world! "
489 "Add World::AddEvent<{}>() during initialization.",
491 local_storage_.WriteEventBulk(events);
492}
493
494template <ecs::EventTrait T>
495inline auto SystemContext::ReadEvents() const noexcept -> ecs::EventReader<T> {
496 HELIOS_ASSERT(world_.HasEvent<T>(),
497 "Failed to get event reader for type '{}': Event type not registered in world! "
498 "Add World::AddEvent<{}>() during initialization.",
500 return world_.ReadEvents<T>();
501}
502
503inline bool SystemContext::EntityExists(ecs::Entity entity) const {
504 HELIOS_ASSERT(entity.Valid(), "Failed to check if entity exists: Entity is invalid!");
505 return world_.Exists(entity);
506}
507
508template <ecs::ComponentTrait T>
509inline bool SystemContext::HasComponent(ecs::Entity entity) const {
510 HELIOS_ASSERT(entity.Valid(), "Failed to check if entity has component: Entity is invalid!");
512 "Failed to check if entity has component: World does not own entity with index '{}'!", entity.Index());
513 return world_.HasComponent<T>(entity);
514}
515
516template <ecs::ComponentTrait... Ts>
517 requires utils::UniqueTypes<Ts...>
518inline auto SystemContext::HasComponents(ecs::Entity entity) const -> std::array<bool, sizeof...(Ts)> {
519 HELIOS_ASSERT(entity.Valid(), "Failed to check if entity has components: Entity is invalid!");
520 HELIOS_ASSERT(EntityExists(entity),
521 "Failed to check if entity has components: World does not own entity with index '{}'!", entity.Index());
522 return world_.HasComponents<Ts...>(entity);
523}
524
527 "Failed to get sub task graph: SubTaskGraph not available in this context! "
528 "System '{}' is likely running on main schedule.",
529 system_info_.name);
530 return std::get<std::reference_wrapper<async::SubTaskGraph>>(async_context_).get();
531}
532
535 "Failed to get executor: Executor not available in this context! "
536 "System '{}' is likely running on a parallel schedule.",
537 system_info_.name);
538 return std::get<std::reference_wrapper<async::Executor>>(async_context_).get();
539}
540
541template <ecs::ResourceTrait T>
542inline void SystemContext::ValidateReadResource() const {
543#ifdef HELIOS_ENABLE_ASSERTS
544 if constexpr (ecs::IsResourceThreadSafe<T>()) {
545 return;
546 } else {
548 const bool can_read =
549 system_info_.access_policy.HasReadResource(type_id) || system_info_.access_policy.HasWriteResource(type_id);
551 "System '{}' attempted to read resource '{}' without declaring it in AccessPolicy! "
552 "Add .ReadResources<{}>() or .WriteResources<{}>() to {}::GetAccessPolicy().",
554 system_info_.name);
555 }
556#endif
557}
558
559template <ecs::ResourceTrait T>
560inline void SystemContext::ValidateWriteResource() const {
561#ifdef HELIOS_ENABLE_ASSERTS
562 if constexpr (ecs::IsResourceThreadSafe<T>()) {
563 return;
564 } else {
566 const bool can_write = system_info_.access_policy.HasWriteResource(type_id);
568 "System '{}' attempted to write resource '{}' without declaring it in AccessPolicy! "
569 "Add .WriteResources<{}>() to {}::GetAccessPolicy().",
570 system_info_.name, ecs::ResourceNameOf<T>(), ecs::ResourceNameOf<T>(), system_info_.name);
571 }
572#endif
573}
574
575} // namespace helios::app
#define HELIOS_ASSERT(condition,...)
Assertion macro that aborts execution in debug builds.
Definition assert.hpp:140
constexpr bool HasWriteResource(ecs::ResourceTypeId type_id) const noexcept
Checks if this policy has the specified resource type for writing.
constexpr bool HasReadResource(ecs::ResourceTypeId type_id) const noexcept
Checks if this policy has the specified resource type for reading.
Per-system execution context with validated access.
T & WriteResource()
Gets mutable reference to a resource.
void EmitEvent(const T &event)
Emits an event to the local event queue.
auto ReadOnlyQuery() const noexcept -> ecs::ReadOnlyQueryBuilder< QueryAllocator >
const T & ReadResource() const
Gets const reference to a resource.
void EmitEventBulk(const R &events)
Emits multiple events in bulk.
async::SubTaskGraph & SubTaskGraph() noexcept
Gets reference to the sub task graph for parallel work.
bool EntityExists(ecs::Entity entity) const
Checks if entity exists in the world.
auto MakeFrameAllocator() noexcept -> memory::STLGrowableAllocator< T, memory::FrameAllocator >
auto Commands() noexcept -> ecs::WorldCmdBuffer< CommandAllocator >
Creates a command buffer for deferred world operations.
const T * TryReadResource() const
Tries to get const pointer to a resource.
auto HasComponents(ecs::Entity entity) const -> std::array< bool, sizeof...(Ts)>
Checks if entity has components.
auto Query() noexcept -> ecs::QueryBuilder< QueryAllocator >
~SystemContext() noexcept=default
SystemContext(SystemContext &&)=delete
std::string_view GetSystemName() const noexcept
Gets the system name.
bool HasComponent(ecs::Entity entity) const
Checks if entity has component.
bool HasExecutor() const noexcept
Checks if Executor is available in this context.
const ecs::details::SystemLocalStorage::FrameAllocatorType & FrameAllocator() const noexcept
Gets const reference to the per-system frame allocator.
auto ReadEvents() const noexcept -> ecs::EventReader< T >
Gets an event reader for type T.
memory::STLGrowableAllocator< std::unique_ptr< ecs::Command >, memory::FrameAllocator > CommandAllocator
Allocator type for command pointers in command buffers.
async::Executor & Executor() noexcept
Gets reference to the executor for async work.
ecs::details::SystemLocalStorage::FrameAllocatorType & FrameAllocator() noexcept
Gets reference to the per-system frame allocator.
auto EntityCommands(ecs::Entity entity) -> ecs::EntityCmdBuffer< CommandAllocator >
Creates an entity command buffer for a specific entity.
SystemContext(ecs::World &world, const details::SystemInfo &system_info, async::Executor &executor, ecs::details::SystemLocalStorage &local_storage) noexcept
Constructs a system context with Executor for main schedule systems.
SystemContext(const SystemContext &)=delete
size_t EntityCount() const noexcept
Gets the number of entities in the world.
bool HasResource() const
Checks if a resource exists.
ecs::Entity ReserveEntity()
Reserves an entity ID for deferred creation.
const details::SystemInfo & GetSystemInfo() const noexcept
Gets the system information.
SystemContext(ecs::World &world, const details::SystemInfo &system_info, async::SubTaskGraph &sub_graph, ecs::details::SystemLocalStorage &local_storage) noexcept
Constructs a system context with SubTaskGraph for parallel schedule systems.
memory::AllocatorStats FrameAllocatorStats() const noexcept
Gets frame allocator statistics.
T * TryWriteResource()
Tries to get mutable pointer to a resource.
memory::STLGrowableAllocator< ecs::ComponentTypeId, memory::FrameAllocator > QueryAllocator
Allocator type for component type IDs in queries.
bool HasSubTaskGraph() const noexcept
Checks if SubTaskGraph is available in this context.
Manages worker threads and executes task graphs using work-stealing scheduling.
Definition executor.hpp:33
Dynamic task graph that can be created within the execution of a task.
Unique identifier for entities with generation counter to handle recycling.
Definition entity.hpp:21
constexpr bool Valid() const noexcept
Checks if the entity is valid.
Definition entity.hpp:58
constexpr IndexType Index() const noexcept
Gets the index component of the entity.
Definition entity.hpp:75
The World class manages entities with their components and systems.
Definition world.hpp:53
bool HasEvent() const
Checks if a event registered.
Definition world.hpp:545
const T & ReadResource() const
Gets const reference to a resource.
Definition world.hpp:939
bool HasResource() const
Checks if a resource exists.
Definition world.hpp:534
Entity ReserveEntity()
Reserves an entity ID for deferred creation.
Definition world.hpp:121
T & WriteResource()
Gets reference to a resource.
Definition world.hpp:933
auto ReadEvents() const noexcept -> EventReader< T >
Gets an event reader for type T.
Definition world.hpp:985
bool Exists(Entity entity) const
Checks if entity exists in the world.
Definition world.hpp:944
T * TryWriteResource()
Tries to get mutable pointer to a resource.
Definition world.hpp:417
bool HasComponent(Entity entity) const
Checks if entity has component.
Definition world.hpp:950
const T * TryReadResource() const
Tries to get const pointer to a resource.
Definition world.hpp:428
size_t EntityCount() const noexcept
Gets the number of entities in the world.
Definition world.hpp:565
Local storage for system-specific data (commands, events, and temporary allocations).
void WriteEvent(const T &event)
Writes an event to the local event queue.
void WriteEventBulk(const R &events)
Writes multiple events to the local event queue in bulk.
memory::AllocatorStats FrameAllocatorStats() const noexcept
Gets frame allocator statistics.
FrameAllocatorType & FrameAllocator() noexcept
Gets reference to the frame allocator.
Linear allocator that clears every frame.
STL-compatible allocator adapter for custom allocators.
Concept to check if a type can be used as a component.
Definition component.hpp:39
Concept for valid event types.
Definition event.hpp:44
size_t ResourceTypeId
Type ID for resources.
Definition resource.hpp:53
BasicQuery< World, Allocator, Components... > Query
Type alias for query with mutable world access.
Definition query.hpp:2481
STL namespace.
Metadata about a system.
app::AccessPolicy access_policy
Access policy for validation.
std::string name
System name (for debugging/profiling)
Statistics for tracking allocator usage.