Skip to main content

ragnarok/
measurement.rs

1use itertools::Itertools;
2
3use crate::{
4    EmmitableEvent,
5    EventsMeasurer,
6    NameOfEvent,
7    NodeKey,
8    PotentialEvent,
9    PotentialEvents,
10    SourceEvent,
11};
12
13/// For every source event and its derived events, a global equivalent event is emitted.
14pub fn measure_source_global_events<
15    Key: NodeKey,
16    Name: NameOfEvent,
17    Source: SourceEvent<Name = Name>,
18    Emmitable: EmmitableEvent<Key = Key, Name = Name>,
19>(
20    events_measurer: &impl EventsMeasurer<
21        Key = Key,
22        Name = Name,
23        Emmitable = Emmitable,
24        Source = Source,
25    >,
26    source_events: &Vec<Source>,
27    emmitable_events: &mut Vec<Emmitable>,
28) {
29    for source_event in source_events {
30        let event_name = source_event.as_event_name();
31        let derived_events_names = event_name.get_derived_events();
32
33        for derived_event_name in derived_events_names {
34            for global_event_name in derived_event_name.get_global_events() {
35                let listeners = events_measurer.get_listeners_of(&global_event_name);
36
37                for listener in listeners {
38                    let event = events_measurer.new_emmitable_event(
39                        *listener,
40                        global_event_name,
41                        source_event.clone(),
42                        None,
43                    );
44                    emmitable_events.push(event)
45                }
46            }
47        }
48    }
49}
50
51/// Measure what event listeners could potentially be triggered
52pub fn measure_potential_events<
53    Key: NodeKey,
54    Name: NameOfEvent,
55    Source: SourceEvent<Name = Name>,
56    Emmitable: EmmitableEvent<Key = Key, Name = Name>,
57>(
58    source_events: &Vec<Source>,
59    events_measurer: &impl EventsMeasurer<
60        Key = Key,
61        Name = Name,
62        Emmitable = Emmitable,
63        Source = Source,
64    >,
65    focus_id: Option<Key>,
66) -> PotentialEvents<Key, Name, Source> {
67    let mut potential_events = PotentialEvents::default();
68
69    // Walk layer by layer from the bottom to the top
70    for (layer, layer_nodes) in events_measurer
71        .get_layers()
72        .sorted_by(|(layer, _), (layer_b, _)| layer.cmp(layer_b))
73    {
74        for node_id in layer_nodes {
75            if !events_measurer.is_node_interactive(node_id) {
76                continue;
77            }
78            for source_event in source_events {
79                let Some(cursor) = source_event.try_location() else {
80                    if focus_id == Some(*node_id) {
81                        let potential_event = PotentialEvent {
82                            node_key: *node_id,
83                            layer: *layer,
84                            name: source_event.as_event_name(),
85                            source_event: source_event.clone(),
86                        };
87                        potential_events
88                            .entry(source_event.as_event_name())
89                            .or_default()
90                            .push(potential_event);
91                    }
92                    continue;
93                };
94
95                if !events_measurer.is_point_inside(node_id, cursor) {
96                    continue;
97                }
98
99                let potential_event = PotentialEvent {
100                    node_key: *node_id,
101                    layer: *layer,
102                    name: source_event.as_event_name(),
103                    source_event: source_event.clone(),
104                };
105
106                potential_events
107                    .entry(source_event.as_event_name())
108                    .or_insert_with(Vec::new)
109                    .push(potential_event);
110            }
111        }
112    }
113
114    potential_events
115}
116
117/// Measure what events could be emitted
118pub fn measure_emmitable_events<
119    Key: NodeKey,
120    Name: NameOfEvent,
121    Source: SourceEvent<Name = Name>,
122    Emmitable: EmmitableEvent,
123>(
124    potential_events: &PotentialEvents<Key, Name, Source>,
125    events_measurer: &impl EventsMeasurer<
126        Key = Key,
127        Name = Name,
128        Emmitable = Emmitable,
129        Source = Source,
130    >,
131) -> Vec<Emmitable> {
132    let mut emmitable_events = Vec::new();
133
134    for (event, potential_events) in potential_events {
135        // Get the derived events, but exclude globals like some file events
136        let derived_events_names = event
137            .get_derived_events()
138            .into_iter()
139            .filter(|event| !event.is_global());
140
141        // Iterate over the derived events (including the source)
142        'event: for derived_event_name in derived_events_names {
143            let mut child_node: Option<Key> = None;
144
145            // Iterate over the potential events in reverse so the ones in higher layers appeat first
146            for PotentialEvent {
147                node_key,
148                name,
149                source_event,
150                ..
151            } in potential_events.iter().rev()
152            {
153                if let Some(child_node) = child_node
154                    && !events_measurer.is_node_parent_of(&child_node, *node_key)
155                {
156                    continue;
157                }
158
159                if events_measurer.is_listening_to(node_key, &derived_event_name) {
160                    let area = events_measurer.try_area_of(node_key);
161                    if let Some(area) = area {
162                        let emmitable_event = events_measurer.new_emmitable_event(
163                            *node_key,
164                            derived_event_name,
165                            source_event.clone(),
166                            Some(area),
167                        );
168                        emmitable_events.push(emmitable_event);
169
170                        // Only emit once for the deepest matching listener.
171                        if derived_event_name.is_emitted_once() {
172                            continue 'event;
173                        }
174                    }
175                }
176
177                if !events_measurer.is_node_transparent(node_key) && !name.does_go_through_solid() {
178                    // If the background isn't transparent,
179                    // we must make sure that next nodes are parent of it
180                    // This only matters for events that bubble up (e.g. cursor click events)
181                    child_node = Some(*node_key);
182                }
183            }
184        }
185    }
186
187    emmitable_events
188}