Avoid triggering change detection for inputs (#6847)
# Objective Fix #5292. ## Solution Avoid derefencing when clearing to ensure that change detection is not triggered when there is nothing to clear.
This commit is contained in:
parent
b37a6ca9a2
commit
0d67c32153
@ -1,6 +1,9 @@
|
|||||||
use crate::{Axis, Input};
|
use crate::{Axis, Input};
|
||||||
use bevy_ecs::event::{EventReader, EventWriter};
|
use bevy_ecs::event::{EventReader, EventWriter};
|
||||||
use bevy_ecs::system::{Res, ResMut, Resource};
|
use bevy_ecs::{
|
||||||
|
change_detection::DetectChanges,
|
||||||
|
system::{Res, ResMut, Resource},
|
||||||
|
};
|
||||||
use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect};
|
use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect};
|
||||||
use bevy_utils::{tracing::info, HashMap};
|
use bevy_utils::{tracing::info, HashMap};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@ -1160,7 +1163,7 @@ pub fn gamepad_event_system(
|
|||||||
mut events: EventWriter<GamepadEvent>,
|
mut events: EventWriter<GamepadEvent>,
|
||||||
settings: Res<GamepadSettings>,
|
settings: Res<GamepadSettings>,
|
||||||
) {
|
) {
|
||||||
button_input.clear();
|
button_input.bypass_change_detection().clear();
|
||||||
for event in raw_events.iter() {
|
for event in raw_events.iter() {
|
||||||
match &event.event_type {
|
match &event.event_type {
|
||||||
GamepadEventType::Connected(_) => {
|
GamepadEventType::Connected(_) => {
|
||||||
|
|||||||
@ -34,6 +34,13 @@ use bevy_ecs::schedule::State;
|
|||||||
/// * Call the [`Input::press`] method for each press event.
|
/// * Call the [`Input::press`] method for each press event.
|
||||||
/// * Call the [`Input::release`] method for each release event.
|
/// * Call the [`Input::release`] method for each release event.
|
||||||
/// * Call the [`Input::clear`] method at each frame start, before processing events.
|
/// * Call the [`Input::clear`] method at each frame start, before processing events.
|
||||||
|
///
|
||||||
|
/// Note: Calling `clear` from a [`ResMut`] will trigger change detection.
|
||||||
|
/// It may be preferable to use [`DetectChanges::bypass_change_detection`]
|
||||||
|
/// to avoid causing the resource to always be marked as changed.
|
||||||
|
///
|
||||||
|
///[`ResMut`]: bevy_ecs::system::ResMut
|
||||||
|
///[`DetectChanges::bypass_change_detection`]: bevy_ecs::change_detection::DetectChanges::bypass_change_detection
|
||||||
#[derive(Debug, Clone, Resource, Reflect)]
|
#[derive(Debug, Clone, Resource, Reflect)]
|
||||||
#[reflect(Default)]
|
#[reflect(Default)]
|
||||||
pub struct Input<T: Copy + Eq + Hash + Send + Sync + 'static> {
|
pub struct Input<T: Copy + Eq + Hash + Send + Sync + 'static> {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{ButtonState, Input};
|
use crate::{ButtonState, Input};
|
||||||
use bevy_ecs::{event::EventReader, system::ResMut};
|
use bevy_ecs::{change_detection::DetectChanges, event::EventReader, system::ResMut};
|
||||||
use bevy_reflect::{FromReflect, Reflect};
|
use bevy_reflect::{FromReflect, Reflect};
|
||||||
|
|
||||||
#[cfg(feature = "serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
@ -41,8 +41,9 @@ pub fn keyboard_input_system(
|
|||||||
mut key_input: ResMut<Input<KeyCode>>,
|
mut key_input: ResMut<Input<KeyCode>>,
|
||||||
mut keyboard_input_events: EventReader<KeyboardInput>,
|
mut keyboard_input_events: EventReader<KeyboardInput>,
|
||||||
) {
|
) {
|
||||||
scan_input.clear();
|
// Avoid clearing if it's not empty to ensure change detection is not triggered.
|
||||||
key_input.clear();
|
scan_input.bypass_change_detection().clear();
|
||||||
|
key_input.bypass_change_detection().clear();
|
||||||
for event in keyboard_input_events.iter() {
|
for event in keyboard_input_events.iter() {
|
||||||
let KeyboardInput {
|
let KeyboardInput {
|
||||||
scan_code, state, ..
|
scan_code, state, ..
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{ButtonState, Input};
|
use crate::{ButtonState, Input};
|
||||||
use bevy_ecs::{event::EventReader, system::ResMut};
|
use bevy_ecs::{change_detection::DetectChanges, event::EventReader, system::ResMut};
|
||||||
use bevy_math::Vec2;
|
use bevy_math::Vec2;
|
||||||
use bevy_reflect::{FromReflect, Reflect};
|
use bevy_reflect::{FromReflect, Reflect};
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ pub fn mouse_button_input_system(
|
|||||||
mut mouse_button_input: ResMut<Input<MouseButton>>,
|
mut mouse_button_input: ResMut<Input<MouseButton>>,
|
||||||
mut mouse_button_input_events: EventReader<MouseButtonInput>,
|
mut mouse_button_input_events: EventReader<MouseButtonInput>,
|
||||||
) {
|
) {
|
||||||
mouse_button_input.clear();
|
mouse_button_input.bypass_change_detection().clear();
|
||||||
for event in mouse_button_input_events.iter() {
|
for event in mouse_button_input_events.iter() {
|
||||||
match event.state {
|
match event.state {
|
||||||
ButtonState::Pressed => mouse_button_input.press(event.button),
|
ButtonState::Pressed => mouse_button_input.press(event.button),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user