ragnarok/
executor.rs

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
126
127
128
129
130
131
132
use crate::{
    EmmitableEvent,
    NameOfEvent,
    NodeKey,
    NodesState,
    NodesStatesUpdate,
    PotentialEvent,
    SourceEvent,
};

#[derive(Clone, Debug, PartialEq)]
pub struct ProcessedEvents<
    Key: NodeKey,
    Name: NameOfEvent,
    Emmitable: EmmitableEvent,
    Source: SourceEvent,
> {
    pub emmitable_events: Vec<Emmitable>,
    pub flattened_potential_events: Vec<PotentialEvent<Key, Name, Source>>,
    pub nodes_states_update: NodesStatesUpdate<Key>,
}

impl<Key: NodeKey, Name: NameOfEvent, Emmitable: EmmitableEvent, Source: SourceEvent> Default
    for ProcessedEvents<Key, Name, Emmitable, Source>
{
    fn default() -> Self {
        Self {
            emmitable_events: Vec::default(),
            flattened_potential_events: Vec::default(),
            nodes_states_update: NodesStatesUpdate::default(),
        }
    }
}

pub trait EventsExecutor
where
    Self: std::marker::Sized,
{
    type Name: NameOfEvent;
    type Key: NodeKey;
    type Emmitable: EmmitableEvent<Key = Self::Key, Name = Self::Name>;
    type Source: SourceEvent;

    /// Call the event handler of the given [Self::Emmitable].
    fn emit_event(&mut self, event: Self::Emmitable) -> bool;

    // All events have been emitted
    fn emitted_events(&mut self) {}
}

impl<T: EventsExecutor> private::Sealed for T {}

impl<T: EventsExecutor + private::Sealed> EventsExecutorRunner for T {
    type Name = T::Name;
    type Key = T::Key;
    type Emmitable = T::Emmitable;
    type Source = T::Source;
    fn run(
        mut self,
        nodes_state: &mut NodesState<Self::Key>,
        ProcessedEvents {
            mut emmitable_events,
            flattened_potential_events,
            mut nodes_states_update,
        }: ProcessedEvents<Self::Key, Self::Name, Self::Emmitable, Self::Source>,
    ) {
        let mut processed_events = Vec::<Self::Emmitable>::new();

        #[cfg(debug_assertions)]
        tracing::info!("Processing {} DOM events", emmitable_events.len());

        while !emmitable_events.is_empty() {
            let emmitable_event = emmitable_events.remove(0);

            let default_action_enabled = self.emit_event(emmitable_event.clone());

            if !default_action_enabled {
                // Get the events that this event can cancel
                let cancellable_events = emmitable_event.name().get_cancellable_events();

                // Remove the rest of emmitable events that are cancellable
                emmitable_events.retain(|event| !cancellable_events.contains(&event.name()));

                // Discard the potential events that dont find a matching emmitable event
                // So for instance, a cancelled potential mousemove event wont be discarded if a emmitable mousenter was processed before
                // At the same time, a cancelled potential mousemove event that actually gets discarded will only discard the node state
                // made in this run, but will not change what was already before this run
                // So if the affected node was already being hovered from the last events run, it will continue to be as so
                for potential_event in &flattened_potential_events {
                    let is_cancellable = cancellable_events.contains(&potential_event.name);
                    if is_cancellable {
                        let processed_event = processed_events.iter().find(|event| {
                            potential_event.name == event.source()
                                && potential_event.node_key == event.key()
                        });
                        if processed_event.is_none() {
                            nodes_states_update
                                .discard(&potential_event.name, &potential_event.node_key);
                        }
                    }
                }
            }

            processed_events.push(emmitable_event);
        }

        self.emitted_events();

        nodes_state.apply_update(nodes_states_update);
    }
}

pub trait EventsExecutorRunner: private::Sealed
where
    Self: std::marker::Sized,
{
    type Name: NameOfEvent;
    type Key: NodeKey;
    type Emmitable: EmmitableEvent<Key = Self::Key, Name = Self::Name>;
    type Source: SourceEvent;

    fn run(
        self,
        nodes_state: &mut NodesState<Self::Key>,
        processed_events: ProcessedEvents<Self::Key, Self::Name, Self::Emmitable, Self::Source>,
    );
}

#[doc(hidden)]
mod private {
    pub trait Sealed {}
}