Skip to content

Commit 9e01f03

Browse files
committed
Merge branch 'demo-state-saving'
2 parents 050c106 + 495ebd1 commit 9e01f03

4 files changed

Lines changed: 82 additions & 42 deletions

File tree

.vscode/launch.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"program": "${workspaceFolder}/target/debug/client.exe",
1212
"args": [],
1313
"stopAtEntry": false,
14-
"cwd": "${fileDirname}",
14+
"cwd": "${workspaceFolder}",
1515
"environment": [],
1616
"console": "externalTerminal",
1717
"preLaunchTask": "pmbuild-debug"
@@ -23,7 +23,7 @@
2323
"program": "${workspaceFolder}/target/release/client.exe",
2424
"args": [],
2525
"stopAtEntry": false,
26-
"cwd": "${fileDirname}",
26+
"cwd": "${workspaceFolder}",
2727
"environment": [],
2828
"console": "externalTerminal",
2929
"preLaunchTask": "pmbuild-release"
@@ -35,7 +35,7 @@
3535
"program": "${workspaceFolder}/target/debug/examples/window.exe",
3636
"args": [],
3737
"stopAtEntry": false,
38-
"cwd": "${fileDirname}",
38+
"cwd": "${workspaceFolder}",
3939
"environment": [],
4040
"console": "externalTerminal",
4141
"preLaunchTask": "examples"
@@ -47,7 +47,7 @@
4747
"program": "${workspaceFolder}/target/debug/examples/swap_chain.exe",
4848
"args": [],
4949
"stopAtEntry": false,
50-
"cwd": "${fileDirname}",
50+
"cwd": "${workspaceFolder}",
5151
"environment": [],
5252
"console": "externalTerminal",
5353
"preLaunchTask": "examples"
@@ -59,7 +59,7 @@
5959
"program": "${workspaceFolder}/target/debug/examples/triangle.exe",
6060
"args": [],
6161
"stopAtEntry": false,
62-
"cwd": "${fileDirname}",
62+
"cwd": "${workspaceFolder}",
6363
"environment": [],
6464
"console": "externalTerminal",
6565
"preLaunchTask": "examples"
@@ -71,7 +71,7 @@
7171
"program": "${workspaceFolder}/target/debug/examples/bindless.exe",
7272
"args": [],
7373
"stopAtEntry": false,
74-
"cwd": "${fileDirname}",
74+
"cwd": "${workspaceFolder}",
7575
"environment": [],
7676
"console": "externalTerminal",
7777
"preLaunchTask": "examples"
@@ -83,7 +83,7 @@
8383
"program": "${workspaceFolder}/target/debug/examples/bindful.exe",
8484
"args": [],
8585
"stopAtEntry": false,
86-
"cwd": "${fileDirname}",
86+
"cwd": "${workspaceFolder}",
8787
"environment": [],
8888
"console": "externalTerminal",
8989
"preLaunchTask": "examples"
@@ -95,7 +95,7 @@
9595
"program": "${workspaceFolder}/target/debug/examples/imgui_demo.exe",
9696
"args": [],
9797
"stopAtEntry": false,
98-
"cwd": "${fileDirname}",
98+
"cwd": "${workspaceFolder}",
9999
"environment": [],
100100
"console": "externalTerminal",
101101
"preLaunchTask": "examples"
@@ -107,7 +107,7 @@
107107
"program": "${workspaceFolder}/target/debug/examples/play_video.exe",
108108
"args": [],
109109
"stopAtEntry": false,
110-
"cwd": "${fileDirname}",
110+
"cwd": "${workspaceFolder}",
111111
"environment": [],
112112
"console": "externalTerminal",
113113
"preLaunchTask": "examples"
@@ -119,7 +119,7 @@
119119
"program": "${workspaceFolder}/target/debug/examples/resource_tests.exe",
120120
"args": ["--test-threads=1", "--nocapture"],
121121
"stopAtEntry": false,
122-
"cwd": "${fileDirname}",
122+
"cwd": "${workspaceFolder}",
123123
"environment": [],
124124
"console": "externalTerminal",
125125
"preLaunchTask": "examples"
@@ -131,7 +131,7 @@
131131
"program": "${workspaceFolder}/target/debug/examples/raytraced_triangle.exe",
132132
"args": [],
133133
"stopAtEntry": false,
134-
"cwd": "${fileDirname}",
134+
"cwd": "${workspaceFolder}",
135135
"environment": [],
136136
"console": "externalTerminal",
137137
"preLaunchTask": "examples"
@@ -143,7 +143,7 @@
143143
"program": "${workspaceFolder}/target/debug/deps/tests-9d060b7b8785eb4b.exe",
144144
"args": ["--test-threads=1", "--nocapture"],
145145
"stopAtEntry": false,
146-
"cwd": "${fileDirname}",
146+
"cwd": "${workspaceFolder}",
147147
"environment": [],
148148
"console": "externalTerminal",
149149
},

