use bevy::prelude::{Component, DetectChanges, Entity, EntityRef, Query, Without};
#[derive(Debug, Component, Default)]
pub struct SharedTextSegment;
#[derive(Debug, Component, Default)]
pub struct FetchedTextSegment(pub String);
impl FetchedTextSegment {
pub const EMPTY: Self = Self(String::new());
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
#[derive(Component)]
#[require(FetchedTextSegment)]
pub struct TextFetch {
entity: Entity,
fetch: Box<dyn FnMut(EntityRef) -> Option<String> + Send + Sync>,
}
impl TextFetch {
pub fn fetch_component<C: Component>(
entity: Entity,
mut fetch: impl (FnMut(&C) -> String) + Send + Sync + 'static,
) -> Self {
TextFetch {
entity,
fetch: Box::new(move |entity: EntityRef| {
if let Some(component) = entity.get_ref::<C>() {
if component.is_changed() {
return Some(fetch(&component));
}
}
None
}),
}
}
pub fn fetch_entity_ref(
entity: Entity,
fetch: impl (FnMut(EntityRef) -> Option<String>) + Send + Sync + 'static,
) -> Self {
TextFetch {
entity,
fetch: Box::new(fetch),
}
}
}
pub fn text_fetch_system(
mut channels: Query<(&mut TextFetch, &mut FetchedTextSegment)>,
other: Query<EntityRef, Without<TextFetch>>,
) {
for (mut channel, mut text) in channels.iter_mut() {
if let Ok(entity_ref) = other.get(channel.entity) {
if let Some(output) = (channel.fetch)(entity_ref) {
text.0 = output;
}
}
}
}