summaryrefslogtreecommitdiff
path: root/engine/src/renderer.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-04-22 16:26:19 +0200
committerHampusM <hampus@hampusmat.com>2026-04-22 16:26:19 +0200
commit0b99ad032ed63253aa3f534bcf8eee39a12c0388 (patch)
treebe3137fc0ca946dc0b4728853aabe7dd70446aca /engine/src/renderer.rs
parent4c378d7173fae64ea77c6ead7258c30ff64f2789 (diff)
feat(engine): make opengl renderer module not handle window removals
Diffstat (limited to 'engine/src/renderer.rs')
-rw-r--r--engine/src/renderer.rs63
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