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::{Color, GraphicsContext, WindowContextDescriptor, WindowManager};
25use astrelis_winit::{
26 FrameTime, WindowId,
27 app::{App, AppCtx, run_app},
28 event::EventBatch,
29 window::{WindowDescriptor, WinitPhysicalSize},
30};
31use std::collections::HashMap;
32
33struct WindowManagerApp {
34 window_manager: WindowManager,
35 window_colors: HashMap<WindowId, Color>,
36}
37
38fn main() {
39 logging::init();
40
41 run_app(|ctx| {
42 let graphics_ctx =
43 GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
44 let mut window_manager = WindowManager::new(graphics_ctx);
45 let mut window_colors = HashMap::new();
46
47 // Create 3 windows with different colors
48 let colors = [
49 Color::rgb(0.8, 0.2, 0.2), // Red
50 Color::rgb(0.2, 0.8, 0.2), // Green
51 Color::rgb(0.2, 0.2, 0.8), // Blue
52 ];
53
54 for (i, color) in colors.iter().enumerate() {
55 let window_id = window_manager
56 .create_window_with_descriptor(
57 ctx,
58 WindowDescriptor {
59 title: format!("Window {} - WindowManager Demo", i + 1),
60 size: Some(WinitPhysicalSize::new(400.0, 300.0)),
61 ..Default::default()
62 },
63 WindowContextDescriptor {
64 format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
65 ..Default::default()
66 },
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 Some(frame) = window.begin_frame() else {
103 return; // Surface not available
104 };
105
106 {
107 let _pass = frame
108 .render_pass()
109 .clear_color(color)
110 .label("window_manager_pass")
111 .build();
112 // Additional rendering would go here
113 }
114 // Frame auto-submits on drop
115 });
116 }
117}