-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Column change detection for immutable components #18788
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
base: main
Are you sure you want to change the base?
Conversation
Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke! If it's expected, please add the M-Deliberate-Rendering-Change label. If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it. |
It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note. Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes. |
|
@@ -20,6 +20,7 @@ pub struct ThinColumn { | |||
pub(super) added_ticks: ThinArrayPtr<UnsafeCell<Tick>>, | |||
pub(super) changed_ticks: ThinArrayPtr<UnsafeCell<Tick>>, | |||
pub(super) changed_by: MaybeLocation<ThinArrayPtr<UnsafeCell<&'static Location<'static>>>>, | |||
change_tick: Tick, |
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.
Maybe we can add a comment here? This is the change_tick
associated with the most recent change in the table (i.e. of any row in the table)
@@ -170,18 +173,19 @@ impl ThinColumn { | |||
&mut self, | |||
row: TableRow, | |||
data: OwningPtr<'_>, | |||
change_tick: Tick, | |||
tick: Tick, |
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 think keeping this as change_tick
was clearer
@@ -227,6 +232,7 @@ impl ThinColumn { | |||
self_changed_by.initialize_unchecked(dst_row.as_usize(), changed_by); | |||
}, | |||
); | |||
self.change_tick = tick; |
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.
The other values (added_ticks/change_ticks) were taken from the other
ThinColumn
, should we do the same for the Table-wide ChangeTick
?
Or is this required for the correctness of archetype_filter_fetch
?
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 feel like it might make the most sense to make both columns take the most recent of their change ticks. But IDK
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.
Wdym table-wide ChangeTick? Currently, change tick only updated when an element is inserted or replaced. This is to reduce false positive of archetype_filter_fetch
for Added
and Changed
. It's can be updated in more cases but not needed for now.
@@ -105,6 +105,18 @@ pub unsafe trait QueryFilter: WorldQuery { | |||
entity: Entity, | |||
table_row: TableRow, | |||
) -> bool; | |||
|
|||
/// # Safety |
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 think we need extra comments to explain what this does.
Basically this is a way to filter/skip an entire table/archetype instead of an individual Entity
or TableRow
.
I would add something similar to the comment of filter_fetch
and explain that currently this is mostly used as an optimization for non-archetypal filters such as Changed/Added
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 agree another comment would be good here. But this is brilliant btw.
The benchmarks you linked in the PR description are only for immutable components, right? There's an extra function call in every query-iteration now |
I tried to run benchmark but it very noisy. The only overhead is size of |
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.
LGTM. A few minor requests, but nothing blocking approval that I see.
I definitely would like benches here to see how this effects the rest of the ecs though. Maybe run them overnight?
@@ -227,6 +232,7 @@ impl ThinColumn { | |||
self_changed_by.initialize_unchecked(dst_row.as_usize(), changed_by); | |||
}, | |||
); | |||
self.change_tick = tick; |
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 feel like it might make the most sense to make both columns take the most recent of their change ticks. But IDK
@@ -105,6 +105,18 @@ pub unsafe trait QueryFilter: WorldQuery { | |||
entity: Entity, | |||
table_row: TableRow, | |||
) -> bool; | |||
|
|||
/// # Safety |
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 agree another comment would be good here. But this is brilliant btw.
Here is the benchmark. The result is kinda weird. Click me
|
Objective
Query<(), Changed<SomeImmutableComponent>>
Solution
Column
/ThinColumn
.Change tick will be updated when inserting, replacing or removing elements. Updating when removing seems unnecessary because change detection doesn't detect removal. I am still updating it because I want to use this somehow to help implement. Change tick will be update when inserting or replacing elements.query.is_changed()
. We may consider introducing a separate tick for removal in the future.Testing
archetype_filter_fetch
Query<Entity, Changed<T>>
. You can reproduce this by runningcargo bench -p benches --bench ecs -- --save-baseline current none_changed_detection
andcritcmp benches current -g '^(none_changed_detection/\d+\w+::\w+::[A-Z][a-z]+)'
Future work
changed_ticks
for immutable component. Because it can't be mutated, useadded_ticks
for is enough.