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
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use crate::ButtonId;
use crate::{ModifierFilterMask, ModifierId, ModifierMask};
use std::collections::HashMap;

/// State of a button
#[derive(Clone, Default, Debug)]
struct ButtonState {
    /// Reset button automatically in prepare pass (ex: used for mouse move to reset axis when mouse is not moved)
    autoreset: bool,

    /// Required modifier mask
    modifier_mask: ModifierFilterMask,

    /// Current value in the [-1,1] range
    value: f32,
}

/// Store the current input state
pub struct State {
    time: u128,                              // The last update time
    cursore_position: (f32, f32),            // Cursore poisition on the normalize [0,1]^2 screen
    modifier_mask: ModifierMask,             // Current modifiers
    autoreset_modifiers: ModifierMask,       // Autoreset modifiers
    buttons: HashMap<ButtonId, ButtonState>, // State of the buttons
}

impl State {
    pub fn new() -> State {
        State {
            time: 0,
            cursore_position: (0., 0.),
            modifier_mask: ModifierMask::default(),
            autoreset_modifiers: ModifierMask::default(),
            buttons: HashMap::new(),
        }
    }

    pub fn clear(&mut self) {
        self.buttons.clear();
        self.modifier_mask.clear();
        self.autoreset_modifiers.clear();
        self.time = 0;
        self.cursore_position = (0., 0.);
    }

    /// Copy the previous state
    pub fn prepare(&mut self, prev: &State, time: u128) {
        self.clear();

        self.time = time;

        self.modifier_mask = ModifierMask::from_masked_clear(&prev.modifier_mask, &prev.autoreset_modifiers);

        self.buttons.clear();
        for (k, j) in prev.buttons.iter() {
            if j.autoreset {
                continue;
            }

            self.buttons.insert(*k, j.clone());
        }
    }

    pub fn get_time(&self) -> u128 {
        self.time
    }

    pub fn set_modifier(&mut self, modifier_id: ModifierId, pressed: bool, autoreset: bool) {
        self.modifier_mask.set(modifier_id, pressed);
        self.autoreset_modifiers.set(modifier_id, autoreset);
    }

    pub fn is_modifier(&self, modifier_id: ModifierId) -> bool {
        self.modifier_mask.get(modifier_id)
    }

    pub fn remove_button(&mut self, button_id: ButtonId) {
        let _ = self.buttons.remove(&button_id);
    }

    pub fn set_button(&mut self, button_id: ButtonId, modifier_mask: ModifierFilterMask, value: f32, autoreset: bool) {
        // clamp input to [-1,1]
        let value = if value > 1. {
            1.
        } else if value < -1. {
            -1.
        } else {
            value
        };

        if value == 0. {
            self.remove_button(button_id);
        } else {
            let entry = self.buttons.entry(button_id);
            let mut state = entry.or_insert_with(ButtonState::default);
            state.value = value;
            state.modifier_mask = modifier_mask;
            state.autoreset = autoreset;
        }
    }

    pub fn get_button(&self, button_id: ButtonId) -> f32 {
        match self.buttons.get(&button_id) {
            None => 0.,
            Some(ref s) => {
                log::trace!("s: {:?}", s);
                if s.modifier_mask.check(&self.modifier_mask) {
                    s.value
                } else {
                    0.
                }
            }
        }
    }

    pub fn is_button(&self, button_id: ButtonId) -> bool {
        self.get_button(button_id) != 0.
    }
}

impl Default for State {
    fn default() -> Self {
        State::new()
    }
}