Skip to content

Commit a01cbb4

Browse files
authored
Refactoring (#170)
* Use 'some Type' over generic type constraints where possible * Use @entry * Remove @sendable from where not need it * Optimise the number of dictionary accesses when initialising atoms not overridden * Use #Preview instead of PreviewProvider
1 parent 8b583f7 commit a01cbb4

32 files changed

+337
-337
lines changed

Examples/Packages/CrossPlatform/Sources/ExampleCounter/ExampleCounter.swift

+3-5
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,8 @@ public struct ExampleCounter: View {
4747
}
4848
}
4949

50-
struct CounterScreen_Preview: PreviewProvider {
51-
static var previews: some View {
52-
AtomRoot {
53-
CounterScreen()
54-
}
50+
#Preview {
51+
AtomRoot {
52+
CounterScreen()
5553
}
5654
}

Examples/Packages/CrossPlatform/Sources/ExampleTodo/Screens.swift

+3-5
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,8 @@ struct TodoListScreen: View {
4343
}
4444
}
4545

46-
struct TodoListScreen_Preview: PreviewProvider {
47-
static var previews: some View {
48-
AtomRoot {
49-
TodoListScreen()
50-
}
46+
#Preview {
47+
AtomRoot {
48+
TodoListScreen()
5149
}
5250
}

Examples/Packages/iOS/Sources/ExampleMap/Screens.swift

+3-5
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,8 @@ struct MapScreen: View {
5454
}
5555
}
5656

57-
struct ExampleScreen_Preview: PreviewProvider {
58-
static var previews: some View {
59-
AtomRoot {
60-
MapScreen()
61-
}
57+
#Preview {
58+
AtomRoot {
59+
MapScreen()
6260
}
6361
}

Examples/Packages/iOS/Sources/ExampleMovieDB/Screens/DetailScreen.swift

+4-6
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ struct DetailScreen: View {
105105
}
106106
}
107107

