use std::fmt::Debug;
use bevy::asset::Asset;
use bevy::reflect::Reflect;
use bevy::utils::HashMap;
use serde::{Deserialize, Serialize};
use crate::bindings::InputBinding;
use crate::config::builder::InputConfigBuilder;
#[derive(Debug, Default, Serialize, Deserialize, Asset, Reflect, Clone, PartialEq)]
pub struct InputConfig {
#[serde(default)]
pub double_click_timing: Option<DurationInMillis>,
#[serde(default)]
pub post_acceptance_delay: Option<DurationInMillis>,
#[serde(default)]
pub bindings: HashMap<String, HashMap<String, Vec<InputBinding>>>,
}
pub type DurationInMillis = u64;
impl InputConfig {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn builder() -> InputConfigBuilder {
InputConfigBuilder::default()
}
#[must_use]
pub fn merge(&self, other: &InputConfig) -> Self {
let mut value = self.clone();
for (group_id, action_id, action) in other.bindings.iter().flat_map(|(group_id, group)| {
group
.iter()
.map(move |(action_id, action)| (group_id, action_id, action))
}) {
let actions = value.bindings.entry(group_id.clone()).or_default();
let bindings = actions.entry(action_id.clone()).or_default();
bindings.clear();
bindings.append(&mut action.clone());
}
if other.post_acceptance_delay.is_some() {
value.post_acceptance_delay = other.post_acceptance_delay;
}
if other.double_click_timing.is_some() {
value.double_click_timing = other.double_click_timing;
}
value
}
}