1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
//! This module contains [`PressScheduler`] and its supporting methods and impls.
//!
//! The [`PressScheduler`] is an optional addition to an [`InputManagerBundle`](crate::InputManagerBundle),
//! which allows for a system that runs in [`Update`] later to correctly press an action.
//! Directly using [`ActionState::press`] would not work, as inputs submitted late would be wiped out by the input manager systems.
//! With this type, the action is pressed on the next time said systems run, making it so other systems can react to it correctly.
use std::marker::PhantomData;
use bevy::prelude::*;
use fixedbitset::FixedBitSet;
use crate::{prelude::ActionState, Actionlike};
/// Allows for scheduling an action to be pressed for the next frame
#[derive(Component, Resource)]
pub struct PressScheduler<A: Actionlike> {
bitset: FixedBitSet,
_phantom: PhantomData<A>,
}
impl<A: Actionlike> Default for PressScheduler<A> {
fn default() -> Self {
Self {
bitset: FixedBitSet::with_capacity(A::n_variants()),
_phantom: Default::default(),
}
}
}
impl<A: Actionlike> PressScheduler<A> {
/// Schedule a press for this action for the next frame
/// The action will be pressed the next time [`crate::systems::update_action_state`] runs.
pub fn schedule_press(&mut self, action: A) {
self.bitset.set(action.index(), true);
}
/// Applies the scheduled presses to the given [`ActionState`]
pub fn apply(&mut self, action_state: &mut ActionState<A>) {
for i in self.bitset.ones() {
action_state.press(A::get_at(i).unwrap())
}
self.bitset.clear();
}
}