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

The ability to create fake windows #3754

Closed
Shatur opened this issue Jan 23, 2022 · 8 comments
Closed

The ability to create fake windows #3754

Shatur opened this issue Jan 23, 2022 · 8 comments
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Usability A targeted quality-of-life change that makes Bevy easier to use

Comments

@Shatur
Copy link
Contributor

Shatur commented Jan 23, 2022

What problem does this solve or what need does it fill?

When writing unit tests for the UI, access to the window is required. But since the tests run in parallel by default, it's impossible to create a real window outside of the main thread. For details, see #1720.

What solution would you like?

But for unit testing, a real window is not needed, it is enough to create a fake one. Currently users can add windows manually using add on Windows resource and pass a Window struct to it. But to create a Window I need to provide RawWindowHandle. I would suggest to turn this field into Option. This way users will be able to create dummy windows and UI plugins will know necessary stuff, like window size and scale. Currently UI plugins such as Egui work in headless mode, but crashes on any access to context because there is no associated window.

@Shatur Shatur added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Jan 23, 2022
@bjorn3
Copy link
Contributor

bjorn3 commented Jan 23, 2022

#3439 implemented a headless mode.

@Shatur
Copy link
Contributor Author

Shatur commented Jan 23, 2022

#3439 implemented a headless mode.

Unfortunately no. I only made it work without renderer in that PR. But there is no "headless window" for now.

@alice-i-cecile alice-i-cecile added A-Windowing Platform-agnostic interface layer to run your app in C-Usability A targeted quality-of-life change that makes Bevy easier to use and removed C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Jan 23, 2022
@Wcubed
Copy link
Contributor

Wcubed commented Jan 29, 2022

I am looking at implementing this, and was wondering: in bevy_render, the RenderPlugin requires a window handle to get a valid drawing surface.

let handle = window.raw_window_handle().get_handle();

When a window doesn't have a handle, we need to skip at least the bits of the RenderPlugin that rely on the handle for information. However, it could mean that resources and such are missing that other components rely on.
We could even forgo adding RenderPlugin in the first place, but that probably breaks even more stuff.

What is your opinion on this? I'm at this point not all to familiar with the rendering side of things to know how much I can "cut out" when there is no window without strange behavior occurring.

@Shatur
Copy link
Contributor Author

Shatur commented Jan 29, 2022

What is your opinion on this?

I think it should work with RenderPlugin. We just need to skip everything that relies on this handle.

@Wcubed
Copy link
Contributor

Wcubed commented Jan 29, 2022

It turned out I didn't even need to skip any of the RenderPlugin code, as the Surface was already used there as an Option.

I can now run an app in a test with almost all of the DefaultPlugins added. The only one that messes things up is the WinitPlugin which doesn't want to be started in a separate thread.

Being able to do .add_plugins(DefaultPlugins), in a test would be quite nice. As the alternative is to add each plugin (except for the WinitPlugin) separately, and that just makes it a long list :P.

Is there a way to skip the WinitPlugin (without setting the feature flag)? Or would it be better to add an option to the plugin to allow running in a separate thread?

@bjorn3
Copy link
Contributor

bjorn3 commented Jan 29, 2022

Is there a way to skip the WinitPlugin (without setting the feature flag)?

You can use something like .add_plugins_with(DefaultPlugins, |group| { group.disable::<bevy::winit::WinitPlugin>() });

Or would it be better to add an option to the plugin to allow running in a separate thread?

On some platforms the OS requires that the event loop runs on the main thread.

@Shatur
Copy link
Contributor Author

Shatur commented Jan 29, 2022

It turned out I didn't even need to skip any of the RenderPlugin code, as the Surface was already used there as an Option.

Awesome!

Is there a way to skip the WinitPlugin (without setting the feature flag)?

Sure can:

.add_plugins_with(DefaultPlugins, |group| group.disable::<WinitPlugin>())

Running DefaultPlugins as is (e.g. with WinitPlugin) doesn't make sense, you don't want to create actual window in each test.

P.S.: for unit tests I would recommend to setup minimal set of plugins for each module (here is how I set things up, for example).
For tests that require RenderPlugin (to run systems that use Mesh or StandardMaterial, for example), I created a custom HeadlessPlugin that adds RenderPlugin and other minimal necessary plugins and disables GPU.
With the ability to fake windows, we will be able to test UI in similar way. So looking forward to your work.

@Shatur
Copy link
Contributor Author

Shatur commented Aug 27, 2023

Solved by ddfafab.

@Shatur Shatur closed this as completed Aug 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Usability A targeted quality-of-life change that makes Bevy easier to use
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants