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

Custom loop runner #1377

Open
codec-abc opened this issue Feb 1, 2021 · 13 comments
Open

Custom loop runner #1377

codec-abc opened this issue Feb 1, 2021 · 13 comments
Labels
A-Core Common functionality for all bevy apps C-Bug An unexpected or incorrect behavior P-Crash A sudden unexpected crash

Comments

@codec-abc
Copy link

Bevy version

0.4.0

Operating system & version

Windows 10 and building for WASM

What you did

I tried to use a custom runner for Bevy under WASM. I had a simple program that worked until I tried to modify the code use a custom runner as shown in this sample. A repro project is here. Be cautious: the master branch compile and run just fine while the custom_loop branches contains the change to use a custom runner. And while it compiles it crashes at runtime.

What you expected to happen

Not to crash when using a custom loop runner.

What actually happened

The engine crashed when using a custom

Additional information

Nothing really more to say, except the original goal was to have some kind of interop between Seed (a Rust frontend framework) and Bevy. My goal was to add some HTML UI that can drove the engine and vice versa.

@rparrett
Copy link
Contributor

rparrett commented Feb 1, 2021

#1255 strikes again?

It looks like set_runner needs to be called earlier. (Before bevy_webgl2?)

@codec-abc
Copy link
Author

It seems like changing order of plugin does fix the problem. About the order it seems it need to be set even before add_plugins(DefaultPlugins) otherwise it still crash.

@codec-abc
Copy link
Author

codec-abc commented Feb 2, 2021

I checked the solution given by @rparrett but I don't think it solves the problem. If I put log in the runner function it doesn't show up. Also the call to app.run() does not return control. I did not understand the code and logic behind custom runner yet but if it works exactly the same with or without it, this doesn't seem right.

@rparrett
Copy link
Contributor

rparrett commented Feb 2, 2021

It looks like bevy_winit via DefaultPlugins sets its own runner that probably overwrites the one you are setting.

It's not clear to me why you wouldn't be able to override that one by calling set_runner after DefaultPlugins though. (But sure enough, that panics)

The bevy_winit runner does a bunch of seemingly useful stuff like handling input events, so overriding may or may not be the way to go anyhow depending on your requirements.

@codec-abc
Copy link
Author

Actually what I want is to be able to run the main event loop of the engine myself so my Rust web app can control it. After trying a simpler program it seems to work by just retrieving the App from the AppBuilder and calling update on it. But it only works if I remove the default, rendering and input systems. At which point I have a engine that cannot do rendering nor process input which isn't really useful. So I believe there are 2 issues here:

1- The custom loop is not taken into account if it registered first.
2- Whether we use a custom loop or do the "running" of the main engine loop ourselves, the engine crash complaining about any resources.

Do you share this analysis and do you see a way to make progress from here?

@codec-abc
Copy link
Author

codec-abc commented Feb 3, 2021

Okay after digging some more and a lot of help from the Discord people, the reason why it is crashing is because if I use my own runner I overwrite the one set by winit which take care to manage the rendering context, the input is so on.

So basically, setting a custom loop runner work as intended but I cannot run a Bevy instance externally in a WASM context I need winit to set up a few things to get the 3D, input and so on to work. Unfortunately, I didn't found a way to let the winit plugin yield control to me so I can run the event loop myself.

@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior P-Crash A sudden unexpected crash A-Core Common functionality for all bevy apps labels Feb 16, 2021
@CleanCut
Copy link
Member

(I came to this issue via #1729 ...)

So in essence, you can't actually use a custom runner unless you omit most of Bevy's functionality, because adding a custom runner replaces the custom winit runner that processes rendering and input (just minor stuff 😝).

What's a good way to solve this?

The only thing that comes to my mind is to find some way to add new logic, rather than replace it. Think: a chain of functions to be run in sequence by the runner (rather than replacing the runner). Would that be a viable approach? Are there better ways to solve this need?

@bjorn3
Copy link
Contributor

bjorn3 commented Mar 22, 2021

When using winit, you have to let winit drive the event loop. On many platforms the event loop can't return without tearing it down conpletely or exiting the process. On macOS for example a new NSApplication is created with the given event callback and then it's run method is invoked. This method doesn't finish until the event loop exits completely: https://github.com/rust-windowing/winit/blob/86748fbc681ea070bc37e90a569c192555b402cd/src/platform_impl/macos/event_loop.rs#L176

@bjorn3
Copy link
Contributor

bjorn3 commented Mar 22, 2021

The only thing that comes to my mind is to find some way to add new logic, rather than replace it. Think: a chain of functions to be run in sequence by the runner (rather than replacing the runner). Would that be a viable approach? Are there better ways to solve this need?

That could work I think.

@zicklag
Copy link
Member

zicklag commented Mar 23, 2021

The only thing that comes to my mind is to find some way to add new logic, rather than replace it. Think: a chain of functions to be run in sequence by the runner (rather than replacing the runner). Would that be a viable approach? Are there better ways to solve this need?

Or maybe the runner could receive a closure of vector of closures/function pointers that it is responsible for running every frame? So your runner would be responsible for driving the winit event loop?

@CleanCut
Copy link
Member

CleanCut commented Mar 23, 2021

Hmm. Given that (at least on macOS) the native window function (NSApplication::run()) never returns between frames...and runs its own event loop, I don't see how we could possibly drive the event loop externally, by definition! If that's true, perhaps the custom runner functionality should be documented as "only works without a window" and this issue should be closed.

I think in my case I can reconsider my approach and set up a bevy system to callback into my external application every frame and sync any info it needs to sync, rather than attempting to drive Bevy from the external application.

@CleanCut
Copy link
Member

I got my workaround concept functioning (external, internal), though I had to resort to a lazy_static!{} to pass logic to Bevy systems to execute.

If anyone's curious I'm working on a wrapper over Bevy to simplify the API down to as close to plain Rust concepts as possible (sacrificing performance and features along the way, but adding built-in assets and systems). It's intended to be a simplified game engine for folks just starting to learn Rust to use as a library for practice projects without the need to learn complicated game engine concepts like ECS, etc. It should be a more interesting approach to learning than the old typical "let's make a to do list" or "let's make an account record" project.

I'll stop hijacking the thread now. 😆

@politrons
Copy link

my requirement is to run the event loop but not in the main thread, since this main thread is already used by iOS. Amy idea how complex it would be to configure the wind event loop to run in another thread?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Core Common functionality for all bevy apps C-Bug An unexpected or incorrect behavior P-Crash A sudden unexpected crash
Projects
None yet
Development

No branches or pull requests

7 participants