File tree Expand file tree Collapse file tree 9 files changed +120
-15
lines changed
Sources/SimplexArchitecture
Tests/SimplexArchitectureTests Expand file tree Collapse file tree 9 files changed +120
-15
lines changed Original file line number Diff line number Diff line change @@ -28,6 +28,7 @@ public extension CombineAction {
2828 . init( kind: . viewAction( action: action) )
2929 }
3030
31+ @_disfavoredOverload
3132 @inlinable
3233 static func action(
3334 _ action: Reducer . ReducerAction
Original file line number Diff line number Diff line change @@ -17,6 +17,7 @@ public struct SideEffect<Reducer: ReducerProtocol>: Sendable {
1717 case concurrentReducerAction( [ Reducer . ReducerAction ] )
1818 case serialCombineAction( [ CombineAction < Reducer > ] )
1919 case concurrentCombineAction( [ CombineAction < Reducer > ] )
20+ case runEffects( [ SideEffect < Reducer > ] )
2021 }
2122
2223 let kind : EffectKind
@@ -86,4 +87,9 @@ public extension SideEffect {
8687 static func serial( _ actions: CombineAction < Reducer > ... ) -> Self {
8788 . init( effectKind: . serialCombineAction( actions) )
8889 }
90+
91+ @inlinable
92+ static func runEffects( _ effects: [ SideEffect < Reducer > ] ) -> Self {
93+ . init( effectKind: . runEffects( effects) )
94+ }
8995}
Original file line number Diff line number Diff line change 11import Dependencies
22
3- public struct _DependenciesOverrideModifier < Base: ReducerProtocol > : _ReducerModifier {
3+ public struct _DependenciesOverrideModifier < Base: ReducerProtocol > : ReducerModifier {
44 public let base : Base
55 public let override : ( inout DependencyValues ) -> Void
66
7+ @usableFromInline
8+ init ( base: Base , override: @escaping ( inout DependencyValues ) -> Void ) {
9+ self . base = base
10+ self . override = override
11+ }
12+
13+ @inlinable
714 public func reduce( into state: StateContainer < Base . Target > , action: Base . Action ) -> SideEffect < Base > {
815 withDependencies ( override) {
916 base. reduce ( into: state, action: action)
1017 }
1118 }
1219
20+ @inlinable
1321 public func reduce( into state: StateContainer < Base . Target > , action: Base . ReducerAction ) -> SideEffect < Base > {
1422 withDependencies ( override) {
1523 base. reduce ( into: state, action: action)
1624 }
1725 }
1826
27+ @inlinable
1928 public func dependency< Value> (
2029 _ keyPath: WritableKeyPath < DependencyValues , Value > ,
2130 value: Value
@@ -28,6 +37,7 @@ public struct _DependenciesOverrideModifier<Base: ReducerProtocol>: _ReducerModi
2837}
2938
3039public extension ReducerProtocol {
40+ @inlinable
3141 func dependency< Value> (
3242 _ keyPath: WritableKeyPath < DependencyValues , Value > ,
3343 value: Value
Original file line number Diff line number Diff line change 11import Foundation
22import Dependencies
33
4- public protocol _ReducerModifier < Base> {
4+ public protocol ReducerModifier < Base> {
55 associatedtype Base : ReducerProtocol
6- var base : Base { get }
76 func reduce( into state: StateContainer < Base . Target > , action: Base . Action ) -> SideEffect < Base >
8- /// Evolve the current state of ActionSendable to the next state.
9- ///
10- /// - Parameters:
11- /// - state: Current state of ActionSendable and ReducerState. ReducerState can be accessed from the `reducerState` property of State..
12- /// - action: A ReducerAction that can change the state of View and ReducerState.
13- /// - Returns: An `SideEffect` representing the side effects generated by the reducer.
147 func reduce( into state: StateContainer < Base . Target > , action: Base . ReducerAction ) -> SideEffect < Base >
158}
169
17- public extension _ReducerModifier {
10+ public extension ReducerModifier {
1811 @inlinable
1912 func reduce(
2013 into state: StateContainer < Base . Target > ,
Original file line number Diff line number Diff line change @@ -114,6 +114,8 @@ public protocol ReducerProtocol<Target> {
114114 /// - action: A ReducerAction that can change the state of View and ReducerState.
115115 /// - Returns: An `SideEffect` representing the side effects generated by the reducer.
116116 func reduce( into state: StateContainer < Target > , action: ReducerAction ) -> SideEffect < Self >
117+
118+ associatedtype Children = Never
117119}
118120
119121public extension ReducerProtocol where ReducerAction == Never {
Original file line number Diff line number Diff line change @@ -37,14 +37,14 @@ public final class Store<Reducer: ReducerProtocol> {
3737 self . initialReducerState = initialReducerState
3838 }
3939
40- public init < R: _ReducerModifier < Reducer > > (
40+ public init < R: ReducerModifier < Reducer > > (
4141 reducer: R
4242 ) where Reducer. ReducerState == Never {
4343 self . reduce = reducer. reduce
4444 }
4545
4646 /// Initialize `Store` with the given `Reducer` and initial `ReducerState`.
47- public init < R: _ReducerModifier < Reducer > > (
47+ public init < R: ReducerModifier < Reducer > > (
4848 reducer: R ,
4949 initialReducerState: @autoclosure @escaping ( ) -> Reducer . ReducerState
5050 ) {
@@ -213,6 +213,11 @@ extension Store {
213213 }
214214 return [ SendTask ( task: task) ]
215215
216+ case let . runEffects( effects) :
217+ return effects. reduce ( into: [ SendTask] ( ) ) { partialResult, effect in
218+ partialResult += runEffect ( effect, send: send)
219+ }
220+
216221 case . none:
217222 return [ ]
218223 }
Original file line number Diff line number Diff line change 1+ @testable import SimplexArchitecture
2+ import SwiftUI
3+ import Dependencies
4+ import XCTest
5+
6+ final class DependenciesOverrideModifierTests : XCTestCase {
7+ func testModifier( ) async {
8+ let base = BaseView (
9+ store: Store (
10+ reducer: _DependenciesOverrideModifier ( base: BaseReducer ( ) ) {
11+ $0. test = . init( asyncThrows: { } )
12+ }
13+ )
14+ )
15+ let container = base. store. setContainerIfNeeded ( for: base, states: . init( ) )
16+ await base. send ( . test) . wait ( )
17+ XCTAssertEqual ( container. count, 1 )
18+ }
19+ }
20+
21+ struct BaseReducer : ReducerProtocol {
22+ enum Action {
23+ case test
24+ case callback
25+ }
26+
27+ @Dependency ( \. test) var test
28+
29+ func reduce( into state: StateContainer < BaseView > , action: Action ) -> SideEffect < BaseReducer > {
30+ switch action {
31+ case . test:
32+ return . run { send in
33+ try await test. asyncThrows ( )
34+ await send ( . callback)
35+ }
36+ case . callback:
37+ state. count += 1
38+ return . none
39+ }
40+ }
41+ }
42+
43+ @ScopeState
44+ struct BaseView : View {
45+ @State var count : Int = 0
46+ let store : Store < BaseReducer >
47+
48+ init ( store: Store < BaseReducer > = . init( reducer: BaseReducer ( ) ) ) {
49+ self . store = store
50+ }
51+
52+ var body : some View { EmptyView ( ) }
53+ }
Original file line number Diff line number Diff line change @@ -99,9 +99,7 @@ final class ReducerTests: XCTestCase {
9999 func testDependencies( ) async {
100100 let testStore = TestView (
101101 store: . init(
102- reducer: TestReducer ( )
103- . dependency ( \. test, value: . init { } )
104- ,
102+ reducer: TestReducer ( ) . dependency ( \. test, value: . init { } ) ,
105103 initialReducerState: . init( )
106104 )
107105 ) . testStore ( states: . init( ) )
@@ -231,3 +229,27 @@ private struct TestView: View {
231229 EmptyView ( )
232230 }
233231}
232+
233+ private struct MyReducer : ReducerProtocol {
234+ enum Action {
235+ case hoge
236+ }
237+
238+ func reduce( into state: StateContainer < MyView > , action: Action ) -> SideEffect < MyReducer > {
239+ . none
240+ }
241+ }
242+
243+ @ScopeState
244+ private struct MyView : View {
245+ @State var count = 0
246+ let store : Store < MyReducer >
247+
248+ init ( store: Store < MyReducer > = Store ( reducer: MyReducer ( ) ) ) {
249+ self . store = store
250+ }
251+
252+ var body : some View {
253+ EmptyView ( )
254+ }
255+ }
Original file line number Diff line number Diff line change 1+ import Foundation
2+
3+ typealias Original = @convention ( thin) ( UnownedJob ) -> Void
4+ typealias Hook = @convention ( thin) ( UnownedJob , Original ) -> Void
5+
6+ private let _swift_task_enqueueGlobal_hook = dlsym (
7+ dlopen ( nil , 0 ) , " swift_task_enqueueGlobal_hook "
8+ ) . assumingMemoryBound ( to: Hook ? . self)
9+
10+ var swift_task_enqueueGlobal_hook : Hook ? {
11+ get { _swift_task_enqueueGlobal_hook. pointee }
12+ set { _swift_task_enqueueGlobal_hook. pointee = newValue }
13+ }
You can’t perform that action at this time.
0 commit comments