Skip to main content

window_manager_demo/
window_manager_demo.rs

1//! WindowManager Example - Simplified Multi-Window Management
2//!
3//! Demonstrates the `WindowManager` abstraction for managing multiple windows:
4//! - Creates 3 windows with different clear colors (Red, Green, Blue)
5//! - Automatic window resize handling
6//! - Shared graphics context management
7//! - Eliminates HashMap boilerplate
8//!
9//! ## Features Showcased
10//! - `WindowManager` for simplified window management
11//! - Automatic resize event handling
12//! - Shared `GraphicsContext` across windows
13//! - Per-window rendering with different clear colors
14//!
15//! ## Usage
16//! ```bash
17//! cargo run -p astrelis-render --example window_manager_demo
18//! ```
19//!
20//! ## Comparison
21//! Compare this to `multi_window.rs` to see the boilerplate reduction!
22
23use astrelis_core::logging;
24use astrelis_render::{
25    Color, GraphicsContext, RenderTarget, WindowContextDescriptor, WindowManager,
26};
27use astrelis_winit::{
28    FrameTime,
29    WindowId,
30    app::{run_app, App, AppCtx},
31    event::EventBatch,
32    window::{WindowBackend, WindowDescriptor, WinitPhysicalSize},
33};
34use std::collections::HashMap;
35
36struct WindowManagerApp {
37    window_manager: WindowManager,
38    window_colors: HashMap<WindowId, Color>,
39}
40
41fn main() {
42    logging::init();
43
44    run_app(|ctx| {
45        let graphics_ctx = GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
46        let mut window_manager = WindowManager::new(graphics_ctx);
47        let mut window_colors = HashMap::new();
48
49        // Create 3 windows with different colors
50        let colors = [
51            Color::rgb(0.8, 0.2, 0.2), // Red
52            Color::rgb(0.2, 0.8, 0.2), // Green
53            Color::rgb(0.2, 0.2, 0.8), // Blue
54        ];
55
56        for (i, color) in colors.iter().enumerate() {
57            let window_id = window_manager.create_window_with_descriptor(
58                ctx,
59                WindowDescriptor {
60                    title: format!("Window {} - WindowManager Demo", i + 1),
61                    size: Some(WinitPhysicalSize::new(400.0, 300.0)),
62                    ..Default::default()
63                },
64                WindowContextDescriptor {
65                    format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
66                    ..Default::default()
67                },
68            ).expect("Failed to create window");
69
70            window_colors.insert(window_id, *color);
71        }
72
73        Box::new(WindowManagerApp {
74            window_manager,
75            window_colors,
76        })
77    });
78}
79
80impl App for WindowManagerApp {
81    fn update(&mut self, _ctx: &mut AppCtx, _time: &FrameTime) {
82        // Global logic - called once per frame
83        // (none needed for this example)
84    }
85
86    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
87        // Get the color for this window
88        let Some(&color) = self.window_colors.get(&window_id) else {
89            return;
90        };
91
92        // WindowManager automatically handles:
93        // 1. Window lookup (no manual HashMap.get_mut)
94        // 2. Resize events (automatic)
95        // 3. Event dispatching
96        self.window_manager
97            .render_window(window_id, events, |window, _events| {
98                // No need to manually handle resize events!
99                // WindowManager already did that for us
100
101                // Just render!
102                let mut frame = window.begin_drawing();
103
104                frame.clear_and_render(RenderTarget::Surface, color, |_pass| {
105                    // Additional rendering would go here
106                });
107
108                frame.finish();
109            });
110    }
111}