* # LeafwingInputManager handling inputs in FixedUpdate
## Background
The leafwing flow is:d
- PreUpdate:
- tick every action from `just_pressed` to `pressed` (let's call this `consuming` the input)
- read from the Input events (emitted every frame) to update the ActionState to `just_pressed` for new inputs
## Problem
We cannot reliably use
`if action.just_pressed()` in `FixedUpdate` systems because:
1. in some cases,`FixedUpdate` runs 2 times in the same frame, which means that they would both had `just_pressed() = True` which is misleading
situation 1 (S1): `F - FU - FU - F`
2. in some cases, `FixedUpdate` runs 0 times in one frame, which means that `just_pressed` becomes `pressed` and the input is never seen by the FixedUpdate system.
situation 2 (S2): `F - F - FU - F`
```
Glossary:
- `F` = `Frame start`
- `FU` = `FixedUpdate start`
```
## Prior work
Relevant bevy issues:
- input events don't have timestamp information [Issue](https://github.com/bevyengine/bevy/issues/5984). This doesn't seem really related. It would solve the problem of disambiguating input order within a single frame.
- inputs can be missed in FixedTimeStep [Issue](https://github.com/bevyengine/bevy/issues/6183): relevant.
The issue talks a lot about fixing this problem for bevy `Events` in general, which is not really what interests us in leafwing. In leafwing, all events are read correctly at the start of the frame, and used to update the `ActionState`. The problem is rather: "at what point do we make an action go from `just_pressed` to `pressed`"?
## What we want
Solve:
1. After a `FixedUpdate` system runs, we want the input to be `consumed`
2. An input must always be seen by a FixedUpdate system; i.e. I want the input to be considered as 'consumed' (`just_pressed`->`pressed`) only if the `FixedUpdate` system saw it once.
Other invariants we want to uphold:
- An input is `just_pressed` only if it's also `pressed`.
```
NOTE: This means that we could still miss inputs if we are in the situation:
`InputPress - F - InputRelease - F - FU - F`
On the `FixedUpdate` run, the button is not pressed anymore so we don't want to have `just_pressed = True`.
(i.e. the button press happened in a single frame, and no FixedUpdate schedule ran during that frame) That should be pretty rare because normally a button press lasts for more than a frame. The real solution is having timestamped inputs as described in [Issue](https://github.com/bevyengine/bevy/issues/5984).
```
## Potential solutions
#### Run leafwing systems in FixedPreUpdate and FixedPostUpdate
This would solve 1.
Problem: an input emitted on the first frame of S2 would get lost, since the leafwing systems would not run for that frame.
This forces users to handle inputs in FixedUpdate, which is not ideal (ideally both Update and FixedUpdate could be used)
#### Just_pressed = input happened since the last time I asked
Currently, `just_pressed` = input happened on this frame, since all inputs are consumed at the beginning of the next frame.
This might not be the definition that we want. Instead what is often useful is:
- `pressed` = give me all inputs that are pressed right now (for example if a user keeps pressing a button)
- `just_pressed` = give me all the button presses that happened since the last time I asked. (which makes sense if FixedUpdate or F)
This could be implemented by storing the WorldTick when the input was emitted, and then `just_pressed` would return all events where the input's tick is more recent than the last run of the system.
(Or maybe the implementation could be more simple, with just two button_states (one for Update and one for FixedUpdate). And two separate `consume` systems.)
Let's see how this would do in the two faulty situations:
- In `InputPress - F - FU - FU - F - InputRelease - F`, the first `F` and `FU` would have `just_pressed` for that input, which is what we want.
- In `InputPress - F - F - FU - InputRelease - F`, the first `F` and `FU` would have `just_pressed` for that input, which is what we want.
How do we update the API?
As for the API, I guess we could have 2 just_pressed, one for FixedUpdate and one for Update; the first one is updated in PreUpdate by comparing the ticks.
The second one is updated in FixedPreUpdate by comparing the tick as mentioned above.
To make this more ergonomic, we could make both `just_pressed` accessible behind the same API, depending on which schedule is running. (similar to the `Time` plugin).
This behavior should also be overridable.