108-
struct DetailScreen_Preview: PreviewProvider {
109-
static let movie = Movie(
108+
#Preview {
109+
let movie = Movie(
110110
id: 680,
111111
title: "Pulp Fiction",
112112
overview: """
@@ -118,9 +118,7 @@ struct DetailScreen_Preview: PreviewProvider {
118118
releaseDate: Date(timeIntervalSinceReferenceDate: -199184400.0)
119119
)
120120

121-
static var previews: some View {
122-
AtomRoot {
123-
DetailScreen(movie: movie)
124-
}
121+
AtomRoot {
122+
DetailScreen(movie: movie)
125123
}
126124
}

Examples/Packages/iOS/Sources/ExampleMovieDB/Screens/MoviesScreen.swift

+4-6
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,10 @@ struct MoviesScreen: View {
9595
}
9696
}
9797

98-
struct MoviesScreen_Preview: PreviewProvider {
99-
static var previews: some View {
100-
AtomRoot {
101-
NavigationStack {
102-
MoviesScreen()
103-
}
98+
#Preview {
99+
AtomRoot {
100+
NavigationStack {
101+
MoviesScreen()
104102
}
105103
}
106104
}

Examples/Packages/iOS/Sources/ExampleMovieDB/Screens/SearchScreen.swift

+7-9
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,13 @@ struct SearchScreen: View {
4444
}
4545
}
4646

47-
struct SearchScreen_Preview: PreviewProvider {
48-
static var previews: some View {
49-
AtomRoot {
50-
NavigationStack {
51-
SearchScreen()
52-
}
53-
}
54-
.override(SearchQueryAtom()) { _ in
55-
"Léon"
47+
#Preview {
48+
AtomRoot {
49+
NavigationStack {
50+
SearchScreen()
5651
}
5752
}
53+
.override(SearchQueryAtom()) { _ in
54+
"Léon"
55+
}
5856
}

Examples/Packages/iOS/Sources/ExampleTimeTravel/ExampleTimeTravel.swift

+4-6
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,10 @@ public struct ExampleTimeTravel: View {
133133
}
134134
}
135135

136-
struct TimeTravelScreen_Preview: PreviewProvider {
137-
static var previews: some View {
138-
AtomRoot {
139-
TimeTravelDebug {
140-
NumberInputScreen()
141-
}
136+
#Preview {
137+
AtomRoot {
138+
TimeTravelDebug {
139+
NumberInputScreen()
142140
}
143141
}
144142
}

Examples/Packages/iOS/Sources/ExampleVoiceMemo/VoiceMemoListScreen.swift

+12-14
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,17 @@ private struct ElapsedTimeDisplay: View {
123123
}
124124
}
125125

126-
struct VoiceMemoListScreen_Preview: PreviewProvider {
127-
static var previews: some View {
128-
AtomRoot {
129-
VoiceMemoListScreen()
130-
}
131-
.override(AudioSessionAtom()) { _ in
132-
MockAudioSession()
133-
}
134-
.override(AudioRecorderAtom()) { _ in
135-
MockAudioRecorder()
136-
}
137-
.override(AudioPlayerAtom.self) { _ in
138-
MockAudioPlayer()
139-
}
126+
#Preview {
127+
AtomRoot {
128+
VoiceMemoListScreen()
129+
}
130+
.override(AudioSessionAtom()) { _ in
131+
MockAudioSession()
132+
}
133+
.override(AudioRecorderAtom()) { _ in
134+
MockAudioRecorder()
135+
}
136+
.override(AudioPlayerAtom.self) { _ in
137+
MockAudioPlayer()
140138
}
141139
}

Sources/Atoms/AtomRoot.swift

+13-13
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ import SwiftUI
6262
///
6363
public struct AtomRoot<Content: View>: View {
6464
private var storage: Storage
65-
private var overrides = [OverrideKey: any OverrideProtocol]()
6665
private var observers = [Observer]()
66+
private var overrideContainer = OverrideContainer()
6767
private let content: Content
6868

6969
/// Creates an atom root with the specified content that will be allowed to use atoms.
@@ -93,16 +93,16 @@ public struct AtomRoot<Content: View>: View {
9393
switch storage {
9494
case .managed:
9595
Managed(
96-
overrides: overrides,
9796
observers: observers,
97+
overrideContainer: overrideContainer,
9898
content: content
9999
)
100100

101101
case .unmanaged(let store):
102102
Scope(
103103
store: store,
104-
overrides: overrides,
105104
observers: observers,
105+
overrideContainer: overrideContainer,
106106
content: content
107107
)
108108
}
@@ -114,7 +114,7 @@ public struct AtomRoot<Content: View>: View {
114114
/// - Parameter onUpdate: A closure to handle a snapshot of recent updates.
115115
///
116116
/// - Returns: The self instance.
117-
public func observe(_ onUpdate: @escaping @MainActor @Sendable (Snapshot) -> Void) -> Self {
117+
public func observe(_ onUpdate: @MainActor @escaping (Snapshot) -> Void) -> Self {
118118
mutating(self) { $0.observers.append(Observer(onUpdate: onUpdate)) }
119119
}
120120

@@ -128,8 +128,8 @@ public struct AtomRoot<Content: View>: View {
128128
/// - value: A value to be used instead of the atom's value.
129129
///
130130
/// - Returns: The self instance.
131-
public func override<Node: Atom>(_ atom: Node, with value: @escaping @MainActor @Sendable (Node) -> Node.Produced) -> Self {
132-
mutating(self) { $0.overrides[OverrideKey(atom)] = Override(getValue: value) }
131+
public func override<Node: Atom>(_ atom: Node, with value: @MainActor @escaping (Node) -> Node.Produced) -> Self {
132+
mutating(self) { $0.overrideContainer.addOverride(for: atom, with: value) }
133133
}
134134

135135
/// Overrides the atoms with the given value.
@@ -144,8 +144,8 @@ public struct AtomRoot<Content: View>: View {
144144
/// - value: A value to be used instead of the atom's value.
145145
///
146146
/// - Returns: The self instance.
147-
public func override<Node: Atom>(_ atomType: Node.Type, with value: @escaping @MainActor @Sendable (Node) -> Node.Produced) -> Self {
148-
mutating(self) { $0.overrides[OverrideKey(atomType)] = Override(getValue: value) }
147+
public func override<Node: Atom>(_ atomType: Node.Type, with value: @MainActor @escaping (Node) -> Node.Produced) -> Self {
148+
mutating(self) { $0.overrideContainer.addOverride(for: atomType, with: value) }
149149
}
150150
}
151151

@@ -156,8 +156,8 @@ private extension AtomRoot {
156156
}
157157

158158
struct Managed: View {
159-
let overrides: [OverrideKey: any OverrideProtocol]
160159
let observers: [Observer]
160+
let overrideContainer: OverrideContainer
161161
let content: Content
162162

163163
@State
@@ -168,17 +168,17 @@ private extension AtomRoot {
168168
var body: some View {
169169
Scope(
170170
store: store,
171-
overrides: overrides,
172171
observers: observers,
172+
overrideContainer: overrideContainer,
173173
content: content
174174
)
175175
}
176176
}
177177

178178
struct Scope: View {
179179
let store: AtomStore
180-
let overrides: [OverrideKey: any OverrideProtocol]
181180
let observers: [Observer]
181+
let overrideContainer: OverrideContainer
182182
let content: Content
183183

184184
@State
@@ -189,8 +189,8 @@ private extension AtomRoot {
189189
let store = StoreContext.registerRoot(
190190
in: store,
191191
scopeKey: scopeKey,
192-
overrides: overrides,
193-
observers: observers
192+
observers: observers,
193+
overrideContainer: overrideContainer
194194
)
195195

196196
state.unregister = {

Sources/Atoms/AtomScope.swift

+10-10
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ import SwiftUI
4949
///
5050
public struct AtomScope<Content: View>: View {
5151
private let inheritance: Inheritance
52-
private var overrides = [OverrideKey: any OverrideProtocol]()
5352
private var observers = [Observer]()
53+
private var overrideContainer = OverrideContainer()
5454
private let content: Content
5555

5656
/// Creates a new scope with the specified content.
@@ -85,8 +85,8 @@ public struct AtomScope<Content: View>: View {
8585
case .environment(let id):
8686
WithEnvironment(
8787
id: id,
88-
overrides: overrides,
8988
observers: observers,
89+
overrideContainer: overrideContainer,
9090
content: content
9191
)
9292

@@ -109,7 +109,7 @@ public struct AtomScope<Content: View>: View {
109109
/// - Parameter onUpdate: A closure to handle a snapshot of recent updates.
110110
///
111111
/// - Returns: The self instance.
112-
public func scopedObserve(_ onUpdate: @escaping @MainActor @Sendable (Snapshot) -> Void) -> Self {
112+
public func scopedObserve(_ onUpdate: @MainActor @escaping (Snapshot) -> Void) -> Self {
113113
mutating(self) { $0.observers.append(Observer(onUpdate: onUpdate)) }
114114
}
115115

@@ -127,8 +127,8 @@ public struct AtomScope<Content: View>: View {
127127
/// - value: A value to be used instead of the atom's value.
128128
///
129129
/// - Returns: The self instance.
130-
public func scopedOverride<Node: Atom>(_ atom: Node, with value: @escaping @MainActor @Sendable (Node) -> Node.Produced) -> Self {
131-
mutating(self) { $0.overrides[OverrideKey(atom)] = Override(getValue: value) }
130+
public func scopedOverride<Node: Atom>(_ atom: Node, with value: @MainActor @escaping (Node) -> Node.Produced) -> Self {
131+
mutating(self) { $0.overrideContainer.addOverride(for: atom, with: value) }
132132
}
133133

134134
/// Override the atoms used in this scope with the given value.
@@ -147,8 +147,8 @@ public struct AtomScope<Content: View>: View {
147147
/// - value: A value to be used instead of the atom's value.
148148
///
149149
/// - Returns: The self instance.
150-
public func scopedOverride<Node: Atom>(_ atomType: Node.Type, with value: @escaping @MainActor @Sendable (Node) -> Node.Produced) -> Self {
151-
mutating(self) { $0.overrides[OverrideKey(atomType)] = Override(getValue: value) }
150+
public func scopedOverride<Node: Atom>(_ atomType: Node.Type, with value: @MainActor @escaping (Node) -> Node.Produced) -> Self {
151+
mutating(self) { $0.overrideContainer.addOverride(for: atomType, with: value) }
152152
}
153153
}
154154

@@ -160,8 +160,8 @@ private extension AtomScope {
160160

161161
struct WithEnvironment: View {
162162
let id: ScopeID
163-
let overrides: [OverrideKey: any OverrideProtocol]
164163
let observers: [Observer]
164+
let overrideContainer: OverrideContainer
165165
let content: Content
166166

167167
@State
@@ -174,8 +174,8 @@ private extension AtomScope {
174174
let store = environmentStore?.registerScope(
175175
scopeID: id,
176176
scopeKey: scopeKey,
177-
overrides: overrides,
178-
observers: observers
177+
observers: observers,
178+
overrideContainer: overrideContainer
179179
)
180180

181181
state.unregister = {

Sources/Atoms/Context/AtomContext.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public protocol AtomContext {
119119
///
120120
/// - Parameter atom: An atom to reset.
121121
@_disfavoredOverload
122-
func reset<Node: Atom>(_ atom: Node)
122+
func reset(_ atom: some Atom)
123123

124124
/// Calls arbitrary reset function of the given atom.
125125
///
@@ -136,7 +136,7 @@ public protocol AtomContext {
136136
/// ```
137137
///
138138
/// - Parameter atom: An atom to reset.
139-
func reset<Node: Resettable>(_ atom: Node)
139+
func reset(_ atom: some Resettable)
140140
}
141141

142142
public extension AtomContext {

Sources/Atoms/Context/AtomCurrentContext.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public struct AtomCurrentContext: AtomContext {
136136
/// - Parameter atom: An atom to reset.
137137
@inlinable
138138
@_disfavoredOverload
139-
public func reset<Node: Atom>(_ atom: Node) {
139+
public func reset(_ atom: some Atom) {
140140
_store.reset(atom)
141141
}
142142

@@ -156,7 +156,7 @@ public struct AtomCurrentContext: AtomContext {
156156
///
157157
/// - Parameter atom: An atom to reset.
158158
@inlinable
159-
public func reset<Node: Resettable>(_ atom: Node) {
159+
public func reset(_ atom: some Resettable) {
160160
_store.reset(atom)
161161
}
162162
}

0 commit comments

Comments
 (0)