bevy_dioxus/src/tick.rs

131 lines
3.9 KiB
Rust
Raw Normal View History

2023-12-07 02:46:50 +00:00
use crate::{
2023-12-16 00:53:25 +00:00
apply_mutations::apply_mutations,
2023-12-15 20:36:53 +00:00
deferred_system::DeferredSystemRegistry,
events::EventReaders,
hooks::{EcsContext, EcsSubscriptions},
2023-12-16 20:41:32 +00:00
DioxusUiRoot, UiRoot, UiRoots,
2023-12-07 02:46:50 +00:00
};
use bevy::{
2023-12-07 20:25:02 +00:00
ecs::{
entity::Entity,
2023-12-16 01:04:29 +00:00
world::{Mut, World},
2023-12-07 20:25:02 +00:00
},
hierarchy::Parent,
2023-12-16 20:41:32 +00:00
utils::HashMap,
2023-12-07 02:46:50 +00:00
};
use std::{any::Any, mem, rc::Rc, sync::Arc};
2023-12-07 02:46:50 +00:00
pub fn tick_dioxus_ui(world: &mut World) {
run_deferred_systems(world);
2023-12-16 00:53:25 +00:00
let ui_events = world.resource_scope(|world, mut event_readers: Mut<EventReaders>| {
event_readers.get_dioxus_events(world.resource())
});
2023-12-16 20:41:32 +00:00
let root_entities: HashMap<Entity, DioxusUiRoot> = world
.query::<(Entity, &DioxusUiRoot)>()
2023-12-16 00:53:25 +00:00
.iter(world)
2023-12-16 20:41:32 +00:00
.map(|(entity, ui_root)| (entity, *ui_root))
2023-12-16 00:53:25 +00:00
.collect();
2023-12-07 02:46:50 +00:00
2023-12-16 20:41:32 +00:00
world
.non_send_resource_mut::<UiRoots>()
.retain(|root_entity, _| root_entities.contains_key(root_entity));
for (root_entity, ui_root) in root_entities {
let mut ui_root = world
.non_send_resource_mut::<UiRoots>()
.remove(&root_entity)
.unwrap_or_else(|| UiRoot::new(*ui_root));
dispatch_ui_events(&ui_events, &mut ui_root, world);
schedule_ui_renders_from_ecs_subscriptions(&mut ui_root, world);
2023-12-07 20:57:34 +00:00
2023-12-16 20:41:32 +00:00
render_ui(root_entity, &mut ui_root, world);
2023-12-07 02:46:50 +00:00
2023-12-16 20:41:32 +00:00
world
.non_send_resource_mut::<UiRoots>()
.insert(root_entity, ui_root);
2023-12-07 02:46:50 +00:00
}
}
2023-12-07 02:46:50 +00:00
fn run_deferred_systems(world: &mut World) {
2023-12-07 20:25:02 +00:00
for system_id in mem::take(&mut *world.resource_mut::<DeferredSystemRegistry>().run_queue) {
let _ = world.run_system(system_id);
2023-12-07 02:46:50 +00:00
}
2023-12-07 20:25:02 +00:00
world.resource_scope(|world, mut system_registry: Mut<DeferredSystemRegistry>| {
system_registry.ref_counts.retain(|system_id, ref_count| {
let cleanup = Arc::strong_count(ref_count) == 1;
if cleanup {
world.remove_system(*system_id).unwrap();
}
!cleanup
});
});
2023-12-07 02:46:50 +00:00
}
2023-12-16 00:53:25 +00:00
fn dispatch_ui_events(
events: &Vec<(Entity, &str, Rc<dyn Any>)>,
2023-12-16 20:41:32 +00:00
ui_root: &mut UiRoot,
world: &World,
) {
2023-12-16 00:53:25 +00:00
for (mut target, name, data) in events {
let mut target_element_id = ui_root.bevy_ui_entity_to_element_id.get(&target).copied();
while target_element_id.is_none() {
2023-12-16 01:04:29 +00:00
target = world.entity(target).get::<Parent>().unwrap().get();
2023-12-16 00:53:25 +00:00
target_element_id = ui_root.bevy_ui_entity_to_element_id.get(&target).copied();
}
2023-12-16 20:41:32 +00:00
ui_root
.virtual_dom
.handle_event(name, Rc::clone(data), target_element_id.unwrap(), true);
2023-12-16 00:53:25 +00:00
}
}
2023-12-16 20:41:32 +00:00
fn schedule_ui_renders_from_ecs_subscriptions(ui_root: &mut UiRoot, world: &World) {
let schedule_update = ui_root.virtual_dom.base_scope().schedule_update_any();
2023-12-16 00:53:25 +00:00
let ecs_subscriptions = world.resource::<EcsSubscriptions>();
for scope_id in &*ecs_subscriptions.world_and_queries {
schedule_update(*scope_id);
}
2023-12-16 00:53:25 +00:00
for (resource_id, scope_ids) in &*ecs_subscriptions.resources {
if world.is_resource_changed_by_id(*resource_id) {
for scope_id in scope_ids {
schedule_update(*scope_id);
}
}
}
}
2023-12-16 20:41:32 +00:00
fn render_ui(root_entity: Entity, ui_root: &mut UiRoot, world: &mut World) {
2023-12-16 01:04:29 +00:00
ui_root
.virtual_dom
.base_scope()
2023-12-16 00:53:25 +00:00
.provide_context(EcsContext { world });
2023-12-16 01:04:29 +00:00
if ui_root.needs_rebuild {
apply_mutations(
2023-12-16 20:41:32 +00:00
ui_root.virtual_dom.rebuild(),
2023-12-16 01:04:29 +00:00
&mut ui_root.element_id_to_bevy_ui_entity,
&mut ui_root.bevy_ui_entity_to_element_id,
&mut ui_root.templates,
root_entity,
world,
);
2023-12-16 01:04:29 +00:00
ui_root.needs_rebuild = false;
}
apply_mutations(
2023-12-16 20:41:32 +00:00
ui_root.virtual_dom.render_immediate(),
2023-12-16 01:04:29 +00:00
&mut ui_root.element_id_to_bevy_ui_entity,
&mut ui_root.bevy_ui_entity_to_element_id,
&mut ui_root.templates,
root_entity,
world,
);
2023-12-07 02:46:50 +00:00
}