Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve background tab behaviour #373

Closed
cBournhonesque opened this issue May 23, 2024 · 9 comments
Closed

Improve background tab behaviour #373

cBournhonesque opened this issue May 23, 2024 · 9 comments

Comments

@cBournhonesque
Copy link
Owner

The main functionality was merged here: #371

But some things could be improved:

  • have more granular control over the interval. At a minimum make it configurable at start. Maybe even overridable?
  • some plugins don't need to run when the tab is background (for example InputPlugin). They should be disabled while the app is hidden in wasm
@simbleau
Copy link
Contributor

I think the general approach should be:

Use the Window winit events to listen for when the window is tabbed-off / minimized / etc.

Keep an attention state (active/inactive).
(eg)

#[derive(State)]
pub enum BevyWindowState {
    Inactive,
    Active,
}

Depending on that, send inputs/etc.

@simbleau
Copy link
Contributor

I'm also torn whether or not that should be in bevy proper, not just a plugin. As it currently stands, the winit event for WindowUnfocused just straight up doesn't work, because it fires after it returns, firing the Unfocused and Refocused at the same time.

It's downright basically a bug, it's not delivering value to anyone.

@simbleau
Copy link
Contributor

I've made a mention in bevy: bevyengine/bevy#13486

@simbleau
Copy link
Contributor

I just thought of something else...

Let's imagine you have a system that is supposed to be an atomic counter.

Every system, the counter += 1.

If we do this WebPlugin, wouldn't we be double-counting every time the webworker runs the Main schedule? This would be a very difficult thing to triage.

Can we adjust the plugin so it only executes the Main schedule if (and only if) the window is not focused? Perhaps using a rolling track of whether the BevyWindowState is BevyWindowState::Inactive.

@cBournhonesque
Copy link
Owner Author

It does execute the Main schedule only if the window is not focused:

if window().unwrap().document().unwrap().hidden() {

Basically the solution is extremely unsafe: we take a raw pointer on the world, which we use only when the window is hidden.
But that is ok to do because we know that the bevy scheduler doesn't run when the tab is hidden (since there are no requestAnimationFrame calls), so nothing else is using the world.

So:

  • when the tab is open: the Main schedule runs normally
  • when the tab is hidden: the Main schedule runs at a set interval in the WebWorker, and does not run in main bevy thread

@Nul-led correct me if i'm wrong

@Nul-led
Copy link
Collaborator

Nul-led commented May 23, 2024

Its technically safe tho since we are in wasm land and everything is single threaded anyways, so we could totally run this alongside winits event loop

@simbleau
Copy link
Contributor

Note these window.unwrap()... calls will panic in a headless environment.

Primarily wasm-pack test --node or using headless browsers.

We should change this to

if window().and_then(w| w.document()).is_some_and(|d| d.hidden()) {
...
}

@Nul-led
Copy link
Collaborator

Nul-led commented May 24, 2024

Note these window.unwrap()... calls will panic in a headless environment.

Primarily wasm-pack test --node or using headless browsers.

We should change this to

if window().and_then(w| w.document()).is_some_and(|d| d.hidden()) {
...
}

Wouldnt it be better to have a toggle for the "hidden" check instead, so we can enable / disable it on app launch

@Nul-led
Copy link
Collaborator

Nul-led commented May 24, 2024

@simbleau
https://crates.io/crates/bevy_web_keepalive
hope this helps :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants