Skip to content

Commit 705d181

Browse files
committed
address PR comments
1 parent 61d6468 commit 705d181

File tree

4 files changed

+68
-32
lines changed

4 files changed

+68
-32
lines changed

Sources/FoundationEssentials/ProgressManager/ProgressFraction.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ internal struct ProgressFraction : Sendable, Equatable, CustomDebugStringConvert
9292
return ProgressFraction(double: operation(lhs.fractionCompleted, rhs.fractionCompleted), overflow: true)
9393
}
9494

95-
//TODO: rdar://148758226 Overflow check
9695
if let lcm = _leastCommonMultiple(lhsTotal, rhsTotal) {
9796
let result = overflowOperation(lhs.completed * (lcm / lhsTotal), rhs.completed * (lcm / rhsTotal))
9897
if result.overflow {

Sources/FoundationEssentials/ProgressManager/ProgressManager+Interop.swift

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ extension Progress {
7171

7272
// MARK: Cycle detection
7373
private func isCycle(reporter: ProgressReporter, visited: Set<ProgressManager> = []) -> Bool {
74-
if self._parent() == nil {
74+
guard let parent = self._parent() else {
7575
return false
7676
}
7777

@@ -132,12 +132,9 @@ internal final class SubprogressBridge: Sendable {
132132
return
133133
}
134134

135-
switch observerState {
136-
case .fractionUpdated(let totalCount, let completedCount):
137-
// This needs to change totalUnitCount before completedUnitCount otherwise progressBridge will finish and mess up the math
138-
self.progressBridge.totalUnitCount = Int64(totalCount)
139-
self.progressBridge.completedUnitCount = Int64(completedCount)
140-
}
135+
// This needs to change totalUnitCount before completedUnitCount otherwise progressBridge will finish and mess up the math
136+
self.progressBridge.totalUnitCount = Int64(observerState.totalCount)
137+
self.progressBridge.completedUnitCount = Int64(observerState.completedCount)
141138
}
142139
}
143140
}
@@ -164,11 +161,8 @@ internal final class ProgressReporterBridge: Sendable {
164161
return
165162
}
166163

167-
switch observerState {
168-
case .fractionUpdated(let totalCount, let completedCount):
169-
self.progressBridge.totalUnitCount = Int64(totalCount)
170-
self.progressBridge.completedUnitCount = Int64(completedCount)
171-
}
164+
self.progressBridge.totalUnitCount = Int64(observerState.totalCount)
165+
self.progressBridge.completedUnitCount = Int64(observerState.completedCount)
172166
}
173167
}
174168

