bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.04k stars 3.44k forks source link

Allow winit event loop to be recreated on web / wasm #12562

Open phisn opened 5 months ago

phisn commented 5 months ago

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

When using Bevy in web currently it is not possible to run bevy multiple times. This is especially important in hybrid application that use Bevy only in game or multiple bevy instances.

A similar issue was mentioned here 12195 in the bevy repo. The proposed solution there is not suited for my usecase since it makes communication between the iframe and the host application difficult to impossible.

What solution would you like?

There exists an already implemented feature in winit solving the same problem I showed. The related issue is 2897 and 2720 in the winit repo. It should be possible to use this feature similarly to how conditionally already some features of android and co are used in the bevy winit plugin.

What alternative(s) have you considered?

Currently there seems at least in the bevy side of things no other solution. It might be possible to completely shutdown wasm and load the bevy application completely from scratch. But these solution seem hacky on not like good solutions.

SolarLiner commented 5 months ago

I'm not too familiar with Bevy's handling of the even loop, but being familiar with winit itself it looks to me to be impossible.

The error comes from here, and the method it originates from is pretty clear that the event loop is to only be created once per application, for cross-platform reasons.

From the implementation it seems like a workaround would be to fully unload the WASM module and re-instantiate it, but the check is there for a reason and there may be unintended consequences.

phisn commented 5 months ago

I think that is not quite right. The code you mentioned does look at an atomic boolean. It can be turned false again to allow reinstantiation in the web implementation of winit. This is done when the event loop is started with spawn instead of run.

I think this is true because the bevy winit code also mentions that it should use spawn on wasm platforms instead of run in the future here. As far as I understand this would solve the problem.

The meaning of spawn is also mentioned here.

SolarLiner commented 5 months ago

I didn't know about spawn, it indeed seems to be made exactly for this use-case.