1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
use std::{any, sync::Arc};
use bevy_ecs::{
component::Component,
entity::Entity,
query::{QueryData, QueryFilter, ROQueryItem},
world::World,
};
use parking_lot::Mutex;
use crate::Client;
impl Client {
/// A convenience function for getting components of our player's entity.
///
/// # Examples
/// ```
/// # use azalea_world::InstanceName;
/// # fn example(mut client: azalea_client::Client) {
/// let is_logged_in = client
/// .query::<Option<&InstanceName>>(&mut client.ecs.lock())
/// .is_some();
/// # }
/// ```
pub fn query<'w, D: QueryData>(&self, ecs: &'w mut World) -> D::Item<'w> {
ecs.query::<D>()
.get_mut(ecs, self.entity)
.unwrap_or_else(|_| {
panic!(
"Our client is missing a required component {:?}",
any::type_name::<D>()
)
})
}
/// Return a lightweight [`Entity`] for the entity that matches the given
/// predicate function.
///
/// You can then use [`Self::entity_component`] to get components from this
/// entity.
///
/// # Example
/// Note that this will very likely change in the future.
/// ```
/// use azalea_client::{Client, GameProfileComponent};
/// use bevy_ecs::query::With;
/// use azalea_entity::{Position, metadata::Player};
///
/// # fn example(mut bot: Client, sender_name: String) {
/// let entity = bot.entity_by::<With<Player>, (&GameProfileComponent,)>(
/// |(profile,): &(&GameProfileComponent,)| profile.name == sender_name,
/// );
/// if let Some(entity) = entity {
/// let position = bot.entity_component::<Position>(entity);
/// // ...
/// }
/// # }
/// ```
///
/// [`Entity`]: bevy_ecs::entity::Entity
pub fn entity_by<F: QueryFilter, Q: QueryData>(
&self,
predicate: impl EntityPredicate<Q, F>,
) -> Option<Entity> {
predicate.find(self.ecs.clone())
}
/// Get a component from an entity. Note that this will return an owned type
/// (i.e. not a reference) so it may be expensive for larger types.
///
/// If you're trying to get a component for this client, use
/// [`Self::component`].
pub fn entity_component<Q: Component + Clone>(&self, entity: Entity) -> Q {
let mut ecs = self.ecs.lock();
let mut q = ecs.query::<&Q>();
let components = q.get(&ecs, entity).unwrap_or_else(|_| {
panic!(
"Entity is missing a required component {:?}",
any::type_name::<Q>()
)
});
components.clone()
}
/// Get a component from an entity, if it exists. This is similar to
/// [`Self::entity_component`] but returns an `Option` instead of panicking
/// if the component isn't present.
pub fn get_entity_component<Q: Component + Clone>(&self, entity: Entity) -> Option<Q> {
let mut ecs = self.ecs.lock();
let mut q = ecs.query::<&Q>();
let components = q.get(&ecs, entity).ok();
components.cloned()
}
}
pub trait EntityPredicate<Q: QueryData, Filter: QueryFilter> {
fn find(&self, ecs_lock: Arc<Mutex<World>>) -> Option<Entity>;
}
impl<F, Q, Filter> EntityPredicate<Q, Filter> for F
where
F: Fn(&ROQueryItem<Q>) -> bool,
Q: QueryData,
Filter: QueryFilter,
{
fn find(&self, ecs_lock: Arc<Mutex<World>>) -> Option<Entity> {
let mut ecs = ecs_lock.lock();
let mut query = ecs.query_filtered::<(Entity, Q), Filter>();
query.iter(&ecs).find(|(_, q)| (self)(q)).map(|(e, _)| e)
}
}
// impl<'a, F, Q1, Q2> EntityPredicate<'a, (Q1, Q2)> for F
// where
// F: Fn(&<Q1 as WorldQuery>::Item<'_>, &<Q2 as WorldQuery>::Item<'_>) ->
// bool, Q1: QueryFilter,
// Q2: QueryFilter,
// {
// fn find(&self, ecs: &mut Ecs) -> Option<Entity> {
// // (self)(query)
// let mut query = ecs.query_filtered::<(Entity, Q1, Q2), ()>();
// let entity = query
// .iter(ecs)
// .find(|(_, q1, q2)| (self)(q1, q2))
// .map(|(e, _, _)| e);
// entity
// }
// }
|