mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Query::get_unique (#1263)
Adds `get_unique` and `get_unique_mut` to extend the query api and cover a common use case. Also establishes a second impl block where non-core APIs that don't access the internal fields of queries can live.
This commit is contained in:
parent
2c203f7b8f
commit
9d60563adf
3 changed files with 48 additions and 10 deletions
|
@ -7,7 +7,7 @@ use crate::{
|
|||
world::{Mut, World},
|
||||
};
|
||||
use bevy_tasks::TaskPool;
|
||||
use std::any::TypeId;
|
||||
use std::{any::TypeId, fmt::Debug};
|
||||
use thiserror::Error;
|
||||
|
||||
/// Provides scoped access to a World according to a given [WorldQuery] and query filter
|
||||
|
@ -212,6 +212,38 @@ where
|
|||
Err(QueryComponentError::MissingWriteAccess)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn single(&self) -> Result<<Q::Fetch as Fetch<'_>>::Item, QuerySingleError>
|
||||
where
|
||||
Q::Fetch: ReadOnlyFetch,
|
||||
{
|
||||
let mut query = self.iter();
|
||||
let first = query.next();
|
||||
let extra = query.next().is_some();
|
||||
|
||||
match (first, extra) {
|
||||
(Some(r), false) => Ok(r),
|
||||
(None, _) => Err(QuerySingleError::NoEntities(std::any::type_name::<Self>())),
|
||||
(Some(_), _) => Err(QuerySingleError::MultipleEntities(std::any::type_name::<
|
||||
Self,
|
||||
>())),
|
||||
}
|
||||
}
|
||||
|
||||
/// See [`Query::single`]
|
||||
pub fn single_mut(&mut self) -> Result<<Q::Fetch as Fetch<'_>>::Item, QuerySingleError> {
|
||||
let mut query = self.iter_mut();
|
||||
let first = query.next();
|
||||
let extra = query.next().is_some();
|
||||
|
||||
match (first, extra) {
|
||||
(Some(r), false) => Ok(r),
|
||||
(None, _) => Err(QuerySingleError::NoEntities(std::any::type_name::<Self>())),
|
||||
(Some(_), _) => Err(QuerySingleError::MultipleEntities(std::any::type_name::<
|
||||
Self,
|
||||
>())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that occurs when retrieving a specific [Entity]'s component from a [Query]
|
||||
|
@ -226,3 +258,11 @@ pub enum QueryComponentError {
|
|||
#[error("The requested entity does not exist.")]
|
||||
NoSuchEntity,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum QuerySingleError {
|
||||
#[error("No entities fit the query {0}")]
|
||||
NoEntities(&'static str),
|
||||
#[error("Multiple entities fit the query {0}!")]
|
||||
MultipleEntities(&'static str),
|
||||
}
|
||||
|
|
|
@ -357,9 +357,8 @@ fn rotate_bonus(game: Res<Game>, time: Res<Time>, mut transforms: Query<&mut Tra
|
|||
|
||||
// update the score displayed during the game
|
||||
fn scoreboard_system(game: Res<Game>, mut query: Query<&mut Text>) {
|
||||
for mut text in query.iter_mut() {
|
||||
text.sections[0].value = format!("Sugar Rush: {}", game.score);
|
||||
}
|
||||
let mut text = query.single_mut().unwrap();
|
||||
text.sections[0].value = format!("Sugar Rush: {}", game.score);
|
||||
}
|
||||
|
||||
// restart the game when pressing spacebar
|
||||
|
|
|
@ -174,7 +174,7 @@ fn paddle_movement_system(
|
|||
keyboard_input: Res<Input<KeyCode>>,
|
||||
mut query: Query<(&Paddle, &mut Transform)>,
|
||||
) {
|
||||
for (paddle, mut transform) in query.iter_mut() {
|
||||
if let Ok((paddle, mut transform)) = query.single_mut() {
|
||||
let mut direction = 0.0;
|
||||
if keyboard_input.pressed(KeyCode::Left) {
|
||||
direction -= 1.0;
|
||||
|
@ -196,15 +196,14 @@ fn ball_movement_system(time: Res<Time>, mut ball_query: Query<(&Ball, &mut Tran
|
|||
// clamp the timestep to stop the ball from escaping when the game starts
|
||||
let delta_seconds = f32::min(0.2, time.delta_seconds());
|
||||
|
||||
for (ball, mut transform) in ball_query.iter_mut() {
|
||||
if let Ok((ball, mut transform)) = ball_query.single_mut() {
|
||||
transform.translation += ball.velocity * delta_seconds;
|
||||
}
|
||||
}
|
||||
|
||||
fn scoreboard_system(scoreboard: Res<Scoreboard>, mut query: Query<&mut Text>) {
|
||||
for mut text in query.iter_mut() {
|
||||
text.sections[1].value = scoreboard.score.to_string();
|
||||
}
|
||||
let mut text = query.single_mut().unwrap();
|
||||
text.sections[0].value = format!("Score: {}", scoreboard.score);
|
||||
}
|
||||
|
||||
fn ball_collision_system(
|
||||
|
@ -213,7 +212,7 @@ fn ball_collision_system(
|
|||
mut ball_query: Query<(&mut Ball, &Transform, &Sprite)>,
|
||||
collider_query: Query<(Entity, &Collider, &Transform, &Sprite)>,
|
||||
) {
|
||||
for (mut ball, ball_transform, sprite) in ball_query.iter_mut() {
|
||||
if let Ok((mut ball, ball_transform, sprite)) = ball_query.single_mut() {
|
||||
let ball_size = sprite.size;
|
||||
let velocity = &mut ball.velocity;
|
||||
|
||||
|
|
Loading…
Reference in a new issue