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
use bevy_ecs::{prelude::*, query::FilteredAccess};
use bevy_reflect::Reflect;
use crate::prelude::{ModSchedules, Sandbox};
/// Represents the access a mod can be given to run in.
///
/// Mods can run in the world and/or in [sandboxes](Sandbox) defined by their entity.
///
/// See: [Mods::enable_access](crate::mods::Mods::enable_access)
#[derive(Reflect, Debug, Eq, PartialEq, Hash, Clone, Copy)]
pub enum ModAccess {
World,
Sandbox(Entity),
}
impl ModAccess {
/// Resolves the schedules configured to run for this mod
pub fn schedules(&self, world: &World) -> ModSchedules {
match self {
Self::Sandbox(entity) => world
.get::<Sandbox>(*entity)
.map(|sandbox| sandbox.schedules().clone())
// The sandbox doesn't exist, so no schedules
.unwrap_or_else(ModSchedules::empty),
Self::World => world
.get_resource::<ModSchedules>()
.cloned()
.expect("ModSchedules be registered"),
}
}
/// Returns world access to only the entities granted by this access.
///
/// This is used by Wasvy to build mod systems that don't conflict (can run in parallel) between different accesses.
pub fn filtered_access(&self, world: &World) -> FilteredAccess {
match self {
Self::Sandbox(entity) => world
.get::<Sandbox>(*entity)
.map(|sandbox| sandbox.access().clone())
// The sandbox doesn't exist, so there is nothing to match
.unwrap_or_else(FilteredAccess::matches_nothing),
Self::World => Sandbox::access_non_sandboxed(world),
}
}
}