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