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