Skip to content
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

Document bevy_ecs::storage #7770

Merged
merged 13 commits into from
Mar 9, 2023
Merged

Conversation

james7132
Copy link
Member

Objective

Move bevy_ecs towards being able to use warn(missing_docs). Aiming to partially address #3492.

Solution

Document bevy_ecs::storage as thoroughly as possible. Added module level, API level, and type level docs wherever possible, including pub(crate) APIs for easier onboarding of newer contributors.


Changelog

Added: Documentation for all bevy::ecs::storage APIs.

@james7132 james7132 added C-Docs An addition or correction to our documentation A-ECS Entities, components, systems, and events labels Feb 21, 2023
@alice-i-cecile
Copy link
Member

Very nice stuff: these are pretty small corrections and requests.

crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/table.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/table.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/table.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/table.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/table.rs Outdated Show resolved Hide resolved
@@ -255,6 +274,7 @@ impl BlobVec {

/// Removes the value at `index` and copies the value stored into `ptr`.
/// Does not do any bounds checking on `index`.
/// The removed element is replaced by the last element of the `BlobVec`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good addition!

@@ -1,4 +1,24 @@
//! Storage layouts for ECS data.
//!
//! This module contains the low level backing data stores for ECS. These all offer minimal and often
//! unsafe APIs, exposed primarily for debugging and monitoring purposes.
Copy link
Contributor

@Carter0 Carter0 Feb 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that you mentioned it was for "debugging and monitoring purposes". You clarified a question I had before I even thought to ask it.

@@ -41,12 +41,18 @@ impl<I, V> SparseArray<I, V> {
macro_rules! impl_sparse_array {
($ty:ident) => {
impl<I: SparseSetIndex, V> $ty<I, V> {
/// Checks if a value is present at `index`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Genuinely asking, are these useful comments? Wouldn't people know what the contains function does just from a glance at the type signature?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, but this is definitely needed for us to enable cfg!(warn(missing_docs)) without breaking CI.

@@ -1,4 +1,24 @@
//! Storage layouts for ECS data.
//!
//! This module contains the low level backing data stores for ECS. These all offer minimal and often
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a “low level backing datastore”? What does low-level mean in this context?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low level meaning it's meant to be the base abstraction above the language primitives. We're directly working with std/alloc/core APIs here.

Backing datastore means it's the authoritative "place" within the ECS where all of the memory for the World is allocated. It's what "backs" the rest of the user-facing interface.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These might be good comments to throw in as well! Makes sense

@@ -12,8 +32,12 @@ pub use table::*;
/// The raw data stores of a [World](crate::world::World)
#[derive(Default)]
pub struct Storages {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a common pattern in Bevy to want to have one world use one kind of storage and then another world use another? In my game I am inserting components one frame and then removing them in another, so I would want to use SparseSets instead of tables for that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The storage type for a component is meant to be universal, defined on the Component type itself. This is managed during Component registration. Though someone could make an incorrect Component registration on different worlds. It's ill advised though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, yes ofc! That's much simpler

Copy link
Contributor

@Carter0 Carter0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should we reasonably expect a reviewer to know when looking at these docs? Where should we explain to new people where to go to learn about some high level concept of the engine vs where should we document more advanced details. I'm not sure how useful my comments are because I am writing from the perspective of someone who knows almost nothing, and these docs might be geared to people who already have some base level of understanding.

@@ -113,6 +130,8 @@ pub struct ComponentSparseSet {
}

impl ComponentSparseSet {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What makes it "sparse" if you catch my meaning? How does it work? I think that's what I really want to know.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SparseSets are sparse because the ID space they occupy do not always have an element. An entity doesn't have to have a Transform component, so if it were stored in a ComponentSparseSet, it wouldn't store a value for every entity.

crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/table.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/table.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@maniwani maniwani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going one file at a time. Where possible, can we please mirror the language in std? Saying "returns" consistently instead of "gets" or "fetches" is one example.

Also, suggestions for BlobVec struct definition.

/// A type-erased [`Vec`].
/// 
/// A [`BlobVec`] is conceptually a [`Vec<MaybeUninit<u8>>`] that stores the [`Layout`] and
/// [`Drop`] function pointer of its element type.
///
/// Because the [`World`](bevy_ecs::world::World) cannot know the static type information of its
/// components, it cannot store them in individual, strongly-typed [`Vec<T>`].
pub(super) struct BlobVec {
    /// The layout of the element type this vector stores.
    item_layout: Layout,
    /// The total number of elements (not bytes) this vector can store without reallocating.
    capacity: usize,
    /// The number of elements (not bytes) in the vector.
    len: usize,
    /// The pointer to the allocation.
    // Note: The layout of the allocation always matches [`array_layout(item_layout, capacity)`].
    data: NonNull<u8>,
    /// The pointer to the element type's [`Drop`] function.
    /// `None` if the element type doesn't need to be dropped.
    drop: Option<unsafe fn(OwningPtr<'_>)>,
}

crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@maniwani maniwani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More doc comments.

Also, side note, maybe we should rename these to match their use as replacements for HashSet and HashMap.

  • SparseArray -> SparseSet
  • SparseSet -> SparseMap

ComponentSparseSet can stay the same.

crates/bevy_ecs/src/storage/mod.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/mod.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/resource.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/resource.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/resource.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/sparse_set.rs Outdated Show resolved Hide resolved
@rparrett
Copy link
Contributor

Just want to +1 all of maniwani's feedback.

Co-authored-by: MinerSebas <[email protected]>
Co-authored-by: Cameron <[email protected]>
@james7132
Copy link
Member Author

@maniwani thanks for helping wordsmith the docs here. Might need to update guidance on our general docs guidance to match.

Also, side note, maybe we should rename these to match their use as replacements for HashSet and HashMap.

* `SparseArray` -> `SparseSet`

* `SparseSet` -> `SparseMap`

I'm not 100% convinced since we very much still use array-like instead of set like terminology for SparseArray, and conceptually we still think of it as one wherever it's used. Happy to discuss this further, but not in this docs PR.

Copy link
Contributor

@Carter0 Carter0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its good enough at this point. Thanks for writing all this up :)

Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid improvements. I'd like to see:

  1. The comment about BlobVec added to the doc strings.
  2. The panic comment from get_2_mut.

Once that's done, this LGTM.

Copy link
Contributor

@rparrett rparrett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: CI failure is real due to two broken doc links.

I can't comment on the validity of specific safety comments but I've read the new docs many times now and they are looking good / make sense to me.

@james7132 james7132 added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Mar 1, 2023
@james7132 james7132 added this to the 0.11 milestone Mar 5, 2023
@james7132 james7132 disabled auto-merge March 9, 2023 05:47
@james7132 james7132 enabled auto-merge March 9, 2023 05:47
@james7132 james7132 added this pull request to the merge queue Mar 9, 2023
Merged via the queue into bevyengine:main with commit 37df316 Mar 9, 2023
@james7132 james7132 deleted the doc-ecs-storage branch March 9, 2023 07:51
@james7132 james7132 modified the milestones: 0.11, 0.10.1 Mar 9, 2023
Shfty pushed a commit to shfty-rust/bevy that referenced this pull request Mar 19, 2023
Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Rob Parrett <[email protected]>
Co-authored-by: Carter Weinberg <[email protected]>
Co-authored-by: MinerSebas <[email protected]>
Co-authored-by: Cameron <[email protected]>
Shfty pushed a commit to shfty-rust/bevy that referenced this pull request Mar 19, 2023
Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Rob Parrett <[email protected]>
Co-authored-by: Carter Weinberg <[email protected]>
Co-authored-by: MinerSebas <[email protected]>
Co-authored-by: Cameron <[email protected]>
mockersf pushed a commit that referenced this pull request Mar 27, 2023
Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Rob Parrett <[email protected]>
Co-authored-by: Carter Weinberg <[email protected]>
Co-authored-by: MinerSebas <[email protected]>
Co-authored-by: Cameron <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Docs An addition or correction to our documentation S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants