Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/component/required.rs
6600 views
1
use alloc::{format, vec::Vec};
2
use bevy_platform::{hash::FixedHasher, sync::Arc};
3
use bevy_ptr::OwningPtr;
4
use core::fmt::Debug;
5
use indexmap::{IndexMap, IndexSet};
6
use thiserror::Error;
7
8
use crate::{
9
bundle::BundleInfo,
10
change_detection::MaybeLocation,
11
component::{Component, ComponentId, Components, ComponentsRegistrator, Tick},
12
entity::Entity,
13
query::DebugCheckedUnwrap as _,
14
storage::{SparseSets, Table, TableRow},
15
};
16
17
/// Metadata associated with a required component. See [`Component`] for details.
18
#[derive(Clone)]
19
pub struct RequiredComponent {
20
/// The constructor used for the required component.
21
pub constructor: RequiredComponentConstructor,
22
}
23
24
/// A Required Component constructor. See [`Component`] for details.
25
#[derive(Clone)]
26
pub struct RequiredComponentConstructor(
27
// Note: this function makes `unsafe` assumptions, so it cannot be public.
28
Arc<dyn Fn(&mut Table, &mut SparseSets, Tick, TableRow, Entity, MaybeLocation)>,
29
);
30
31
impl RequiredComponentConstructor {
32
/// Creates a new instance of `RequiredComponentConstructor` for the given type
33
///
34
/// # Safety
35
///
36
/// - `component_id` must be a valid component for type `C`.
37
pub unsafe fn new<C: Component>(component_id: ComponentId, constructor: fn() -> C) -> Self {
38
RequiredComponentConstructor({
39
// `portable-atomic-util` `Arc` is not able to coerce an unsized
40
// type like `std::sync::Arc` can. Creating a `Box` first does the
41
// coercion.
42
//
43
// This would be resolved by https://github.com/rust-lang/rust/issues/123430
44
45
#[cfg(not(target_has_atomic = "ptr"))]
46
use alloc::boxed::Box;
47
48
type Constructor = dyn for<'a, 'b> Fn(
49
&'a mut Table,
50
&'b mut SparseSets,
51
Tick,
52
TableRow,
53
Entity,
54
MaybeLocation,
55
);
56
57
#[cfg(not(target_has_atomic = "ptr"))]
58
type Intermediate<T> = Box<T>;
59
60
#[cfg(target_has_atomic = "ptr")]
61
type Intermediate<T> = Arc<T>;
62
63
let boxed: Intermediate<Constructor> = Intermediate::new(
64
move |table, sparse_sets, change_tick, table_row, entity, caller| {
65
OwningPtr::make(constructor(), |ptr| {
66
// SAFETY: This will only be called in the context of `BundleInfo::write_components`, which will
67
// pass in a valid table_row and entity requiring a C constructor
68
// C::STORAGE_TYPE is the storage type associated with `component_id` / `C`
69
// `ptr` points to valid `C` data, which matches the type associated with `component_id`
70
unsafe {
71
BundleInfo::initialize_required_component(
72
table,
73
sparse_sets,
74
change_tick,
75
table_row,
76
entity,
77
component_id,
78
C::STORAGE_TYPE,
79
ptr,
80
caller,
81
);
82
}
83
});
84
},
85
);
86
87
Arc::from(boxed)
88
})
89
}
90
91
/// # Safety
92
/// This is intended to only be called in the context of [`BundleInfo::write_components`] to initialized required components.
93
/// Calling it _anywhere else_ should be considered unsafe.
94
///
95
/// `table_row` and `entity` must correspond to a valid entity that currently needs a component initialized via the constructor stored
96
/// on this [`RequiredComponentConstructor`]. The stored constructor must correspond to a component on `entity` that needs initialization.
97
/// `table` and `sparse_sets` must correspond to storages on a world where `entity` needs this required component initialized.
98
///
99
/// Again, don't call this anywhere but [`BundleInfo::write_components`].
100
pub(crate) unsafe fn initialize(
101
&self,
102
table: &mut Table,
103
sparse_sets: &mut SparseSets,
104
change_tick: Tick,
105
table_row: TableRow,
106
entity: Entity,
107
caller: MaybeLocation,
108
) {
109
(self.0)(table, sparse_sets, change_tick, table_row, entity, caller);
110
}
111
}
112
113
/// The collection of metadata for components that are required for a given component.
114
///
115
/// For more information, see the "Required Components" section of [`Component`].
116
#[derive(Default, Clone)]
117
pub struct RequiredComponents {
118
/// The components that are directly required (i.e. excluding inherited ones), in the order of their precedence.
119
///
120
/// # Safety
121
/// The [`RequiredComponent`] instance associated to each ID must be valid for its component.
122
pub(crate) direct: IndexMap<ComponentId, RequiredComponent, FixedHasher>,
123
/// All the components that are required (i.e. including inherited ones), in depth-first order. Most importantly,
124
/// components in this list always appear after all the components that they require.
125
///
126
/// Note that the direct components are not necessarily at the end of this list, for example if A and C are directly
127
/// requires, and A requires B requires C, then `all` will hold [C, B, A].
128
///
129
/// # Safety
130
/// The [`RequiredComponent`] instance associated to each ID must be valid for its component.
131
pub(crate) all: IndexMap<ComponentId, RequiredComponent, FixedHasher>,
132
}
133
134
impl Debug for RequiredComponents {
135
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
136
f.debug_struct("RequiredComponents")
137
.field("direct", &self.direct.keys())
138
.field("all", &self.all.keys())
139
.finish()
140
}
141
}
142
143
impl RequiredComponents {
144
/// Registers the [`Component`] `C` as an explicitly required component.
145
///
146
/// If the component was not already registered as an explicit required component then it is added
147
/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.
148
///
149
/// # Safety
150
///
151
/// - all other components in this [`RequiredComponents`] instance must have been registered in `components`.
152
unsafe fn register<C: Component>(
153
&mut self,
154
components: &mut ComponentsRegistrator<'_>,
155
constructor: fn() -> C,
156
) {
157
let id = components.register_component::<C>();
158
// SAFETY:
159
// - `id` was just registered in `components`;
160
// - the caller guarantees all other components were registered in `components`.
161
unsafe { self.register_by_id::<C>(id, components, constructor) };
162
}
163
164
/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.
165
///
166
/// If the component was not already registered as an explicit required component then it is added
167
/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.
168
///
169
/// # Safety
170
///
171
/// - `component_id` must be a valid component in `components` for the type `C`;
172
/// - all other components in this [`RequiredComponents`] instance must have been registered in `components`.
173
unsafe fn register_by_id<C: Component>(
174
&mut self,
175
component_id: ComponentId,
176
components: &Components,
177
constructor: fn() -> C,
178
) {
179
// SAFETY: the caller guarantees that `component_id` is valid for the type `C`.
180
let constructor =
181
|| unsafe { RequiredComponentConstructor::new(component_id, constructor) };
182
183
// SAFETY:
184
// - the caller guarantees that `component_id` is valid in `components`
185
// - the caller guarantees all other components were registered in `components`;
186
// - constructor is guaranteed to create a valid constructor for the component with id `component_id`.
187
unsafe { self.register_dynamic_with(component_id, components, constructor) };
188
}
189
190
/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.
191
///
192
/// If the component was not already registered as an explicit required component then it is added
193
/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.
194
///
195
/// # Safety
196
///
197
/// - `component_id` must be a valid component in `components`;
198
/// - all other components in `self` must have been registered in `components`;
199
/// - `constructor` must return a [`RequiredComponentConstructor`] that constructs a valid instance for the
200
/// component with ID `component_id`.
201
unsafe fn register_dynamic_with(
202
&mut self,
203
component_id: ComponentId,
204
components: &Components,
205
constructor: impl FnOnce() -> RequiredComponentConstructor,
206
) {
207
// If already registered as a direct required component then bail.
208
let entry = match self.direct.entry(component_id) {
209
indexmap::map::Entry::Vacant(entry) => entry,
210
indexmap::map::Entry::Occupied(_) =>
211
panic!("Error while registering required component {component_id:?}: already directly required"),
212
};
213
214
// Insert into `direct`.
215
let constructor = constructor();
216
let required_component = RequiredComponent { constructor };
217
entry.insert(required_component.clone());
218
219
// Register inherited required components.
220
// SAFETY:
221
// - the caller guarantees all components that were in `self` have been registered in `components`;
222
// - `component_id` has just been added, but is also guaranteed by the called to be valid in `components`.
223
unsafe {
224
Self::register_inherited_required_components_unchecked(
225
&mut self.all,
226
component_id,
227
required_component,
228
components,
229
);
230
}
231
}
232
233
/// Rebuild the `all` list
234
///
235
/// # Safety
236
///
237
/// - all components in `self` must have been registered in `components`.
238
unsafe fn rebuild_inherited_required_components(&mut self, components: &Components) {
239
// Clear `all`, we are re-initializing it.
240
self.all.clear();
241
242
// Register all inherited components as if we just registered all components in `direct` one-by-one.
243
for (&required_id, required_component) in &self.direct {
244
// SAFETY:
245
// - the caller guarantees that all components in this instance have been registered in `components`,
246
// meaning both `all` and `required_id` have been registered in `components`;
247
// - `required_component` was associated to `required_id`, so it must hold a constructor valid for it.
248
unsafe {
249
Self::register_inherited_required_components_unchecked(
250
&mut self.all,
251
required_id,
252
required_component.clone(),
253
components,
254
);
255
}
256
}
257
}
258
259
/// Registers all the inherited required components from `required_id`.
260
///
261
/// # Safety
262
///
263
/// - all components in `all` must have been registered in `components`;
264
/// - `required_id` must have been registered in `components`;
265
/// - `required_component` must hold a valid constructor for the component with id `required_id`.
266
unsafe fn register_inherited_required_components_unchecked(
267
all: &mut IndexMap<ComponentId, RequiredComponent, FixedHasher>,
268
required_id: ComponentId,
269
required_component: RequiredComponent,
270
components: &Components,
271
) {
272
// SAFETY: the caller guarantees that `required_id` is valid in `components`.
273
let info = unsafe { components.get_info(required_id).debug_checked_unwrap() };
274
275
// Now we need to "recursively" register the
276
// Small optimization: if the current required component was already required recursively
277
// by an earlier direct required component then all its inherited components have all already
278
// been inserted, so let's not try to reinsert them.
279
if !all.contains_key(&required_id) {
280
for (&inherited_id, inherited_required) in &info.required_components().all {
281
// This is an inherited required component: insert it only if not already present.
282
// By the invariants of `RequiredComponents`, `info.required_components().all` holds the required
283
// components in a depth-first order, and this makes us store the components in `self.all` also
284
// in depth-first order, as long as we don't overwrite existing ones.
285
//
286
// SAFETY:
287
// `inherited_required` was associated to `inherited_id`, so it must have been valid for its component.
288
all.entry(inherited_id)
289
.or_insert_with(|| inherited_required.clone());
290
}
291
}
292
293
// For direct required components:
294
// - insert them after inherited components to follow the depth-first order;
295
// - insert them unconditionally in order to make their constructor the one that's used.
296
// Note that `insert` does not change the order of components, meaning `component_id` will still appear
297
// before any other component that requires it.
298
//
299
// SAFETY: the caller guaranees that `required_component` is valid for the component with ID `required_id`.
300
all.insert(required_id, required_component);
301
}
302
303
/// Iterates the ids of all required components. This includes recursive required components.
304
pub fn iter_ids(&self) -> impl Iterator<Item = ComponentId> + '_ {
305
self.all.keys().copied()
306
}
307
}
308
309
impl Components {
310
/// Registers the components in `required_components` as required by `requiree`.
311
///
312
/// # Safety
313
///
314
/// - `requiree` must have been registered in `self`
315
/// - all components in `required_components` must have been registered in `self`;
316
/// - this is called with `requiree` before being called on any component requiring `requiree`.
317
pub(crate) unsafe fn register_required_by(
318
&mut self,
319
requiree: ComponentId,
320
required_components: &RequiredComponents,
321
) {
322
for &required in required_components.all.keys() {
323
// SAFETY: the caller guarantees that all components in `required_components` have been registered in `self`.
324
let required_by = unsafe { self.get_required_by_mut(required).debug_checked_unwrap() };
325
// This preserves the invariant of `required_by` because:
326
// - components requiring `required` and required by `requiree` are already initialized at this point
327
// and hence registered in `required_by` before `requiree`;
328
// - components requiring `requiree` cannot exist yet, as this is called on `requiree` before them.
329
required_by.insert(requiree);
330
}
331
}
332
333
/// Registers the given component `R` and [required components] inherited from it as required by `T`.
334
///
335
/// When `T` is added to an entity, `R` will also be added if it was not already provided.
336
/// The given `constructor` will be used for the creation of `R`.
337
///
338
/// [required components]: Component#required-components
339
///
340
/// # Safety
341
///
342
/// - the given component IDs `required` and `requiree` must be valid in `self`;
343
/// - the given component ID `required` must be valid for the component type `R`.
344
///
345
///
346
/// # Errors
347
///
348
/// Returns a [`RequiredComponentsError`] if either of these are true:
349
/// - the `required` component is already a *directly* required component for the `requiree`; indirect
350
/// requirements through other components are allowed. In those cases, the more specific
351
/// registration will be used.
352
/// - the `requiree` component is already a (possibly indirect) required component for the `required` component.
353
pub(crate) unsafe fn register_required_components<R: Component>(
354
&mut self,
355
requiree: ComponentId,
356
required: ComponentId,
357
constructor: fn() -> R,
358
) -> Result<(), RequiredComponentsError> {
359
// First step: validate inputs and return errors.
360
361
// SAFETY: The caller ensures that the `required` is valid.
362
let required_required_components = unsafe {
363
self.get_required_components(required)
364
.debug_checked_unwrap()
365
};
366
367
// Cannot create cyclic requirements.
368
if required_required_components.all.contains_key(&requiree) {
369
return Err(RequiredComponentsError::CyclicRequirement(
370
requiree, required,
371
));
372
}
373
374
// SAFETY: The caller ensures that the `requiree` is valid.
375
let required_components = unsafe {
376
self.get_required_components_mut(requiree)
377
.debug_checked_unwrap()
378
};
379
380
// Cannot directly require the same component twice.
381
if required_components.direct.contains_key(&required) {
382
return Err(RequiredComponentsError::DuplicateRegistration(
383
requiree, required,
384
));
385
}
386
387
// Second step: register the single requirement requiree->required
388
389
// Store the old count of (all) required components. This will help determine which ones are new.
390
let old_required_count = required_components.all.len();
391
392
// SAFETY: the caller guarantees that `requiree` is valid in `self`.
393
self.required_components_scope(requiree, |this, required_components| {
394
// SAFETY: the caller guarantees that `required` is valid for type `R` in `self`
395
unsafe { required_components.register_by_id(required, this, constructor) };
396
});
397
398
// Third step: update the required components and required_by of all the indirect requirements/requirees.
399
400
// Borrow again otherwise it conflicts with the `self.required_components_scope` call.
401
// SAFETY: The caller ensures that the `requiree` is valid.
402
let required_components = unsafe {
403
self.get_required_components_mut(requiree)
404
.debug_checked_unwrap()
405
};
406
407
// Optimization: get all the new required components, i.e. those that were appended.
408
// Other components that might be inherited when requiring `required` can be safely ignored because
409
// any component requiring `requiree` will already transitively require them.
410
// Note: the only small exception is for `required` itself, for which we cannot ignore the value of the
411
// constructor. But for simplicity we will rebuild any `RequiredComponents`
412
let new_required_components = required_components.all[old_required_count..]
413
.keys()
414
.copied()
415
.collect::<Vec<_>>();
416
417
// Get all the new requiree components, i.e. `requiree` and all the components that `requiree` is required by.
418
// SAFETY: The caller ensures that the `requiree` is valid.
419
let requiree_required_by = unsafe { self.get_required_by(requiree).debug_checked_unwrap() };
420
let new_requiree_components = [requiree]
421
.into_iter()
422
.chain(requiree_required_by.iter().copied())
423
.collect::<IndexSet<_, FixedHasher>>();
424
425
// We now need to update the required and required_by components of all the components
426
// directly or indirectly involved.
427
// Important: we need to be careful about the order we do these operations in.
428
// Since computing the required components of some component depends on the required components of
429
// other components, and while we do this operations not all required components are up-to-date, we need
430
// to ensure we update components in such a way that we update a component after the components it depends on.
431
// Luckily, `new_requiree_components` comes from `ComponentInfo::required_by`, which guarantees an order
432
// with that property.
433
434
// Update the inherited required components of all requiree components (directly or indirectly).
435
// Skip the first one (requiree) because we already updates it.
436
for &indirect_requiree in &new_requiree_components[1..] {
437
// SAFETY: `indirect_requiree` comes from `self` so it must be valid.
438
self.required_components_scope(indirect_requiree, |this, required_components| {
439
// Rebuild the inherited required components.
440
// SAFETY: `required_components` comes from `self`, so all its components must have be valid in `self`.
441
unsafe { required_components.rebuild_inherited_required_components(this) };
442
});
443
}
444
445
// Update the `required_by` of all the components that were newly required (directly or indirectly).
446
for &indirect_required in &new_required_components {
447
// SAFETY: `indirect_required` comes from `self`, so it must be valid.
448
let required_by = unsafe {
449
self.get_required_by_mut(indirect_required)
450
.debug_checked_unwrap()
451
};
452
453
// Remove and re-add all the components in `new_requiree_components`
454
// This preserves the invariant of `required_by` because `new_requiree_components`
455
// satisfies its invariant, due to being `requiree` followed by its `required_by` components,
456
// and because any component not in `new_requiree_components` cannot require a component in it,
457
// since if that was the case it would appear in the `required_by` for `requiree`.
458
required_by.retain(|id| !new_requiree_components.contains(id));
459
required_by.extend(&new_requiree_components);
460
}
461
462
Ok(())
463
}
464
465
/// Temporarily take out the [`RequiredComponents`] of the component with id `component_id`
466
/// and runs the given closure with mutable access to `self` and the given [`RequiredComponents`].
467
///
468
/// SAFETY:
469
///
470
/// `component_id` is valid in `self.components`
471
unsafe fn required_components_scope<R>(
472
&mut self,
473
component_id: ComponentId,
474
f: impl FnOnce(&mut Self, &mut RequiredComponents) -> R,
475
) -> R {
476
struct DropGuard<'a> {
477
components: &'a mut Components,
478
component_id: ComponentId,
479
required_components: RequiredComponents,
480
}
481
482
impl Drop for DropGuard<'_> {
483
fn drop(&mut self) {
484
// SAFETY: The caller ensures that the `component_id` is valid.
485
let required_components = unsafe {
486
self.components
487
.get_required_components_mut(self.component_id)
488
.debug_checked_unwrap()
489
};
490
491
debug_assert!(required_components.direct.is_empty());
492
debug_assert!(required_components.all.is_empty());
493
494
*required_components = core::mem::take(&mut self.required_components);
495
}
496
}
497
498
let mut guard = DropGuard {
499
component_id,
500
// SAFETY: The caller ensures that the `component_id` is valid.
501
required_components: core::mem::take(unsafe {
502
self.get_required_components_mut(component_id)
503
.debug_checked_unwrap()
504
}),
505
components: self,
506
};
507
508
f(guard.components, &mut guard.required_components)
509
}
510
}
511
512
/// An error returned when the registration of a required component fails.
513
#[derive(Error, Debug)]
514
#[non_exhaustive]
515
pub enum RequiredComponentsError {
516
/// The component is already a directly required component for the requiree.
517
#[error("Component {0:?} already directly requires component {1:?}")]
518
DuplicateRegistration(ComponentId, ComponentId),
519
/// Adding the given requirement would create a cycle.
520
#[error("Cyclic requirement found: the requiree component {0:?} is required by the required component {1:?}")]
521
CyclicRequirement(ComponentId, ComponentId),
522
/// An archetype with the component that requires other components already exists
523
#[error("An archetype with the component {0:?} that requires other components already exists")]
524
ArchetypeExists(ComponentId),
525
}
526
527
pub(super) fn enforce_no_required_components_recursion(
528
components: &Components,
529
recursion_check_stack: &[ComponentId],
530
required: ComponentId,
531
) {
532
if let Some(direct_recursion) = recursion_check_stack
533
.iter()
534
.position(|&id| id == required)
535
.map(|index| index == recursion_check_stack.len() - 1)
536
{
537
panic!(
538
"Recursive required components detected: {}\nhelp: {}",
539
recursion_check_stack
540
.iter()
541
.map(|id| format!("{}", components.get_name(*id).unwrap().shortname()))
542
.collect::<Vec<_>>()
543
.join(""),
544
if direct_recursion {
545
format!(
546
"Remove require({}).",
547
components.get_name(required).unwrap().shortname()
548
)
549
} else {
550
"If this is intentional, consider merging the components.".into()
551
}
552
);
553
}
554
}
555
556
/// This is a safe handle around `ComponentsRegistrator` and `RequiredComponents` to register required components.
557
pub struct RequiredComponentsRegistrator<'a, 'w> {
558
components: &'a mut ComponentsRegistrator<'w>,
559
required_components: &'a mut RequiredComponents,
560
}
561
562
impl<'a, 'w> RequiredComponentsRegistrator<'a, 'w> {
563
/// # Safety
564
///
565
/// All components in `required_components` must have been registered in `components`
566
pub(super) unsafe fn new(
567
components: &'a mut ComponentsRegistrator<'w>,
568
required_components: &'a mut RequiredComponents,
569
) -> Self {
570
Self {
571
components,
572
required_components,
573
}
574
}
575
576
/// Registers the [`Component`] `C` as an explicitly required component.
577
///
578
/// If the component was not already registered as an explicit required component then it is added
579
/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.
580
pub fn register_required<C: Component>(&mut self, constructor: fn() -> C) {
581
// SAFETY: we internally guarantee that all components in `required_components`
582
// are registered in `components`
583
unsafe {
584
self.required_components
585
.register(self.components, constructor);
586
}
587
}
588
589
/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.
590
///
591
/// If the component was not already registered as an explicit required component then it is added
592
/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.
593
///
594
/// # Safety
595
///
596
/// `component_id` must be a valid [`ComponentId`] for `C` in the [`Components`] instance of `self`.
597
pub unsafe fn register_required_by_id<C: Component>(
598
&mut self,
599
component_id: ComponentId,
600
constructor: fn() -> C,
601
) {
602
// SAFETY:
603
// - the caller guarantees `component_id` is a valid component in `components` for `C`;
604
// - we internally guarantee all other components in `required_components` are registered in `components`.
605
unsafe {
606
self.required_components.register_by_id::<C>(
607
component_id,
608
self.components,
609
constructor,
610
);
611
}
612
}
613
614
/// Registers the [`Component`] with the given `component_id` ID as an explicitly required component.
615
///
616
/// If the component was not already registered as an explicit required component then it is added
617
/// as one, potentially overriding the constructor of a inherited required component, otherwise panics.
618
///
619
/// # Safety
620
///
621
/// - `component_id` must be valid in the [`Components`] instance of `self`;
622
/// - `constructor` must return a [`RequiredComponentConstructor`] that constructs a valid instance for the
623
/// component with ID `component_id`.
624
pub unsafe fn register_required_dynamic_with(
625
&mut self,
626
component_id: ComponentId,
627
constructor: impl FnOnce() -> RequiredComponentConstructor,
628
) {
629
// SAFETY:
630
// - the caller guarantees `component_id` is valid in `components`;
631
// - the caller guarantees `constructor` returns a valid constructor for `component_id`;
632
// - we internally guarantee all other components in `required_components` are registered in `components`.
633
unsafe {
634
self.required_components.register_dynamic_with(
635
component_id,
636
self.components,
637
constructor,
638
);
639
}
640
}
641
}
642
643
#[cfg(test)]
644
mod tests {
645
use alloc::string::{String, ToString};
646
647
use crate::{
648
bundle::Bundle,
649
component::{Component, RequiredComponentsError},
650
prelude::Resource,
651
world::World,
652
};
653
654
#[test]
655
fn required_components() {
656
#[derive(Component)]
657
#[require(Y)]
658
struct X;
659
660
#[derive(Component)]
661
#[require(Z = new_z())]
662
struct Y {
663
value: String,
664
}
665
666
#[derive(Component)]
667
struct Z(u32);
668
669
impl Default for Y {
670
fn default() -> Self {
671
Self {
672
value: "hello".to_string(),
673
}
674
}
675
}
676
677
fn new_z() -> Z {
678
Z(7)
679
}
680
681
let mut world = World::new();
682
let id = world.spawn(X).id();
683
assert_eq!(
684
"hello",
685
world.entity(id).get::<Y>().unwrap().value,
686
"Y should have the default value"
687
);
688
assert_eq!(
689
7,
690
world.entity(id).get::<Z>().unwrap().0,
691
"Z should have the value provided by the constructor defined in Y"
692
);
693
694
let id = world
695
.spawn((
696
X,
697
Y {
698
value: "foo".to_string(),
699
},
700
))
701
.id();
702
assert_eq!(
703
"foo",
704
world.entity(id).get::<Y>().unwrap().value,
705
"Y should have the manually provided value"
706
);
707
assert_eq!(
708
7,
709
world.entity(id).get::<Z>().unwrap().0,
710
"Z should have the value provided by the constructor defined in Y"
711
);
712
713
let id = world.spawn((X, Z(8))).id();
714
assert_eq!(
715
"hello",
716
world.entity(id).get::<Y>().unwrap().value,
717
"Y should have the default value"
718
);
719
assert_eq!(
720
8,
721
world.entity(id).get::<Z>().unwrap().0,
722
"Z should have the manually provided value"
723
);
724
}
725
726
#[test]
727
fn generic_required_components() {
728
#[derive(Component)]
729
#[require(Y<usize>)]
730
struct X;
731
732
#[derive(Component, Default)]
733
struct Y<T> {
734
value: T,
735
}
736
737
let mut world = World::new();
738
let id = world.spawn(X).id();
739
assert_eq!(
740
0,
741
world.entity(id).get::<Y<usize>>().unwrap().value,
742
"Y should have the default value"
743
);
744
}
745
746
#[test]
747
fn required_components_spawn_nonexistent_hooks() {
748
#[derive(Component)]
749
#[require(Y)]
750
struct X;
751
752
#[derive(Component, Default)]
753
struct Y;
754
755
#[derive(Resource)]
756
struct A(usize);
757
758
#[derive(Resource)]
759
struct I(usize);
760
761
let mut world = World::new();
762
world.insert_resource(A(0));
763
world.insert_resource(I(0));
764
world
765
.register_component_hooks::<Y>()
766
.on_add(|mut world, _| world.resource_mut::<A>().0 += 1)
767
.on_insert(|mut world, _| world.resource_mut::<I>().0 += 1);
768
769
// Spawn entity and ensure Y was added
770
assert!(world.spawn(X).contains::<Y>());
771
772
assert_eq!(world.resource::<A>().0, 1);
773
assert_eq!(world.resource::<I>().0, 1);
774
}
775
776
#[test]
777
fn required_components_insert_existing_hooks() {
778
#[derive(Component)]
779
#[require(Y)]
780
struct X;
781
782
#[derive(Component, Default)]
783
struct Y;
784
785
#[derive(Resource)]
786
struct A(usize);
787
788
#[derive(Resource)]
789
struct I(usize);
790
791
let mut world = World::new();
792
world.insert_resource(A(0));
793
world.insert_resource(I(0));
794
world
795
.register_component_hooks::<Y>()
796
.on_add(|mut world, _| world.resource_mut::<A>().0 += 1)
797
.on_insert(|mut world, _| world.resource_mut::<I>().0 += 1);
798
799
// Spawn entity and ensure Y was added
800
assert!(world.spawn_empty().insert(X).contains::<Y>());
801
802
assert_eq!(world.resource::<A>().0, 1);
803
assert_eq!(world.resource::<I>().0, 1);
804
}
805
806
#[test]
807
fn required_components_take_leaves_required() {
808
#[derive(Component)]
809
#[require(Y)]
810
struct X;
811
812
#[derive(Component, Default)]
813
struct Y;
814
815
let mut world = World::new();
816
let e = world.spawn(X).id();
817
let _ = world.entity_mut(e).take::<X>().unwrap();
818
assert!(world.entity_mut(e).contains::<Y>());
819
}
820
821
#[test]
822
fn required_components_retain_keeps_required() {
823
#[derive(Component)]
824
#[require(Y)]
825
struct X;
826
827
#[derive(Component, Default)]
828
struct Y;
829
830
#[derive(Component, Default)]
831
struct Z;
832
833
let mut world = World::new();
834
let e = world.spawn((X, Z)).id();
835
world.entity_mut(e).retain::<X>();
836
assert!(world.entity_mut(e).contains::<X>());
837
assert!(world.entity_mut(e).contains::<Y>());
838
assert!(!world.entity_mut(e).contains::<Z>());
839
}
840
841
#[test]
842
fn required_components_spawn_then_insert_no_overwrite() {
843
#[derive(Component)]
844
#[require(Y)]
845
struct X;
846
847
#[derive(Component, Default)]
848
struct Y(usize);
849
850
let mut world = World::new();
851
let id = world.spawn((X, Y(10))).id();
852
world.entity_mut(id).insert(X);
853
854
assert_eq!(
855
10,
856
world.entity(id).get::<Y>().unwrap().0,
857
"Y should still have the manually provided value"
858
);
859
}
860
861
#[test]
862
fn dynamic_required_components() {
863
#[derive(Component)]
864
#[require(Y)]
865
struct X;
866
867
#[derive(Component, Default)]
868
struct Y;
869
870
let mut world = World::new();
871
let x_id = world.register_component::<X>();
872
873
let mut e = world.spawn_empty();
874
875
// SAFETY: x_id is a valid component id
876
bevy_ptr::OwningPtr::make(X, |ptr| unsafe {
877
e.insert_by_id(x_id, ptr);
878
});
879
880
assert!(e.contains::<Y>());
881
}
882
883
#[test]
884
fn remove_component_and_its_runtime_required_components() {
885
#[derive(Component)]
886
struct X;
887
888
#[derive(Component, Default)]
889
struct Y;
890
891
#[derive(Component, Default)]
892
struct Z;
893
894
#[derive(Component)]
895
struct V;
896
897
let mut world = World::new();
898
world.register_required_components::<X, Y>();
899
world.register_required_components::<Y, Z>();
900
901
let e = world.spawn((X, V)).id();
902
assert!(world.entity(e).contains::<X>());
903
assert!(world.entity(e).contains::<Y>());
904
assert!(world.entity(e).contains::<Z>());
905
assert!(world.entity(e).contains::<V>());
906
907
//check that `remove` works as expected
908
world.entity_mut(e).remove::<X>();
909
assert!(!world.entity(e).contains::<X>());
910
assert!(world.entity(e).contains::<Y>());
911
assert!(world.entity(e).contains::<Z>());
912
assert!(world.entity(e).contains::<V>());
913
914
world.entity_mut(e).insert(X);
915
assert!(world.entity(e).contains::<X>());
916
assert!(world.entity(e).contains::<Y>());
917
assert!(world.entity(e).contains::<Z>());
918
assert!(world.entity(e).contains::<V>());
919
920
//remove `X` again and ensure that `Y` and `Z` was removed too
921
world.entity_mut(e).remove_with_requires::<X>();
922
assert!(!world.entity(e).contains::<X>());
923
assert!(!world.entity(e).contains::<Y>());
924
assert!(!world.entity(e).contains::<Z>());
925
assert!(world.entity(e).contains::<V>());
926
}
927
928
#[test]
929
fn remove_component_and_its_required_components() {
930
#[derive(Component)]
931
#[require(Y)]
932
struct X;
933
934
#[derive(Component, Default)]
935
#[require(Z)]
936
struct Y;
937
938
#[derive(Component, Default)]
939
struct Z;
940
941
#[derive(Component)]
942
struct V;
943
944
let mut world = World::new();
945
946
let e = world.spawn((X, V)).id();
947
assert!(world.entity(e).contains::<X>());
948
assert!(world.entity(e).contains::<Y>());
949
assert!(world.entity(e).contains::<Z>());
950
assert!(world.entity(e).contains::<V>());
951
952
//check that `remove` works as expected
953
world.entity_mut(e).remove::<X>();
954
assert!(!world.entity(e).contains::<X>());
955
assert!(world.entity(e).contains::<Y>());
956
assert!(world.entity(e).contains::<Z>());
957
assert!(world.entity(e).contains::<V>());
958
959
world.entity_mut(e).insert(X);
960
assert!(world.entity(e).contains::<X>());
961
assert!(world.entity(e).contains::<Y>());
962
assert!(world.entity(e).contains::<Z>());
963
assert!(world.entity(e).contains::<V>());
964
965
//remove `X` again and ensure that `Y` and `Z` was removed too
966
world.entity_mut(e).remove_with_requires::<X>();
967
assert!(!world.entity(e).contains::<X>());
968
assert!(!world.entity(e).contains::<Y>());
969
assert!(!world.entity(e).contains::<Z>());
970
assert!(world.entity(e).contains::<V>());
971
}
972
973
#[test]
974
fn remove_bundle_and_his_required_components() {
975
#[derive(Component, Default)]
976
#[require(Y)]
977
struct X;
978
979
#[derive(Component, Default)]
980
struct Y;
981
982
#[derive(Component, Default)]
983
#[require(W)]
984
struct Z;
985
986
#[derive(Component, Default)]
987
struct W;
988
989
#[derive(Component)]
990
struct V;
991
992
#[derive(Bundle, Default)]
993
struct TestBundle {
994
x: X,
995
z: Z,
996
}
997
998
let mut world = World::new();
999
let e = world.spawn((TestBundle::default(), V)).id();
1000
1001
assert!(world.entity(e).contains::<X>());
1002
assert!(world.entity(e).contains::<Y>());
1003
assert!(world.entity(e).contains::<Z>());
1004
assert!(world.entity(e).contains::<W>());
1005
assert!(world.entity(e).contains::<V>());
1006
1007
world.entity_mut(e).remove_with_requires::<TestBundle>();
1008
assert!(!world.entity(e).contains::<X>());
1009
assert!(!world.entity(e).contains::<Y>());
1010
assert!(!world.entity(e).contains::<Z>());
1011
assert!(!world.entity(e).contains::<W>());
1012
assert!(world.entity(e).contains::<V>());
1013
}
1014
1015
#[test]
1016
fn runtime_required_components() {
1017
// Same as `required_components` test but with runtime registration
1018
1019
#[derive(Component)]
1020
struct X;
1021
1022
#[derive(Component)]
1023
struct Y {
1024
value: String,
1025
}
1026
1027
#[derive(Component)]
1028
struct Z(u32);
1029
1030
impl Default for Y {
1031
fn default() -> Self {
1032
Self {
1033
value: "hello".to_string(),
1034
}
1035
}
1036
}
1037
1038
let mut world = World::new();
1039
1040
world.register_required_components::<X, Y>();
1041
world.register_required_components_with::<Y, Z>(|| Z(7));
1042
1043
let id = world.spawn(X).id();
1044
1045
assert_eq!(
1046
"hello",
1047
world.entity(id).get::<Y>().unwrap().value,
1048
"Y should have the default value"
1049
);
1050
assert_eq!(
1051
7,
1052
world.entity(id).get::<Z>().unwrap().0,
1053
"Z should have the value provided by the constructor defined in Y"
1054
);
1055
1056
let id = world
1057
.spawn((
1058
X,
1059
Y {
1060
value: "foo".to_string(),
1061
},
1062
))
1063
.id();
1064
assert_eq!(
1065
"foo",
1066
world.entity(id).get::<Y>().unwrap().value,
1067
"Y should have the manually provided value"
1068
);
1069
assert_eq!(
1070
7,
1071
world.entity(id).get::<Z>().unwrap().0,
1072
"Z should have the value provided by the constructor defined in Y"
1073
);
1074
1075
let id = world.spawn((X, Z(8))).id();
1076
assert_eq!(
1077
"hello",
1078
world.entity(id).get::<Y>().unwrap().value,
1079
"Y should have the default value"
1080
);
1081
assert_eq!(
1082
8,
1083
world.entity(id).get::<Z>().unwrap().0,
1084
"Z should have the manually provided value"
1085
);
1086
}
1087
1088
#[test]
1089
fn runtime_required_components_override_1() {
1090
#[derive(Component)]
1091
struct X;
1092
1093
#[derive(Component, Default)]
1094
struct Y;
1095
1096
#[derive(Component)]
1097
struct Z(u32);
1098
1099
let mut world = World::new();
1100
1101
// - X requires Y with default constructor
1102
// - Y requires Z with custom constructor
1103
// - X requires Z with custom constructor (more specific than X -> Y -> Z)
1104
world.register_required_components::<X, Y>();
1105
world.register_required_components_with::<Y, Z>(|| Z(5));
1106
world.register_required_components_with::<X, Z>(|| Z(7));
1107
1108
let id = world.spawn(X).id();
1109
1110
assert_eq!(
1111
7,
1112
world.entity(id).get::<Z>().unwrap().0,
1113
"Z should have the value provided by the constructor defined in X"
1114
);
1115
}
1116
1117
#[test]
1118
fn runtime_required_components_override_2() {
1119
// Same as `runtime_required_components_override_1` test but with different registration order
1120
1121
#[derive(Component)]
1122
struct X;
1123
1124
#[derive(Component, Default)]
1125
struct Y;
1126
1127
#[derive(Component)]
1128
struct Z(u32);
1129
1130
let mut world = World::new();
1131
1132
// - X requires Y with default constructor
1133
// - X requires Z with custom constructor (more specific than X -> Y -> Z)
1134
// - Y requires Z with custom constructor
1135
world.register_required_components::<X, Y>();
1136
world.register_required_components_with::<X, Z>(|| Z(7));
1137
world.register_required_components_with::<Y, Z>(|| Z(5));
1138
1139
let id = world.spawn(X).id();
1140
1141
assert_eq!(
1142
7,
1143
world.entity(id).get::<Z>().unwrap().0,
1144
"Z should have the value provided by the constructor defined in X"
1145
);
1146
}
1147
1148
#[test]
1149
fn runtime_required_components_propagate_up() {
1150
// `A` requires `B` directly.
1151
#[derive(Component)]
1152
#[require(B)]
1153
struct A;
1154
1155
#[derive(Component, Default)]
1156
struct B;
1157
1158
#[derive(Component, Default)]
1159
struct C;
1160
1161
let mut world = World::new();
1162
1163
// `B` requires `C` with a runtime registration.
1164
// `A` should also require `C` because it requires `B`.
1165
world.register_required_components::<B, C>();
1166
1167
let id = world.spawn(A).id();
1168
1169
assert!(world.entity(id).get::<C>().is_some());
1170
}
1171
1172
#[test]
1173
fn runtime_required_components_propagate_up_even_more() {
1174
#[derive(Component)]
1175
struct A;
1176
1177
#[derive(Component, Default)]
1178
struct B;
1179
1180
#[derive(Component, Default)]
1181
struct C;
1182
1183
#[derive(Component, Default)]
1184
struct D;
1185
1186
let mut world = World::new();
1187
1188
world.register_required_components::<A, B>();
1189
world.register_required_components::<B, C>();
1190
world.register_required_components::<C, D>();
1191
1192
let id = world.spawn(A).id();
1193
1194
assert!(world.entity(id).get::<D>().is_some());
1195
}
1196
1197
#[test]
1198
fn runtime_required_components_deep_require_does_not_override_shallow_require() {
1199
#[derive(Component)]
1200
struct A;
1201
#[derive(Component, Default)]
1202
struct B;
1203
#[derive(Component, Default)]
1204
struct C;
1205
#[derive(Component)]
1206
struct Counter(i32);
1207
#[derive(Component, Default)]
1208
struct D;
1209
1210
let mut world = World::new();
1211
1212
world.register_required_components::<A, B>();
1213
world.register_required_components::<B, C>();
1214
world.register_required_components::<C, D>();
1215
world.register_required_components_with::<D, Counter>(|| Counter(2));
1216
// This should replace the require constructor in A since it is
1217
// shallower.
1218
world.register_required_components_with::<C, Counter>(|| Counter(1));
1219
1220
let id = world.spawn(A).id();
1221
1222
// The "shallower" of the two components is used.
1223
assert_eq!(world.entity(id).get::<Counter>().unwrap().0, 1);
1224
}
1225
1226
#[test]
1227
fn runtime_required_components_deep_require_does_not_override_shallow_require_deep_subtree_after_shallow(
1228
) {
1229
#[derive(Component)]
1230
struct A;
1231
#[derive(Component, Default)]
1232
struct B;
1233
#[derive(Component, Default)]
1234
struct C;
1235
#[derive(Component, Default)]
1236
struct D;
1237
#[derive(Component, Default)]
1238
struct E;
1239
#[derive(Component)]
1240
struct Counter(i32);
1241
#[derive(Component, Default)]
1242
struct F;
1243
1244
let mut world = World::new();
1245
1246
world.register_required_components::<A, B>();
1247
world.register_required_components::<B, C>();
1248
world.register_required_components::<C, D>();
1249
world.register_required_components::<D, E>();
1250
world.register_required_components_with::<E, Counter>(|| Counter(1));
1251
world.register_required_components_with::<F, Counter>(|| Counter(2));
1252
world.register_required_components::<E, F>();
1253
1254
let id = world.spawn(A).id();
1255
1256
// The "shallower" of the two components is used.
1257
assert_eq!(world.entity(id).get::<Counter>().unwrap().0, 1);
1258
}
1259
1260
#[test]
1261
fn runtime_required_components_existing_archetype() {
1262
#[derive(Component)]
1263
struct X;
1264
1265
#[derive(Component, Default)]
1266
struct Y;
1267
1268
let mut world = World::new();
1269
1270
// Registering required components after the archetype has already been created should panic.
1271
// This may change in the future.
1272
world.spawn(X);
1273
assert!(matches!(
1274
world.try_register_required_components::<X, Y>(),
1275
Err(RequiredComponentsError::ArchetypeExists(_))
1276
));
1277
}
1278
1279
#[test]
1280
fn runtime_required_components_fail_with_duplicate() {
1281
#[derive(Component)]
1282
#[require(Y)]
1283
struct X;
1284
1285
#[derive(Component, Default)]
1286
struct Y;
1287
1288
let mut world = World::new();
1289
1290
// This should fail: Tried to register Y as a requirement for X, but the requirement already exists.
1291
assert!(matches!(
1292
world.try_register_required_components::<X, Y>(),
1293
Err(RequiredComponentsError::DuplicateRegistration(_, _))
1294
));
1295
}
1296
1297
#[test]
1298
fn required_components_bundle_priority() {
1299
#[derive(Component, PartialEq, Eq, Clone, Copy, Debug)]
1300
struct MyRequired(bool);
1301
1302
#[derive(Component, Default)]
1303
#[require(MyRequired(false))]
1304
struct MiddleMan;
1305
1306
#[derive(Component, Default)]
1307
#[require(MiddleMan)]
1308
struct ConflictingRequire;
1309
1310
#[derive(Component, Default)]
1311
#[require(MyRequired(true))]
1312
struct MyComponent;
1313
1314
let mut world = World::new();
1315
let order_a = world
1316
.spawn((ConflictingRequire, MyComponent))
1317
.get::<MyRequired>()
1318
.cloned();
1319
let order_b = world
1320
.spawn((MyComponent, ConflictingRequire))
1321
.get::<MyRequired>()
1322
.cloned();
1323
1324
assert_eq!(order_a, Some(MyRequired(false)));
1325
assert_eq!(order_b, Some(MyRequired(true)));
1326
}
1327
1328
#[test]
1329
#[should_panic]
1330
fn required_components_recursion_errors() {
1331
#[derive(Component, Default)]
1332
#[require(B)]
1333
struct A;
1334
1335
#[derive(Component, Default)]
1336
#[require(C)]
1337
struct B;
1338
1339
#[derive(Component, Default)]
1340
#[require(B)]
1341
struct C;
1342
1343
World::new().register_component::<A>();
1344
}
1345
1346
#[test]
1347
#[should_panic]
1348
fn required_components_self_errors() {
1349
#[derive(Component, Default)]
1350
#[require(A)]
1351
struct A;
1352
1353
World::new().register_component::<A>();
1354
}
1355
1356
#[test]
1357
fn regression_19333() {
1358
#[derive(Component)]
1359
struct X(usize);
1360
1361
#[derive(Default, Component)]
1362
#[require(X(0))]
1363
struct Base;
1364
1365
#[derive(Default, Component)]
1366
#[require(X(1), Base)]
1367
struct A;
1368
1369
#[derive(Default, Component)]
1370
#[require(A, Base)]
1371
struct B;
1372
1373
#[derive(Default, Component)]
1374
#[require(B, Base)]
1375
struct C;
1376
1377
let mut w = World::new();
1378
1379
assert_eq!(w.spawn(B).get::<X>().unwrap().0, 1);
1380
assert_eq!(w.spawn(C).get::<X>().unwrap().0, 1);
1381
}
1382
1383
#[test]
1384
fn required_components_depth_first_2v1() {
1385
#[derive(Component)]
1386
struct X(usize);
1387
1388
#[derive(Component)]
1389
#[require(Left, Right)]
1390
struct Root;
1391
1392
#[derive(Component, Default)]
1393
#[require(LeftLeft)]
1394
struct Left;
1395
1396
#[derive(Component, Default)]
1397
#[require(X(0))] // This is at depth 2 but is more on the left of the tree
1398
struct LeftLeft;
1399
1400
#[derive(Component, Default)]
1401
#[require(X(1))] //. This is at depth 1 but is more on the right of the tree
1402
struct Right;
1403
1404
let mut world = World::new();
1405
1406
// LeftLeft should have priority over Right
1407
assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);
1408
}
1409
1410
#[test]
1411
fn required_components_depth_first_3v1() {
1412
#[derive(Component)]
1413
struct X(usize);
1414
1415
#[derive(Component)]
1416
#[require(Left, Right)]
1417
struct Root;
1418
1419
#[derive(Component, Default)]
1420
#[require(LeftLeft)]
1421
struct Left;
1422
1423
#[derive(Component, Default)]
1424
#[require(LeftLeftLeft)]
1425
struct LeftLeft;
1426
1427
#[derive(Component, Default)]
1428
#[require(X(0))] // This is at depth 3 but is more on the left of the tree
1429
struct LeftLeftLeft;
1430
1431
#[derive(Component, Default)]
1432
#[require(X(1))] //. This is at depth 1 but is more on the right of the tree
1433
struct Right;
1434
1435
let mut world = World::new();
1436
1437
// LeftLeftLeft should have priority over Right
1438
assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);
1439
}
1440
1441
#[test]
1442
fn runtime_required_components_depth_first_2v1() {
1443
#[derive(Component)]
1444
struct X(usize);
1445
1446
#[derive(Component)]
1447
struct Root;
1448
1449
#[derive(Component, Default)]
1450
struct Left;
1451
1452
#[derive(Component, Default)]
1453
struct LeftLeft;
1454
1455
#[derive(Component, Default)]
1456
struct Right;
1457
1458
// Register bottom up: registering higher level components should pick up lower level ones.
1459
let mut world = World::new();
1460
world.register_required_components_with::<LeftLeft, X>(|| X(0));
1461
world.register_required_components_with::<Right, X>(|| X(1));
1462
world.register_required_components::<Left, LeftLeft>();
1463
world.register_required_components::<Root, Left>();
1464
world.register_required_components::<Root, Right>();
1465
assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);
1466
1467
// Register top down: registering lower components should propagate to higher ones
1468
let mut world = World::new();
1469
world.register_required_components::<Root, Left>(); // Note: still register Left before Right
1470
world.register_required_components::<Root, Right>();
1471
world.register_required_components::<Left, LeftLeft>();
1472
world.register_required_components_with::<Right, X>(|| X(1));
1473
world.register_required_components_with::<LeftLeft, X>(|| X(0));
1474
assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);
1475
1476
// Register top down again, but this time LeftLeft before Right
1477
let mut world = World::new();
1478
world.register_required_components::<Root, Left>();
1479
world.register_required_components::<Root, Right>();
1480
world.register_required_components::<Left, LeftLeft>();
1481
world.register_required_components_with::<LeftLeft, X>(|| X(0));
1482
world.register_required_components_with::<Right, X>(|| X(1));
1483
assert_eq!(world.spawn(Root).get::<X>().unwrap().0, 0);
1484
}
1485
1486
#[test]
1487
fn runtime_required_components_propagate_metadata_alternate() {
1488
#[derive(Component, Default)]
1489
#[require(L1)]
1490
struct L0;
1491
1492
#[derive(Component, Default)]
1493
struct L1;
1494
1495
#[derive(Component, Default)]
1496
#[require(L3)]
1497
struct L2;
1498
1499
#[derive(Component, Default)]
1500
struct L3;
1501
1502
#[derive(Component, Default)]
1503
#[require(L5)]
1504
struct L4;
1505
1506
#[derive(Component, Default)]
1507
struct L5;
1508
1509
// Try to piece the 3 requirements together
1510
let mut world = World::new();
1511
world.register_required_components::<L1, L2>();
1512
world.register_required_components::<L3, L4>();
1513
let e = world.spawn(L0).id();
1514
assert!(world
1515
.query::<(&L0, &L1, &L2, &L3, &L4, &L5)>()
1516
.get(&world, e)
1517
.is_ok());
1518
1519
// Repeat but in the opposite order
1520
let mut world = World::new();
1521
world.register_required_components::<L3, L4>();
1522
world.register_required_components::<L1, L2>();
1523
let e = world.spawn(L0).id();
1524
assert!(world
1525
.query::<(&L0, &L1, &L2, &L3, &L4, &L5)>()
1526
.get(&world, e)
1527
.is_ok());
1528
}
1529
1530
#[test]
1531
fn runtime_required_components_propagate_metadata_chain() {
1532
#[derive(Component, Default)]
1533
#[require(L1)]
1534
struct L0;
1535
1536
#[derive(Component, Default)]
1537
struct L1;
1538
1539
#[derive(Component, Default)]
1540
struct L2;
1541
1542
#[derive(Component, Default)]
1543
#[require(L4)]
1544
struct L3;
1545
1546
#[derive(Component, Default)]
1547
struct L4;
1548
1549
// Try to piece the 3 requirements together
1550
let mut world = World::new();
1551
world.register_required_components::<L1, L2>();
1552
world.register_required_components::<L2, L3>();
1553
let e = world.spawn(L0).id();
1554
assert!(world
1555
.query::<(&L0, &L1, &L2, &L3, &L4)>()
1556
.get(&world, e)
1557
.is_ok());
1558
1559
// Repeat but in the opposite order
1560
let mut world = World::new();
1561
world.register_required_components::<L2, L3>();
1562
world.register_required_components::<L1, L2>();
1563
let e = world.spawn(L0).id();
1564
assert!(world
1565
.query::<(&L0, &L1, &L2, &L3, &L4)>()
1566
.get(&world, e)
1567
.is_ok());
1568
}
1569
1570
#[test]
1571
fn runtime_required_components_cyclic() {
1572
#[derive(Component, Default)]
1573
#[require(B)]
1574
struct A;
1575
1576
#[derive(Component, Default)]
1577
struct B;
1578
1579
#[derive(Component, Default)]
1580
struct C;
1581
1582
let mut world = World::new();
1583
1584
assert!(world.try_register_required_components::<B, C>().is_ok());
1585
assert!(matches!(
1586
world.try_register_required_components::<C, A>(),
1587
Err(RequiredComponentsError::CyclicRequirement(_, _))
1588
));
1589
}
1590
}
1591
1592