@@ -301,6 +301,18 @@ extension ProgressManager {
301
301
}
302
302
303
303
// MARK: Clean up dirty paths
304
+ internal struct FileCountUpdateInfo {
305
+ let currentSummary : Int
306
+ let dirtyChildren : [ ( index: Int , manager: ProgressManager ) ]
307
+ let nonDirtySummaries : [ ( index: Int , summary: Int , isAlive: Bool ) ]
308
+ let type : CountType
309
+ }
310
+
311
+ internal struct FileCountUpdate {
312
+ let index : Int
313
+ let updatedSummary : Int
314
+ }
315
+
304
316
internal struct ByteCountUpdateInfo {
305
317
let currentSummary : UInt64
306
318
let dirtyChildren : [ ( index: Int , manager: ProgressManager ) ]
@@ -335,6 +347,111 @@ extension ProgressManager {
335
347
let updatedSummary : Duration
336
348
}
337
349
350
+ internal mutating func getFileCountUpdateInfo( type: CountType ) -> FileCountUpdateInfo {
351
+ let currentSummary : Int
352
+ var dirtyChildren : [ ( index: Int , manager: ProgressManager ) ] = [ ]
353
+ var nonDirtySummaries : [ ( index: Int , summary: Int , isAlive: Bool ) ] = [ ]
354
+
355
+ switch type {
356
+ case . total:
357
+ var value : Int = 0
358
+ ProgressManager . Properties. TotalFileCount. reduce ( into: & value, value: totalFileCount)
359
+ currentSummary = value
360
+
361
+ guard !children. isEmpty else {
362
+ return FileCountUpdateInfo (
363
+ currentSummary: currentSummary,
364
+ dirtyChildren: [ ] ,
365
+ nonDirtySummaries: [ ] ,
366
+ type: type
367
+ )
368
+ }
369
+
370
+ for (idx, childState) in children. enumerated ( ) {
371
+ if childState. totalFileCount. isDirty {
372
+ if let child = childState. child {
373
+ dirtyChildren. append ( ( idx, child) )
374
+ }
375
+ } else {
376
+ let isAlive = childState. child != nil
377
+ nonDirtySummaries. append ( ( idx, childState. totalFileCount. value, isAlive) )
378
+ }
379
+ }
380
+
381
+ case . completed:
382
+ var value : Int = 0
383
+ ProgressManager . Properties. CompletedFileCount. reduce ( into: & value, value: completedFileCount)
384
+ currentSummary = value
385
+
386
+ guard !children. isEmpty else {
387
+ return FileCountUpdateInfo (
388
+ currentSummary: currentSummary,
389
+ dirtyChildren: [ ] ,
390
+ nonDirtySummaries: [ ] ,
391
+ type: type
392
+ )
393
+ }
394
+
395
+ for (idx, childState) in children. enumerated ( ) {
396
+ if childState. completedFileCount. isDirty {
397
+ if let child = childState. child {
398
+ dirtyChildren. append ( ( idx, child) )
399
+ }
400
+ } else {
401
+ let isAlive = childState. child != nil
402
+ nonDirtySummaries. append ( ( idx, childState. completedFileCount. value, isAlive) )
403
+ }
404
+ }
405
+ }
406
+
407
+ return FileCountUpdateInfo (
408
+ currentSummary: currentSummary,
409
+ dirtyChildren: dirtyChildren,
410
+ nonDirtySummaries: nonDirtySummaries,
411
+ type: type
412
+ )
413
+ }
414
+
415
+ internal mutating func updateFileCount( _ updateInfo: FileCountUpdateInfo , _ childUpdates: [ FileCountUpdate ] ) -> Int {
416
+ var value = updateInfo. currentSummary
417
+
418
+ switch updateInfo. type {
419
+ case . total:
420
+ // Apply updates from children that were dirty
421
+ for update in childUpdates {
422
+ children [ update. index] . totalFileCount = PropertyStateInt ( value: update. updatedSummary, isDirty: false )
423
+ value = ProgressManager . Properties. TotalFileCount. merge ( value, update. updatedSummary)
424
+ }
425
+
426
+ // Apply values from non-dirty children
427
+ for (_, childSummary, isAlive) in updateInfo. nonDirtySummaries {
428
+ if isAlive {
429
+ value = ProgressManager . Properties. TotalFileCount. merge ( value, childSummary)
430
+ } else {
431
+ value = ProgressManager . Properties. TotalFileCount. finalSummary ( value, childSummary)
432
+ }
433
+ }
434
+
435
+ case . completed:
436
+ // Apply updates from children that were dirty
437
+ for update in childUpdates {
438
+ children [ update. index] . completedFileCount = PropertyStateInt ( value: update. updatedSummary, isDirty: false )
439
+ value = ProgressManager . Properties. CompletedFileCount. merge ( value, update. updatedSummary)
440
+ }
441
+
442
+ // Apply values from non-dirty children
443
+ for (_, childSummary, isAlive) in updateInfo. nonDirtySummaries {
444
+ if isAlive {
445
+ value = ProgressManager . Properties. CompletedFileCount. merge ( value, childSummary)
446
+ } else {
447
+ value = ProgressManager . Properties. CompletedFileCount. finalSummary ( value, childSummary)
448
+ }
449
+ }
450
+ }
451
+
452
+ return value
453
+ }
454
+
338
455
internal mutating func getByteCountUpdateInfo( type: CountType ) -> ByteCountUpdateInfo {
339
456
let currentSummary : UInt64
340
457
var dirtyChildren : [ ( index: Int , manager: ProgressManager ) ] = [ ]
0 commit comments