Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/component/mod.rs
9374 views
1
//! Types for declaring and storing [`Component`]s.
2
3
mod clone;
4
mod constants;
5
mod info;
6
mod register;
7
mod required;
8
9
pub use clone::*;
10
pub use constants::*;
11
pub use info::*;
12
pub use register::*;
13
pub use required::*;
14
15
use crate::{
16
entity::EntityMapper,
17
lifecycle::ComponentHook,
18
relationship::ComponentRelationshipAccessor,
19
system::{Local, SystemParam},
20
world::{FromWorld, World},
21
};
22
pub use bevy_ecs_macros::Component;
23
use core::{fmt::Debug, marker::PhantomData, ops::Deref};
24
25
/// A data type that can be used to store data for an [entity].
26
///
27
/// `Component` is a [derivable trait]: this means that a data type can implement it by applying a `#[derive(Component)]` attribute to it.
28
/// However, components must always satisfy the `Send + Sync + 'static` trait bounds.
29
///
30
/// [entity]: crate::entity
31
/// [derivable trait]: https://doc.rust-lang.org/book/appendix-03-derivable-traits.html
32
///
33
/// # Examples
34
///
35
/// Components can take many forms: they are usually structs, but can also be of every other kind of data type, like enums or zero sized types.
36
/// The following examples show how components are laid out in code.
37
///
38
/// ```
39
/// # use bevy_ecs::component::Component;
40
/// # struct Color;
41
/// #
42
/// // A component can contain data...
43
/// #[derive(Component)]
44
/// struct LicensePlate(String);
45
///
46
/// // ... but it can also be a zero-sized marker.
47
/// #[derive(Component)]
48
/// struct Car;
49
///
50
/// // Components can also be structs with named fields...
51
/// #[derive(Component)]
52
/// struct VehiclePerformance {
53
/// acceleration: f32,
54
/// top_speed: f32,
55
/// handling: f32,
56
/// }
57
///
58
/// // ... or enums.
59
/// #[derive(Component)]
60
/// enum WheelCount {
61
/// Two,
62
/// Three,
63
/// Four,
64
/// }
65
/// ```
66
///
67
/// # Component and data access
68
///
69
/// Components can be marked as immutable by adding the `#[component(immutable)]`
70
/// attribute when using the derive macro.
71
/// See the documentation for [`ComponentMutability`] for more details around this
72
/// feature.
73
///
74
/// See the [`entity`] module level documentation to learn how to add or remove components from an entity.
75
///
76
/// See the documentation for [`Query`] to learn how to access component data from a system.
77
///
78
/// [`entity`]: crate::entity#usage
79
/// [`Query`]: crate::system::Query
80
/// [`ComponentMutability`]: crate::component::ComponentMutability
81
///
82
/// # Choosing a storage type
83
///
84
/// Components can be stored in the world using different strategies with their own performance implications.
85
/// By default, components are added to the [`Table`] storage, which is optimized for query iteration.
86
///
87
/// Alternatively, components can be added to the [`SparseSet`] storage, which is optimized for component insertion and removal.
88
/// This is achieved by adding an additional `#[component(storage = "SparseSet")]` attribute to the derive one:
89
///
90
/// ```
91
/// # use bevy_ecs::component::Component;
92
/// #
93
/// #[derive(Component)]
94
/// #[component(storage = "SparseSet")]
95
/// struct ComponentA;
96
/// ```
97
///
98
/// [`Table`]: crate::storage::Table
99
/// [`SparseSet`]: crate::storage::SparseSet
100
///
101
/// # Required Components
102
///
103
/// Components can specify Required Components. If some [`Component`] `A` requires [`Component`] `B`, then when `A` is inserted,
104
/// `B` will _also_ be initialized and inserted (if it was not manually specified).
105
///
106
/// The [`Default`] constructor will be used to initialize the component, by default:
107
///
108
/// ```
109
/// # use bevy_ecs::prelude::*;
110
/// #[derive(Component)]
111
/// #[require(B)]
112
/// struct A;
113
///
114
/// #[derive(Component, Default, PartialEq, Eq, Debug)]
115
/// struct B(usize);
116
///
117
/// # let mut world = World::default();
118
/// // This will implicitly also insert B with the Default constructor
119
/// let id = world.spawn(A).id();
120
/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
121
///
122
/// // This will _not_ implicitly insert B, because it was already provided
123
/// world.spawn((A, B(11)));
124
/// ```
125
///
126
/// Components can have more than one required component:
127
///
128
/// ```
129
/// # use bevy_ecs::prelude::*;
130
/// #[derive(Component)]
131
/// #[require(B, C)]
132
/// struct A;
133
///
134
/// #[derive(Component, Default, PartialEq, Eq, Debug)]
135
/// #[require(C)]
136
/// struct B(usize);
137
///
138
/// #[derive(Component, Default, PartialEq, Eq, Debug)]
139
/// struct C(u32);
140
///
141
/// # let mut world = World::default();
142
/// // This will implicitly also insert B and C with their Default constructors
143
/// let id = world.spawn(A).id();
144
/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
145
/// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());
146
/// ```
147
///
148
/// You can define inline component values that take the following forms:
149
/// ```
150
/// # use bevy_ecs::prelude::*;
151
/// #[derive(Component)]
152
/// #[require(
153
/// B(1), // tuple structs
154
/// C { // named-field structs
155
/// x: 1,
156
/// ..Default::default()
157
/// },
158
/// D::One, // enum variants
159
/// E::ONE, // associated consts
160
/// F::new(1) // constructors
161
/// )]
162
/// struct A;
163
///
164
/// #[derive(Component, PartialEq, Eq, Debug)]
165
/// struct B(u8);
166
///
167
/// #[derive(Component, PartialEq, Eq, Debug, Default)]
168
/// struct C {
169
/// x: u8,
170
/// y: u8,
171
/// }
172
///
173
/// #[derive(Component, PartialEq, Eq, Debug)]
174
/// enum D {
175
/// Zero,
176
/// One,
177
/// }
178
///
179
/// #[derive(Component, PartialEq, Eq, Debug)]
180
/// struct E(u8);
181
///
182
/// impl E {
183
/// pub const ONE: Self = Self(1);
184
/// }
185
///
186
/// #[derive(Component, PartialEq, Eq, Debug)]
187
/// struct F(u8);
188
///
189
/// impl F {
190
/// fn new(value: u8) -> Self {
191
/// Self(value)
192
/// }
193
/// }
194
///
195
/// # let mut world = World::default();
196
/// let id = world.spawn(A).id();
197
/// assert_eq!(&B(1), world.entity(id).get::<B>().unwrap());
198
/// assert_eq!(&C { x: 1, y: 0 }, world.entity(id).get::<C>().unwrap());
199
/// assert_eq!(&D::One, world.entity(id).get::<D>().unwrap());
200
/// assert_eq!(&E(1), world.entity(id).get::<E>().unwrap());
201
/// assert_eq!(&F(1), world.entity(id).get::<F>().unwrap());
202
/// ````
203
///
204
///
205
/// You can also define arbitrary expressions by using `=`
206
///
207
/// ```
208
/// # use bevy_ecs::prelude::*;
209
/// #[derive(Component)]
210
/// #[require(C = init_c())]
211
/// struct A;
212
///
213
/// #[derive(Component, PartialEq, Eq, Debug)]
214
/// #[require(C = C(20))]
215
/// struct B;
216
///
217
/// #[derive(Component, PartialEq, Eq, Debug)]
218
/// struct C(usize);
219
///
220
/// fn init_c() -> C {
221
/// C(10)
222
/// }
223
///
224
/// # let mut world = World::default();
225
/// // This will implicitly also insert C with the init_c() constructor
226
/// let id = world.spawn(A).id();
227
/// assert_eq!(&C(10), world.entity(id).get::<C>().unwrap());
228
///
229
/// // This will implicitly also insert C with the `|| C(20)` constructor closure
230
/// let id = world.spawn(B).id();
231
/// assert_eq!(&C(20), world.entity(id).get::<C>().unwrap());
232
/// ```
233
///
234
/// Required components are _recursive_. This means, if a Required Component has required components,
235
/// those components will _also_ be inserted if they are missing:
236
///
237
/// ```
238
/// # use bevy_ecs::prelude::*;
239
/// #[derive(Component)]
240
/// #[require(B)]
241
/// struct A;
242
///
243
/// #[derive(Component, Default, PartialEq, Eq, Debug)]
244
/// #[require(C)]
245
/// struct B(usize);
246
///
247
/// #[derive(Component, Default, PartialEq, Eq, Debug)]
248
/// struct C(u32);
249
///
250
/// # let mut world = World::default();
251
/// // This will implicitly also insert B and C with their Default constructors
252
/// let id = world.spawn(A).id();
253
/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
254
/// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());
255
/// ```
256
///
257
/// Note that cycles in the "component require tree" will result in stack overflows when attempting to
258
/// insert a component.
259
///
260
/// This "multiple inheritance" pattern does mean that it is possible to have duplicate requires for a given type
261
/// at different levels of the inheritance tree:
262
///
263
/// ```
264
/// # use bevy_ecs::prelude::*;
265
/// #[derive(Component)]
266
/// struct X(usize);
267
///
268
/// #[derive(Component, Default)]
269
/// #[require(X(1))]
270
/// struct Y;
271
///
272
/// #[derive(Component)]
273
/// #[require(
274
/// Y,
275
/// X(2),
276
/// )]
277
/// struct Z;
278
///
279
/// # let mut world = World::default();
280
/// // In this case, the x2 constructor is used for X
281
/// let id = world.spawn(Z).id();
282
/// assert_eq!(2, world.entity(id).get::<X>().unwrap().0);
283
/// ```
284
///
285
/// In general, this shouldn't happen often, but when it does the algorithm for choosing the constructor from the tree is simple and predictable:
286
/// 1. A constructor from a direct `#[require()]`, if one exists, is selected with priority.
287
/// 2. Otherwise, perform a Depth First Search on the tree of requirements and select the first one found.
288
///
289
/// From a user perspective, just think about this as the following:
290
/// 1. Specifying a required component constructor for Foo directly on a spawned component Bar will result in that constructor being used (and overriding existing constructors lower in the inheritance tree). This is the classic "inheritance override" behavior people expect.
291
/// 2. For cases where "multiple inheritance" results in constructor clashes, Components should be listed in "importance order". List a component earlier in the requirement list to initialize its inheritance tree earlier.
292
///
293
/// ## Registering required components at runtime
294
///
295
/// In most cases, required components should be registered using the `require` attribute as shown above.
296
/// However, in some cases, it may be useful to register required components at runtime.
297
///
298
/// This can be done through [`World::register_required_components`] or [`World::register_required_components_with`]
299
/// for the [`Default`] and custom constructors respectively:
300
///
301
/// ```
302
/// # use bevy_ecs::prelude::*;
303
/// #[derive(Component)]
304
/// struct A;
305
///
306
/// #[derive(Component, Default, PartialEq, Eq, Debug)]
307
/// struct B(usize);
308
///
309
/// #[derive(Component, PartialEq, Eq, Debug)]
310
/// struct C(u32);
311
///
312
/// # let mut world = World::default();
313
/// // Register B as required by A and C as required by B.
314
/// world.register_required_components::<A, B>();
315
/// world.register_required_components_with::<B, C>(|| C(2));
316
///
317
/// // This will implicitly also insert B with its Default constructor
318
/// // and C with the custom constructor defined by B.
319
/// let id = world.spawn(A).id();
320
/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());
321
/// assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());
322
/// ```
323
///
324
/// Similar rules as before apply to duplicate requires fer a given type at different levels
325
/// of the inheritance tree. `A` requiring `C` directly would take precedence over indirectly
326
/// requiring it through `A` requiring `B` and `B` requiring `C`.
327
///
328
/// Unlike with the `require` attribute, directly requiring the same component multiple times
329
/// for the same component will result in a panic. This is done to prevent conflicting constructors
330
/// and confusing ordering dependencies.
331
///
332
/// Note that requirements must currently be registered before the requiring component is inserted
333
/// into the world for the first time. Registering requirements after this will lead to a panic.
334
///
335
/// # Relationships between Entities
336
///
337
/// Sometimes it is useful to define relationships between entities. A common example is the
338
/// parent / child relationship. Since Components are how data is stored for Entities, one might
339
/// naturally think to create a Component which has a field of type [`Entity`].
340
///
341
/// To facilitate this pattern, Bevy provides the [`Relationship`](`crate::relationship::Relationship`)
342
/// trait. You can derive the [`Relationship`](`crate::relationship::Relationship`) and
343
/// [`RelationshipTarget`](`crate::relationship::RelationshipTarget`) traits in addition to the
344
/// Component trait in order to implement data driven relationships between entities, see the trait
345
/// docs for more details.
346
///
347
/// In addition, Bevy provides canonical implementations of the parent / child relationship via the
348
/// [`ChildOf`](crate::hierarchy::ChildOf) [`Relationship`](crate::relationship::Relationship) and
349
/// the [`Children`](crate::hierarchy::Children)
350
/// [`RelationshipTarget`](crate::relationship::RelationshipTarget).
351
///
352
/// # Adding component's hooks
353
///
354
/// See [`ComponentHooks`] for a detailed explanation of component's hooks.
355
///
356
/// Alternatively to the example shown in [`ComponentHooks`]' documentation, hooks can be configured using following attributes:
357
/// - `#[component(on_add = on_add_function)]`
358
/// - `#[component(on_insert = on_insert_function)]`
359
/// - `#[component(on_replace = on_replace_function)]`
360
/// - `#[component(on_remove = on_remove_function)]`
361
///
362
/// ```
363
/// # use bevy_ecs::component::Component;
364
/// # use bevy_ecs::lifecycle::HookContext;
365
/// # use bevy_ecs::world::DeferredWorld;
366
/// # use bevy_ecs::entity::Entity;
367
/// # use bevy_ecs::component::ComponentId;
368
/// # use core::panic::Location;
369
/// #
370
/// #[derive(Component)]
371
/// #[component(on_add = my_on_add_hook)]
372
/// #[component(on_insert = my_on_insert_hook)]
373
/// // Another possible way of configuring hooks:
374
/// // #[component(on_add = my_on_add_hook, on_insert = my_on_insert_hook)]
375
/// //
376
/// // We don't have a replace or remove hook, so we can leave them out:
377
/// // #[component(on_replace = my_on_replace_hook, on_remove = my_on_remove_hook)]
378
/// struct ComponentA;
379
///
380
/// fn my_on_add_hook(world: DeferredWorld, context: HookContext) {
381
/// // ...
382
/// }
383
///
384
/// // You can also destructure items directly in the signature
385
/// fn my_on_insert_hook(world: DeferredWorld, HookContext { caller, .. }: HookContext) {
386
/// // ...
387
/// }
388
/// ```
389
///
390
/// This also supports function calls that yield closures
391
///
392
/// ```
393
/// # use bevy_ecs::component::Component;
394
/// # use bevy_ecs::lifecycle::HookContext;
395
/// # use bevy_ecs::world::DeferredWorld;
396
/// #
397
/// #[derive(Component)]
398
/// #[component(on_add = my_msg_hook("hello"))]
399
/// #[component(on_despawn = my_msg_hook("yoink"))]
400
/// struct ComponentA;
401
///
402
/// // a hook closure generating function
403
/// fn my_msg_hook(message: &'static str) -> impl Fn(DeferredWorld, HookContext) {
404
/// move |_world, _ctx| {
405
/// println!("{message}");
406
/// }
407
/// }
408
///
409
/// ```
410
///
411
/// A hook's function path can be elided if it is `Self::on_add`, `Self::on_insert` etc.
412
/// ```
413
/// # use bevy_ecs::lifecycle::HookContext;
414
/// # use bevy_ecs::prelude::*;
415
/// # use bevy_ecs::world::DeferredWorld;
416
/// #
417
/// #[derive(Component, Debug)]
418
/// #[component(on_add)]
419
/// struct DoubleOnSpawn(usize);
420
///
421
/// impl DoubleOnSpawn {
422
/// fn on_add(mut world: DeferredWorld, context: HookContext) {
423
/// let mut entity = world.get_mut::<Self>(context.entity).unwrap();
424
/// entity.0 *= 2;
425
/// }
426
/// }
427
/// #
428
/// # let mut world = World::new();
429
/// # let entity = world.spawn(DoubleOnSpawn(2));
430
/// # assert_eq!(entity.get::<DoubleOnSpawn>().unwrap().0, 4);
431
/// ```
432
///
433
/// # Setting the clone behavior
434
///
435
/// You can specify how the [`Component`] is cloned when deriving it.
436
///
437
/// Your options are the functions and variants of [`ComponentCloneBehavior`]
438
/// See [Clone Behaviors section of `EntityCloner`](crate::entity::EntityCloner#clone-behaviors) to understand how this affects handler priority.
439
/// ```
440
/// # use bevy_ecs::prelude::*;
441
///
442
/// #[derive(Component)]
443
/// #[component(clone_behavior = Ignore)]
444
/// struct MyComponent;
445
///
446
/// ```
447
///
448
/// # Implementing the trait for foreign types
449
///
450
/// As a consequence of the [orphan rule], it is not possible to separate into two different crates the implementation of `Component` from the definition of a type.
451
/// This means that it is not possible to directly have a type defined in a third party library as a component.
452
/// This important limitation can be easily worked around using the [newtype pattern]:
453
/// this makes it possible to locally define and implement `Component` for a tuple struct that wraps the foreign type.
454
/// The following example gives a demonstration of this pattern.
455
///
456
/// ```
457
/// // `Component` is defined in the `bevy_ecs` crate.
458
/// use bevy_ecs::component::Component;
459
///
460
/// // `Duration` is defined in the `std` crate.
461
/// use std::time::Duration;
462
///
463
/// // It is not possible to implement `Component` for `Duration` from this position, as they are
464
/// // both foreign items, defined in an external crate. However, nothing prevents to define a new
465
/// // `Cooldown` type that wraps `Duration`. As `Cooldown` is defined in a local crate, it is
466
/// // possible to implement `Component` for it.
467
/// #[derive(Component)]
468
/// struct Cooldown(Duration);
469
/// ```
470
///
471
/// [orphan rule]: https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type
472
/// [newtype pattern]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#using-the-newtype-pattern-to-implement-external-traits-on-external-types
473
///
474
/// # `!Sync` Components
475
/// A `!Sync` type cannot implement `Component`. However, it is possible to wrap a `Send` but not `Sync`
476
/// type in [`SyncCell`] or the currently unstable [`Exclusive`] to make it `Sync`. This forces only
477
/// having mutable access (`&mut T` only, never `&T`), but makes it safe to reference across multiple
478
/// threads.
479
///
480
/// This will fail to compile since `RefCell` is `!Sync`.
481
/// ```compile_fail
482
/// # use std::cell::RefCell;
483
/// # use bevy_ecs::component::Component;
484
/// #[derive(Component)]
485
/// struct NotSync {
486
/// counter: RefCell<usize>,
487
/// }
488
/// ```
489
///
490
/// This will compile since the `RefCell` is wrapped with `SyncCell`.
491
/// ```
492
/// # use std::cell::RefCell;
493
/// # use bevy_ecs::component::Component;
494
/// use bevy_platform::cell::SyncCell;
495
///
496
/// // This will compile.
497
/// #[derive(Component)]
498
/// struct ActuallySync {
499
/// counter: SyncCell<RefCell<usize>>,
500
/// }
501
/// ```
502
///
503
/// [`SyncCell`]: bevy_platform::cell::SyncCell
504
/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
505
/// [`ComponentHooks`]: crate::lifecycle::ComponentHooks
506
#[diagnostic::on_unimplemented(
507
message = "`{Self}` is not a `Component`",
508
label = "invalid `Component`",
509
note = "consider annotating `{Self}` with `#[derive(Component)]`"
510
)]
511
pub trait Component: Send + Sync + 'static {
512
/// A constant indicating the storage type used for this component.
513
const STORAGE_TYPE: StorageType;
514
515
/// A marker type to assist Bevy with determining if this component is
516
/// mutable, or immutable. Mutable components will have [`Component<Mutability = Mutable>`],
517
/// while immutable components will instead have [`Component<Mutability = Immutable>`].
518
///
519
/// * For a component to be mutable, this type must be [`Mutable`].
520
/// * For a component to be immutable, this type must be [`Immutable`].
521
type Mutability: ComponentMutability;
522
523
/// Gets the `on_add` [`ComponentHook`] for this [`Component`] if one is defined.
524
fn on_add() -> Option<ComponentHook> {
525
None
526
}
527
528
/// Gets the `on_insert` [`ComponentHook`] for this [`Component`] if one is defined.
529
fn on_insert() -> Option<ComponentHook> {
530
None
531
}
532
533
/// Gets the `on_replace` [`ComponentHook`] for this [`Component`] if one is defined.
534
fn on_replace() -> Option<ComponentHook> {
535
None
536
}
537
538
/// Gets the `on_remove` [`ComponentHook`] for this [`Component`] if one is defined.
539
fn on_remove() -> Option<ComponentHook> {
540
None
541
}
542
543
/// Gets the `on_despawn` [`ComponentHook`] for this [`Component`] if one is defined.
544
fn on_despawn() -> Option<ComponentHook> {
545
None
546
}
547
548
/// Registers required components.
549
///
550
/// # Safety
551
///
552
/// - `_required_components` must only contain components valid in `_components`.
553
fn register_required_components(
554
_component_id: ComponentId,
555
_required_components: &mut RequiredComponentsRegistrator,
556
) {
557
}
558
559
/// Called when registering this component, allowing to override clone function (or disable cloning altogether) for this component.
560
///
561
/// See [Clone Behaviors section of `EntityCloner`](crate::entity::EntityCloner#clone-behaviors) to understand how this affects handler priority.
562
#[inline]
563
fn clone_behavior() -> ComponentCloneBehavior {
564
ComponentCloneBehavior::Default
565
}
566
567
/// Maps the entities on this component using the given [`EntityMapper`]. This is used to remap entities in contexts like scenes and entity cloning.
568
/// When deriving [`Component`], this is populated by annotating fields containing entities with `#[entities]`
569
///
570
/// ```
571
/// # use bevy_ecs::{component::Component, entity::Entity};
572
/// #[derive(Component)]
573
/// struct Inventory {
574
/// #[entities]
575
/// items: Vec<Entity>
576
/// }
577
/// ```
578
///
579
/// Fields with `#[entities]` must implement [`MapEntities`](crate::entity::MapEntities).
580
///
581
/// Bevy provides various implementations of [`MapEntities`](crate::entity::MapEntities), so that arbitrary combinations like these are supported with `#[entities]`:
582
///
583
/// ```rust
584
/// # use bevy_ecs::{component::Component, entity::Entity};
585
/// #[derive(Component)]
586
/// struct Inventory {
587
/// #[entities]
588
/// items: Vec<Option<Entity>>
589
/// }
590
/// ```
591
///
592
/// You might need more specialized logic. A likely cause of this is your component contains collections of entities that
593
/// don't implement [`MapEntities`](crate::entity::MapEntities). In that case, you can annotate your component with
594
/// `#[component(map_entities)]`. Using this attribute, you must implement `MapEntities` for the
595
/// component itself, and this method will simply call that implementation.
596
///
597
/// ```
598
/// # use bevy_ecs::{component::Component, entity::{Entity, MapEntities, EntityMapper}};
599
/// # use std::collections::HashMap;
600
/// #[derive(Component)]
601
/// #[component(map_entities)]
602
/// struct Inventory {
603
/// items: HashMap<Entity, usize>
604
/// }
605
///
606
/// impl MapEntities for Inventory {
607
/// fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
608
/// self.items = self.items
609
/// .drain()
610
/// .map(|(id, count)|(entity_mapper.get_mapped(id), count))
611
/// .collect();
612
/// }
613
/// }
614
/// # let a = Entity::from_bits(0x1_0000_0001);
615
/// # let b = Entity::from_bits(0x1_0000_0002);
616
/// # let mut inv = Inventory { items: Default::default() };
617
/// # inv.items.insert(a, 10);
618
/// # <Inventory as Component>::map_entities(&mut inv, &mut (a,b));
619
/// # assert_eq!(inv.items.get(&b), Some(&10));
620
/// ````
621
///
622
/// Alternatively, you can specify the path to a function with `#[component(map_entities = function_path)]`, similar to component hooks.
623
/// In this case, the inputs of the function should mirror the inputs to this method, with the second parameter being generic.
624
///
625
/// ```
626
/// # use bevy_ecs::{component::Component, entity::{Entity, MapEntities, EntityMapper}};
627
/// # use std::collections::HashMap;
628
/// #[derive(Component)]
629
/// #[component(map_entities = map_the_map)]
630
/// // Also works: map_the_map::<M> or map_the_map::<_>
631
/// struct Inventory {
632
/// items: HashMap<Entity, usize>
633
/// }
634
///
635
/// fn map_the_map<M: EntityMapper>(inv: &mut Inventory, entity_mapper: &mut M) {
636
/// inv.items = inv.items
637
/// .drain()
638
/// .map(|(id, count)|(entity_mapper.get_mapped(id), count))
639
/// .collect();
640
/// }
641
/// # let a = Entity::from_bits(0x1_0000_0001);
642
/// # let b = Entity::from_bits(0x1_0000_0002);
643
/// # let mut inv = Inventory { items: Default::default() };
644
/// # inv.items.insert(a, 10);
645
/// # <Inventory as Component>::map_entities(&mut inv, &mut (a,b));
646
/// # assert_eq!(inv.items.get(&b), Some(&10));
647
/// ````
648
///
649
/// You can use the turbofish (`::<A,B,C>`) to specify parameters when a function is generic, using either M or _ for the type of the mapper parameter.
650
#[inline]
651
fn map_entities<E: EntityMapper>(_this: &mut Self, _mapper: &mut E) {}
652
653
/// Returns [`ComponentRelationshipAccessor`] required for working with relationships in dynamic contexts.
654
///
655
/// If component is not a [`Relationship`](crate::relationship::Relationship) or [`RelationshipTarget`](crate::relationship::RelationshipTarget), this should return `None`.
656
fn relationship_accessor() -> Option<ComponentRelationshipAccessor<Self>> {
657
None
658
}
659
}
660
661
mod private {
662
pub trait Seal {}
663
}
664
665
/// The mutability option for a [`Component`]. This can either be:
666
/// * [`Mutable`]
667
/// * [`Immutable`]
668
///
669
/// This is controlled through either [`Component::Mutability`] or `#[component(immutable)]`
670
/// when using the derive macro.
671
///
672
/// Immutable components are guaranteed to never have an exclusive reference,
673
/// `&mut ...`, created while inserted onto an entity.
674
/// In all other ways, they are identical to mutable components.
675
/// This restriction allows hooks to observe all changes made to an immutable
676
/// component, effectively turning the `Insert` and `Replace` hooks into a
677
/// `OnMutate` hook.
678
/// This is not practical for mutable components, as the runtime cost of invoking
679
/// a hook for every exclusive reference created would be far too high.
680
///
681
/// # Examples
682
///
683
/// ```rust
684
/// # use bevy_ecs::component::Component;
685
/// #
686
/// #[derive(Component)]
687
/// #[component(immutable)]
688
/// struct ImmutableFoo;
689
/// ```
690
pub trait ComponentMutability: private::Seal + 'static {
691
/// Boolean to indicate if this mutability setting implies a mutable or immutable
692
/// component.
693
const MUTABLE: bool;
694
}
695
696
/// Parameter indicating a [`Component`] is immutable.
697
///
698
/// See [`ComponentMutability`] for details.
699
pub struct Immutable;
700
701
impl private::Seal for Immutable {}
702
703
impl ComponentMutability for Immutable {
704
const MUTABLE: bool = false;
705
}
706
707
/// Parameter indicating a [`Component`] is mutable.
708
///
709
/// See [`ComponentMutability`] for details.
710
pub struct Mutable;
711
712
impl private::Seal for Mutable {}
713
714
impl ComponentMutability for Mutable {
715
const MUTABLE: bool = true;
716
}
717
718
/// The storage used for a specific component type.
719
///
720
/// # Examples
721
/// The [`StorageType`] for a component is configured via the derive attribute
722
///
723
/// ```
724
/// # use bevy_ecs::{prelude::*, component::*};
725
/// #[derive(Component)]
726
/// #[component(storage = "SparseSet")]
727
/// struct A;
728
/// ```
729
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
730
pub enum StorageType {
731
/// Provides fast and cache-friendly iteration, but slower addition and removal of components.
732
/// This is the default storage type.
733
#[default]
734
Table,
735
/// Provides fast addition and removal of components, but slower iteration.
736
SparseSet,
737
}
738
739
/// A [`SystemParam`] that provides access to the [`ComponentId`] for a specific component type.
740
///
741
/// # Example
742
/// ```
743
/// # use bevy_ecs::{system::Local, component::{Component, ComponentId, ComponentIdFor}};
744
/// #[derive(Component)]
745
/// struct Player;
746
/// fn my_system(component_id: ComponentIdFor<Player>) {
747
/// let component_id: ComponentId = component_id.get();
748
/// // ...
749
/// }
750
/// ```
751
#[derive(SystemParam)]
752
pub struct ComponentIdFor<'s, T: Component>(Local<'s, InitComponentId<T>>);
753
754
impl<T: Component> ComponentIdFor<'_, T> {
755
/// Gets the [`ComponentId`] for the type `T`.
756
#[inline]
757
pub fn get(&self) -> ComponentId {
758
**self
759
}
760
}
761
762
impl<T: Component> Deref for ComponentIdFor<'_, T> {
763
type Target = ComponentId;
764
fn deref(&self) -> &Self::Target {
765
&self.0.component_id
766
}
767
}
768
769
impl<T: Component> From<ComponentIdFor<'_, T>> for ComponentId {
770
#[inline]
771
fn from(to_component_id: ComponentIdFor<T>) -> ComponentId {
772
*to_component_id
773
}
774
}
775
776
/// Initializes the [`ComponentId`] for a specific type when used with [`FromWorld`].
777
struct InitComponentId<T: Component> {
778
component_id: ComponentId,
779
marker: PhantomData<T>,
780
}
781
782
impl<T: Component> FromWorld for InitComponentId<T> {
783
fn from_world(world: &mut World) -> Self {
784
Self {
785
component_id: world.register_component::<T>(),
786
marker: PhantomData,
787
}
788
}
789
}
790
791