@@ -27,6 +27,7 @@ internal struct FractionState {
27
27
var overallFraction : _ProgressFraction {
28
28
selfFraction + childFraction
29
29
}
30
+ var children : Set < ProgressManager >
30
31
var interopChild : ProgressManager ? // read from this if self is actually an interop ghost
31
32
}
32
33
@@ -153,6 +154,13 @@ internal struct AnyMetatypeWrapper: Hashable, Equatable, Sendable {
153
154
}
154
155
state. fractionState. selfFraction. total = newValue ?? 0
155
156
157
+ // Updating my own childFraction here because previously they did not get updated because my total was 0
158
+ if !state. fractionState. children. isEmpty {
159
+ for child in state. fractionState. children {
160
+ child. updateChildFractionSpecial ( of: manager, state: & state)
161
+ }
162
+ }
163
+
156
164
// if newValue is nil, reset indeterminate to true
157
165
if newValue != nil {
158
166
state. fractionState. indeterminate = false
@@ -227,16 +235,15 @@ internal struct AnyMetatypeWrapper: Hashable, Equatable, Sendable {
227
235
}
228
236
229
237
internal let parents : LockedState < [ ProgressManager : Int ] >
230
- private let children : LockedState < Set < ProgressManager > >
231
238
private let state : LockedState < State >
232
239
233
240
internal init ( total: Int ? , ghostReporter: ProgressManager ? , interopObservation: ( any Sendable ) ? ) {
234
241
self . parents = . init( initialState: [ : ] )
235
- self . children = . init( initialState: Set ( ) )
236
242
let fractionState = FractionState (
237
243
indeterminate: total == nil ? true : false ,
238
244
selfFraction: _ProgressFraction ( completed: 0 , total: total ?? 0 ) ,
239
245
childFraction: _ProgressFraction ( completed: 0 , total: 1 ) ,
246
+ children: Set < ProgressManager > ( ) ,
240
247
interopChild: nil
241
248
)
242
249
let state = State ( fractionState: fractionState, otherProperties: [ : ] , childrenOtherProperties: [ : ] )
@@ -324,7 +331,7 @@ internal struct AnyMetatypeWrapper: Hashable, Equatable, Sendable {
324
331
return try state. withLock { ( state) throws ( E) -> T in
325
332
var values = Values ( manager: self , state: state)
326
333
// This is done to avoid copy on write later
327
- state = State ( fractionState: FractionState ( indeterminate: true , selfFraction: _ProgressFraction ( ) , childFraction: _ProgressFraction ( ) ) , otherProperties: [ : ] , childrenOtherProperties: [ : ] )
334
+ state = State ( fractionState: FractionState ( indeterminate: true , selfFraction: _ProgressFraction ( ) , childFraction: _ProgressFraction ( ) , children : Set ( ) ) , otherProperties: [ : ] , childrenOtherProperties: [ : ] )
328
335
let result = try closure ( & values)
329
336
state = values. state
330
337
return result
@@ -402,6 +409,23 @@ internal struct AnyMetatypeWrapper: Hashable, Equatable, Sendable {
402
409
return UpdateState ( previous: previous, current: current)
403
410
}
404
411
412
+ // This is used when parent has its lock acquired and wants its child to update parent's childFraction to reflect child's own changes
413
+ private func updateChildFractionSpecial( of manager: ProgressManager , state managerState: inout State ) {
414
+ let portion = parents. withLock { parents in
415
+ return parents [ manager]
416
+ }
417
+
418
+ if let portionOfParent = portion {
419
+ let myFraction = state. withLock { $0. fractionState. overallFraction }
420
+
421
+ if myFraction. isFinished {
422
+ // If I'm not finished, update my entry in parent's childFraction
423
+ managerState. fractionState. childFraction = managerState. fractionState. childFraction + _ProgressFraction( completed: portionOfParent, total: managerState. fractionState. selfFraction. total) * myFraction
424
+
425
+ }
426
+ }
427
+ }
428
+
405
429
private func updateFractionCompleted( from: _ProgressFraction , to: _ProgressFraction ) {
406
430
_ $observationRegistrar. withMutation ( of: self , keyPath: \. fractionCompleted) {
407
431
if from != to {
@@ -491,8 +515,8 @@ internal struct AnyMetatypeWrapper: Hashable, Equatable, Sendable {
491
515
}
492
516
493
517
internal func addToChildren( childManager: ProgressManager ) {
494
- _ = children . withLock { children in
495
- children. insert ( childManager)
518
+ _ = state . withLock { state in
519
+ state . fractionState . children. insert ( childManager)
496
520
}
497
521
}
498
522
0 commit comments