1010//
1111//===----------------------------------------------------------------------===//
1212
13+ internal import Synchronization
14+
1315@available ( FoundationPreview 6 . 2 , * )
1416extension ProgressManager {
17+
18+ /// Returns a summary for specified property in subtree.
19+ /// - Parameter metatype: Type of property.
20+ /// - Returns: Summary of property as specified.
21+
22+ public func summary< P: Property > ( of property: P . Type ) -> P . Summary where P. Value == Int , P. Summary == Int {
23+ return getUpdatedIntSummary ( property: MetatypeWrapper ( property) )
24+ }
25+
26+ public func summary< P: Property > ( of property: P . Type ) -> P . Summary where P. Value == Double , P. Summary == Double {
27+ return getUpdatedDoubleSummary ( property: MetatypeWrapper ( property) )
28+ }
29+
30+ public func summary< P: Property > ( of property: P . Type ) -> P . Summary where P. Value == String , P. Summary == String {
31+ return getUpdatedStringSummary ( property: MetatypeWrapper ( property) )
32+ }
33+
34+ public func summary( of property: ProgressManager . Properties . TotalFileCount . Type ) -> Int {
35+ return getUpdatedFileCount ( type: . total)
36+ }
37+
38+ public func summary( of property: ProgressManager . Properties . CompletedFileCount . Type ) -> Int {
39+ return getUpdatedFileCount ( type: . completed)
40+ }
41+
42+ public func summary( of property: ProgressManager . Properties . TotalByteCount . Type ) -> Int64 {
43+ return getUpdatedByteCount ( type: . total)
44+ }
45+
46+ public func summary( of property: ProgressManager . Properties . CompletedByteCount . Type ) -> Int64 {
47+ return getUpdatedByteCount ( type: . completed)
48+ }
49+
50+ public func summary( of property: ProgressManager . Properties . Throughput . Type ) -> Int64 {
51+ let throughput = getUpdatedThroughput ( )
52+ return throughput. values / Int64( throughput. count)
53+ }
54+
55+ public func summary( of property: ProgressManager . Properties . EstimatedTimeRemaining . Type ) -> Duration {
56+ return getUpdatedEstimatedTimeRemaining ( )
57+ }
58+
59+ public func summary( of property: ProgressManager . Properties . FileURL . Type ) -> [ URL ] {
60+ return getUpdatedFileURL ( )
61+ }
62+
63+ // MARK: Additional Properties Methods
64+ internal func getProperties< T, E: Error > (
65+ _ closure: ( sending Values) throws ( E ) -> sending T
66+ ) throws ( E) -> sending T {
67+ try state. withLock { state throws ( E) -> T in
68+ let values = Values ( state: state)
69+ let result = try closure ( values)
70+ return result
71+ }
72+ }
73+
74+ /// Mutates any settable properties that convey information about progress.
75+ public func withProperties< T, E: Error > (
76+ _ closure: ( inout sending Values) throws ( E ) -> sending T
77+ ) throws ( E) -> sending T {
78+ return try state. withLock { ( state) throws ( E) -> T in
79+ var values = Values ( state: state)
80+ // This is done to avoid copy on write later
81+ state = State (
82+ selfFraction: ProgressFraction ( ) ,
83+ children: [ ] ,
84+ parents: [ ] ,
85+ totalFileCount: ProgressManager . Properties. TotalFileCount. defaultValue,
86+ completedFileCount: ProgressManager . Properties. CompletedFileCount. defaultValue,
87+ totalByteCount: ProgressManager . Properties. TotalByteCount. defaultValue,
88+ completedByteCount: ProgressManager . Properties. CompletedByteCount. defaultValue,
89+ throughput: ProgressManager . Properties. Throughput. defaultValue,
90+ estimatedTimeRemaining: ProgressManager . Properties. EstimatedTimeRemaining. defaultValue,
91+ propertiesInt: [ : ] ,
92+ propertiesDouble: [ : ] ,
93+ propertiesString: [ : ] ,
94+ interopObservation: InteropObservation ( subprogressBridge: nil ) ,
95+ observers: [ ]
96+ )
97+ let result = try closure ( & values)
98+ if values. fractionalCountDirty {
99+ markSelfDirty ( parents: values. state. parents)
100+ }
101+
102+ if values. totalFileCountDirty {
103+ markSelfDirty ( property: Properties . TotalFileCount. self, parents: values. state. parents)
104+ }
105+
106+ if values. completedFileCountDirty {
107+ markSelfDirty ( property: Properties . CompletedFileCount. self, parents: values. state. parents)
108+ }
109+
110+ if values. totalByteCountDirty {
111+ markSelfDirty ( property: Properties . TotalByteCount. self, parents: values. state. parents)
112+ }
113+
114+ if values. completedByteCountDirty {
115+ markSelfDirty ( property: Properties . CompletedByteCount. self, parents: values. state. parents)
116+ }
117+
118+ if values. throughputDirty {
119+ markSelfDirty ( property: Properties . Throughput. self, parents: values. state. parents)
120+ }
121+
122+ if values. estimatedTimeRemainingDirty {
123+ markSelfDirty ( property: Properties . EstimatedTimeRemaining. self, parents: values. state. parents)
124+ }
125+
126+ if values. fileURLDirty {
127+ markSelfDirty ( property: Properties . FileURL. self, parents: values. state. parents)
128+ }
129+
130+ if values. dirtyPropertiesInt. count > 0 {
131+ for property in values. dirtyPropertiesInt {
132+ markSelfDirty ( property: property, parents: values. state. parents)
133+ }
134+ }
135+
136+ if values. dirtyPropertiesDouble. count > 0 {
137+ for property in values. dirtyPropertiesDouble {
138+ markSelfDirty ( property: property, parents: values. state. parents)
139+ }
140+ }
141+
142+ if values. dirtyPropertiesString. count > 0 {
143+ for property in values. dirtyPropertiesString {
144+ markSelfDirty ( property: property, parents: values. state. parents)
145+ }
146+ }
147+
148+ if let observerState = values. observerState {
149+ if let _ = state. interopObservation. reporterBridge {
150+ notifyObservers ( with: observerState)
151+ }
152+ }
153+ state = values. state
154+ return result
155+ }
156+ }
157+
15158 /// A container that holds values for properties that specify information on progress.
16159 @dynamicMemberLookup
17160 public struct Values : Sendable {
@@ -44,15 +187,12 @@ extension ProgressManager {
44187
45188 state. selfFraction. total = newValue
46189
47- state. progressParentProgressManagerChildMessenger? . notifyObservers ( with: . fractionUpdated( totalCount: state. selfFraction. total ?? 0 , completedCount: state. selfFraction. completed) )
48-
49- observerState = . fractionUpdated( totalCount: state. selfFraction. total ?? 0 , completedCount: state. selfFraction. completed)
190+ interopNotifications ( )
50191
51192 fractionalCountDirty = true
52193 }
53194 }
54195
55-
56196 /// The completed units of work.
57197 public var completedCount : Int {
58198 mutating get {
@@ -66,9 +206,7 @@ extension ProgressManager {
66206
67207 state. selfFraction. completed = newValue
68208
69- state. progressParentProgressManagerChildMessenger? . notifyObservers ( with: . fractionUpdated( totalCount: state. selfFraction. total ?? 0 , completedCount: state. selfFraction. completed) )
70-
71- observerState = . fractionUpdated( totalCount: state. selfFraction. total ?? 0 , completedCount: state. selfFraction. completed)
209+ interopNotifications ( )
72210
73211 fractionalCountDirty = true
74212 }
@@ -235,5 +373,11 @@ extension ProgressManager {
235373 dirtyPropertiesString. append ( MetatypeWrapper ( P . self) )
236374 }
237375 }
376+
377+ private mutating func interopNotifications( ) {
378+ state. interopObservation. subprogressBridge? . manager. notifyObservers ( with: . fractionUpdated( totalCount: state. selfFraction. total ?? 0 , completedCount: state. selfFraction. completed) )
379+
380+ self . observerState = . fractionUpdated( totalCount: state. selfFraction. total ?? 0 , completedCount: state. selfFraction. completed)
381+ }
238382 }
239383}
0 commit comments