use itertools::sorted;
use crate::{
EmmitableEvent,
EventsMeasurer,
NameOfEvent,
NodeKey,
PotentialEvent,
PotentialEvents,
SourceEvent,
};
pub fn measure_source_global_events<
Key: NodeKey,
Name: NameOfEvent,
Source: SourceEvent<Name = Name>,
Emmitable: EmmitableEvent<Key = Key, Name = Name>,
>(
events_measurer: &impl EventsMeasurer<
Key = Key,
Name = Name,
Emmitable = Emmitable,
Source = Source,
>,
source_events: &Vec<Source>,
emmitable_events: &mut Vec<Emmitable>,
) {
for source_event in source_events {
let event_name = source_event.as_event_name();
let derived_events_names = event_name.get_derived_events();
for derived_event_name in derived_events_names {
for global_event_name in derived_event_name.get_global_events() {
let listeners = events_measurer.get_listeners_of(&global_event_name);
for listener in listeners {
let event = events_measurer.new_emmitable_event(
listener,
global_event_name,
source_event.clone(),
None,
);
emmitable_events.push(event)
}
}
}
}
}
pub fn measure_potential_events<
Key: NodeKey,
Name: NameOfEvent,
Source: SourceEvent<Name = Name>,
Emmitable: EmmitableEvent<Key = Key, Name = Name>,
>(
source_events: &Vec<Source>,
events_measurer: &impl EventsMeasurer<
Key = Key,
Name = Name,
Emmitable = Emmitable,
Source = Source,
>,
focus_id: Option<Key>,
) -> PotentialEvents<Key, Name, Source> {
let mut potential_events = PotentialEvents::default();
for (layer, layer_nodes) in sorted(events_measurer.get_layers()) {
for node_id in layer_nodes.iter() {
for source_event in source_events {
let Some(cursor) = source_event.try_cursor() else {
if focus_id == Some(*node_id) {
let potential_event = PotentialEvent {
node_key: *node_id,
layer: *layer,
name: source_event.as_event_name(),
source_event: source_event.clone(),
};
potential_events
.entry(source_event.as_event_name())
.or_default()
.push(potential_event);
}
continue;
};
if !events_measurer.is_point_inside(*node_id, cursor) {
continue;
}
let potential_event = PotentialEvent {
node_key: *node_id,
layer: *layer,
name: source_event.as_event_name(),
source_event: source_event.clone(),
};
potential_events
.entry(source_event.as_event_name())
.or_insert_with(Vec::new)
.push(potential_event);
}
}
}
potential_events
}
pub fn measure_emmitable_events<
Key: NodeKey,
Name: NameOfEvent,
Source: SourceEvent<Name = Name>,
Emmitable: EmmitableEvent,
>(
potential_events: &PotentialEvents<Key, Name, Source>,
events_measurer: &impl EventsMeasurer<
Key = Key,
Name = Name,
Emmitable = Emmitable,
Source = Source,
>,
) -> Vec<Emmitable> {
let mut emmitable_events = Vec::new();
for (event, potential_events) in potential_events {
let derived_events_names = event
.get_derived_events()
.into_iter()
.filter(|event| !event.is_global());
'event: for derived_event_name in derived_events_names {
let mut child_node: Option<Key> = None;
for PotentialEvent {
node_key: node_id,
name,
source_event,
..
} in potential_events.iter().rev()
{
if let Some(child_node) = child_node {
if !events_measurer.is_node_parent_of(child_node, *node_id) {
continue;
}
}
if events_measurer.is_listening_to(*node_id, &derived_event_name) {
let area = events_measurer.try_area_of(*node_id);
if let Some(area) = area {
let emmitable_event = events_measurer.new_emmitable_event(
*node_id,
derived_event_name,
source_event.clone(),
Some(area),
);
emmitable_events.push(emmitable_event);
if name.does_bubble() {
continue 'event;
}
}
}
if !events_measurer.is_node_transparent(*node_id) && !name.does_go_through_solid() {
child_node = Some(*node_id);
}
}
}
}
emmitable_events
}