-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
[Merged by Bors] - Improve entity and component API docs #4767
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d6f56bd
897ef61
392a35f
509794a
a14e051
55039b8
f347989
03d89db
5d06e38
5bdb80b
7267848
5f8274c
0147802
e71bf0b
dc93bbc
ae1b302
b4b95cd
bc45807
2926989
9b991aa
d956aea
3224296
498b689
607e6bd
a0421c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,26 +14,102 @@ use std::{ | |
| mem::needs_drop, | ||
| }; | ||
|
|
||
| /// A component is data associated with an [`Entity`](crate::entity::Entity). Each entity can have | ||
| /// multiple different types of components, but only one of them per type. | ||
| /// A data type that can be used to store data for an [entity]. | ||
| /// | ||
| /// Any type that is `Send + Sync + 'static` can implement `Component` using `#[derive(Component)]`. | ||
| /// | ||
| /// In order to use foreign types as components, wrap them using a newtype pattern. | ||
| /// `Component` is a [derivable trait]: this means that a data type can implement it by applying a `#[derive(Component)]` attribute to it. | ||
| /// However, components must always satisfy the `Send + Sync + 'static` trait bounds. | ||
| /// | ||
| /// [entity]: crate::entity | ||
| /// [derivable trait]: https://doc.rust-lang.org/book/appendix-03-derivable-traits.html | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// 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. | ||
| /// The following examples show how components are laid out in code. | ||
| /// | ||
| /// ``` | ||
| /// # use bevy_ecs::component::Component; | ||
| /// # struct Color; | ||
| /// # | ||
| /// // A component can contain data... | ||
| /// #[derive(Component)] | ||
| /// struct LicensePlate(String); | ||
| /// | ||
| /// // ... but it can also be a zero-sized marker. | ||
| /// #[derive(Component)] | ||
| /// struct Car; | ||
| /// | ||
| /// // Components can also be structs with named fields... | ||
| /// #[derive(Component)] | ||
| /// struct VehiclePerformance { | ||
| /// acceleration: f32, | ||
| /// top_speed: f32, | ||
| /// handling: f32, | ||
| /// } | ||
| /// | ||
| /// // ... or enums. | ||
| /// #[derive(Component)] | ||
| /// enum WheelCount { | ||
| /// Two, | ||
| /// Three, | ||
| /// Four, | ||
| /// } | ||
| /// ``` | ||
Nilirad marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /// | ||
| /// # Component and data access | ||
| /// | ||
| /// See the [`entity`] module level documentation to learn how to add or remove components from an entity. | ||
| /// | ||
| /// See the documentation for [`Query`] to learn how to access component data from a system. | ||
| /// | ||
| /// [`entity`]: crate::entity#usage | ||
| /// [`Query`]: crate::system::Query | ||
| /// | ||
| /// # Choosing a storage type | ||
| /// | ||
| /// Components can be stored in the world using different strategies with their own performance implications. | ||
| /// By default, components are added to the [`Table`] storage, which is optimized for query iteration. | ||
| /// | ||
| /// Alternatively, components can be added to the [`SparseSet`] storage, which is optimized for component insertion and removal. | ||
| /// This is achieved by adding an additional `#[component(storage = "SparseSet")]` attribute to the derive one: | ||
| /// | ||
| /// ``` | ||
| /// # use bevy_ecs::component::Component; | ||
| /// # | ||
| /// #[derive(Component)] | ||
| /// #[component(storage = "SparseSet")] | ||
| /// struct ComponentA; | ||
| /// ``` | ||
| /// | ||
| /// [`Table`]: crate::storage::Table | ||
| /// [`SparseSet`]: crate::storage::SparseSet | ||
| /// | ||
| /// # Implementing the trait for foreign types | ||
Nilirad marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /// | ||
| /// 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. | ||
| /// This means that it is not possible to directly have a type defined in a third party library as a component. | ||
| /// This important limitation can be easily worked around using the [newtype pattern]: | ||
| /// this makes it possible to locally define and implement `Component` for a tuple struct that wraps the foreign type. | ||
| /// The following example gives a demonstration of this pattern. | ||
| /// | ||
| /// ``` | ||
| /// // `Component` is defined in the `bevy_ecs` crate. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are those comments really useful? This information is already in the path. Same comment for Duration
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added those comments to make the line of thought explicit about explaining the orphan rule in the context of deriving
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to say this should be more explicit, but I can't figure out something to suggest so 🤷♂️. I'm fine with it either way.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In any case, this is a temporary solution until the new book includes it and it gets merged. Then it will be removed. |
||
| /// use bevy_ecs::component::Component; | ||
| /// | ||
| /// // `Duration` is defined in the `std` crate. | ||
| /// use std::time::Duration; | ||
| /// | ||
| /// // It is not possible to implement `Component` for `Duration` from this position, as they are | ||
| /// // both foreign items, defined in an external crate. However, nothing prevents to define a new | ||
| /// // `Cooldown` type that wraps `Duration`. As `Cooldown` is defined in a local crate, it is | ||
| /// // possible to implement `Component` for it. | ||
| /// #[derive(Component)] | ||
| /// struct Cooldown(Duration); | ||
| /// ``` | ||
| /// Components are added with new entities using [`Commands::spawn`](crate::system::Commands::spawn), | ||
| /// or to existing entities with [`EntityCommands::insert`](crate::system::EntityCommands::insert), | ||
| /// or their [`World`](crate::world::World) equivalents. | ||
| /// | ||
| /// Components can be accessed in systems by using a [`Query`](crate::system::Query) | ||
| /// as one of the arguments. | ||
| /// | ||
| /// Components can be grouped together into a [`Bundle`](crate::bundle::Bundle). | ||
| /// [orphan rule]: https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type | ||
| /// [newtype pattern]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#using-the-newtype-pattern-to-implement-external-traits-on-external-types | ||
| pub trait Component: Send + Sync + 'static { | ||
| type Storage: ComponentStorage; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is completely irrelevant, but I don't like using cars as examples
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried with people before publishing the PR, but I was struggling to not come up with stereotypes lol 🤣