concinnity_core/ecs/system_entry.rs
1//! The system table a host hands [`World::start`](crate::ecs::World::start):
2//! one entry per system in run order, plus the load-time passes that bracket
3//! them.
4//!
5//! The table is a document. Table order is run order, and the `after` / `before`
6//! edges are checked against it rather than resolved into one, so a reader can
7//! take the file top to bottom as the tick. What builds the systems is a gate
8//! per entry: it inspects the world's content and returns the constructed
9//! system, or `None` to leave it out.
10
11use alloc::boxed::Box;
12
13use crate::ecs::{Access, EventStore, PipelineContext, System, World};
14
15/// One row of the system table. Table order is run order.
16pub struct SystemEntry {
17 /// The entry name; the system's stable display name.
18 pub name: &'static str,
19 /// Human-readable gate condition, for docs and CLI reporting.
20 pub present_when: &'static str,
21 /// Constructs the system from world content when its gate holds. Runs from
22 /// `World::start` and from `World::system_manifest`, which discards the
23 /// value, so a system's constructor must stay cheap and side-effect-free.
24 pub gate: fn(&World) -> Option<Box<dyn System>>,
25 /// Systems (by entry name) that must run earlier in the tick than this one.
26 /// Validated against table order at schedule build: the table stays the one
27 /// execution order, and an edge that contradicts it is a startup panic, not
28 /// a silent reorder.
29 pub after: &'static [&'static str],
30 /// Systems this one must run before.
31 pub before: &'static [&'static str],
32}
33
34/// A host's system table and the load-time passes only the host can supply.
35///
36/// The entries name the host's own system types, so the table is written where
37/// those types live; everything that runs it is here.
38pub struct SystemTable {
39 /// One entry per system, in run order.
40 pub entries: &'static [SystemEntry],
41 /// Runs over the world once its systems are built and before their `init`.
42 /// Absent leaves the loaded content exactly as it was added.
43 pub before_init: Option<fn(&mut PipelineContext)>,
44 /// Pre-creates the event queues a scheduled system's declared access can
45 /// touch, so its `events_mut` never grows the store's map mid-tick. Absent
46 /// leaves every queue to be created on first use.
47 pub prepare_events: Option<fn(&mut EventStore, Access)>,
48}
49
50impl SystemTable {
51 /// A table with no systems and no load-time passes: what a world runs when
52 /// its host contributes none.
53 pub const EMPTY: Self = Self {
54 entries: &[],
55 before_init: None,
56 prepare_events: None,
57 };
58}