@@ -183,18 +177,18 @@ internal final class NSProgressBridge: Progress, @unchecked Sendable {
183177

184178
init(manager: ProgressManager, progress: Progress, portion: Int) {
185179
self.manager = manager
186-
self.managerBridge = ProgressManager(totalCount: Int(progress.totalUnitCount))
180+
self.managerBridge = ProgressManager(totalCount: Int(clamping: progress.totalUnitCount))
187181
self.progress = progress
188182
super.init(parent: nil, userInfo: nil)
189183

190184
managerBridge.setCounts { completed, total in
191-
completed = Int(progress.completedUnitCount)
185+
completed = Int(clamping: progress.completedUnitCount)
192186
}
193187

194188
let position = manager.addChild(
195189
child: managerBridge,
196190
portion: portion,
197-
childFraction: ProgressFraction(completed: Int(completedUnitCount), total: Int(totalUnitCount))
191+
childFraction: ProgressFraction(completed: Int(clamping: completedUnitCount), total: Int(clamping: totalUnitCount))
198192
)
199193
managerBridge.addParent(parent: manager, positionInParent: position)
200194
}
@@ -203,8 +197,8 @@ internal final class NSProgressBridge: Progress, @unchecked Sendable {
203197
// so that the parent that gets updated is the ProgressManager parent
204198
override func _updateChild(_ child: Foundation.Progress, fraction: _NSProgressFractionTuple, portion: Int64) {
205199
managerBridge.setCounts { completed, total in
206-
completed = Int(fraction.next.completed)
207-
total = Int(fraction.next.total)
200+
completed = Int(clamping: fraction.next.completed)
201+
total = Int(clamping: fraction.next.total)
208202
}
209203
managerBridge.markSelfDirty()
210204
}
@@ -213,8 +207,9 @@ internal final class NSProgressBridge: Progress, @unchecked Sendable {
213207
@available(FoundationPreview 6.4, *)
214208
extension ProgressManager {
215209
// Keeping this as an enum in case we have other states to track in the future.
216-
internal enum ObserverState {
217-
case fractionUpdated(totalCount: Int, completedCount: Int)
210+
internal struct ObserverState {
211+
var totalCount: Int
212+
var completedCount: Int
218213
}
219214

220215
internal struct InteropObservation {

Sources/FoundationEssentials/ProgressManager/ProgressManager+State.swift

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ extension ProgressManager {
139139

140140
/// Returns nil if `self` was instantiated without total units;
141141
/// returns a `Int` value otherwise.
142-
internal func getTotalCount() -> Int? {
142+
internal var totalCount: Int? {
143143
#if FOUNDATION_FRAMEWORK
144144
if let interopTotalCount = interopType?.totalCount {
145145
return interopTotalCount
@@ -150,7 +150,7 @@ extension ProgressManager {
150150

151151
/// Returns 0 if `self` has `nil` total units;
152152
/// returns a `Int` value otherwise.
153-
internal mutating func getCompletedCount() -> Int {
153+
internal mutating func completedCount() -> Int {
154154
#if FOUNDATION_FRAMEWORK
155155
if let interopCompletedCount = interopType?.completedCount {
156156
return interopCompletedCount
@@ -160,7 +160,7 @@ extension ProgressManager {
160160
return selfFraction.completed
161161
}
162162

163-
internal mutating func getFractionCompleted() -> Double {
163+
internal mutating func fractionCompleted() -> Double {
164164
#if FOUNDATION_FRAMEWORK
165165
if let interopFractionCompleted = interopType?.fractionCompleted {
166166
return interopFractionCompleted
@@ -170,7 +170,7 @@ extension ProgressManager {
170170
return overallFraction.fractionCompleted
171171
}
172172

173-
internal func getIsIndeterminate() -> Bool {
173+
internal var isIndeterminate: Bool {
174174
#if FOUNDATION_FRAMEWORK
175175
if let interopIsIndeterminate = interopType?.isIndeterminate {
176176
return interopIsIndeterminate
@@ -179,7 +179,7 @@ extension ProgressManager {
179179
return selfFraction.isIndeterminate
180180
}
181181

182-
internal mutating func getIsFinished() -> Bool {
182+
internal mutating func isFinished() -> Bool {
183183
#if FOUNDATION_FRAMEWORK
184184
if let interopIsFinished = interopType?.isFinished {
185185
return interopIsFinished
@@ -227,15 +227,15 @@ extension ProgressManager {
227227
switch interopType {
228228
case .interopObservation(let observation):
229229
observation.subprogressBridge?.manager.notifyObservers(
230-
with: .fractionUpdated(
230+
with: ObserverState(
231231
totalCount: selfFraction.total ?? 0,
232232
completedCount: selfFraction.completed
233233
)
234234
)
235235

236236
if let _ = observation.reporterBridge {
237237
notifyObservers(
238-
with: .fractionUpdated(
238+
with: ObserverState(
239239
totalCount: selfFraction.total ?? 0,
240240
completedCount: selfFraction.completed
241241
)
@@ -251,6 +251,9 @@ extension ProgressManager {
251251

252252
// MARK: Mark paths dirty
253253
internal mutating func markChildDirty(at position: Int) -> [ParentState]? {
254+
guard position >= 0 && position < children.count else {
255+
return nil
256+
}
254257
guard !children[position].isDirty else {
255258
return nil
256259
}
@@ -259,66 +262,105 @@ extension ProgressManager {
259262
}
260263

261264
internal mutating func markChildDirty(property: MetatypeWrapper<Int, Int>, at position: Int) -> [ParentState] {
265+
guard position >= 0 && position < children.count else {
266+
return parents
267+
}
262268
children[position].childPropertiesInt[property]?.isDirty = true
263269
return parents
264270
}
265271

266272
internal mutating func markChildDirty(property: MetatypeWrapper<UInt64, UInt64>, at position: Int) -> [ParentState] {
273+
guard position >= 0 && position < children.count else {
274+
return parents
275+
}
267276
children[position].childPropertiesUInt64[property]?.isDirty = true
268277
return parents
269278
}
270279

271280
internal mutating func markChildDirty(property: MetatypeWrapper<Double, Double>, at position: Int) -> [ParentState] {
281+
guard position >= 0 && position < children.count else {
282+
return parents
283+
}
272284
children[position].childPropertiesDouble[property]?.isDirty = true
273285
return parents
274286
}
275287

276288
internal mutating func markChildDirty(property: MetatypeWrapper<String?, [String?]>, at position: Int) -> [ParentState] {
289+
guard position >= 0 && position < children.count else {
290+
return parents
291+
}
277292
children[position].childPropertiesString[property]?.isDirty = true
278293
return parents
279294
}
280295

281296
internal mutating func markChildDirty(property: MetatypeWrapper<URL?, [URL?]>, at position: Int) -> [ParentState] {
297+
guard position >= 0 && position < children.count else {
298+
return parents
299+
}
282300
children[position].childPropertiesURL[property]?.isDirty = true
283301
return parents
284302
}
285303

286304
internal mutating func markChildDirty(property: MetatypeWrapper<UInt64, [UInt64]>, at position: Int) -> [ParentState] {
305+
guard position >= 0 && position < children.count else {
306+
return parents
307+
}
287308
children[position].childPropertiesUInt64Array[property]?.isDirty = true
288309
return parents
289310
}
290311

291312
internal mutating func markChildDirty(property: MetatypeWrapper<Duration, Duration>, at position: Int) -> [ParentState] {
313+
guard position >= 0 && position < children.count else {
314+
return parents
315+
}
292316
children[position].childPropertiesDuration[property]?.isDirty = true
293317
return parents
294318
}
295319

296320
internal mutating func markChildDirty(property: ProgressManager.Properties.TotalFileCount.Type, at position: Int) -> [ParentState] {
321+
guard position >= 0 && position < children.count else {
322+
return parents
323+
}
297324
children[position].totalFileCount.isDirty = true
298325
return parents
299326
}
300327

301328
internal mutating func markChildDirty(property: ProgressManager.Properties.CompletedFileCount.Type, at position: Int) -> [ParentState] {
329+
guard position >= 0 && position < children.count else {
330+
return parents
331+
}
302332
children[position].completedFileCount.isDirty = true
303333
return parents
304334
}
305335

306336
internal mutating func markChildDirty(property: ProgressManager.Properties.TotalByteCount.Type, at position: Int) -> [ParentState] {
337+
guard position >= 0 && position < children.count else {
338+
return parents
339+
}
307340
children[position].totalByteCount.isDirty = true
308341
return parents
309342
}
310343

311344
internal mutating func markChildDirty(property: ProgressManager.Properties.CompletedByteCount.Type, at position: Int) -> [ParentState] {
345+
guard position >= 0 && position < children.count else {
346+
return parents
347+
}
312348
children[position].completedByteCount.isDirty = true
313349
return parents
314350
}
315351

316352
internal mutating func markChildDirty(property: ProgressManager.Properties.Throughput.Type, at position: Int) -> [ParentState] {
353+
guard position >= 0 && position < children.count else {
354+
return parents
355+
}
317356
children[position].throughput.isDirty = true
318357
return parents
319358
}
320359

321360
internal mutating func markChildDirty(property: ProgressManager.Properties.EstimatedTimeRemaining.Type, at position: Int) -> [ParentState] {
361+
guard position >= 0 && position < children.count else {
362+
return parents
363+
}
322364
children[position].estimatedTimeRemaining.isDirty = true
323365
return parents
324366
}

Sources/FoundationEssentials/ProgressManager/ProgressManager.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ internal import _FoundationCollections
4040
public var totalCount: Int? {
4141
self.access(keyPath: \.totalCount)
4242
return state.withLock { state in
43-
state.getTotalCount()
43+
state.totalCount
4444
}
4545
}
4646

4747
/// The completed units of work.
4848
public var completedCount: Int {
4949
self.access(keyPath: \.completedCount)
5050
let (children, completedCount) = state.withLock { state in
51-
(state.children.compactMap { $0.child }, state.getCompletedCount())
51+
(state.children.compactMap { $0.child }, state.completedCount())
5252
}
5353
for child in children {
5454
child.access(keyPath: \.completedCount)
@@ -63,7 +63,7 @@ internal import _FoundationCollections
6363
self.access(keyPath: \.totalCount)
6464
self.access(keyPath: \.completedCount)
6565
let (children, fractionCompleted) = state.withLock { state in
66-
(state.children.compactMap { $0.child }, state.getFractionCompleted())
66+
(state.children.compactMap { $0.child }, state.fractionCompleted())
6767
}
6868
for child in children {
6969
child.access(keyPath: \.totalCount)
@@ -77,7 +77,7 @@ internal import _FoundationCollections
7777
public var isIndeterminate: Bool {
7878
self.access(keyPath: \.totalCount)
7979
return state.withLock { state in
80-
state.getIsIndeterminate()
80+
state.isIndeterminate
8181
}
8282
}
8383

@@ -87,7 +87,7 @@ internal import _FoundationCollections
8787
self.access(keyPath: \.totalCount)
8888
self.access(keyPath: \.completedCount)
8989
let (children, isFinished) = state.withLock { state in
90-
(state.children.compactMap { $0.child }, state.getIsFinished())
90+
(state.children.compactMap { $0.child }, state.isFinished())
9191
}
9292
for child in children {
9393
child.access(keyPath: \.totalCount)

0 commit comments

Comments
 (0)