diff options
| author | HampusM <hampus@hampusmat.com> | 2026-04-22 16:26:19 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-04-22 16:26:19 +0200 |
| commit | 0b99ad032ed63253aa3f534bcf8eee39a12c0388 (patch) | |
| tree | be3137fc0ca946dc0b4728853aabe7dd70446aca /engine/src/renderer.rs | |
| parent | 4c378d7173fae64ea77c6ead7258c30ff64f2789 (diff) | |
feat(engine): make opengl renderer module not handle window removals
Diffstat (limited to 'engine/src/renderer.rs')
| -rw-r--r-- | engine/src/renderer.rs | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 970a241..14b8d49 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -3,8 +3,9 @@ use std::collections::VecDeque; use std::sync::atomic::{AtomicU64, Ordering}; use bitflags::bitflags; +use ecs::actions::Actions; use ecs::entity::obtainer::Obtainer as EntityObtainer; -use ecs::event::component::Changed; +use ecs::event::component::{Changed, Removed}; use ecs::pair::{ChildOf, Pair, Wildcard}; use ecs::phase::{POST_UPDATE as POST_UPDATE_PHASE, Phase}; use ecs::sole::Single; @@ -97,6 +98,7 @@ impl ecs::extension::Extension for Extension collector.add_system(*RENDER_PHASE, enqueue_commands_from_render_passes); collector.add_observer(handle_window_changed); + collector.add_observer(handle_window_removed); opengl::Extension::default().collect(collector); } @@ -212,6 +214,7 @@ pub struct RenderPass #[non_exhaustive] pub enum Command { + RemoveSurface(SurfaceId), MakeCurrent(SurfaceId), ClearBuffers(BufferClearMask), SwapBuffers(SurfaceId), @@ -550,6 +553,64 @@ fn handle_window_changed( } } +#[tracing::instrument(skip_all)] +fn handle_window_removed(observe: Observe<Pair<Removed, Window>>, mut actions: Actions) +{ + for evt_match in &observe { + let window_ent_id = evt_match.id(); + + let window_ent = evt_match.get_ent_infallible(); + + tracing::debug!( + entity_id = %window_ent_id, + title = %evt_match.get_removed_comp().title, + "Handling removal of window" + ); + + let Some(window_surface_spec) = window_ent.get::<SurfaceSpec>() else { + continue; + }; + + actions.remove_comps::<(SurfaceSpec,)>(window_ent_id); + + let Some(with_renderer_ctx_pair) = window_ent + .get_first_wildcard_pair_match::<WindowUsingRendererCtx, Wildcard>() + else { + tracing::warn!( + "Window entity is missing a ({}, *) pair", + type_name::<WindowUsingRendererCtx>() + ); + continue; + }; + + let Some(renderer_context_ent) = with_renderer_ctx_pair.get_target_ent() else { + continue; + }; + + let Some(mut command_queue) = renderer_context_ent.get_mut::<CommandQueue>() + else { + continue; + }; + + command_queue + .queue + .push_front(Command::RemoveSurface(window_surface_spec.id)); + + let renderer_context_ent_id = with_renderer_ctx_pair.id().target_entity(); + + actions.remove_components( + renderer_context_ent_id, + [Pair::builder() + .relation::<CtxUsedByWindow>() + .target_id(window_ent_id) + .build() + .id()], + ); + + actions.remove_components(window_ent_id, [with_renderer_ctx_pair.id()]); + } +} + // TODO: Maybe move this struct to somewhere more appropriate #[derive(Default, Clone, Component)] pub struct PendingShaderBindings |