plugins/ecs/src/lib.rs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -676,21 +676,37 @@ impl Plugin<gfx_platform::Device, os_platform::App> for BevyPlugin {
676676
let (open, selected) = client.imgui.combo_list("Demo", &demo_list, &self.session_info.active_demo);
677677
if open {
678678
if selected != self.session_info.active_demo {
679+
// save current demo's camera and debug flags
680+
let old_demo = self.session_info.active_demo.clone();
681+
if let Some(camera) = self.session_info.main_camera {
682+
self.session_info.demo_cameras
683+
.get_or_insert_with(HashMap::new)
684+
.insert(old_demo.clone(), camera);
685+
}
686+
self.session_info.demo_debug_flags
687+
.get_or_insert_with(HashMap::new)
688+
.insert(old_demo, self.session_info.debug_draw_flags);
689+
679690
// update session info
680691
self.session_info.active_demo = selected;
681692
resetup = true;
682693
}
683694
}
684695

685-
// camera type select
696+
// save per-demo camera + debug draw defaults
686697
if client.imgui.button_size(font_awesome::strs::CAMERA, 32.0, 0.0) {
687-
// save default
688-
if self.session_info.default_cameras.is_none() {
689-
self.session_info.default_cameras = Some(HashMap::new());
698+
let demo = self.session_info.active_demo.clone();
699+
if let Some(camera) = self.session_info.main_camera {
700+
self.session_info.default_cameras
701+
.get_or_insert_with(HashMap::new)
702+
.insert(demo.clone(), camera);
703+
self.session_info.demo_cameras
704+
.get_or_insert_with(HashMap::new)
705+
.insert(demo.clone(), camera);
690706
}
691-
let default_cam_map = self.session_info.default_cameras.as_mut().unwrap();
692-
let entry = default_cam_map.entry(self.session_info.active_demo.to_string()).or_default();
693-
*entry = self.session_info.main_camera.unwrap();
707+
self.session_info.demo_debug_flags
708+
.get_or_insert_with(HashMap::new)
709+
.insert(demo, self.session_info.debug_draw_flags);
694710
}
695711
client.imgui.same_line();
696712

@@ -786,12 +802,21 @@ impl Plugin<gfx_platform::Device, os_platform::App> for BevyPlugin {
786802

787803
// preform any re-setup actions
788804
if resetup {
789-
// set camera to the default position for the selected demo
790-
if let Some(default_cameras) = &self.session_info.default_cameras {
791-
if default_cameras.contains_key(&self.session_info.active_demo) {
792-
self.session_info.main_camera = Some(default_cameras[&self.session_info.active_demo]);
793-
}
805+
let demo = &self.session_info.active_demo.clone();
806+
807+
// restore per-demo camera: demo_cameras takes priority, then default_cameras, then keep current
808+
if let Some(cam) = self.session_info.demo_cameras.as_ref().and_then(|m| m.get(demo)) {
809+
self.session_info.main_camera = Some(*cam);
810+
} else if let Some(cam) = self.session_info.default_cameras.as_ref().and_then(|m| m.get(demo)) {
811+
self.session_info.main_camera = Some(*cam);
794812
}
813+
814+
// restore per-demo debug draw flags
815+
self.session_info.debug_draw_flags = self.session_info.demo_debug_flags
816+
.as_ref()
817+
.and_then(|m| m.get(demo).copied())
818+
.unwrap_or_default();
819+
795820
self.resetup(client);
796821
}
797822

src/client.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,26 @@ impl<D, A> Client<D, A> where D: gfx::Device, A: os::App, D::RenderPipeline: gfx
219219
depth_stencil_heap_size: info.depth_stencil_heap_size,
220220
});
221221

222+
// validate saved window rect is visible on a connected monitor and clamp to keep title bar accessible
223+
let monitors = app.enumerate_display_monitors();
224+
let mut window_rect = user_config.main_window_rect;
225+
let target_monitor = monitors.iter().find(|m| {
226+
let mid_x = window_rect.x + window_rect.width / 2;
227+
mid_x >= m.rect.x && mid_x < m.rect.x + m.rect.width
228+
});
229+
if let Some(monitor) = target_monitor {
230+
// clamp position to keep the window within the monitor's work area (excludes taskbar)
231+
let work = &monitor.client_rect;
232+
window_rect.x = window_rect.x.max(work.x).min(work.x + work.width - window_rect.width);
233+
window_rect.y = window_rect.y.max(work.y).min(work.y + work.height - window_rect.height);
234+
} else {
235+
window_rect = info.window_rect;
236+
};
237+
222238
// main window
223239
let main_window = app.create_window(os::WindowInfo {
224240
title: info.name.to_string(),
225-
rect: user_config.main_window_rect,
241+
rect: window_rect,
226242
style: os::WindowStyleFlags::NONE,
227243
parent_handle: None,
228244
});
@@ -403,25 +419,20 @@ impl<D, A> Client<D, A> where D: gfx::Device, A: os::App, D::RenderPipeline: gfx
403419
// track any changes and write once
404420
let mut invalidated = false;
405421

406-
// main window pos / size
407-
let current = self.main_window.get_window_rect();
408-
if current.x > 0 && current.y > 0 && self.user_config.main_window_rect != current {
409-
self.user_config.main_window_rect = self.main_window.get_window_rect();
410-
invalidated = true;
411-
}
412-
413-
// console window pos / size
414-
if let Some(console_window_rect) = self.user_config.console_window_rect {
415-
let current = self.app.get_console_window_rect();
416-
if current.x > 0 && current.y > 0 && console_window_rect != current {
417-
self.user_config.console_window_rect = Some(self.app.get_console_window_rect());
422+
// main window pos / size (skip if minimised to avoid saving bad coordinates)
423+
if !self.main_window.is_minimised() {
424+
let current = self.main_window.get_window_rect();
425+
if self.user_config.main_window_rect != current {
426+
self.user_config.main_window_rect = current;
418427
invalidated = true;
419428
}
420429
}
421-
else {
422-
let current = self.app.get_console_window_rect();
423-
if current.x > 0 && current.y > 0 {
424-
self.user_config.console_window_rect = Some(self.app.get_console_window_rect());
430+
431+
// console window pos / size
432+
let console_current = self.app.get_console_window_rect();
433+
if console_current.width > 0 && console_current.height > 0 {
434+
if self.user_config.console_window_rect != Some(console_current) {
435+
self.user_config.console_window_rect = Some(console_current);
425436
invalidated = true;
426437
}
427438
}

src/ecs_base.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ pub struct SessionInfo {
7979
/// Default camera for a demo, can be set by the camera button in the UI
8080
pub default_cameras: Option<HashMap<String, CameraInfo>>,
8181
/// Debug draw flags
82-
pub debug_draw_flags: DebugDrawFlags
82+
pub debug_draw_flags: DebugDrawFlags,
83+
/// Per-demo camera state, auto-saved on demo switch
84+
pub demo_cameras: Option<HashMap<String, CameraInfo>>,
85+
/// Per-demo debug draw flags, auto-saved on demo switch
86+
pub demo_debug_flags: Option<HashMap<String, DebugDrawFlags>>,
8387
}
8488

8589
/// This macro allows you to create a newtype which will automatically deref and deref_mut

0 commit comments

Comments
 (0)