use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use concinnity_core::ecs::World;
use concinnity_core::render::backend::RenderBackend;
use crate::ecs::ActiveRenderBackend;
use crate::gfx::system::hot_reload_sources::HotReloadSources;
use crate::gfx::system::parked::{PushedFogSettings, TextureNameSlots};
pub use crate::animation::AnimationReloadEntry;
pub use crate::ecs::take_render_backend;
pub use crate::gfx::system::{hot_reload_sources, parked, sdf_field_sources, shader_sources};
pub use crate::gfx::{draw_preview, lighting_preview, material_preview, shape_preview};
pub struct PendingBackend(pub Box<dyn RenderBackend>);
pub struct RenderHandoff<'a> {
pub backend: Option<&'a mut (dyn RenderBackend + 'static)>,
pub fog: Option<&'a mut PushedFogSettings>,
pub texture_slots: Option<&'a TextureNameSlots>,
}
pub fn render_handoff(world: &mut World) -> RenderHandoff<'_> {
let (_, resources) = world.systems_and_resources();
let (backend, fog, texture_slots) =
resources.get_disjoint_mut::<ActiveRenderBackend, PushedFogSettings, TextureNameSlots>();
RenderHandoff {
backend: backend.and_then(|slot| slot.0.as_deref_mut()),
fog,
texture_slots: texture_slots.map(|slots| &*slots),
}
}
pub fn take_hot_reload_sources(world: &mut World) -> Option<HotReloadSources> {
world.remove_resource::<HotReloadSources>()
}
pub fn shader_reload_flag(world: &World) -> Option<Arc<AtomicBool>> {
world
.resource::<ActiveRenderBackend>()
.and_then(|slot| slot.0.as_ref())
.and_then(|backend| backend.shader_reload_flag())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn accessors_without_a_backend() {
let mut world = World::new();
assert!(shader_reload_flag(&world).is_none());
assert!(take_render_backend(&mut world).is_none());
assert!(take_hot_reload_sources(&mut world).is_none());
let handoff = render_handoff(&mut world);
assert!(handoff.backend.is_none());
assert!(handoff.fog.is_none());
assert!(handoff.texture_slots.is_none());
}
#[test]
fn render_handoff_borrows_the_parked_state_together() {
let mut world = World::new();
world.insert_resource(PushedFogSettings(None));
world.insert_resource(TextureNameSlots(
[(concinnity_core::ecs::asset_id::AssetId(3), 7)].into(),
));
world.insert_resource(HotReloadSources::default());
let handoff = render_handoff(&mut world);
assert!(handoff.backend.is_none());
let slots = handoff.texture_slots.expect("texture-name map parked");
assert_eq!(slots.0.len(), 1);
let fog = concinnity_core::render::volumetric_fog::resolve_asset(
&concinnity_core::components::VolumetricFog {
enabled: true,
..Default::default()
},
);
handoff.fog.expect("fog parked").0 = fog;
assert!(world.resource::<PushedFogSettings>().unwrap().0.is_some());
assert!(take_hot_reload_sources(&mut world).is_some());
assert!(take_hot_reload_sources(&mut world).is_none());
}
}