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//! Utility systems for generic system pipeline construction.
use bevy_ecs::prelude::*;
/// A [`System`] which checks if a given resource exists.
///
/// # Example
/// ```
/// use bevy::prelude::*;
/// use moonshine_util::system::has_resource;
///
/// #[derive(Resource)]
/// struct R;
///
/// fn system(resource: Option<Res<R>>) {
/// assert!(resource.is_some());
/// }
///
/// let mut app = App::new();
/// app.add_plugins(MinimalPlugins);
/// app.add_systems(Update, system.run_if(has_resource::<R>));
/// app.update(); // If resource does't exist (it doesn't), system will panic!
/// ```
pub fn has_resource<T: Resource>(resource: Option<Res<T>>) -> bool {
resource.is_some()
}
/// A [`System`] which checks if any event of a given type has been dispatched.
///
/// # Example
/// ```
/// use bevy::prelude::*;
/// use moonshine_util::system::has_event;
///
/// #[derive(Event)]
/// struct E;
///
/// fn system(mut events: EventReader<E>) {
/// assert!(events.read().next().is_some());
/// }
///
/// let mut app = App::new();
/// app.add_plugins(MinimalPlugins).add_event::<E>();
/// app.add_systems(Update, system.run_if(has_event::<E>));
/// app.update(); // If event isn't dispatched (it wasn't), system will panic!
/// ```
pub fn has_event<T: Event>(events: EventReader<T>) -> bool {
!events.is_empty()
}
/// A [`System`] which removes a resource from the world using [`Commands`].
///
/// # Example
/// ```
/// use bevy::prelude::*;
/// use moonshine_util::system::{remove_resource, has_resource};
///
/// #[derive(Resource)]
/// struct R;
///
/// let mut app = App::new();
/// app.insert_resource(R);
/// app.add_plugins(MinimalPlugins);
/// app.add_systems(Update, remove_resource::<R>.run_if(has_resource::<R>));
/// app.update(); // Resource is removed from the world.
///
/// assert!(!app.world().contains_resource::<R>());
/// ```
pub fn remove_resource<T: Resource>(mut commands: Commands) {
commands.remove_resource::<T>();
}
/// A [`System`] which removes a resource from the world immediately.
///
/// # Example
/// ```
/// use bevy::prelude::*;
/// use moonshine_util::system::{remove_resource_immediate, has_resource};
///
/// #[derive(Resource)]
/// struct R;
///
/// let mut app = App::new();
/// app.insert_resource(R);
/// app.add_plugins(MinimalPlugins);
/// app.add_systems(Update, remove_resource_immediate::<R>.run_if(has_resource::<R>));
/// app.update(); // Resource is removed from the world.
///
/// assert!(!app.world().contains_resource::<R>());
/// ```
pub fn remove_resource_immediate<T: Resource>(world: &mut World) {
world.remove_resource::<T>();
}
/// A [`System`] which removes all instances of a given [`Component`].
///
/// # Example
/// ```
/// use bevy::prelude::*;
/// use moonshine_util::system::remove_all_components;
///
/// #[derive(Component)]
/// struct T;
///
/// let mut app = App::new();
/// app.add_plugins(MinimalPlugins);
/// app.add_systems(Update, remove_all_components::<T>);
/// let entity = app.world_mut().spawn(T).id();
/// app.update();
///
/// assert!(!app.world().entity(entity).contains::<T>());
/// ```
pub fn remove_all_components<T: Component>(query: Query<Entity, With<T>>, mut commands: Commands) {
for entity in &query {
commands.entity(entity).remove::<T>();
}
}