Skip to content

Commit b16ca8c

Browse files
committed
Implement DynamicPreferenceCombiner
1 parent 21945b8 commit b16ca8c

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

Sources/OpenSwiftUICore/Layout/Dynamic/DynamicContainer.swift

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// OpenSwiftUICore
44
//
55
// Audited for 6.5.4
6-
// Status: Blocked by DynamicPreferenceCombiner
6+
// Status: Complete
77
// ID: E7D4CD2D59FB8C77D6C7E9C534464C17 (SwiftUICore)
88

99
package import OpenAttributeGraphShims
@@ -167,7 +167,7 @@ package struct DynamicContainer {
167167
var outputs = _ViewOutputs()
168168
for key in inputs.preferences.keys {
169169
func project<K>(_ key: K.Type) where K: PreferenceKey {
170-
outputs[key] = Attribute(DynamicPreferenceCombiner<K>(info: .init()))
170+
outputs[key] = Attribute(DynamicPreferenceCombiner<K>())
171171
}
172172
project(key)
173173
}
@@ -222,21 +222,61 @@ private class DynamicAnimationListener: AnimationListener, @unchecked Sendable {
222222
}
223223
}
224224

225-
// MARK: - DynamicPreferenceCombiner [WIP]
225+
// MARK: - DynamicPreferenceCombiner
226226

227227
private struct DynamicPreferenceCombiner<K>: Rule, AsyncAttribute, CustomStringConvertible where K: PreferenceKey {
228-
@OptionalAttribute
229-
var info: DynamicContainer.Info?
228+
@OptionalAttribute var info: DynamicContainer.Info?
229+
230+
init() {
231+
_openSwiftUIEmptyStub()
232+
}
230233

231234
var value: K.Value {
232-
// TODO:
233-
_openSwiftUIUnimplementedWarning()
234-
return K.defaultValue
235+
let info = info!
236+
let inusedCount = info.items.count - info.unusedCount
237+
let validCount = inusedCount - info.removedCount
238+
239+
var value = K.defaultValue
240+
let includesRemovedValues = inusedCount != validCount && K._includesRemovedValues
241+
let count = includesRemovedValues ? inusedCount : validCount
242+
243+
var initialValue = true
244+
for index in 0 ..< count {
245+
let itemIndex: Int
246+
if let displayMap = info.displayMap {
247+
if includesRemovedValues {
248+
itemIndex = Int(displayMap[validCount + index])
249+
} else {
250+
itemIndex = Int(displayMap[index])
251+
}
252+
} else {
253+
if includesRemovedValues {
254+
itemIndex = index >= info.removedCount ? index &- info.removedCount : validCount &+ index
255+
} else {
256+
itemIndex = index
257+
}
258+
}
259+
let item = info.items[itemIndex]
260+
guard let attribute = item.outputs[K.self] else {
261+
return value
262+
}
263+
if initialValue {
264+
value = attribute.value
265+
} else {
266+
K.reduce(value: &value) {
267+
attribute.value
268+
}
269+
}
270+
initialValue = false
271+
}
272+
return value
235273
}
236274

237275
var description: String {
238276
"∪+ \(K.readableName)"
239277
}
278+
279+
static var initialValue: K.Value { K.defaultValue }
240280
}
241281

242282
// MARK: - DynamicContainerInfo

0 commit comments

Comments
 (0)