Skip to main content

ferroui_base/input/
input_manager.rs

1use super::raw::IRawInputEventArgs;
2use super::IInputManager;
3use crate::reactive::{IObservable, IObserver, LightweightSubject};
4use crate::{FerroLocator, LocatorExtensions};
5use std::rc::Rc;
6
7type RawSubject = LightweightSubject<Rc<dyn IRawInputEventArgs>>;
8
9/// Receives input from the windowing subsystem and dispatches it to
10/// interested parties for processing.
11pub struct InputManager {
12    pre_process: RawSubject,
13    process: RawSubject,
14    post_process: RawSubject,
15}
16
17impl Default for InputManager {
18    fn default() -> Self {
19        Self::new()
20    }
21}
22
23impl InputManager {
24    /// Creates an input manager.
25    pub fn new() -> Self {
26        Self {
27            pre_process: LightweightSubject::new(),
28            process: LightweightSubject::new(),
29            post_process: LightweightSubject::new(),
30        }
31    }
32
33    /// The input manager registered with the locator.
34    pub fn instance() -> Option<Rc<dyn IInputManager>> {
35        FerroLocator::current().get_service::<dyn IInputManager>()
36    }
37
38    /// Completes the observables of the input manager.
39    pub fn dispose(&self) {
40        self.pre_process.on_completed();
41        self.process.on_completed();
42        self.post_process.on_completed();
43    }
44}
45
46impl IInputManager for InputManager {
47    fn pre_process(&self) -> Rc<dyn IObservable<Rc<dyn IRawInputEventArgs>>> {
48        Rc::new(self.pre_process.clone())
49    }
50
51    fn process(&self) -> Rc<dyn IObservable<Rc<dyn IRawInputEventArgs>>> {
52        Rc::new(self.process.clone())
53    }
54
55    fn post_process(&self) -> Rc<dyn IObservable<Rc<dyn IRawInputEventArgs>>> {
56        Rc::new(self.post_process.clone())
57    }
58
59    fn process_input(&self, e: Rc<dyn IRawInputEventArgs>) {
60        self.pre_process.on_next(e.clone());
61        e.device().process_raw_event(&*e);
62        self.process.on_next(e.clone());
63        self.post_process.on_next(e);
64    }
65}