1use std::borrow::Cow;
4
5use bit_set::BitSet;
6
7use super::{
8 entity::Entity,
9 entry::{EntryMut, EntryRef},
10 permissions::Permissions,
11 query::{
12 filter::EntityFilter,
13 view::{IntoView, View},
14 Query,
15 },
16 storage::{archetype::ArchetypeIndex, component::ComponentTypeId},
17 world::{EntityAccessError, EntityStore, StorageAccessor, World, WorldId},
18};
19
20pub enum ArchetypeAccess {
22 All,
24 Some(BitSet),
26}
27
28impl ArchetypeAccess {
29 pub fn is_disjoint(&self, other: &ArchetypeAccess) -> bool {
31 match self {
32 Self::All => false,
33 Self::Some(mine) => {
34 match other {
35 Self::All => false,
36 Self::Some(theirs) => mine.is_disjoint(theirs),
37 }
38 }
39 }
40 }
41
42 pub fn bitset(&self) -> Option<&BitSet> {
44 match self {
45 Self::All => None,
46 Self::Some(bitset) => Some(bitset),
47 }
48 }
49}
50
51#[derive(Clone, Debug)]
53pub enum ComponentAccess<'a> {
54 All,
56 Allow(Cow<'a, Permissions<ComponentTypeId>>),
58 Disallow(Cow<'a, Permissions<ComponentTypeId>>),
60}
61
62impl<'a> ComponentAccess<'a> {
63 pub fn allows_read(&self, component: ComponentTypeId) -> bool {
65 match self {
66 Self::All => true,
67 Self::Allow(components) => components.reads().contains(&component),
68 Self::Disallow(components) => !components.reads().contains(&component),
69 }
70 }
71
72 pub fn allows_write(&self, component: ComponentTypeId) -> bool {
74 match self {
75 Self::All => true,
76 Self::Allow(components) => components.writes().contains(&component),
77 Self::Disallow(components) => !components.writes().contains(&component),
78 }
79 }
80
81 pub(crate) fn split(&mut self, access: Permissions<ComponentTypeId>) -> (Self, Self) {
84 fn append_incompatible(
85 denied: &mut Permissions<ComponentTypeId>,
86 to_deny: &Permissions<ComponentTypeId>,
87 ) {
88 for read in to_deny.reads() {
90 denied.push_write(*read);
91 }
92
93 for write in to_deny.writes() {
95 denied.push(*write);
96 }
97 }
98
99 fn incompatible(
100 permissions: &Permissions<ComponentTypeId>,
101 ) -> Permissions<ComponentTypeId> {
102 let mut denied = Permissions::new();
103 for read in permissions.reads_only() {
105 denied.push_write(*read);
106 }
107
108 for write in permissions.writes() {
110 denied.push(*write);
111 }
112
113 denied
114 }
115
116 match self {
117 Self::All => {
118 let denied = incompatible(&access);
119 (
120 Self::Allow(Cow::Owned(access)),
121 Self::Disallow(Cow::Owned(denied)),
122 )
123 }
124 Self::Allow(allowed) => {
125 if !allowed.is_superset(&access) {
126 panic!("view accesses components unavailable in this world: world allows only {}, view requires {}", allowed, access);
127 }
128
129 let mut allowed = allowed.clone();
130 allowed.to_mut().subtract(&access);
131
132 (Self::Allow(Cow::Owned(access)), Self::Allow(allowed))
133 }
134 Self::Disallow(denied) => {
135 if !denied.is_disjoint(&access) {
136 panic!("view accesses components unavailable in this world: world disallows {}, view requires {}", denied, access);
137 }
138
139 let mut denied = denied.clone();
140 append_incompatible(denied.to_mut(), &access);
141
142 (Self::Allow(Cow::Owned(access)), Self::Disallow(denied))
143 }
144 }
145 }
146}
147
148#[derive(Clone)]
161pub struct SubWorld<'a> {
162 world: &'a World,
163 components: ComponentAccess<'a>,
164 archetypes: Option<&'a BitSet>,
165}
166
167impl<'a> SubWorld<'a> {
168 pub unsafe fn new_unchecked(
174 world: &'a World,
175 components: ComponentAccess<'a>,
176 archetypes: Option<&'a BitSet>,
177 ) -> Self {
178 Self {
179 world,
180 components,
181 archetypes,
182 }
183 }
184
185 pub fn split<'b, T: IntoView>(&'b mut self) -> (SubWorld<'b>, SubWorld<'b>)
210 where
211 'a: 'b,
212 {
213 let permissions = T::View::requires_permissions();
214 let (left, right) = self.components.split(permissions);
215
216 (
217 SubWorld {
218 world: self.world,
219 components: left,
220 archetypes: self.archetypes,
221 },
222 SubWorld {
223 world: self.world,
224 components: right,
225 archetypes: self.archetypes,
226 },
227 )
228 }
229
230 pub fn split_for_query<'q, V: IntoView, F: EntityFilter>(
233 &mut self,
234 _: &'q Query<V, F>,
235 ) -> (SubWorld, SubWorld) {
236 self.split::<V>()
237 }
238
239 fn validate_archetype_access(&self, ArchetypeIndex(arch_index): ArchetypeIndex) -> bool {
240 if let Some(archetypes) = self.archetypes {
241 archetypes.contains(arch_index as usize)
242 } else {
243 true
244 }
245 }
246}
247
248impl<'a> EntityStore for SubWorld<'a> {
249 fn get_component_storage<V: for<'b> View<'b>>(
250 &self,
251 ) -> Result<StorageAccessor, EntityAccessError> {
252 if V::validate_access(&self.components) {
253 Ok(self
254 .world
255 .get_component_storage::<V>()
256 .unwrap()
257 .with_allowed_archetypes(self.archetypes))
258 } else {
259 Err(EntityAccessError::AccessDenied)
260 }
261 }
262
263 fn entry_ref(&self, entity: Entity) -> Result<EntryRef, EntityAccessError> {
264 let entry = self.world.entry_ref(entity)?;
265
266 if !self.validate_archetype_access(entry.location().archetype()) {
267 return Err(EntityAccessError::AccessDenied);
268 }
269
270 Ok(EntryRef {
271 allowed_components: self.components.clone(),
272 ..entry
273 })
274 }
275
276 fn entry_mut(&mut self, entity: Entity) -> Result<EntryMut, EntityAccessError> {
277 let entry = unsafe { self.world.entry_unchecked(entity)? };
279
280 if !self.validate_archetype_access(entry.location().archetype()) {
281 return Err(EntityAccessError::AccessDenied);
282 }
283
284 Ok(EntryMut {
285 allowed_components: self.components.clone(),
286 ..entry
287 })
288 }
289
290 fn id(&self) -> WorldId {
291 self.world.id()
292 }
293}
294
295impl<'a> From<&'a mut World> for SubWorld<'a> {
296 fn from(world: &'a mut World) -> Self {
297 Self {
298 world,
299 components: ComponentAccess::All,
300 archetypes: None,
301 }
302 }
303}
304
305#[cfg(test)]
306mod tests {
307 use crate::{
308 internals::{
309 query::view::{read::Read, write::Write},
310 world::{EntityStore, World},
311 },
312 world::ComponentError,
313 };
314
315 #[test]
316 fn split_write_permissions() {
317 let mut world = World::default();
318 let entity = world.push((1usize, false));
319
320 let (mut left, mut right) = world.split::<Write<usize>>();
321
322 let mut left_entry = left.entry_mut(entity).unwrap();
323 let mut right_entry = right.entry_mut(entity).unwrap();
324
325 assert!(left_entry.get_component::<usize>().is_ok());
326 assert!(left_entry.get_component_mut::<usize>().is_ok());
327
328 assert!(matches!(
329 left_entry.get_component::<bool>(),
330 Err(ComponentError::Denied { .. })
331 ));
332 assert!(matches!(
333 left_entry.get_component_mut::<bool>(),
334 Err(ComponentError::Denied { .. })
335 ));
336
337 assert!(right_entry.get_component::<bool>().is_ok());
338 assert!(right_entry.get_component_mut::<bool>().is_ok());
339
340 assert!(matches!(
341 right_entry.get_component::<usize>(),
342 Err(ComponentError::Denied { .. })
343 ));
344 assert!(matches!(
345 right_entry.get_component_mut::<usize>(),
346 Err(ComponentError::Denied { .. })
347 ));
348 }
349
350 #[test]
351 fn split_read_permissions() {
352 let mut world = World::default();
353 let entity = world.push((1usize, false));
354
355 let (mut left, mut right) = world.split::<Read<usize>>();
356
357 let mut left_entry = left.entry_mut(entity).unwrap();
358 let mut right_entry = right.entry_mut(entity).unwrap();
359
360 assert!(left_entry.get_component::<usize>().is_ok());
361 assert!(matches!(
362 left_entry.get_component_mut::<usize>(),
363 Err(ComponentError::Denied { .. })
364 ));
365
366 assert!(matches!(
367 left_entry.get_component::<bool>(),
368 Err(ComponentError::Denied { .. })
369 ));
370 assert!(matches!(
371 left_entry.get_component_mut::<bool>(),
372 Err(ComponentError::Denied { .. })
373 ));
374
375 assert!(right_entry.get_component::<bool>().is_ok());
376 assert!(right_entry.get_component_mut::<bool>().is_ok());
377
378 assert!(right_entry.get_component::<usize>().is_ok());
379 assert!(matches!(
380 right_entry.get_component_mut::<usize>(),
381 Err(ComponentError::Denied { .. })
382 ));
383 }
384
385 #[test]
386 fn complex_split() {
387 struct A;
388 struct B;
389 struct C;
390
391 let mut world = World::default();
392 let entity = world.push((A, B, C));
393
394 let (mut left, mut right) = world.split::<(Read<A>, Write<B>)>();
395
396 let mut left_entry = left.entry_mut(entity).unwrap();
397 let mut right_entry = right.entry_mut(entity).unwrap();
398
399 assert!(left_entry.get_component::<A>().is_ok());
401 assert!(matches!(
402 left_entry.get_component_mut::<A>(),
403 Err(ComponentError::Denied { .. })
404 ));
405
406 assert!(left_entry.get_component::<B>().is_ok());
408 assert!(left_entry.get_component_mut::<B>().is_ok());
409
410 assert!(matches!(
412 left_entry.get_component::<C>(),
413 Err(ComponentError::Denied { .. })
414 ));
415 assert!(matches!(
416 left_entry.get_component_mut::<C>(),
417 Err(ComponentError::Denied { .. })
418 ));
419
420 assert!(right_entry.get_component::<A>().is_ok());
422 assert!(matches!(
423 right_entry.get_component_mut::<A>(),
424 Err(ComponentError::Denied { .. })
425 ));
426
427 assert!(matches!(
429 right_entry.get_component::<B>(),
430 Err(ComponentError::Denied { .. })
431 ));
432 assert!(matches!(
433 right_entry.get_component_mut::<B>(),
434 Err(ComponentError::Denied { .. })
435 ));
436
437 assert!(right_entry.get_component::<C>().is_ok());
439 assert!(right_entry.get_component_mut::<C>().is_ok());
440 }
441}