leafwing_input_manager/
systems.rs1use crate::prelude::updating::CentralInputStore;
4use bevy::ecs::query::QueryFilter;
5use bevy::log::debug;
6
7use crate::{
8 Actionlike, action_state::ActionState, clashing_inputs::ClashStrategy, input_map::InputMap,
9};
10
11use bevy::ecs::prelude::*;
12use bevy::input::gamepad::Gamepad;
13use bevy::{
14 platform::time::Instant,
15 time::{Real, Time},
16};
17
18use crate::action_diff::{ActionDiffMessage, SummarizedActionState};
19
20pub fn swap_to_update<A: Actionlike>(mut query: Query<&mut ActionState<A>>) {
24 for mut action_state in query.iter_mut() {
25 action_state.swap_to_update_state();
26 }
27}
28
29pub fn swap_to_fixed_update<A: Actionlike>(mut query: Query<&mut ActionState<A>>) {
33 for mut action_state in query.iter_mut() {
34 action_state.swap_to_fixed_update_state();
35 }
36}
37
38pub fn tick_action_state<A: Actionlike>(
43 mut query: Query<&mut ActionState<A>>,
44 time: Res<Time<Real>>,
45 mut stored_previous_instant: Local<Option<Instant>>,
46) {
47 let current_instant = time.last_update().unwrap_or_else(|| time.startup());
49 let previous_instant = stored_previous_instant.unwrap_or_else(|| time.startup());
50
51 for mut action_state in query.iter_mut() {
53 action_state.tick(current_instant, previous_instant);
56 }
57
58 *stored_previous_instant = time.last_update();
60}
61
62pub fn update_action_state<A: Actionlike>(
67 input_store: Res<CentralInputStore>,
68 clash_strategy: Res<ClashStrategy>,
69 mut gamepads: Query<Entity, With<Gamepad>>,
70 mut query: Query<(&mut ActionState<A>, &InputMap<A>)>,
71) {
72 for (mut action_state, input_map) in query.iter_mut() {
73 action_state.update(input_map.process_actions(
74 Some(gamepads.reborrow()),
75 &input_store,
76 *clash_strategy,
77 ));
78 }
79}
80
81pub fn generate_action_diffs<A: Actionlike>(
87 action_state_query: Query<(Entity, &ActionState<A>)>,
88 previous_action_state: Local<SummarizedActionState<A>>,
89 action_diff_messages: MessageWriter<ActionDiffMessage<A>>,
90) {
91 generate_action_diffs_filtered(
92 action_state_query,
93 previous_action_state,
94 action_diff_messages,
95 )
96}
97
98pub fn generate_action_diffs_filtered<A: Actionlike, F: QueryFilter>(
106 action_state_query: Query<(Entity, &ActionState<A>), F>,
107 mut previous_action_state: Local<SummarizedActionState<A>>,
108 mut action_diff_messages: MessageWriter<ActionDiffMessage<A>>,
109) {
110 let current_action_state = SummarizedActionState::summarize_filtered(action_state_query);
111 current_action_state.send_diffs(&previous_action_state, &mut action_diff_messages);
112 debug!("previous_action_state: {:?}", previous_action_state);
113 debug!("current_action_state: {:?}", current_action_state);
114 *previous_action_state = current_action_state;
115}
116
117pub fn release_on_input_map_removed<A: Actionlike>(
123 mut removed_components: RemovedComponents<InputMap<A>>,
124 mut action_state_query: Query<&mut ActionState<A>>,
125) {
126 let mut iter = action_state_query.iter_many_mut(removed_components.read());
127 while let Some(mut action_state) = iter.fetch_next() {
128 action_state.reset_all();
129 }
130}
131
132pub fn clear_central_input_store(mut input_store: ResMut<CentralInputStore>) {
135 input_store.clear();
136}