nightshade 0.53.0

A cross-platform data-oriented game engine.
Documentation
use crate::ecs::world::World;

use crate::prelude::*;
pub fn ui_event_bubble_system(world: &mut World) {
    if !world.resources.retained_ui.visible {
        return;
    }

    world.resources.retained_ui.frame.bubbled_events.clear();

    let events: Vec<crate::ecs::ui::resources::UiEvent> =
        world.resources.retained_ui.events_for_active().to_vec();

    sync_hierarchy_index(world);

    for event in &events {
        if !event.bubbles() {
            continue;
        }
        let target = event.target_entity();
        let mut current = target;

        loop {
            let parent_opt = world
                .get::<freecs::dynamic::ChildOf>(current)
                .map(|child_of| child_of.0);

            let Some(parent) = parent_opt else {
                break;
            };

            world.resources.retained_ui.frame.bubbled_events.push(
                crate::ecs::ui::resources::BubbledUiEvent {
                    event: event.clone(),
                    target,
                    ancestor: parent,
                    stopped: false,
                },
            );

            current = parent;
        }
    }
}

pub fn ui_emit_click_events_system(world: &mut World) {
    if !world.resources.retained_ui.visible {
        return;
    }

    let already_emitted: std::collections::HashSet<freecs::Entity> = world
        .resources
        .retained_ui
        .events_for_active()
        .iter()
        .map(|event| event.target_entity())
        .collect();

    let candidates: Vec<freecs::Entity> = world.ecs.worlds[UI]
        .query_entities(crate::ecs::world::UI_NODE_INTERACTION)
        .collect();

    for entity in candidates {
        if already_emitted.contains(&entity) {
            continue;
        }
        let clicked = world
            .get::<crate::ecs::ui::components::UiNodeInteraction>(entity)
            .is_some_and(|interaction| interaction.clicked);
        if clicked {
            world
                .resources
                .retained_ui
                .events_for_active_mut()
                .push(crate::ecs::ui::resources::UiEvent::ButtonClicked(entity));
        }
    }
}