bevy_ecs/world/filtered_resource.rs
1use crate::{
2 change_detection::{Mut, MutUntyped, Ref, Ticks, TicksMut},
3 component::{ComponentId, Tick},
4 query::Access,
5 resource::Resource,
6 world::{unsafe_world_cell::UnsafeWorldCell, World},
7};
8use bevy_ptr::{Ptr, UnsafeCellDeref};
9
10use super::error::ResourceFetchError;
11
12/// Provides read-only access to a set of [`Resource`]s defined by the contained [`Access`].
13///
14/// Use [`FilteredResourcesMut`] if you need mutable access to some resources.
15///
16/// To be useful as a [`SystemParam`](crate::system::SystemParam),
17/// this must be configured using a [`FilteredResourcesParamBuilder`](crate::system::FilteredResourcesParamBuilder)
18/// to build the system using a [`SystemParamBuilder`](crate::prelude::SystemParamBuilder).
19///
20/// # Examples
21///
22/// ```
23/// # use bevy_ecs::{prelude::*, system::*};
24/// #
25/// # #[derive(Default, Resource)]
26/// # struct A;
27/// #
28/// # #[derive(Default, Resource)]
29/// # struct B;
30/// #
31/// # #[derive(Default, Resource)]
32/// # struct C;
33/// #
34/// # let mut world = World::new();
35/// // Use `FilteredResourcesParamBuilder` to declare access to resources.
36/// let system = (FilteredResourcesParamBuilder::new(|builder| {
37/// builder.add_read::<B>().add_read::<C>();
38/// }),)
39/// .build_state(&mut world)
40/// .build_system(resource_system);
41///
42/// world.init_resource::<A>();
43/// world.init_resource::<C>();
44///
45/// fn resource_system(res: FilteredResources) {
46/// // The resource exists, but we have no access, so we can't read it.
47/// assert!(res.get::<A>().is_err());
48/// // The resource doesn't exist, so we can't read it.
49/// assert!(res.get::<B>().is_err());
50/// // The resource exists and we have access, so we can read it.
51/// let c = res.get::<C>().unwrap();
52/// // The type parameter can be left out if it can be determined from use.
53/// let c: Ref<C> = res.get().unwrap();
54/// }
55/// #
56/// # world.run_system_once(system);
57/// ```
58///
59/// This can be used alongside ordinary [`Res`](crate::system::Res) and [`ResMut`](crate::system::ResMut) parameters if they do not conflict.
60///
61/// ```
62/// # use bevy_ecs::{prelude::*, system::*};
63/// #
64/// # #[derive(Default, Resource)]
65/// # struct A;
66/// #
67/// # #[derive(Default, Resource)]
68/// # struct B;
69/// #
70/// # let mut world = World::new();
71/// # world.init_resource::<A>();
72/// # world.init_resource::<B>();
73/// #
74/// let system = (
75/// FilteredResourcesParamBuilder::new(|builder| {
76/// builder.add_read::<A>();
77/// }),
78/// ParamBuilder,
79/// ParamBuilder,
80/// )
81/// .build_state(&mut world)
82/// .build_system(resource_system);
83///
84/// // Read access to A does not conflict with read access to A or write access to B.
85/// fn resource_system(filtered: FilteredResources, res_a: Res<A>, res_mut_b: ResMut<B>) {
86/// let res_a_2: Ref<A> = filtered.get::<A>().unwrap();
87/// }
88/// #
89/// # world.run_system_once(system);
90/// ```
91///
92/// But it will conflict if it tries to read the same resource that another parameter writes.
93///
94/// ```should_panic
95/// # use bevy_ecs::{prelude::*, system::*};
96/// #
97/// # #[derive(Default, Resource)]
98/// # struct A;
99/// #
100/// # let mut world = World::new();
101/// # world.init_resource::<A>();
102/// #
103/// let system = (
104/// FilteredResourcesParamBuilder::new(|builder| {
105/// builder.add_read::<A>();
106/// }),
107/// ParamBuilder,
108/// )
109/// .build_state(&mut world)
110/// .build_system(invalid_resource_system);
111///
112/// // Read access to A conflicts with write access to A.
113/// fn invalid_resource_system(filtered: FilteredResources, res_mut_a: ResMut<A>) { }
114/// #
115/// # world.run_system_once(system);
116/// ```
117#[derive(Clone, Copy)]
118pub struct FilteredResources<'w, 's> {
119 world: UnsafeWorldCell<'w>,
120 access: &'s Access<ComponentId>,
121 last_run: Tick,
122 this_run: Tick,
123}
124
125impl<'w, 's> FilteredResources<'w, 's> {
126 /// Creates a new [`FilteredResources`].
127 /// # Safety
128 /// It is the callers responsibility to ensure that nothing else may access the any resources in the `world` in a way that conflicts with `access`.
129 pub(crate) unsafe fn new(
130 world: UnsafeWorldCell<'w>,
131 access: &'s Access<ComponentId>,
132 last_run: Tick,
133 this_run: Tick,
134 ) -> Self {
135 Self {
136 world,
137 access,
138 last_run,
139 this_run,
140 }
141 }
142
143 /// Returns a reference to the underlying [`Access`].
144 pub fn access(&self) -> &Access<ComponentId> {
145 self.access
146 }
147
148 /// Returns `true` if the `FilteredResources` has access to the given resource.
149 /// Note that [`Self::get()`] may still return `Err` if the resource does not exist.
150 pub fn has_read<R: Resource>(&self) -> bool {
151 let component_id = self.world.components().resource_id::<R>();
152 component_id.is_some_and(|component_id| self.access.has_resource_read(component_id))
153 }
154
155 /// Gets a reference to the resource of the given type if it exists and the `FilteredResources` has access to it.
156 pub fn get<R: Resource>(&self) -> Result<Ref<'w, R>, ResourceFetchError> {
157 let component_id = self
158 .world
159 .components()
160 .resource_id::<R>()
161 .ok_or(ResourceFetchError::NotRegistered)?;
162 if !self.access.has_resource_read(component_id) {
163 return Err(ResourceFetchError::NoResourceAccess(component_id));
164 }
165
166 // SAFETY: We have read access to this resource
167 let (value, ticks, caller) = unsafe { self.world.get_resource_with_ticks(component_id) }
168 .ok_or(ResourceFetchError::DoesNotExist(component_id))?;
169
170 Ok(Ref {
171 // SAFETY: `component_id` was obtained from the type ID of `R`.
172 value: unsafe { value.deref() },
173 // SAFETY: We have read access to the resource, so no mutable reference can exist.
174 ticks: unsafe { Ticks::from_tick_cells(ticks, self.last_run, self.this_run) },
175 // SAFETY: We have read access to the resource, so no mutable reference can exist.
176 changed_by: unsafe { caller.map(|caller| caller.deref()) },
177 })
178 }
179
180 /// Gets a pointer to the resource with the given [`ComponentId`] if it exists and the `FilteredResources` has access to it.
181 pub fn get_by_id(&self, component_id: ComponentId) -> Result<Ptr<'w>, ResourceFetchError> {
182 if !self.access.has_resource_read(component_id) {
183 return Err(ResourceFetchError::NoResourceAccess(component_id));
184 }
185 // SAFETY: We have read access to this resource
186 unsafe { self.world.get_resource_by_id(component_id) }
187 .ok_or(ResourceFetchError::DoesNotExist(component_id))
188 }
189}
190
191impl<'w, 's> From<FilteredResourcesMut<'w, 's>> for FilteredResources<'w, 's> {
192 fn from(resources: FilteredResourcesMut<'w, 's>) -> Self {
193 // SAFETY:
194 // - `FilteredResourcesMut` guarantees exclusive access to all resources in the new `FilteredResources`.
195 unsafe {
196 FilteredResources::new(
197 resources.world,
198 resources.access,
199 resources.last_run,
200 resources.this_run,
201 )
202 }
203 }
204}
205
206impl<'w, 's> From<&'w FilteredResourcesMut<'_, 's>> for FilteredResources<'w, 's> {
207 fn from(resources: &'w FilteredResourcesMut<'_, 's>) -> Self {
208 // SAFETY:
209 // - `FilteredResourcesMut` guarantees exclusive access to all components in the new `FilteredResources`.
210 unsafe {
211 FilteredResources::new(
212 resources.world,
213 resources.access,
214 resources.last_run,
215 resources.this_run,
216 )
217 }
218 }
219}
220
221impl<'w> From<&'w World> for FilteredResources<'w, 'static> {
222 fn from(value: &'w World) -> Self {
223 const READ_ALL_RESOURCES: &Access<ComponentId> = {
224 const ACCESS: Access<ComponentId> = {
225 let mut access = Access::new();
226 access.read_all_resources();
227 access
228 };
229 &ACCESS
230 };
231
232 let last_run = value.last_change_tick();
233 let this_run = value.read_change_tick();
234 // SAFETY: We have a reference to the entire world, so nothing else can alias with read access to all resources.
235 unsafe {
236 Self::new(
237 value.as_unsafe_world_cell_readonly(),
238 READ_ALL_RESOURCES,
239 last_run,
240 this_run,
241 )
242 }
243 }
244}
245
246impl<'w> From<&'w mut World> for FilteredResources<'w, 'static> {
247 fn from(value: &'w mut World) -> Self {
248 Self::from(&*value)
249 }
250}
251
252/// Provides mutable access to a set of [`Resource`]s defined by the contained [`Access`].
253///
254/// Use [`FilteredResources`] if you only need read-only access to resources.
255///
256/// To be useful as a [`SystemParam`](crate::system::SystemParam),
257/// this must be configured using a [`FilteredResourcesMutParamBuilder`](crate::system::FilteredResourcesMutParamBuilder)
258/// to build the system using a [`SystemParamBuilder`](crate::prelude::SystemParamBuilder).
259///
260/// # Examples
261///
262/// ```
263/// # use bevy_ecs::{prelude::*, system::*};
264/// #
265/// # #[derive(Default, Resource)]
266/// # struct A;
267/// #
268/// # #[derive(Default, Resource)]
269/// # struct B;
270/// #
271/// # #[derive(Default, Resource)]
272/// # struct C;
273/// #
274/// # #[derive(Default, Resource)]
275/// # struct D;
276/// #
277/// # let mut world = World::new();
278/// // Use `FilteredResourcesMutParamBuilder` to declare access to resources.
279/// let system = (FilteredResourcesMutParamBuilder::new(|builder| {
280/// builder.add_write::<B>().add_read::<C>().add_write::<D>();
281/// }),)
282/// .build_state(&mut world)
283/// .build_system(resource_system);
284///
285/// world.init_resource::<A>();
286/// world.init_resource::<C>();
287/// world.init_resource::<D>();
288///
289/// fn resource_system(mut res: FilteredResourcesMut) {
290/// // The resource exists, but we have no access, so we can't read it or write it.
291/// assert!(res.get::<A>().is_err());
292/// assert!(res.get_mut::<A>().is_err());
293/// // The resource doesn't exist, so we can't read it or write it.
294/// assert!(res.get::<B>().is_err());
295/// assert!(res.get_mut::<B>().is_err());
296/// // The resource exists and we have read access, so we can read it but not write it.
297/// let c = res.get::<C>().unwrap();
298/// assert!(res.get_mut::<C>().is_err());
299/// // The resource exists and we have write access, so we can read it or write it.
300/// let d = res.get::<D>().unwrap();
301/// let d = res.get_mut::<D>().unwrap();
302/// // The type parameter can be left out if it can be determined from use.
303/// let c: Ref<C> = res.get().unwrap();
304/// }
305/// #
306/// # world.run_system_once(system);
307/// ```
308///
309/// This can be used alongside ordinary [`Res`](crate::system::ResMut) and [`ResMut`](crate::system::ResMut) parameters if they do not conflict.
310///
311/// ```
312/// # use bevy_ecs::{prelude::*, system::*};
313/// #
314/// # #[derive(Default, Resource)]
315/// # struct A;
316/// #
317/// # #[derive(Default, Resource)]
318/// # struct B;
319/// #
320/// # #[derive(Default, Resource)]
321/// # struct C;
322/// #
323/// # let mut world = World::new();
324/// # world.init_resource::<A>();
325/// # world.init_resource::<B>();
326/// # world.init_resource::<C>();
327/// #
328/// let system = (
329/// FilteredResourcesMutParamBuilder::new(|builder| {
330/// builder.add_read::<A>().add_write::<B>();
331/// }),
332/// ParamBuilder,
333/// ParamBuilder,
334/// )
335/// .build_state(&mut world)
336/// .build_system(resource_system);
337///
338/// // Read access to A does not conflict with read access to A or write access to C.
339/// // Write access to B does not conflict with access to A or C.
340/// fn resource_system(mut filtered: FilteredResourcesMut, res_a: Res<A>, res_mut_c: ResMut<C>) {
341/// let res_a_2: Ref<A> = filtered.get::<A>().unwrap();
342/// let res_mut_b: Mut<B> = filtered.get_mut::<B>().unwrap();
343/// }
344/// #
345/// # world.run_system_once(system);
346/// ```
347///
348/// But it will conflict if it tries to read the same resource that another parameter writes,
349/// or write the same resource that another parameter reads.
350///
351/// ```should_panic
352/// # use bevy_ecs::{prelude::*, system::*};
353/// #
354/// # #[derive(Default, Resource)]
355/// # struct A;
356/// #
357/// # let mut world = World::new();
358/// # world.init_resource::<A>();
359/// #
360/// let system = (
361/// FilteredResourcesMutParamBuilder::new(|builder| {
362/// builder.add_write::<A>();
363/// }),
364/// ParamBuilder,
365/// )
366/// .build_state(&mut world)
367/// .build_system(invalid_resource_system);
368///
369/// // Read access to A conflicts with write access to A.
370/// fn invalid_resource_system(filtered: FilteredResourcesMut, res_a: Res<A>) { }
371/// #
372/// # world.run_system_once(system);
373/// ```
374pub struct FilteredResourcesMut<'w, 's> {
375 world: UnsafeWorldCell<'w>,
376 access: &'s Access<ComponentId>,
377 last_run: Tick,
378 this_run: Tick,
379}
380
381impl<'w, 's> FilteredResourcesMut<'w, 's> {
382 /// Creates a new [`FilteredResources`].
383 /// # Safety
384 /// It is the callers responsibility to ensure that nothing else may access the any resources in the `world` in a way that conflicts with `access`.
385 pub(crate) unsafe fn new(
386 world: UnsafeWorldCell<'w>,
387 access: &'s Access<ComponentId>,
388 last_run: Tick,
389 this_run: Tick,
390 ) -> Self {
391 Self {
392 world,
393 access,
394 last_run,
395 this_run,
396 }
397 }
398
399 /// Gets read-only access to all of the resources this `FilteredResourcesMut` can access.
400 pub fn as_readonly(&self) -> FilteredResources<'_, 's> {
401 FilteredResources::from(self)
402 }
403
404 /// Returns a new instance with a shorter lifetime.
405 /// This is useful if you have `&mut FilteredResourcesMut`, but you need `FilteredResourcesMut`.
406 pub fn reborrow(&mut self) -> FilteredResourcesMut<'_, 's> {
407 // SAFETY: We have exclusive access to this access for the duration of `'_`, so there cannot be anything else that conflicts.
408 unsafe { Self::new(self.world, self.access, self.last_run, self.this_run) }
409 }
410
411 /// Returns a reference to the underlying [`Access`].
412 pub fn access(&self) -> &Access<ComponentId> {
413 self.access
414 }
415
416 /// Returns `true` if the `FilteredResources` has read access to the given resource.
417 /// Note that [`Self::get()`] may still return `Err` if the resource does not exist.
418 pub fn has_read<R: Resource>(&self) -> bool {
419 let component_id = self.world.components().resource_id::<R>();
420 component_id.is_some_and(|component_id| self.access.has_resource_read(component_id))
421 }
422
423 /// Returns `true` if the `FilteredResources` has write access to the given resource.
424 /// Note that [`Self::get_mut()`] may still return `Err` if the resource does not exist.
425 pub fn has_write<R: Resource>(&self) -> bool {
426 let component_id = self.world.components().resource_id::<R>();
427 component_id.is_some_and(|component_id| self.access.has_resource_write(component_id))
428 }
429
430 /// Gets a reference to the resource of the given type if it exists and the `FilteredResources` has access to it.
431 pub fn get<R: Resource>(&self) -> Result<Ref<'_, R>, ResourceFetchError> {
432 self.as_readonly().get()
433 }
434
435 /// Gets a pointer to the resource with the given [`ComponentId`] if it exists and the `FilteredResources` has access to it.
436 pub fn get_by_id(&self, component_id: ComponentId) -> Result<Ptr<'_>, ResourceFetchError> {
437 self.as_readonly().get_by_id(component_id)
438 }
439
440 /// Gets a mutable reference to the resource of the given type if it exists and the `FilteredResources` has access to it.
441 pub fn get_mut<R: Resource>(&mut self) -> Result<Mut<'_, R>, ResourceFetchError> {
442 // SAFETY: We have exclusive access to the resources in `access` for `'_`, and we shorten the returned lifetime to that.
443 unsafe { self.get_mut_unchecked() }
444 }
445
446 /// Gets a mutable pointer to the resource with the given [`ComponentId`] if it exists and the `FilteredResources` has access to it.
447 pub fn get_mut_by_id(
448 &mut self,
449 component_id: ComponentId,
450 ) -> Result<MutUntyped<'_>, ResourceFetchError> {
451 // SAFETY: We have exclusive access to the resources in `access` for `'_`, and we shorten the returned lifetime to that.
452 unsafe { self.get_mut_by_id_unchecked(component_id) }
453 }
454
455 /// Consumes self and gets mutable access to resource of the given type with the world `'w` lifetime if it exists and the `FilteredResources` has access to it.
456 pub fn into_mut<R: Resource>(mut self) -> Result<Mut<'w, R>, ResourceFetchError> {
457 // SAFETY: This consumes self, so we have exclusive access to the resources in `access` for the entirety of `'w`.
458 unsafe { self.get_mut_unchecked() }
459 }
460
461 /// Consumes self and gets mutable access to resource with the given [`ComponentId`] with the world `'w` lifetime if it exists and the `FilteredResources` has access to it.
462 pub fn into_mut_by_id(
463 mut self,
464 component_id: ComponentId,
465 ) -> Result<MutUntyped<'w>, ResourceFetchError> {
466 // SAFETY: This consumes self, so we have exclusive access to the resources in `access` for the entirety of `'w`.
467 unsafe { self.get_mut_by_id_unchecked(component_id) }
468 }
469
470 /// Gets a mutable pointer to the resource of the given type if it exists and the `FilteredResources` has access to it.
471 /// # Safety
472 /// It is the callers responsibility to ensure that there are no conflicting borrows of anything in `access` for the duration of the returned value.
473 unsafe fn get_mut_unchecked<R: Resource>(&mut self) -> Result<Mut<'w, R>, ResourceFetchError> {
474 let component_id = self
475 .world
476 .components()
477 .resource_id::<R>()
478 .ok_or(ResourceFetchError::NotRegistered)?;
479 // SAFETY: THe caller ensures that there are no conflicting borrows.
480 unsafe { self.get_mut_by_id_unchecked(component_id) }
481 // SAFETY: The underlying type of the resource is `R`.
482 .map(|ptr| unsafe { ptr.with_type::<R>() })
483 }
484
485 /// Gets a mutable pointer to the resource with the given [`ComponentId`] if it exists and the `FilteredResources` has access to it.
486 /// # Safety
487 /// It is the callers responsibility to ensure that there are no conflicting borrows of anything in `access` for the duration of the returned value.
488 unsafe fn get_mut_by_id_unchecked(
489 &mut self,
490 component_id: ComponentId,
491 ) -> Result<MutUntyped<'w>, ResourceFetchError> {
492 if !self.access.has_resource_write(component_id) {
493 return Err(ResourceFetchError::NoResourceAccess(component_id));
494 }
495
496 // SAFETY: We have read access to this resource
497 let (value, ticks, caller) = unsafe { self.world.get_resource_with_ticks(component_id) }
498 .ok_or(ResourceFetchError::DoesNotExist(component_id))?;
499
500 Ok(MutUntyped {
501 // SAFETY: We have exclusive access to the underlying storage.
502 value: unsafe { value.assert_unique() },
503 // SAFETY: We have exclusive access to the underlying storage.
504 ticks: unsafe { TicksMut::from_tick_cells(ticks, self.last_run, self.this_run) },
505 // SAFETY: We have exclusive access to the underlying storage.
506 changed_by: unsafe { caller.map(|caller| caller.deref_mut()) },
507 })
508 }
509}
510
511impl<'w> From<&'w mut World> for FilteredResourcesMut<'w, 'static> {
512 fn from(value: &'w mut World) -> Self {
513 const WRITE_ALL_RESOURCES: &Access<ComponentId> = {
514 const ACCESS: Access<ComponentId> = {
515 let mut access = Access::new();
516 access.write_all_resources();
517 access
518 };
519 &ACCESS
520 };
521
522 let last_run = value.last_change_tick();
523 let this_run = value.change_tick();
524 // SAFETY: We have a mutable reference to the entire world, so nothing else can alias with mutable access to all resources.
525 unsafe {
526 Self::new(
527 value.as_unsafe_world_cell_readonly(),
528 WRITE_ALL_RESOURCES,
529 last_run,
530 this_run,
531 )
532 }
533 }
534}
535
536/// Builder struct to define the access for a [`FilteredResources`].
537///
538/// This is passed to a callback in [`FilteredResourcesParamBuilder`](crate::system::FilteredResourcesParamBuilder).
539pub struct FilteredResourcesBuilder<'w> {
540 world: &'w mut World,
541 access: Access<ComponentId>,
542}
543
544impl<'w> FilteredResourcesBuilder<'w> {
545 /// Creates a new builder with no access.
546 pub fn new(world: &'w mut World) -> Self {
547 Self {
548 world,
549 access: Access::new(),
550 }
551 }
552
553 /// Returns a reference to the underlying [`Access`].
554 pub fn access(&self) -> &Access<ComponentId> {
555 &self.access
556 }
557
558 /// Add accesses required to read all resources.
559 pub fn add_read_all(&mut self) -> &mut Self {
560 self.access.read_all_resources();
561 self
562 }
563
564 /// Add accesses required to read the resource of the given type.
565 pub fn add_read<R: Resource>(&mut self) -> &mut Self {
566 let component_id = self.world.components_registrator().register_resource::<R>();
567 self.add_read_by_id(component_id)
568 }
569
570 /// Add accesses required to read the resource with the given [`ComponentId`].
571 pub fn add_read_by_id(&mut self, component_id: ComponentId) -> &mut Self {
572 self.access.add_resource_read(component_id);
573 self
574 }
575
576 /// Create an [`Access`] that represents the accesses of the builder.
577 pub fn build(self) -> Access<ComponentId> {
578 self.access
579 }
580}
581
582/// Builder struct to define the access for a [`FilteredResourcesMut`].
583///
584/// This is passed to a callback in [`FilteredResourcesMutParamBuilder`](crate::system::FilteredResourcesMutParamBuilder).
585pub struct FilteredResourcesMutBuilder<'w> {
586 world: &'w mut World,
587 access: Access<ComponentId>,
588}
589
590impl<'w> FilteredResourcesMutBuilder<'w> {
591 /// Creates a new builder with no access.
592 pub fn new(world: &'w mut World) -> Self {
593 Self {
594 world,
595 access: Access::new(),
596 }
597 }
598
599 /// Returns a reference to the underlying [`Access`].
600 pub fn access(&self) -> &Access<ComponentId> {
601 &self.access
602 }
603
604 /// Add accesses required to read all resources.
605 pub fn add_read_all(&mut self) -> &mut Self {
606 self.access.read_all_resources();
607 self
608 }
609
610 /// Add accesses required to read the resource of the given type.
611 pub fn add_read<R: Resource>(&mut self) -> &mut Self {
612 let component_id = self.world.components_registrator().register_resource::<R>();
613 self.add_read_by_id(component_id)
614 }
615
616 /// Add accesses required to read the resource with the given [`ComponentId`].
617 pub fn add_read_by_id(&mut self, component_id: ComponentId) -> &mut Self {
618 self.access.add_resource_read(component_id);
619 self
620 }
621
622 /// Add accesses required to get mutable access to all resources.
623 pub fn add_write_all(&mut self) -> &mut Self {
624 self.access.write_all_resources();
625 self
626 }
627
628 /// Add accesses required to get mutable access to the resource of the given type.
629 pub fn add_write<R: Resource>(&mut self) -> &mut Self {
630 let component_id = self.world.components_registrator().register_resource::<R>();
631 self.add_write_by_id(component_id)
632 }
633
634 /// Add accesses required to get mutable access to the resource with the given [`ComponentId`].
635 pub fn add_write_by_id(&mut self, component_id: ComponentId) -> &mut Self {
636 self.access.add_resource_write(component_id);
637 self
638 }
639
640 /// Create an [`Access`] that represents the accesses of the builder.
641 pub fn build(self) -> Access<ComponentId> {
642 self.access
643 }
644}