feat: bindings deduplication

This commit is contained in:
2026-09-05 04:13:44 +00:00
parent a75fb650e3
commit d80bd8b03a
+40 -4
View File
@@ -495,10 +495,16 @@ impl<Gs: GameState> Default for Bindings<Gs> {
impl<Gs: GameState> Bindings<Gs> { impl<Gs: GameState> Bindings<Gs> {
pub fn new(bindings: Vec<Binding<Gs>>) -> Self { pub fn new(bindings: Vec<Binding<Gs>>) -> Self {
Self { let mut result = Self {
list: bindings, list: Vec::with_capacity(bindings.len()),
..Default::default() ..Default::default()
};
// To avoid duplicates
for binding in bindings {
result.force_push(binding);
} }
result
} }
pub fn customizable(mut self) -> Self { pub fn customizable(mut self) -> Self {
@@ -517,6 +523,9 @@ impl<Gs: GameState> Bindings<Gs> {
} }
pub fn force_push(&mut self, binding: Binding<Gs>) { pub fn force_push(&mut self, binding: Binding<Gs>) {
if self.list.contains(&binding) {
return;
}
self.list.push(binding); self.list.push(binding);
} }
@@ -525,7 +534,7 @@ impl<Gs: GameState> Bindings<Gs> {
warn!("You try to push binding to immutable bindings"); warn!("You try to push binding to immutable bindings");
return; return;
} }
self.list.push(binding); self.force_push(binding);
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {
@@ -716,9 +725,16 @@ impl<A: Action, Gs: GameState> Controls<A, Gs> {
} }
} }
#[cfg(all(test, feature = "logical-keyboard"))] #[cfg(all(
test,
feature = "logical-keyboard",
not(feature = "serialize"),
not(feature = "reflect"),
not(feature = "inspector-egui")
))]
mod tests { mod tests {
use super::*; use super::*;
use bevy_state::state::States;
#[test] #[test]
fn keyboard_variants_are_distinct() { fn keyboard_variants_are_distinct() {
@@ -727,4 +743,24 @@ mod tests {
assert_ne!(physical, logical); assert_ne!(physical, logical);
} }
#[derive(States, PartialEq, Eq, Clone, Hash, Debug, Default)]
enum TestState {
#[default]
Playing,
}
impl crate::contract::GameState for TestState {}
#[test]
fn bindings_reject_duplicates() {
let binding: Binding<TestState> =
Binding::from_single(InputType::Keyboard(Keyboard::KeyCode(KeyCode::KeyH)));
let mut bindings = Bindings::new(vec![binding.clone(), binding.clone()]).customizable();
bindings.push(binding.clone());
bindings.force_push(binding);
assert_eq!(bindings.iter().count(), 1);
}
} }