fix previous_position / previous_force being discarded too early (#12556)
# Objective Fixes #12442 ## Solution Change `process_touch_event` to not update previous_position / previous_force, and change it once per frame in `touch_screen_input_system`.
This commit is contained in:
parent
891c2f1203
commit
aa477028ef
@ -373,8 +373,9 @@ impl Touches {
|
|||||||
}
|
}
|
||||||
TouchPhase::Moved => {
|
TouchPhase::Moved => {
|
||||||
if let Some(mut new_touch) = self.pressed.get(&event.id).cloned() {
|
if let Some(mut new_touch) = self.pressed.get(&event.id).cloned() {
|
||||||
new_touch.previous_position = new_touch.position;
|
// NOTE: This does not update the previous_force / previous_position field;
|
||||||
new_touch.previous_force = new_touch.force;
|
// they should be updated once per frame, not once per event
|
||||||
|
// See https://github.com/bevyengine/bevy/issues/12442
|
||||||
new_touch.position = event.position;
|
new_touch.position = event.position;
|
||||||
new_touch.force = event.force;
|
new_touch.force = event.force;
|
||||||
self.pressed.insert(event.id, new_touch);
|
self.pressed.insert(event.id, new_touch);
|
||||||
@ -427,8 +428,15 @@ pub fn touch_screen_input_system(
|
|||||||
touch_state.just_canceled.clear();
|
touch_state.just_canceled.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in touch_input_events.read() {
|
if !touch_input_events.is_empty() {
|
||||||
touch_state.process_touch_event(event);
|
for touch in touch_state.pressed.values_mut() {
|
||||||
|
touch.previous_position = touch.position;
|
||||||
|
touch.previous_force = touch.force;
|
||||||
|
}
|
||||||
|
|
||||||
|
for event in touch_input_events.read() {
|
||||||
|
touch_state.process_touch_event(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,6 +559,69 @@ mod test {
|
|||||||
assert_ne!(touch.previous_position, touch.position);
|
assert_ne!(touch.previous_position, touch.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See https://github.com/bevyengine/bevy/issues/12442
|
||||||
|
#[test]
|
||||||
|
fn touch_process_multi_event() {
|
||||||
|
use crate::{touch::TouchPhase, TouchInput, Touches};
|
||||||
|
use bevy_ecs::entity::Entity;
|
||||||
|
use bevy_math::Vec2;
|
||||||
|
|
||||||
|
let mut touches = Touches::default();
|
||||||
|
|
||||||
|
let started_touch_event = TouchInput {
|
||||||
|
phase: TouchPhase::Started,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
force: None,
|
||||||
|
id: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
let moved_touch_event1 = TouchInput {
|
||||||
|
phase: TouchPhase::Moved,
|
||||||
|
position: Vec2::splat(5.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
force: None,
|
||||||
|
id: started_touch_event.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let moved_touch_event2 = TouchInput {
|
||||||
|
phase: TouchPhase::Moved,
|
||||||
|
position: Vec2::splat(6.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
force: None,
|
||||||
|
id: started_touch_event.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
// tick 1: touch is started during frame
|
||||||
|
for touch in touches.pressed.values_mut() {
|
||||||
|
// update ONCE, at start of frame
|
||||||
|
touch.previous_position = touch.position;
|
||||||
|
}
|
||||||
|
touches.process_touch_event(&started_touch_event);
|
||||||
|
touches.process_touch_event(&moved_touch_event1);
|
||||||
|
touches.process_touch_event(&moved_touch_event2);
|
||||||
|
|
||||||
|
{
|
||||||
|
let touch = touches.get_pressed(started_touch_event.id).unwrap();
|
||||||
|
assert_eq!(touch.previous_position, started_touch_event.position);
|
||||||
|
assert_eq!(touch.position, moved_touch_event2.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tick 2: touch was started before frame
|
||||||
|
for touch in touches.pressed.values_mut() {
|
||||||
|
touch.previous_position = touch.position;
|
||||||
|
}
|
||||||
|
touches.process_touch_event(&moved_touch_event1);
|
||||||
|
touches.process_touch_event(&moved_touch_event2);
|
||||||
|
touches.process_touch_event(&moved_touch_event1);
|
||||||
|
|
||||||
|
{
|
||||||
|
let touch = touches.get_pressed(started_touch_event.id).unwrap();
|
||||||
|
assert_eq!(touch.previous_position, moved_touch_event2.position);
|
||||||
|
assert_eq!(touch.position, moved_touch_event1.position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn touch_pressed() {
|
fn touch_pressed() {
|
||||||
use crate::{touch::TouchPhase, TouchInput, Touches};
|
use crate::{touch::TouchPhase, TouchInput, Touches};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user