Skip to content

Commit

Permalink
Refactor rescoping for non-optional action sending (pointfreeco#2654)
Browse files Browse the repository at this point in the history
Store rescoping optionalizes the action embedding in order to
short-circuit actions sent from invalid bindings, but we can push that
bit of logic into the reducer itself.
  • Loading branch information
stephencelis authored Dec 13, 2023
1 parent a2f5052 commit 4cdf670
Showing 1 changed file with 6 additions and 10 deletions.
16 changes: 6 additions & 10 deletions Sources/ComposableArchitecture/Store.swift
Original file line number Diff line number Diff line change
Expand Up @@ -971,7 +971,7 @@ extension Reducer {
private final class ScopedStoreReducer<RootState, RootAction, State, Action>: Reducer {
private let rootStore: Store<RootState, RootAction>
private let toState: (RootState) -> State
private let fromAction: (Action) -> RootAction?
private let fromAction: (Action) -> RootAction
private let isInvalid: () -> Bool
private let onInvalidate: () -> Void
private(set) var isSending = false
Expand All @@ -980,7 +980,7 @@ private final class ScopedStoreReducer<RootState, RootAction, State, Action>: Re
init(
rootStore: Store<RootState, RootAction>,
state toState: @escaping (RootState) -> State,
action fromAction: @escaping (Action) -> RootAction?,
action fromAction: @escaping (Action) -> RootAction,
isInvalid: @escaping () -> Bool,
onInvalidate: @escaping () -> Void
) {
Expand Down Expand Up @@ -1014,9 +1014,8 @@ private final class ScopedStoreReducer<RootState, RootAction, State, Action>: Re
}
self.isSending = false
}
if let action = self.fromAction(action),
let task = self.rootStore.send(action, originatingFrom: nil)
{
if BindingLocal.isActive && isInvalid() { return .none }
if let task = self.rootStore.send(self.fromAction(action), originatingFrom: nil) {
return .run { _ in await task.cancellableValue }
} else {
return .none
Expand Down Expand Up @@ -1050,7 +1049,7 @@ extension ScopedStoreReducer: AnyScopedStoreReducer {
{
return childStore
}
let fromAction = self.fromAction as! (A) -> RootAction?
let fromAction = self.fromAction as! (A) -> RootAction
let isInvalid =
id == nil || !store.canCacheChildren
? {
Expand All @@ -1060,13 +1059,10 @@ extension ScopedStoreReducer: AnyScopedStoreReducer {
guard let store = store else { return true }
return store._isInvalidated() || isInvalid?(store.stateSubject.value) == true
}
let fromChildAction = {
BindingLocal.isActive && isInvalid() ? nil : fromChildAction($0)
}
let reducer = ScopedStoreReducer<RootState, RootAction, ChildState, ChildAction>(
rootStore: self.rootStore,
state: { [stateSubject = store.stateSubject] _ in toChildState(stateSubject.value) },
action: { fromChildAction($0).flatMap(fromAction) },
action: { fromAction(fromChildAction($0)) },
isInvalid: isInvalid,
onInvalidate: { [weak store] in
guard let id = id else { return }
Expand Down

0 comments on commit 4cdf670

Please sign in to comment.