use crate::prelude::updating::CentralInputStore;
use bevy::ecs::query::QueryFilter;
use bevy::log::debug;
use crate::{
Actionlike, action_state::ActionState, clashing_inputs::ClashStrategy, input_map::InputMap,
};
use bevy::ecs::prelude::*;
use bevy::input::gamepad::Gamepad;
use bevy::{
platform::time::Instant,
time::{Real, Time},
};
use crate::action_diff::{ActionDiffMessage, SummarizedActionState};
pub fn swap_to_update<A: Actionlike>(mut query: Query<&mut ActionState<A>>) {
for mut action_state in query.iter_mut() {
action_state.swap_to_update_state();
}
}
pub fn swap_to_fixed_update<A: Actionlike>(mut query: Query<&mut ActionState<A>>) {
for mut action_state in query.iter_mut() {
action_state.swap_to_fixed_update_state();
}
}
pub fn tick_action_state<A: Actionlike>(
mut query: Query<&mut ActionState<A>>,
time: Res<Time<Real>>,
mut stored_previous_instant: Local<Option<Instant>>,
) {
let current_instant = time.last_update().unwrap_or_else(|| time.startup());
let previous_instant = stored_previous_instant.unwrap_or_else(|| time.startup());
for mut action_state in query.iter_mut() {
action_state.tick(current_instant, previous_instant);
}
*stored_previous_instant = time.last_update();
}
pub fn update_action_state<A: Actionlike>(
input_store: Res<CentralInputStore>,
clash_strategy: Res<ClashStrategy>,
mut gamepads: Query<Entity, With<Gamepad>>,
mut query: Query<(&mut ActionState<A>, &InputMap<A>)>,
) {
for (mut action_state, input_map) in query.iter_mut() {
action_state.update(input_map.process_actions(
Some(gamepads.reborrow()),
&input_store,
*clash_strategy,
));
}
}
pub fn generate_action_diffs<A: Actionlike>(
action_state_query: Query<(Entity, &ActionState<A>)>,
previous_action_state: Local<SummarizedActionState<A>>,
action_diff_messages: MessageWriter<ActionDiffMessage<A>>,
) {
generate_action_diffs_filtered(
action_state_query,
previous_action_state,
action_diff_messages,
)
}
pub fn generate_action_diffs_filtered<A: Actionlike, F: QueryFilter>(
action_state_query: Query<(Entity, &ActionState<A>), F>,
mut previous_action_state: Local<SummarizedActionState<A>>,
mut action_diff_messages: MessageWriter<ActionDiffMessage<A>>,
) {
let current_action_state = SummarizedActionState::summarize_filtered(action_state_query);
current_action_state.send_diffs(&previous_action_state, &mut action_diff_messages);
debug!("previous_action_state: {:?}", previous_action_state);
debug!("current_action_state: {:?}", current_action_state);
*previous_action_state = current_action_state;
}
pub fn release_on_input_map_removed<A: Actionlike>(
mut removed_components: RemovedComponents<InputMap<A>>,
mut action_state_query: Query<&mut ActionState<A>>,
) {
let mut iter = action_state_query.iter_many_mut(removed_components.read());
while let Some(mut action_state) = iter.fetch_next() {
action_state.reset_all();
}
}
pub fn clear_central_input_store(mut input_store: ResMut<CentralInputStore>) {
input_store.clear();
}