Skip to content

Commit 2e9b976

Browse files
muukiiclaude
andcommitted
Apply same hasNotifiedCompletion guard to RemovingTransitionContext
Prevent re-entry between invalidate(), transitionSucceeded(), and notifyCancelled() so callbacks fire exactly once. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ab0fd5f commit 2e9b976

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

Sources/FluidStack/Transition/RemovingTransitionContext.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public final class RemovingTransitionContext: TransitionContext {
2626
private let onRequestedDisplayOnTop:
2727
(DisplaySource) -> FluidStackController.DisplayingOnTopSubscription
2828

29+
private var hasNotifiedCompletion: Bool = false
2930
private var callbacks: [(CompletionEvent) -> Void] = []
3031

3132
init(
@@ -57,6 +58,7 @@ public final class RemovingTransitionContext: TransitionContext {
5758
assert(Thread.isMainThread)
5859
guard isInvalidated == false, isCompleted == false else { return }
5960
isInvalidated = true
61+
hasNotifiedCompletion = true
6062
callbacks.forEach { $0(.cancelled) }
6163
onAnimationCompleted(self)
6264
}
@@ -97,6 +99,8 @@ public final class RemovingTransitionContext: TransitionContext {
9799
override func invalidate() {
98100
assert(Thread.isMainThread)
99101
isInvalidated = true
102+
guard hasNotifiedCompletion == false else { return }
103+
hasNotifiedCompletion = true
100104
callbacks.forEach { $0(.interrupted) }
101105
}
102106

@@ -115,6 +119,8 @@ public final class RemovingTransitionContext: TransitionContext {
115119
Triggers ``addCompletionEventHandler(_:)`` with ``TransitionContext/CompletionEvent/succeeded``
116120
*/
117121
func transitionSucceeded() {
122+
guard hasNotifiedCompletion == false else { return }
123+
hasNotifiedCompletion = true
118124
callbacks.forEach { $0(.succeeded) }
119125
}
120126

0 commit comments

Comments
 (0)