pub(crate) mod access_ids;
#[cfg(test)]
mod active_scene_flow_tests;
pub(crate) mod by_asset_id;
#[cfg(test)]
mod consumed_columns_tests;
pub(crate) mod decompose;
#[cfg(test)]
mod determinism_tests;
#[cfg(test)]
mod headless_drift_tests;
mod registry;
pub mod render_mode;
pub mod schedule;
mod world_queries;
use concinnity_core::ecs::MeshBoundsRecord;
use concinnity_core::ecs::Resources;
use concinnity_core::ecs::SceneGroup;
use concinnity_core::ecs::asset_id::AssetId;
use concinnity_core::render::backend;
use concinnity_core::render::scene_flow;
use concinnity_core::render::scene_residency;
use concinnity_core::window::display_mode;
pub use registry::SYSTEMS;
pub use world_queries::{
RenderHandoff, animation_system_mut, gpu_profile, memory_budget, memory_drift, render_handoff,
renders, state_tree, streaming_pressure, streaming_stats, take_hot_reload_sources,
take_render_backend, thread_budget,
};
pub struct PendingBackend(pub Box<dyn backend::RenderBackend>);
pub struct RenderInitFailure(pub concinnity_core::render::error::RenderError);
#[derive(Default)]
pub(crate) struct InputMailbox(pub Option<concinnity_core::input::snapshot::InputPacket>);
impl InputMailbox {
pub(crate) fn deposit(&mut self, packet: concinnity_core::input::snapshot::InputPacket) {
match &mut self.0 {
Some(pending) => pending.merge_from(packet),
None => self.0 = Some(packet),
}
}
}
pub(crate) struct RenderQueues {
pub ops: concinnity_core::render::ops::RenderOps,
pub slots: crate::gfx::render_slots::RenderSlots,
}
#[derive(Clone, Copy)]
pub(crate) struct ActiveDeviceCaps(pub concinnity_core::render::backend::DeviceCapabilities);
pub(crate) struct ActiveRenderQueues(pub Option<RenderQueues>);
impl ActiveRenderQueues {
pub(crate) fn take(resources: &mut Resources) -> Option<RenderQueues> {
resources.get_mut::<Self>()?.0.take()
}
pub(crate) fn put(resources: &mut Resources, queues: RenderQueues) {
match resources.get_mut::<Self>() {
Some(slot) => slot.0 = Some(queues),
None => {
resources.insert(Self(Some(queues)));
}
}
}
}
#[derive(Default)]
pub(crate) struct RenderOpFailures(pub Vec<concinnity_core::render::ops::OpFailure>);
pub(crate) struct PipelinedFrames(pub Option<PipelineChannels>);
pub(crate) struct PipelineChannels {
pub(crate) snapshot_tx:
std::sync::mpsc::SyncSender<concinnity_core::render::snapshot::RenderSnapshot>,
pub(crate) feedback_rx:
std::sync::mpsc::Receiver<concinnity_core::render::feedback::FrameFeedback>,
}
impl PipelinedFrames {
pub(crate) fn take(resources: &mut Resources) -> Option<PipelineChannels> {
resources.get_mut::<Self>()?.0.take()
}
pub(crate) fn put(resources: &mut Resources, channels: PipelineChannels) {
match resources.get_mut::<Self>() {
Some(slot) => slot.0 = Some(channels),
None => {
resources.insert(Self(Some(channels)));
}
}
}
}
pub struct ActiveRenderBackend(pub Option<Box<dyn backend::RenderBackend>>);
impl ActiveRenderBackend {
pub(crate) fn take(resources: &mut Resources) -> Option<Box<dyn backend::RenderBackend>> {
resources.get_mut::<Self>()?.0.take()
}
pub(crate) fn put(resources: &mut Resources, backend: Box<dyn backend::RenderBackend>) {
match resources.get_mut::<Self>() {
Some(slot) => slot.0 = Some(backend),
None => {
resources.insert(Self(Some(backend)));
}
}
}
}
pub(crate) struct ActiveSceneFlow {
pub flow: Option<scene_flow::SceneFlow>,
epoch: Option<f32>,
}
impl ActiveSceneFlow {
pub(crate) fn new(flow: Option<scene_flow::SceneFlow>) -> Self {
Self { flow, epoch: None }
}
pub(crate) fn elapsed(&mut self, now: f32) -> f32 {
(now - *self.epoch.get_or_insert(now)).max(0.0)
}
}
pub struct BlobSceneGroups(pub Vec<SceneGroup>);
pub struct BlobMeshBounds(pub Vec<MeshBoundsRecord>);
pub(crate) struct SceneResidencyStatus {
pub scenes: Vec<(AssetId, scene_residency::SceneLoadState, f32)>,
}
#[derive(Debug, Clone, Default)]
pub(crate) struct DisabledSettingRows(
pub std::collections::HashSet<concinnity_core::settings::SettingKey>,
);
#[derive(Debug, Clone, Default)]
pub(crate) struct DisplayModes(pub Vec<display_mode::DisplayMode>);
#[macro_export]
macro_rules! define_systems {
( complete_world: $complete_world:path,
before_init: $before_init:path,
prepare_events: $prepare_events:path,
$( $name:ident => $behavior:path {
gate: $gate:path,
present_when: $present_when:literal,
phase: $phase:ident,
after: [ $( $after:ident ),* $(,)? ],
before: [ $( $before:ident ),* $(,)? ] $(,)?
} ),* $(,)? ) => {
pub const SYSTEMS: &::concinnity_core::ecs::SystemTable = &::concinnity_core::ecs::SystemTable {
entries: &[
$( ::concinnity_core::ecs::SystemEntry {
name: stringify!($name),
present_when: $present_when,
phase: ::concinnity_core::ecs::Phase::$phase,
gate: {
fn build(
world: &::concinnity_core::ecs::World,
) -> Option<::std::boxed::Box<dyn ::concinnity_core::ecs::System>> {
let built: Option<$behavior> = $gate(world);
built.map(|s| -> ::std::boxed::Box<dyn ::concinnity_core::ecs::System> {
::std::boxed::Box::new(s)
})
}
build
},
after: &[ $( stringify!($after) ),* ],
before: &[ $( stringify!($before) ),* ],
}, )*
],
complete_world: Some($complete_world),
before_init: Some($before_init),
prepare_events: Some($prepare_events),
};
};
}