Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 47 additions & 19 deletions packages/flame/lib/src/components/core/component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -430,10 +430,21 @@ class Component {
bool Function(T) handler, {
bool includeSelf = false,
}) {
return descendants(
reversed: true,
includeSelf: includeSelf,
).whereType<T>().every(handler);
final children = _children;
if (children != null) {
for (final child in children.reversed()) {
if (!child.propagateToChildren(handler, includeSelf: true)) {
return false;
}
}
}
if (includeSelf) {
final self = this;
if (self is T && !handler(self)) {
return false;
}
}
return true;
}

@internal
Expand Down Expand Up @@ -1183,24 +1194,41 @@ class Component {

void _remove(Component parent) {
parent._internalChildren.remove(this);
propagateToChildren(
(Component component) {
component
..onRemove()
.._unregisterKey()
.._clearMountedBit()
.._clearRemovingBit()
.._setRemovedBit()
.._removeCompleter?.complete()
.._removeCompleter = null
.._parent!.onChildrenChanged(component, ChildrenChangeType.removed);
return true;
},
includeSelf: true,
);
for (final component in _collectDescendants()) {
component
..onRemove()
.._unregisterKey()
.._clearMountedBit()
.._clearRemovingBit()
.._setRemovedBit()
.._removeCompleter?.complete()
.._removeCompleter = null
.._parent!.onChildrenChanged(component, ChildrenChangeType.removed);
}
_parent = null;
}

/// Collects this component and all its descendants into a list, in the
/// order that `descendants(reversed: true, includeSelf: true)` would
/// produce: leaves first, siblings in reverse order, ancestors after their
/// subtrees. The snapshot allows [_remove] to run user callbacks that
/// mutate the tree while it walks the subtree, without allocating generator
/// frames per tree level the way [descendants] does.
///
/// The [out] parameter is only used by the recursive calls, so that the
/// whole subtree is collected into a single list.
List<Component> _collectDescendants([List<Component>? out]) {
out ??= [];
final children = _children;
if (children != null) {
for (final child in children.reversed()) {
child._collectDescendants(out);
}
}
out.add(this);
return out;
}

void _unregisterKey() {
if (key != null) {
final game = findGame();
Expand Down
18 changes: 8 additions & 10 deletions packages/flame/lib/src/events/messages/event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@ abstract class Event<R> {
Component rootComponent,
void Function(T component) eventHandler,
) {
for (final child
in rootComponent
.descendants(reversed: true, includeSelf: true)
.whereType<T>()) {
continuePropagation = false;
eventHandler(child);
if (!continuePropagation) {
break;
}
}
rootComponent.propagateToChildren<T>(
(component) {
continuePropagation = false;
eventHandler(component);
return continuePropagation;
},
includeSelf: true,
);
}
}
Loading