Skip to content

Commit

Permalink
Update outdated docs and simplify internal code (#607)
Browse files Browse the repository at this point in the history
* Update outdated docs and simplify internal code

* Fix CI

* minor
  • Loading branch information
Shute052 authored Aug 25, 2024
1 parent c15d0e6 commit 020435d
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 296 deletions.
79 changes: 23 additions & 56 deletions src/action_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub enum ActionDiff<A: Actionlike> {
DualAxisChanged {
/// The value of the action
action: A,
/// The new value of the axis
/// The new value of the axes
axis_pair: Vec2,
},
}
Expand Down Expand Up @@ -179,15 +179,13 @@ impl<A: Actionlike> SummarizedActionState<A> {
let previous_button = previous_button.unwrap_or_default();
let current_button = current_button?;

if previous_button != current_button {
(previous_button != current_button).then(|| {
if current_button {
Some(ActionDiff::Pressed { action })
ActionDiff::Pressed { action }
} else {
Some(ActionDiff::Released { action })
ActionDiff::Released { action }
}
} else {
None
}
})
}

/// Generates an [`ActionDiff`] for axis data,
Expand All @@ -202,14 +200,10 @@ impl<A: Actionlike> SummarizedActionState<A> {
let previous_axis = previous_axis.unwrap_or_default();
let current_axis = current_axis?;

if previous_axis != current_axis {
Some(ActionDiff::AxisChanged {
action,
value: current_axis,
})
} else {
None
}
(previous_axis != current_axis).then(|| ActionDiff::AxisChanged {
action,
value: current_axis,
})
}

/// Generates an [`ActionDiff`] for dual axis data,
Expand All @@ -222,29 +216,18 @@ impl<A: Actionlike> SummarizedActionState<A> {
let previous_dual_axis = previous_dual_axis.unwrap_or_default();
let current_dual_axis = current_dual_axis?;

if previous_dual_axis != current_dual_axis {
Some(ActionDiff::DualAxisChanged {
action,
axis_pair: current_dual_axis,
})
} else {
None
}
(previous_dual_axis != current_dual_axis).then(|| ActionDiff::DualAxisChanged {
action,
axis_pair: current_dual_axis,
})
}

/// Generates all [`ActionDiff`]s for a single entity.
pub fn entity_diffs(
&self,
previous_button_state: Option<&HashMap<A, bool>>,
current_button_state: Option<&HashMap<A, bool>>,
previous_axis_state: Option<&HashMap<A, f32>>,
current_axis_state: Option<&HashMap<A, f32>>,
previous_dual_axis_state: Option<&HashMap<A, Vec2>>,
current_dual_axis_state: Option<&HashMap<A, Vec2>>,
) -> Vec<ActionDiff<A>> {
pub fn entity_diffs(&self, entity: &Entity, previous: &Self) -> Vec<ActionDiff<A>> {
let mut action_diffs = Vec::new();

if let Some(current_button_state) = current_button_state {
if let Some(current_button_state) = self.button_state_map.get(entity) {
let previous_button_state = previous.button_state_map.get(entity);
for (action, current_button) in current_button_state {
let previous_button = previous_button_state
.and_then(|previous_button_state| previous_button_state.get(action))
Expand All @@ -258,7 +241,8 @@ impl<A: Actionlike> SummarizedActionState<A> {
}
}

if let Some(current_axis_state) = current_axis_state {
if let Some(current_axis_state) = self.axis_state_map.get(entity) {
let previous_axis_state = previous.axis_state_map.get(entity);
for (action, current_axis) in current_axis_state {
let previous_axis = previous_axis_state
.and_then(|previous_axis_state| previous_axis_state.get(action))
Expand All @@ -272,7 +256,8 @@ impl<A: Actionlike> SummarizedActionState<A> {
}
}

if let Some(current_dual_axis_state) = current_dual_axis_state {
if let Some(current_dual_axis_state) = self.dual_axis_state_map.get(entity) {
let previous_dual_axis_state = previous.dual_axis_state_map.get(entity);
for (action, current_dual_axis) in current_dual_axis_state {
let previous_dual_axis = previous_dual_axis_state
.and_then(|previous_dual_axis_state| previous_dual_axis_state.get(action))
Expand All @@ -294,27 +279,9 @@ impl<A: Actionlike> SummarizedActionState<A> {
/// Compares the current frame to the previous frame, generates [`ActionDiff`]s and then sends them as batched [`ActionDiffEvent`]s.
pub fn send_diffs(&self, previous: &Self, writer: &mut EventWriter<ActionDiffEvent<A>>) {
for entity in self.all_entities() {
let owner = if entity == Entity::PLACEHOLDER {
None
} else {
Some(entity)
};

let previous_button_state = previous.button_state_map.get(&entity);
let current_button_state = self.button_state_map.get(&entity);
let previous_axis_state = previous.axis_state_map.get(&entity);
let current_axis_state = self.axis_state_map.get(&entity);
let previous_dual_axis_state = previous.dual_axis_state_map.get(&entity);
let current_dual_axis_state = self.dual_axis_state_map.get(&entity);

let action_diffs = self.entity_diffs(
previous_button_state,
current_button_state,
previous_axis_state,
current_axis_state,
previous_dual_axis_state,
current_dual_axis_state,
);
let owner = (entity != Entity::PLACEHOLDER).then_some(entity);

let action_diffs = self.entity_diffs(&entity, previous);

if !action_diffs.is_empty() {
writer.send(ActionDiffEvent {
Expand Down
4 changes: 2 additions & 2 deletions src/action_state/action_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,13 @@ pub struct AxisData {
pub fixed_update_value: f32,
}

/// The raw data for an [`ActionState`](super::ActionState) corresponding to a pair of virtual axes.
/// The raw data for an [`ActionState`](super::ActionState) corresponding to a pair of virtual axes.
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
pub struct DualAxisData {
/// The XY coordinates of the axis
pub pair: Vec2,
/// The `pair` of the action in the `Main` schedule
pub update_pair: Vec2,
/// The `value` of the action in the `FixedMain` schedule
/// The `pair` of the action in the `FixedMain` schedule
pub fixed_update_pair: Vec2,
}
16 changes: 8 additions & 8 deletions src/action_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ impl<A: Actionlike> ActionState<A> {

match self.action_data(action) {
Some(action_data) => match action_data.kind_data {
ActionKindData::DualAxis(ref axis_data) => Some(axis_data),
ActionKindData::DualAxis(ref dual_axis_data) => Some(dual_axis_data),
_ => None,
},
None => None,
Expand All @@ -412,12 +412,12 @@ impl<A: Actionlike> ActionState<A> {
///
/// # Caution
///
/// To insert a default [`ButtonData`] if it doesn't exist,
/// To insert a default [`DualAxisData`] if it doesn't exist,
/// use [`dual_axis_data_mut_or_default`](Self::dual_axis_data_mut_or_default) method.
///
/// # Returns
///
/// - `Some(ButtonData)` if it exists.
/// - `Some(DualAxisData)` if it exists.
/// - `None` if the `action` has never been triggered (pressed, clicked, etc.).
#[inline]
#[must_use]
Expand All @@ -433,7 +433,7 @@ impl<A: Actionlike> ActionState<A> {
}
}

/// A mutable reference of the [`ButtonData`] corresponding to the `action` initializing it if needed.
/// A mutable reference of the [`DualAxisData`] corresponding to the `action` initializing it if needed.
///
/// If the `action` has no data yet (because the `action` has not been triggered),
/// this method will create and insert a default [`DualAxisData`] for you,
Expand All @@ -448,7 +448,7 @@ impl<A: Actionlike> ActionState<A> {

let action_data = self.action_data_mut_or_default(action);
let ActionKindData::DualAxis(ref mut dual_axis_data) = action_data.kind_data else {
panic!("{action:?} is not a Dual Axis");
panic!("{action:?} is not a DualAxis");
};
dual_axis_data
}
Expand Down Expand Up @@ -500,14 +500,14 @@ impl<A: Actionlike> ActionState<A> {
/// # Warning
///
/// This value will be 0. by default,
/// even if the action is not a axislike action.
/// even if the action is not an axislike action.
pub fn clamped_value(&self, action: &A) -> f32 {
self.value(action).clamp(-1., 1.)
}

/// Get the [`Vec2`] from the binding that triggered the corresponding `action`.
///
/// Only events that represent dual-axis control provide an [`Vec2`],
/// Only events that represent dual-axis control provide a [`Vec2`],
/// and this will return [`None`] for other events.
///
/// If multiple inputs with an axis pair trigger the same game action at the same time, the
Expand Down Expand Up @@ -548,7 +548,7 @@ impl<A: Actionlike> ActionState<A> {
/// even if the action is not a dual-axislike action.
pub fn clamped_axis_pair(&self, action: &A) -> Vec2 {
let pair = self.axis_pair(action);
Vec2::new(pair.x.clamp(-1.0, 1.0), pair.y.clamp(-1.0, 1.0))
pair.clamp(Vec2::NEG_ONE, Vec2::ONE)
}

/// Manually sets the [`ButtonData`] of the corresponding `action`
Expand Down
8 changes: 4 additions & 4 deletions src/input_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,18 +630,18 @@ impl<A: Actionlike> InputMap<A> {
)
}
InputControlKind::Axis => {
let buttonlike = self.axislike_map.get(action)?;
let axislike = self.axislike_map.get(action)?;
Some(
buttonlike
axislike
.iter()
.map(|input| UserInputWrapper::Axis(input.clone()))
.collect(),
)
}
InputControlKind::DualAxis => {
let buttonlike = self.dual_axislike_map.get(action)?;
let dual_axislike = self.dual_axislike_map.get(action)?;
Some(
buttonlike
dual_axislike
.iter()
.map(|input| UserInputWrapper::DualAxis(input.clone()))
.collect(),
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub mod prelude {
///
/// # Customizing variant behavior
///
/// By default, The derive macro for this trait assumes that all actions are buttonlike.
/// By default, the derive macro for this trait assumes that all actions are buttonlike.
///
/// You can customize this behavior by using the `#[actionlike]` attribute,
/// either on the entire enum or on individual variants.
Expand All @@ -97,9 +97,9 @@ pub mod prelude {
/// enum CameraAction {
/// Zoom, // This action is controlled by axes
/// #[actionlike(DualAxis)]
/// Move, // This action is controlled by dual axes since we have overrode the default option
/// Move, // This action is controlled by dual axes since we have overridden the default option
/// #[actionlike(Button)]
/// TakePhoto, // This action is controlled by buttons since we have override the default option
/// TakePhoto, // This action is controlled by buttons since we have overridden the default option
/// }
/// ```
pub trait Actionlike:
Expand Down
26 changes: 5 additions & 21 deletions src/user_input/chord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ use super::{Axislike, DualAxislike};
/// A combined input that groups multiple [`Buttonlike`]s together,
/// allowing you to define complex input combinations like hotkeys, shortcuts, and macros.
///
/// # Behaviors
/// A chord is pressed only if all its constituent buttons are pressed simultaneously.
///
/// - Activation: All included inputs must be active simultaneously.
/// - Deduplication: Adding duplicate inputs within a chord will ignore the extras,
/// preventing redundant data fetching.
/// Adding duplicate buttons within a chord will ignore the extras,
/// preventing redundant data fetching from multiple instances of the same input.
///
/// ```rust
/// use bevy::prelude::*;
Expand Down Expand Up @@ -61,9 +60,6 @@ impl ButtonlikeChord {
/// Creates a [`ButtonlikeChord`] from multiple [`Buttonlike`]s, avoiding duplicates.
/// Note that all elements within the iterator must be of the same type (homogeneous).
/// You can still use other methods to add different types of inputs into the chord.
///
/// This ensures that the same input isn't added multiple times,
/// preventing redundant data fetching from multiple instances of the same input.
#[inline]
pub fn new<U: Buttonlike>(inputs: impl IntoIterator<Item = U>) -> Self {
Self::default().with_multiple(inputs)
Expand All @@ -83,9 +79,6 @@ impl ButtonlikeChord {
}

/// Adds the given [`Buttonlike`] into this chord, avoiding duplicates.
///
/// This ensures that the same input isn't added multiple times,
/// preventing redundant data fetching from multiple instances of the same input.
#[inline]
pub fn with(mut self, input: impl Buttonlike) -> Self {
self.push_boxed_unique(Box::new(input));
Expand All @@ -94,9 +87,6 @@ impl ButtonlikeChord {

/// Adds multiple [`Buttonlike`]s into this chord, avoiding duplicates.
/// Note that all elements within the iterator must be of the same type (homogeneous).
///
/// This ensures that the same input isn't added multiple times,
/// preventing redundant data fetching from multiple instances of the same input.
#[inline]
pub fn with_multiple<U: Buttonlike>(mut self, inputs: impl IntoIterator<Item = U>) -> Self {
for input in inputs.into_iter() {
Expand All @@ -106,9 +96,6 @@ impl ButtonlikeChord {
}

/// Adds the given boxed dyn [`Buttonlike`] to this chord, avoiding duplicates.
///
/// This ensures that the same input isn't added multiple times,
/// preventing redundant data fetching from multiple instances of the same input.
#[inline]
fn push_boxed_unique(&mut self, input: Box<dyn Buttonlike>) {
if !self.0.contains(&input) {
Expand Down Expand Up @@ -178,9 +165,6 @@ impl<U: Buttonlike> FromIterator<U> for ButtonlikeChord {
/// Creates a [`ButtonlikeChord`] from an iterator over multiple [`Buttonlike`]s, avoiding duplicates.
/// Note that all elements within the iterator must be of the same type (homogeneous).
/// You can still use other methods to add different types of inputs into the chord.
///
/// This ensures that the same input isn't added multiple times,
/// preventing redundant data fetching from multiple instances of the same input.
#[inline]
fn from_iter<T: IntoIterator<Item = U>>(iter: T) -> Self {
Self::default().with_multiple(iter)
Expand Down Expand Up @@ -247,14 +231,14 @@ impl Axislike for AxislikeChord {
#[derive(Debug, Clone, PartialEq, Eq, Hash, Reflect, Serialize, Deserialize)]
#[must_use]
pub struct DualAxislikeChord {
/// The button that must be pressed to read the axis value.
/// The button that must be pressed to read the axis values.
pub button: Box<dyn Buttonlike>,
/// The dual axis data that is read when the button is pressed.
pub dual_axis: Box<dyn DualAxislike>,
}

impl DualAxislikeChord {
/// Creates a new [`AxislikeChord`] from the given [`Buttonlike`] and [`Axislike`].
/// Creates a new [`DualAxislikeChord`] from the given [`Buttonlike`] and [`DualAxislike`].
#[inline]
pub fn new(button: impl Buttonlike, dual_axis: impl DualAxislike) -> Self {
Self {
Expand Down
Loading

0 comments on commit 020435d

Please sign in to comment.