Skip to content

Commit 7365f07

Browse files
committed
Implement ArchivedAnimation
1 parent 0740340 commit 7365f07

File tree

1 file changed

+121
-6
lines changed

1 file changed

+121
-6
lines changed

Sources/OpenSwiftUICore/Animation/Animation/AnimationModifier.swift

Lines changed: 121 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
// OpenSwiftUICore
44
//
55
// Audited: 6.5.4
6-
// Status: Blocked by ArichevedView
6+
// Status: Complete
77
// ID: 530459AF10BEFD7ED901D8CE93C1E289 (SwiftUICore)
88

99
import OpenAttributeGraphShims
1010

11+
// MARK: - _AnimationModifier
12+
1113
@available(OpenSwiftUI_v1_0, *)
1214
@frozen
1315
public struct _AnimationModifier<Value>: ViewModifier, PrimitiveViewModifier where Value: Equatable {
@@ -50,8 +52,11 @@ public struct _AnimationModifier<Value>: ViewModifier, PrimitiveViewModifier whe
5052
) -> _ViewOutputs {
5153
let archivedView = inputs.archivedView
5254
if archivedView.isArchived {
53-
// makeArchivedView
54-
_openSwiftUIUnimplementedFailure()
55+
return makeArchivedView(
56+
modifier: modifier,
57+
inputs: inputs,
58+
body: body
59+
)
5560
} else {
5661
var inputs = inputs
5762
_makeInputs(modifier: modifier, inputs: &inputs.base)
@@ -66,19 +71,76 @@ public struct _AnimationModifier<Value>: ViewModifier, PrimitiveViewModifier whe
6671
) -> _ViewListOutputs {
6772
let archivedView = inputs.archivedView
6873
if archivedView.isArchived {
69-
// makeArchivedViewList
70-
_openSwiftUIUnimplementedFailure()
74+
return makeArchivedViewList(
75+
modifier: modifier,
76+
inputs: inputs,
77+
body: body
78+
)
7179
} else {
7280
var inputs = inputs
7381
_makeInputs(modifier: modifier, inputs: &inputs.base)
7482
return body(_Graph(), inputs)
7583
}
7684
}
85+
86+
nonisolated private static func makeArchivedView(
87+
modifier: _GraphValue<Self>,
88+
inputs: _ViewInputs,
89+
body: @escaping (_Graph, _ViewInputs) -> _ViewOutputs
90+
) -> _ViewOutputs {
91+
var inputs = inputs
92+
func project<T>(type: T.Type) -> _ViewOutputs where T: Encodable & Equatable {
93+
let modifier = modifier.value.unsafeBitCast(to: _AnimationModifier<T>.self)
94+
inputs.displayListOptions.formUnion(.disableCanonicalization)
95+
let effect = Attribute(
96+
ArchivedAnimationModifier(modifier: modifier)
97+
)
98+
return ArchivedAnimationModifier.Effect
99+
._makeRendererEffect(
100+
effect: .init(effect),
101+
inputs: inputs,
102+
body: body
103+
)
104+
}
105+
guard let type = Value.self as? (any (Encodable & Equatable).Type) else {
106+
return body(_Graph(), inputs)
107+
}
108+
return project(type: type)
109+
}
110+
111+
nonisolated private static func makeArchivedViewList(
112+
modifier: _GraphValue<Self>,
113+
inputs: _ViewListInputs,
114+
body: @escaping (_Graph, _ViewListInputs) -> _ViewListOutputs
115+
) -> _ViewListOutputs {
116+
var inputs = inputs
117+
func project<T>(type: T.Type) where T: Encodable & Equatable {
118+
let modifier = modifier.value.unsafeBitCast(to: _AnimationModifier<T>.self)
119+
inputs.traits = Attribute(
120+
ArchivedAnimationTrait(
121+
modifier: modifier,
122+
traits: .init(inputs.traits)
123+
)
124+
)
125+
inputs.addTraitKey(ArchivedAnimationTraitKey.self)
126+
}
127+
if inputs.options.contains(.needsArchivedAnimationTraits),
128+
let type = Value.self as? (any (Encodable & Equatable).Type) {
129+
project(type: type)
130+
}
131+
return Self.makeMultiViewList(
132+
modifier: modifier,
133+
inputs: inputs,
134+
body: body
135+
)
136+
}
77137
}
78138

79139
@available(*, unavailable)
80140
extension _AnimationModifier: Sendable {}
81141

142+
// MARK: - _AnimationView
143+
82144
@available(OpenSwiftUI_v3_0, *)
83145
@frozen
84146
public struct _AnimationView<Content>: View, PrimitiveView where Content: Equatable, Content: View {
@@ -193,7 +255,60 @@ struct ValueTransactionSeed<V>: StatefulRule, AsyncAttribute where V: Equatable
193255
}
194256
}
195257

196-
// TODO: Archived stuff
258+
// MARK: - ArchivedAnimationModifier
259+
260+
private struct ArchivedAnimationModifier<Value>: Rule, AsyncAttribute where Value: Encodable, Value: Equatable {
261+
struct Effect: _RendererEffect {
262+
var animation: Animation?
263+
var value: StrongHash
264+
265+
func effectValue(size: CGSize) -> DisplayList.Effect {
266+
.interpolatorAnimation(.init(value: value, animation: animation))
267+
}
268+
}
269+
270+
@Attribute var modifier: _AnimationModifier<Value>
271+
272+
var value: Effect {
273+
let value = (try? StrongHash(encodable: modifier.value)) ?? .random()
274+
return Effect(animation: modifier.animation, value: value)
275+
}
276+
}
277+
278+
// MARK: - ArchivedAnimationTraitKey
279+
280+
struct ArchivedAnimationTraitKey: _ViewTraitKey {
281+
var animation: Animation?
282+
var hash: StrongHash
283+
284+
static var defaultValue: ArchivedAnimationTraitKey? {
285+
nil
286+
}
287+
}
288+
289+
extension ViewTraitCollection {
290+
@inline(__always)
291+
var archivedAnimationTrait: ArchivedAnimationTraitKey? {
292+
get { self[ArchivedAnimationTraitKey.self] }
293+
set { self[ArchivedAnimationTraitKey.self] = newValue }
294+
}
295+
}
296+
297+
// MARK: - ArchivedAnimationTrait
298+
299+
private struct ArchivedAnimationTrait<Value>: Rule, AsyncAttribute where Value: Encodable, Value: Equatable {
300+
@Attribute var modifier: _AnimationModifier<Value>
301+
@OptionalAttribute var traits: ViewTraitCollection?
302+
303+
var value: ViewTraitCollection {
304+
let value = (try? StrongHash(encodable: modifier.value)) ?? .random()
305+
var traits = traits ?? .init()
306+
traits.archivedAnimationTrait = .init(animation: modifier.animation, hash: value)
307+
return traits
308+
}
309+
}
310+
311+
// MARK: - ChildTransaction
197312

198313
private struct ChildTransaction: Rule, AsyncAttribute {
199314
@Attribute var valueTransactionSeed: UInt32

0 commit comments

Comments
 (0)