playcanvas / engine

JavaScript game engine built on WebGL, WebGPU, WebXR and glTF
https://playcanvas.com
MIT License
9.59k stars 1.34k forks source link

Mouse events during frame update #6110

Open LeXXik opened 7 months ago

LeXXik commented 7 months ago

At the moment the mouse/touch event callbacks are executed immediately on browser detecting those. This makes it hard to fence a logic that depends on those events, as they are fired outside of the application update loop.

Since we (end users) are not subscribing to the window events directly, but listening for the application to tell us when an event happened, the application could fire them at a proper time during the frame update instead, in line with its update logic. We can then use its frameend event as a guarantee that all systems and all inputs have been processed and the application is done updating the frame.

Maksims commented 7 months ago

The problem that can happen is when multiple events are triggered within one frame. So timings between these events - should not be relied on in such cases. Also, the event-based nature of the mouse/touch is not as "friendly" with gamedev. Due to that, I've created "mr-Tap" library that allows you to access taps in a sync manner. It is designed in such a way that it covers the mouse and touch, and using iterators your application will be multi-touch out of the box.

LeXXik commented 3 months ago

@Maksims I suppose such a library would only cover half the use cases. I think the engine would still fire UI button events as soon as those are detected, so we'd still have to write some sort of pooler to collect those and fire together with other touch events.

Maksims commented 3 months ago

@Maksims I suppose such a library would only cover half the use cases. I think the engine would still fire UI button events as soon as those are detected, so we'd still have to write some sort of pooler to collect those and fire together with other touch events.

Yep. For that it would require not to create: Mouse, Keyboard and TouchDevice on App, and instead create own that implements similar events and provides them to UI component systems.

marklundin commented 3 months ago

Would it not make sense to just debounce the listener?

Maksims commented 3 months ago

Would it not make sense to just debounce the listener?

No. The whole concept of accessing mouse/touch data in events - is a problem. Instead it would be convenient to access that data in sync maner.

We've been using mr-Taps in pretty much every project for years, making multi-touch, input-agnostic, sync access to input data a breeze. And it solves plenty of complex issues. Although UI is still based on async events.

Also in gamedev it is common to do things in sync during update, instead of splitting logic in async methods. Which also complicates the order of execution and control of it by the developer.

Basically: sync access to input - is great and solves a lot of complex issues.