Skip to content

Commit 164b725

Browse files
committed
More tracing + attempt to make mouse capturing more robust
1 parent 669568e commit 164b725

File tree

4 files changed

+69
-14
lines changed

4 files changed

+69
-14
lines changed

toybox-gfx/src/core.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ impl Core {
7373

7474
log::info!("OpenGL {capabilities:#?}");
7575

76+
// TODO(pat.m): this doesn't really do much atm - but doesn't hurt lol
77+
if capabilities.parallel_shader_compilation_supported {
78+
unsafe {
79+
gl.MaxShaderCompilerThreadsARB(2);
80+
}
81+
}
82+
7683
Core {
7784
gl,
7885
capabilities,

toybox-input/src/lib.rs

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ pub struct System {
2929
pub mouse_sensitivity: f32,
3030

3131
window: Rc<Window>,
32+
3233
wants_capture: bool,
34+
occluded: bool,
35+
has_focus: bool,
36+
37+
is_mouse_captured: bool,
3338

3439
window_size: Vec2i,
3540
}
@@ -83,6 +88,16 @@ impl System {
8388
pub fn set_capture_mouse(&mut self, capture: bool) {
8489
self.wants_capture = capture;
8590

91+
let should_capture = self.should_capture();
92+
if self.is_mouse_captured != should_capture {
93+
self.try_capture_mouse_internal(should_capture);
94+
}
95+
}
96+
97+
#[instrument(skip_all, name="input System::try_capture_mouse_internal")]
98+
fn try_capture_mouse_internal(&mut self, capture: bool) {
99+
log::info!("try_capture_mouse_internal({capture})");
100+
86101
if capture {
87102
if let Err(error) = self.window.set_cursor_grab(CursorGrabMode::Confined)
88103
.inspect_err(|error| log::warn!("Failed to capture mouse with 'confined' mode - falling back to 'locked' mode. {error}"))
@@ -93,27 +108,39 @@ impl System {
93108
}
94109

95110
self.window.set_cursor_visible(false);
111+
self.is_mouse_captured = true;
96112

97113
} else {
98114
if let Err(error) = self.window.set_cursor_grab(CursorGrabMode::None) {
99115
log::error!("Failed to release cursor grab: {error}");
100116
}
101117

102118
self.window.set_cursor_visible(true);
119+
self.is_mouse_captured = false;
103120
}
104121
}
122+
123+
fn should_capture(&self) -> bool {
124+
self.wants_capture && !self.occluded && self.has_focus
125+
}
105126
}
106127

107128

108129
/// Internal. Will be called by core.
109130
impl System {
110131
#[instrument(skip_all, name="input System::new")]
111132
pub fn new(window: Rc<Window>) -> System {
133+
let has_focus = window.has_focus();
134+
112135
System {
113136
tracker: Tracker::default(),
114137
// gil: gilrs::Gilrs::new().unwrap(),
115138
window,
139+
116140
wants_capture: false,
141+
occluded: false,
142+
has_focus,
143+
is_mouse_captured: false,
117144

118145
// Default half way between quake and source sdk defaults
119146
// https://github.com/ValveSoftware/source-sdk-2013/blob/master/sp/src/game/client/in_mouse.cpp#L85
@@ -126,14 +153,23 @@ impl System {
126153

127154
// Clear any 'this frame' state in the tracker and prepare for recieving new inputs
128155
pub fn reset_tracker(&mut self) {
156+
if self.should_capture() != self.is_mouse_captured {
157+
self.try_capture_mouse_internal(self.should_capture());
158+
}
159+
160+
self.window.set_cursor_visible(!self.is_mouse_captured);
161+
129162
self.tracker.reset();
130163
}
131164

132165
/// Called when something (e.g., egui) changes its mind about whether or not it wants to claim input.
133166
/// We're assuming that when we become _not_ occluded we can safely manage things without interference.
134167
pub fn set_occluded(&mut self, occluded: bool) {
135-
if !occluded {
136-
self.set_capture_mouse(self.wants_capture);
168+
self.occluded = occluded;
169+
170+
let should_capture = self.should_capture();
171+
if self.is_mouse_captured != should_capture {
172+
self.try_capture_mouse_internal(should_capture);
137173
}
138174
}
139175

@@ -164,8 +200,19 @@ impl System {
164200

165201
WindowEvent::CursorLeft{..} => self.tracker.track_mouse_left(),
166202

167-
WindowEvent::Focused(false) => self.tracker.track_focus_lost(),
168-
WindowEvent::Focused(true) => self.tracker.track_focus_gained(),
203+
WindowEvent::Focused(false) => {
204+
self.has_focus = false;
205+
self.tracker.track_focus_lost();
206+
207+
self.try_capture_mouse_internal(self.should_capture());
208+
}
209+
210+
WindowEvent::Focused(true) => {
211+
self.has_focus = true;
212+
self.tracker.track_focus_gained();
213+
214+
self.try_capture_mouse_internal(self.should_capture());
215+
}
169216

170217
// TODO(pat.m): track dpi
171218

toybox-vfs/src/lib.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ pub struct Vfs {
1212
}
1313

1414
impl Vfs {
15+
#[instrument(name="vfs init")]
1516
pub fn new() -> anyhow::Result<Vfs> {
16-
Ok(Vfs {
17-
resource_root: find_resource_folder()
18-
.context("Can't find resource directory")?
19-
.into_boxed_path()
20-
})
17+
let resource_root = find_resource_folder()
18+
.context("Can't find resource directory")?
19+
.into_boxed_path();
20+
21+
log::info!("Resource Root Path: {}", resource_root.display());
22+
23+
Ok(Vfs { resource_root })
2124
}
2225

2326
pub fn resource_root(&self) -> &Path {
@@ -130,7 +133,7 @@ fn find_resource_folder() -> anyhow::Result<PathBuf> {
130133
fn try_find_resource_folder_from(search_dir: &Path, dirs_scanned: &mut Vec<PathBuf>) -> anyhow::Result<Option<PathBuf>> {
131134
// Try scanning the current search dir first, and then one directory above.
132135
for search_dir in search_dir.ancestors().take(2) {
133-
log::debug!("Trying to scan {}", search_dir.display());
136+
log::trace!("Trying to scan {}", search_dir.display());
134137

135138
let Ok(children) = search_dir.read_dir() else {
136139
continue
@@ -145,7 +148,7 @@ fn try_find_resource_folder_from(search_dir: &Path, dirs_scanned: &mut Vec<PathB
145148
{
146149
let dir_path = dir_entry.path();
147150

148-
log::debug!("=== Testing {}", dir_path.display());
151+
log::trace!("=== Testing {}", dir_path.display());
149152
if dir_path.ends_with("resource") {
150153
return Ok(Some(dir_path))
151154
}
@@ -168,7 +171,7 @@ fn try_find_resource_folder_from(search_dir: &Path, dirs_scanned: &mut Vec<PathB
168171
fn try_find_resource_folder_in(search_dir: &Path, dirs_scanned: &mut Vec<PathBuf>) -> anyhow::Result<Option<PathBuf>> {
169172
let path = search_dir.join("resource");
170173
dirs_scanned.push(path.clone());
171-
log::debug!("=== Testing {}", path.display());
174+
log::trace!("=== Testing {}", path.display());
172175

173176
if path.try_exists()? {
174177
return Ok(Some(path))

toybox/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ pub fn run_with_settings<F, A>(settings: host::Settings<'_>, start_app: F) -> an
3737
let vfs = vfs::Vfs::new()
3838
.context("Initialising Vfs")?;
3939

40-
log::info!("Resource Root Path: {}", vfs.resource_root().display());
41-
4240
let cfg = cfg::Config::for_app_name(app_name)?;
4341
let audio = audio::init();
4442

0 commit comments

Comments
 (0)