use bevy::ecs::query::{QueryData, QueryItem, ROQueryItem};
use bevy::ecs::system::SystemParam;
use bevy::prelude::*;
use crate::render::NoesisView;
#[derive(SystemParam)]
pub struct NoesisUi<'w, 's, D: QueryData + 'static = ()> {
view: Query<'w, 's, (Entity, D), With<NoesisView>>,
}
impl<'w, 's, D: QueryData + 'static> NoesisUi<'w, 's, D> {
pub fn entity(&self) -> Option<Entity> {
self.view.single().ok().map(|(entity, _)| entity)
}
pub fn get(&self) -> Option<ROQueryItem<'_, 's, D>> {
self.view.single().ok().map(|(_, data)| data)
}
pub fn get_mut(&mut self) -> Option<QueryItem<'_, 's, D>> {
self.view.single_mut().ok().map(|(_, data)| data)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::render::NoesisView;
use crate::text::NoesisText;
fn write_score(mut ui: NoesisUi<&mut NoesisText>) {
if let Some(mut text) = ui.get_mut() {
text.write("Score", "42");
}
}
fn record_entity(ui: NoesisUi, mut out: ResMut<SeenEntity>) {
out.0 = ui.entity();
}
#[derive(Resource, Default)]
struct SeenEntity(Option<Entity>);
#[test]
fn resolves_single_view_entity_and_component() {
let mut app = App::new();
app.init_resource::<SeenEntity>();
let view = app
.world_mut()
.spawn((
NoesisView {
xaml_uri: "x.xaml".to_string(),
..default()
},
NoesisText::new(),
))
.id();
app.add_systems(Update, (write_score, record_entity));
app.update();
assert_eq!(app.world().resource::<SeenEntity>().0, Some(view));
let text = app.world().entity(view).get::<NoesisText>().unwrap();
assert_eq!(text.set.get("Score").map(String::as_str), Some("42"));
}
#[test]
fn none_when_no_view() {
let mut app = App::new();
app.init_resource::<SeenEntity>();
app.add_systems(Update, record_entity);
app.update();
assert_eq!(app.world().resource::<SeenEntity>().0, None);
}
}