diff --git a/packages/flame/lib/src/components/core/component.dart b/packages/flame/lib/src/components/core/component.dart index 0097139dea6..d16ddf6a0b2 100644 --- a/packages/flame/lib/src/components/core/component.dart +++ b/packages/flame/lib/src/components/core/component.dart @@ -594,7 +594,7 @@ class Component { _clearRemovingBit(); } game.enqueueMove(child, this); - } else if (isMounted && !child.isMounted) { + } else if (isMounted && !isRemoving && !child.isMounted) { child._parent = this; game.enqueueAdd(child, this); } else { diff --git a/packages/flame/test/components/component_test.dart b/packages/flame/test/components/component_test.dart index 3dd96e61cbc..1eb61d6aa81 100644 --- a/packages/flame/test/components/component_test.dart +++ b/packages/flame/test/components/component_test.dart @@ -556,6 +556,27 @@ void main() { expect(wrapper.contains(child), true); }, ); + + testWithFlameGame('when parent is in removing state', (game) async { + final parent = Component(); + final child = Component(); + + await game.add(parent); + await game.ready(); + + // Remove the parent and add the child in the same tick. + parent.removeFromParent(); + await parent.add(child); + + // Timeout is added because processLifecycleEvents of ComponentTreeRoot + // gets blocked in such cases. + expect(game.ready().timeout(const Duration(seconds: 2)), completes); + + // Adding the parent again should eventually mount the child as well. + await game.add(parent); + await game.ready(); + expect(child.isMounted, true); + }); }); group('Removing components', () {