removeAll(children) crashes in onRemove
Current bug behavior
If you do removeAll(children) in a component's onRemove method it will assert with:
threw _AssertionError:<'package:flame/src/components/core/component.dart': Failed assertion: line 627 pos 7: 'child._parent != null': Trying to remove a component that doesn't belong to any parent>
Expected behavior
To be able to remove all children in onRemove so that one can do clean-up in there, if you add the children in onMount for example.
Steps to reproduce
testWithFlameGame(
'Remove all children in onRemove',
(game) async {
final component = _RemoveAllChildrenComponent();
component.addAll([Component(), Component()]);
game.add(component);
await game.ready();
expect(() => game.remove(component), returnsNormally);
expect(() => game.update(0), returnsNormally); // Here is the assertion.
},
);
class _RemoveAllChildrenComponent extends Component {
@override
void onRemove() {
removeAll(children);
}
}
More environment information
- Flame version:
main
Hi there !
I've ran some tests, and according to the doc, onRemove is also called on all the children of the component when you call game.remove(component)
If you add a
class _RemoveWatcherComponent extends Component {
@override
void onRemove() {
debugPrint('onRemove');
super.onRemove();
}
}
and transform using component.addAll([Component(), Component()]); you can see that calling game.remove(component) calls onRemove on every child of component before calling onRemove() on the component itself.
It might be because of propagateToChildren in Component#_remove that calls onRemove without calling _remove, therefor putting _parent = null without removing itself from the list of children ?
Is it possible that the issue comes from there ?
It might be because of propagateToChildren in Component#_remove that calls onRemove without calling _remove, therefor putting _parent = null without removing itself from the list of children ?
Is it possible that the issue comes from there ?
Yeah, that's definitely where it comes from. Not sure how to solve it nicely though, because we want the children to have their onRemove called removed before the parent is removed.