ignore (but print a warning about) invalid action ids in the config file, instead of failing to deserialize and reverting to default

This commit is contained in:
Crispy 2025-04-13 23:26:06 +02:00
parent 7222993156
commit 5f5a831569
2 changed files with 15 additions and 6 deletions

View file

@ -7,6 +7,7 @@ Game store page: https://crispypin.itch.io/marble-machinations
- click to collapse chapters in level list - click to collapse chapters in level list
- input bindings for eraser (X), selection (B), blueprint list (Ctrl B), no tool (no default binding) - input bindings for eraser (X), selection (B), blueprint list (Ctrl B), no tool (no default binding)
### fixed ### fixed
- invalid action ids in the config file key bindings caused everything to revert to default.
- when start and stop are bound to the same thing (as by default), only start works - when start and stop are bound to the same thing (as by default), only start works
- When two input bindings had the same trigger but one has a strict subset of the others modifiers, both would activate when the one with more modifiers was pressed. For example (Ctrl+S -> Save) would also trigger (S -> Wire Tool). Now, Shift+S will still trigger Wire Tool, unless Shift+S (or eg. Shift+Ctrl+S) is bound to something else. - When two input bindings had the same trigger but one has a strict subset of the others modifiers, both would activate when the one with more modifiers was pressed. For example (Ctrl+S -> Save) would also trigger (S -> Wire Tool). Now, Shift+S will still trigger Wire Tool, unless Shift+S (or eg. Shift+Ctrl+S) is bound to something else.

View file

@ -110,7 +110,7 @@ enum BindingState {
Released, Released,
} }
type InputMap = BTreeMap<ActionId, Vec<Binding>>; type InputMap = BTreeMap<String, Vec<Binding>>;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(from = "InputMap", into = "InputMap")] #[serde(from = "InputMap", into = "InputMap")]
@ -390,10 +390,15 @@ pub struct Binding {
} }
impl From<InputMap> for Input { impl From<InputMap> for Input {
fn from(value: InputMap) -> Self { fn from(map: InputMap) -> Self {
let mut new = Self::default(); let mut new = Self::default();
for (action, loaded_bindings) in value { for (action, loaded_bindings) in map {
new.bindings[action as usize] = loaded_bindings; let temp_json = format!("\"{action}\"");
if let Ok(action) = serde_json::from_str::<ActionId>(&temp_json) {
new.bindings[action as usize] = loaded_bindings;
} else {
println!("'{action}' is not a valid action id, bindings discarded");
}
} }
new new
} }
@ -405,8 +410,11 @@ impl From<Input> for InputMap {
.bindings .bindings
.iter() .iter()
.enumerate() .enumerate()
// for this to panic, the .bindings array would have to be larger than ActionId::SIZE .map(|(i, b)| {
.map(|(i, b)| (ActionId::from_usize(i).unwrap(), b.clone())) // for this to panic, the .bindings array would have to be larger than ActionId::SIZE
let action = ActionId::from_usize(i).unwrap();
(format!("{action:?}"), b.clone())
})
.collect() .collect()
} }
} }