|
42 | 42 | - Expanded Alternatives Considered
|
43 | 43 | * **v6** Minor Updates:
|
44 | 44 | - Replaced `withProperties` method with `setCounts`
|
45 |
| - - Removed `ProgressManager.Values` struct |
46 |
| - - Made `ProgressManager` conform to `@dynamicMemberLookup` and moved `subscript(dynamicMember:)` methods from `ProgressManager.Values` to `ProgressManager` |
| 45 | + - Added `@dynamicMemberLookup` attribute to `ProgressManager` and `ProgressReporter` |
47 | 46 | - Changed behavior of API so that additional properties are restricted to either `Int`, `Double`, `String?`, `URL?`, `UInt64` or `Duration` types instead of `any Sendable` types
|
48 |
| - - Added overloads for `subscript(dynamicMember:)` to account for currently-allowed types |
49 | 47 | - Added requirements to `ProgressManager.Property` protocol to define summarization and termination (deinit) behavior
|
50 | 48 | - Replaced `total(of:)` with overloads for `summary(of:)` to account for all available types and removed `values(of:)` method
|
51 | 49 |
|
@@ -1434,6 +1432,21 @@ There were discussions about representing indeterminate state in `ProgressManage
|
1434 | 1432 | ### Allow declared custom additional property to be any type that can be casted as `any Sendable`
|
1435 | 1433 | We initially allowed the full flexibility of allowing developers to declare `ProgressManager.Property` types to be of any type, including structs. However, we realized that this has a severely negative impact on performance of the API. Thus, for now, we allow developers to only declare `ProgressManager.Property` with only certain `Value` and `Summary` types.
|
1436 | 1434 |
|
| 1435 | +### Introduce `withProperties` closure as an entry point to atomically mutate multiple properties |
| 1436 | +We initially considered introducing a withProperties closure as an entry point to atomically mutate multiple properties. This approach would have used a dedicated ProgressManager.Values struct with `@dynamicMemberLookup` to provide a unified interface for modifying all properties within a single atomic operation. |
| 1437 | + |
| 1438 | +However, this design had several drawbacks: |
| 1439 | +• Limited atomicity: While it allowed atomic mutation of `totalCount` and `completedCount`, it could not achieve the same atomicity for additional properties due to their differences in backing storage |
| 1440 | +• Less intuitive API: The withProperties closure promoted a less natural pattern for accessing and mutating additional properties, particularly when combined with `@dynamicMemberLookup` on the nested `ProgressManager.Values` struct |
| 1441 | +• Inconsistent access patterns: Developers would need to use different patterns for accessing fraction-related properties and additional properties |
| 1442 | + |
| 1443 | +We ultimately decided to replace this approach with a more streamlined design: |
| 1444 | +• `setCounts` closure: Atomically update `totalCount` and `completedCount` |
| 1445 | +• `ProgressManager` directly using `@dynamicMemberLookup`: Applied directly to the ProgressManager class, enabling intuitive dot-syntax access for all additional properties (e.g., manager.totalFileCount = 100) |
| 1446 | +• Consistent access pattern: Both accessing and mutating additional properties now use the same dot-syntax pattern, making the API more discoverable and natural to use |
| 1447 | + |
| 1448 | +With this change, we allow developers to atomically update `totalCount` and `completedCount` via the `setCounts` closure, and access and mutate additional properties via dot syntax. |
| 1449 | + |
1437 | 1450 | ## Acknowledgements
|
1438 | 1451 | Thanks to
|
1439 | 1452 | - [Tony Parker](https://github.com/parkera),
|
|
0 commit comments