Comments (10)
- Deletion (and removal) tracking is kept until you call
clear_all_deleted
orclear_all_deleted_older_than_timestamp
to only remove some of the tracking info. - Workloads don't really exist after they are added to the
World
, they are just a list of systems but they don't do anything and their start and end isn't recorded. So the fact thatsystemD
is the last one isn't important. - The tracking cycle is kind of in 2 places, there is the running cycle, each system has only one and it increases each time the system runs. Then you have stored cycles, like if you delete a component, the current cycle is stored with the deleted component. That's all per component and per tracking, like you can insert at cycle 3 and modify at cycle 5 to then delete at cycle 10 it's all stored at different places.
Here's a few important code pieces:
- where the running counter is initialized
- where the running counter is increased
where the running counter is initializedwhere the last_run counter is initializedwhere the running counter is increased each time it runswhere the last_run counter is updated each time it runs- where the deleted info is stored
- where
deleted
does its filtering
In the last one timestamp
is when the component was deleted, last_removal_or_deletion
is the last time the system ran (the counter is split further outside workloads, that's why the variable has this name) and current
is the curent cycle.
I don't say it enough but thanks for opening this kind of issue.
from shipyard.
Thanks for a detailed explanation!
After reading your answer and looking some code, I have some more questions.
In View
struct, there's a current
field which means current cycle as you said.
Let's suppose I have 10 systems and 3 systems have a View<ComponentA>
.
(
system1,
system2, // contains `View<ComponentA>`
system3,
system4, // contains `View<ComponentA>`
...
system10 // contains `View<ComponentA>`
).into_workload()
-
In this case,
View<ComponentA>
'scurrent
field is set to 3 after one loop?
What if system2, 4, 10 run in parallel? -
If I understand correctly about deletion, to enhance performance, should I minimize using delete?
If I delete continuously withoutclear_all_deleted
, deletion's vector keeps increasing and it'll increase time to filter.
(there's a filter_map withis_track_within_bounds
function.)
Even if I use clear_all_deleted, it's not that cheap I think. (Is it right?) -
What's the meaning of
u32::Max / 2
inis_track_within_bounds
function?
Thank you in advance.
from shipyard.
- My previous comment was wrong, the third link wasn't the running counter. It was the
last_run
counter. This is the running counter which is global for all systems. And there is onelast_run
counter per system.
So whenSee below for accurate counters.system10
runs it has acurrent
counter of 9 (it starts at 0) and alast_run
counter of 3. Then the loop ends and whensystem2
gets aView<ComponentA>
again it has acurrent
counter of 11 and alast_counter
last_run
counter of91.
If other systems run in parallel then the counter will be kind of random between them. But since they run in parallel it shouldn't matter, they can't borrow conflicting views (you couldn't have aViewMut<ComponentA>
and aView<ComponentA>
run in parallel). - I would say yes you should avoid deleting, or more exactly you shouldn't go out of your way to delete if you can remove.
To delete an entity I wouldn't useremove
on all components and then delete the entity but I wouldn't usedelete
overremove
when possible.
Yes if you never clear then theVec
it'll keep growing, that's why it can't be enabled by default. And yes the filter will take more and more time. But if you clear regularly then it shouldn't take a big amount of time, the filter is iterating a singleVec
which is fast. u32::Max / 2
was supposed to be the window where tracking is valid but as I'm writing this and try to come up with an example I'm not sure this window is useful.
The tracking counter wraps on overflow so I was using half the fullu32
range to be safe when getting close to the max value.
Let's say you have yourcurrent
at1
and you havelast_run
atu32::MAX - 1
.
But since the counter is global, you can't getViewMut
in parallel and the counter only increases then I don't think there can be any problem using the full range.
You can see the same kind of logic here: https://github.com/bevyengine/bevy/blob/c3a46822e14003970e2de0ea20ca09839a64d913/crates/bevy_ecs/src/change_detection.rs.
If I can't find a good example of this I'll change the implementation to something like that:
fn is_track_within_bounds(timestamp: u32, last: u32, current: u32) -> bool {
let bounds = current.wrapping_sub(last);
let track = current.wrapping_sub(timestamp);
track < bounds
}
from shipyard.
Then the loop ends and when system2 gets a
View<ComponentA>
again it has acurrent
counter of 11 and alast_counter
of 9.
In this part, why last_counter
is 9?? I think it would be 4.
Don't you mean second loop?
-----edited--------
ah, I understand. last_run
will be 4 ?
So last_counter
means last_insert
or last_modification
or last_removal_or_deletion
in View
struct?
from shipyard.
Yes 4 not 9 It's 1 right? 🤦♂️ (Only the run counter is global not the last_run one)
And yes "last_run
counter" not "last_counter
".
So
last_counter
meanslast_insert
orlast_modification
orlast_removal_or_deletion
inView
struct?
It's all of them in workloads, outside each one has a different last_run
counter and the View
will use them.
You can see it here:
Lines 223 to 226 in 54009de
last_run
is Some
in workloads so that's the value used, and if it's None
then we'll look inside SparseSet
to get the last time a clear_*
call was used.from shipyard.
ah..? 1?
So when
system10
runs it has acurrent
counter of 9 (it starts at 0) and alast_run
counter of 3.
So In this part, 3 also should be 1??
why is it 1..? Some global struct has last_run
field. It'll count whenever View<ComponentA>
is called. There are 3 systems which contain View<ComponentA>
. So last_run
is 3.
Doesn't this what you mean?
I'm confused now lol
from shipyard.
It should be... 0 (it doesn't have a last_run
yet so it starts at 0).
Sorry I messed up all numbers >_<
The run
counter is global, it increases each time a system runs and starts at 1 (not 0 like I said before). That will be 1 for system1
, then 2 for system2
,... and system10
is 10. Then second loop, system1
is 11 then system2
is 12,... and system10
will be 20.
At the same time each of these system has a last_run
counter. They all start at 0 and during the first loop, they are all at 0. Then second loop, system1
will be 1, system2
will be 2,... and system10
will be 10.
from shipyard.
Ok run
counter is increased whenever any system is called. If system1 is called twice in one loop, is it increased twice?
and I don't still understand last_run
counter. why system2
will be 2, .. and system10
will be 10 in second loop?
You said each system has a last_run
counter. so I think all system's last_run
will be 1 in second loop if last_run
was 0 in the first loop.
from shipyard.
Ok run counter is increased whenever any system is called. If system1 is called twice in one loop, is it increased twice?
Yes
last_run
counter is storing what the run
counter value was the last time this system ran. Maybe it's not really the right name to call it a counter
, it doesn't really count anything, it's more a timestamp.
shipyard/src/scheduler/into_workload_system.rs
Lines 145 to 146 in 54009de
Here you can see that
last_run
store the value of current
.from shipyard.
ah it gets world's current so each system's last_run
is increased even different systems ran before.
I understand now.
from shipyard.
Related Issues (20)
- clear_all_modified function doesn't work in test code HOT 2
- How to know all of the components that some entity has? HOT 1
- [new feature] deleting entity's components temporarily HOT 4
- How to query a entity by a component value, not component type? HOT 1
- Is there any way to add multiple tracking options to component except #[track(All)]? HOT 4
- Workload scheduling re-evaluation
- How to get+modify a component on one entity? HOT 5
- How to make certain systems always run first? HOT 8
- Help me some lifetime issue.. HOT 3
- Can I run some systems in parallel if UniqueViewMut is thread-safe? HOT 2
- Create a way to easily derive the Label trait HOT 1
- AtomicU64 is not available on 32-bit platforms HOT 6
- Component iteration without modification tracking HOT 2
- Tracking compiles but panics on run HOT 6
- Potential memory leak HOT 2
- Cannot create Unique component with non-sync wgpu properties in WASM demo HOT 4
- Question about EntityId management HOT 3
- Can I get all of the components of the entity? HOT 2
- Better error message for boxed traits in components HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from shipyard.