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

Fix removal of script contexts #81

Merged
merged 23 commits into from
Oct 14, 2023
Merged

Fix removal of script contexts #81

merged 23 commits into from
Oct 14, 2023

Conversation

zwazel
Copy link
Contributor

@zwazel zwazel commented Oct 13, 2023

This should fix #79.

Okay i found following issue:
the system script_remove_synchronizer handles removing the contexts of the script.

pub fn script_remove_synchronizer<H: ScriptHost>(
mut query: RemovedComponents<ScriptCollection<H::ScriptAsset>>,
mut contexts: ResMut<ScriptContexts<H::ScriptContext>>,
) {
query.iter().for_each(|v| {
// we know that this entity used to have a script component
// ergo a script context must exist in ctxts, remove all scripts on the entity
contexts.remove_context(v.index());
})
}

The problem here is, that .remove_context expects the script ID, as context_entities uses it as the Key.

pub struct ScriptContexts<C> {
/// holds script contexts for all scripts given their instance ids.
/// This also stores contexts which are not fully loaded hence the Option
pub context_entities: HashMap<u32, (Entity, Option<C>, String)>,
}

Which results in a very unreliable removing of the scripts. especially once the entities have multiple scripts and not just one.

I have updated the script_remove_synchronizer system, to loop through all context_entities and find those with a matching entity id.
The problem I see with this solution is that we have to loop through everything, as we can't break after one found match. because each entity could have multiple scripts, so we need to loop through all of them to find all.

pub fn script_remove_synchronizer<H: ScriptHost>(
mut query: RemovedComponents<ScriptCollection<H::ScriptAsset>>,
mut contexts: ResMut<ScriptContexts<H::ScriptContext>>,
) {
for v in query.iter() {
// we know that this entity used to have a script component
// ergo a script context must exist in ctxts, remove all scripts on the entity
let mut script_ids = Vec::new();
for (script_id, (entity, ..)) in contexts.context_entities.iter() {
if entity.index() == v.index() {
script_ids.push(*script_id);
}
}
for script_id in script_ids {
contexts.remove_context(script_id);
}
}
}

@zwazel
Copy link
Contributor Author

zwazel commented Oct 13, 2023

I just added some changes to the context_entities.
It now takes Entity as a key and holds a Vec of Script IDs.

pub struct ScriptContexts<C> {
/// holds script contexts for all scripts given their instance ids.
/// This also stores contexts which are not fully loaded hence the Option
pub context_entities: HashMap<Entity, Vec<(u32, Option<C>, String)>>,
}

I would love to hear some feedback from you, I personally think it makes more sense to use the entity as a key, instead of the script ID.

I'll now work on fixing the tests, and the other CI issues.

Copy link
Owner

@makspll makspll left a comment

Choose a reason for hiding this comment

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

While I see the benefits of keeping entities as the keys in change detection, it adds load to the hot path, i.e. iterating through all the scripts on top of decreasing cache locality with a nested Vec.

I'd much rather have to iterate through all the contexts to find the right scripts to remove than have to do some additional work when handling events :)

@zwazel
Copy link
Contributor Author

zwazel commented Oct 14, 2023

I see, haven't considered that!
In that case I'll quickly revert back to how it was before!

@zwazel
Copy link
Contributor Author

zwazel commented Oct 14, 2023

Merge Request is back at only fixing the bug in removing script context

@zwazel zwazel requested a review from makspll October 14, 2023 15:59
@makspll
Copy link
Owner

makspll commented Oct 14, 2023

No worries, much appreciated! Just one code style comment and I am happy!

@makspll makspll merged commit a3bccba into makspll:main Oct 14, 2023
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

How do I correctly despawn Entities with scripts?
2 participants