concinnity_core/ecs/mod.rs
1//! The renderer-free half of the engine's ECS: the storage mechanism, the
2//! per-tick context systems see, and the asset identity + registry layer the
3//! build / validate pipeline and the client runtime share.
4//!
5//! The storage mechanism is closed-world and carries no engine domain type. It
6//! provides the generic primitives only: entities ([`Entity`], [`Entities`]),
7//! typed storage columns ([`Column`]), change ticks ([`Tick`]), component masks
8//! ([`ComponentMask`]) and a join index ([`JoinIndex`]), resources
9//! ([`Resources`]), events ([`Events`]), and the per-system access sets
10//! ([`Access`]) the scheduler uses to run two systems concurrently. Nothing in
11//! that half knows about meshes, blobs, or rendering, and none of it stores a
12//! type the project did not register at compile time: there is no TypeId-keyed
13//! type erasure and no open-world insert of arbitrary external types.
14//!
15//! The concrete component set is registered in `registry` and expanded by
16//! [`define_components!`](crate::define_components), which pairs the asset-enum
17//! dispatch with the storage half from
18//! [`define_component_storage!`](crate::define_component_storage).
19//!
20//! On top of that sit the pieces the engine reaches for: the [`Component`]
21//! metadata trait, the plain data types the registry and blob format are built
22//! from ([`AssetOrigin`], [`AssetPayload`], [`PayloadLocator`],
23//! [`BlobAssetDef`], [`AssetKind`]), the [`System`] behavior trait, and the
24//! [`World`]: the components, resources, events, payloads, profile, and frame
25//! scratch a tick reads and writes, plus the systems that run over them and
26//! their schedule. The system table itself ([`SystemTable`]) names a host's own
27//! system types, so it is written in the client crate, whose `ecs` module
28//! re-exports everything here under the historical `crate::ecs::*` paths
29//! alongside the `ComponentAsset` value enum.
30//!
31//! The interner that assigns asset identities keeps a per-thread table and
32//! lives in concinnity-host. The authoring `Registration` record lives in
33//! concinnity-cook, constructed from the trait's metadata consts.
34
35pub mod access_check;
36pub mod asset_id;
37pub mod asset_ref;
38pub mod handle;
39pub mod locator;
40pub mod resolver;
41
42mod access;
43mod built_system;
44mod clock;
45mod column;
46mod component;
47mod context;
48mod define_components;
49mod entity;
50mod entity_by_name;
51mod event;
52mod event_store;
53mod frame;
54mod headless;
55mod join;
56mod mask;
57mod payload_store;
58mod protocol;
59mod registry;
60mod resource;
61mod storage;
62mod system;
63mod system_entry;
64mod tick;
65mod waves;
66mod world;
67
68#[cfg(test)]
69mod join_bench;
70#[cfg(test)]
71mod storage_bench;
72#[cfg(test)]
73mod world_run_tests;
74
75// The storage primitives. `Column`, `Entities`, `JoinIndex` and `AtomicTick`
76// are named by the expansion of `define_component_storage!`, so they are public
77// here for every crate that expands it.
78pub use access::Access;
79pub use column::{Column, ColumnTicks};
80pub use entity::{Entities, Entity};
81pub use event::{EventCursor, Events};
82pub use event_store::EventStore;
83pub use join::JoinIndex;
84pub use mask::{ComponentId, ComponentMask};
85pub use resource::Resources;
86pub use tick::{AtomicTick, MAX_CHANGE_AGE, Tick};
87
88// The runtime-facing component contract and the metadata enums the registry and
89// the blob format are built from.
90pub use component::{AssetOrigin, AssetPayload, Component, ResourceAsset, RuntimeComponent};
91
92// Systems' view of the world during a tick.
93pub use context::PipelineContext;
94
95// Per-frame facilities carried on `PipelineContext`. Re-exported by the client
96// `ecs` module under the historical `crate::ecs::*` paths, like the rest.
97// `Arena` comes with it so a crate that only builds a context (the physics and
98// audio subsystems, and every test world) can name the scratch type without
99// taking its own dependency on the allocation layer.
100pub use crate::memory::Arena;
101pub use frame::{FrameContext, FrameVec};
102
103// Renderer-free resources the runtime systems publish and read to coordinate a
104// tick (menu state, frame-rate cap, HUD prefs, cursor + dropdown views), plus
105// the world's cook-counted physics reservation. They name no renderer type, so
106// they live here where the physics / audio subsystem crates can reach them; the
107// client `ecs` module re-exports them under the historical `crate::ecs::*`
108// paths.
109pub use protocol::{
110 CursorShape, CursorState, DesiredCursor, DropdownView, ExecutionTrace, FlyCam, FrameRateCap,
111 GpuMemoryPressure, HiddenAssets, HudLayers, HudPrefs, MenuActive, MenuOverride, OpenDropdown,
112 OverlayImage, OverlayImages, PickEntry, PickIndex, ScheduleMode, ScreenStack, SimTiming,
113 TraceEvent, TracePath, TracePaths, TraceRequest, TraceStep, TraceVal, TransientSaves,
114 ViewOverrides, WorldLines, WorldPhysicsBudget,
115};
116
117// The runtime behavior trait every engine system implements + its per-step
118// control signal. Renderer-free (they name only `PipelineContext`), so they live
119// here for the physics / audio subsystem crates; the client `ecs` module
120// re-exports them under the historical `crate::ecs::*` paths and its
121// `define_systems!` table names the gate that builds each one.
122pub use system::{StepResult, System};
123
124// The name -> Entity index the load-time Prop decomposition pass publishes.
125// Renderer-free, so the physics / audio subsystem crates can resolve a name
126// reference to an Entity through it; the client `ecs::decompose` module
127// re-exports it under the historical `crate::ecs::decompose::EntityByName` path.
128pub use entity_by_name::EntityByName;
129
130// The payload-access seam systems reach through: keeps the storage mechanism
131// free of blob file I/O (`concinnity_host::store`'s `BlobData` is the runtime
132// implementor).
133pub use payload_store::{NoPayloads, PayloadStore};
134
135// A world, the systems built over it, and the table a host starts it from: one
136// entry per system in run order, plus the load-time passes bracketing them.
137// This crate writes one such table itself, listing the simulation systems it
138// owns, for a world that runs with no host beyond it.
139pub use built_system::BuiltSystem;
140pub use headless::HEADLESS_SYSTEMS;
141pub use system_entry::{CompleteWorld, SystemEntry, SystemTable};
142pub use world::{BakedMesh, ScratchStats, World};
143
144// The host-installed monotonic clock the step loop times systems with.
145pub use clock::Clock;
146
147// Runtime asset-registry types, generated by the macros in `define_components`
148// (invoked in `registry`). Re-exported here so the rest of the crate (and the
149// client, which re-exports this module under `crate::ecs::*`) can keep using
150// the historical `crate::ecs::*` paths. The authoring `RegisteredType` registry
151// is built from the same component list in the build crate. Systems have no
152// registry here: they are built client-side from the `System` behavior trait.
153pub use registry::{ComponentAsset, ComponentSlot, ComponentStorage, ComponentTag};
154
155// Points to an asset's compiled binary payload within the data blob files.
156// Blob-backed asset structs carry it as a `#[serde(skip)]` field.
157pub use locator::PayloadLocator;
158
159// Per-kind resource handles (dense per-kind indices into the runtime resource
160// tables), Cook assigns them;
161// components and the resource tables address resources by them.
162pub use handle::{
163 AudioClipHandle, ColorLutHandle, CubemapTextureHandle, EnvironmentMapHandle, FontHandle,
164 MaterialHandle, MeshHandle, ShaderHandle, SkinnedMeshHandle, TextureHandle,
165 de_audio_clip_handle_vec, de_opt_audio_clip_handle, de_opt_font_handle, de_opt_material_handle,
166 de_opt_mesh_handle, de_opt_shader_handle, de_opt_skinned_mesh_handle, de_opt_texture_handle,
167 de_texture_handle,
168};
169pub use resolver::{
170 set_audio_clip_handle_resolver, set_font_handle_resolver, set_material_handle_resolver,
171 set_mesh_handle_resolver, set_shader_handle_resolver, set_skinned_mesh_handle_resolver,
172 set_texture_handle_resolver,
173};
174
175// The blob record schema (the component defs stream + the resource stream) is
176// owned by the `blob` format module; re-exported here so the runtime, cook, and
177// the registry macros keep naming `ecs::{BlobAssetDef, ResourceKind, ...}`
178// unchanged.
179pub use crate::blob::{
180 AssetKind, BlobAssetDef, BlobMeta, MeshBoundsRecord, PhysicsBudgetRecord, ResourceKind,
181 ResourceRecord, SceneGroup,
182};