Skip to content

Commit 022a9f4

Browse files
committed
Add _DisplayList_StableIdentity
1 parent e89783b commit 022a9f4

File tree

3 files changed

+339
-65
lines changed

3 files changed

+339
-65
lines changed

Sources/OpenSwiftUICore/Render/DisplayList.swift

+163-65
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// Status: WIP
77
// ID: F37E3733E490AA5E3BDC045E3D34D9F8
88

9+
import Foundation
910

1011
// MARK: - _DisplayList_Identity
1112

@@ -66,17 +67,20 @@ package struct DisplayList: Equatable {
6667
}
6768

6869
package init(_ items: [Item]) {
70+
guard !items.isEmpty else {
71+
self.init()
72+
return
73+
}
6974
fatalError("TODO")
7075
}
7176

7277
package mutating func append(_ item: Item) {
78+
fatalError("TODO")
7379
}
7480

7581
package mutating func append(contentsOf other: DisplayList) {
76-
77-
}
78-
79-
// TODO
82+
fatalError("TODO")
83+
}
8084
}
8185

8286
@available(*, unavailable)
@@ -86,37 +90,44 @@ extension DisplayList: Sendable {}
8690
extension DisplayList.Version: Sendable {}
8791

8892
extension DisplayList {
89-
// package typealias Identity = _DisplayList_Identity
90-
// package typealias StableIdentity = _DisplayList_StableIdentity
91-
// package typealias StableIdentityMap = _DisplayList_StableIdentityMap
92-
// package typealias StableIdentityRoot = _DisplayList_StableIdentityRoot
93-
// package typealias StableIdentityScope = _DisplayList_StableIdentityScope
94-
package struct Item : Equatable {
95-
// package var frame: CGRect
96-
// package var version: Version
97-
// package var value: Item.Value
98-
// package var identity: Identity
99-
// package enum Value {
100-
// case empty
101-
// case content(Content)
102-
// case effect(Effect, DisplayList)
103-
// case states([(StrongHash, DisplayList)])
104-
// }
105-
// package init(_ value: Item.Value, frame: CGRect, identity: Identity, version: Version)
106-
// package static func == (lhs: Item, rhs: Item) -> Bool
107-
// package var position: CGPoint {
108-
// get
109-
// }
110-
// package var size: CGSize {
111-
// get
112-
// }
93+
package typealias Identity = _DisplayList_Identity
94+
package typealias StableIdentity = _DisplayList_StableIdentity
95+
package typealias StableIdentityMap = _DisplayList_StableIdentityMap
96+
package typealias StableIdentityRoot = _DisplayList_StableIdentityRoot
97+
package typealias StableIdentityScope = _DisplayList_StableIdentityScope
98+
99+
package struct Item: Equatable {
100+
package var frame: CGRect
101+
package var version: Version
102+
package var value: Item.Value
103+
package var identity: Identity
104+
package enum Value {
105+
case empty
106+
case content(Content)
107+
case effect(Effect, DisplayList)
108+
case states([(StrongHash, DisplayList)])
109+
}
110+
package init(_ value: Item.Value, frame: CGRect, identity: Identity, version: Version) {
111+
self.frame = frame
112+
self.version = version
113+
self.value = value
114+
self.identity = identity
115+
}
116+
117+
package static func == (lhs: Item, rhs: Item) -> Bool {
118+
lhs.identity == rhs.identity && lhs.version == rhs.version
119+
}
120+
121+
package var position: CGPoint { frame.origin }
122+
package var size: CGSize { frame.size }
113123
}
114-
// package struct Content {
115-
// package var value: Content.Value
116-
// package var seed: Seed
117-
// package enum Value {
124+
125+
package struct Content {
126+
package var value: Content.Value
127+
package var seed: Seed
128+
package enum Value {
118129
// indirect case backdrop(BackdropEffect)
119-
// indirect case color(Color.Resolved)
130+
indirect case color(Color.Resolved)
120131
// indirect case chameleonColor(fallback: Color.Resolved, filters: [GraphicsFilter])
121132
// indirect case image(GraphicsImage)
122133
// indirect case shape(Path, AnyResolvedPaint, FillStyle)
@@ -127,20 +138,25 @@ extension DisplayList {
127138
// indirect case flattened(DisplayList, CGPoint, RasterizationOptions)
128139
// indirect case drawing(any RenderBox.RBDisplayListContents, CGPoint, RasterizationOptions)
129140
// indirect case view(any _DisplayList_ViewFactory)
130-
// case placeholder(id: Identity)
131-
// }
132-
// package init(_ value: Content.Value, seed: Seed)
133-
// }
141+
case placeholder(id: Identity)
142+
}
143+
package init(_ value: Content.Value, seed: Seed) {
144+
self.value = value
145+
self.seed = seed
146+
}
147+
}
148+
134149
// package typealias ViewFactory = _DisplayList_ViewFactory
135-
// package enum Effect {
136-
// case identity
137-
// case geometryGroup
138-
// case compositingGroup
139-
// case backdropGroup(Bool)
140-
// indirect case archive(ArchiveIDs?)
141-
// case properties(Properties)
150+
151+
package enum Effect {
152+
case identity
153+
case geometryGroup
154+
case compositingGroup
155+
case backdropGroup(Bool)
156+
indirect case archive(ArchiveIDs?)
157+
case properties(Properties)
142158
// indirect case platformGroup(any PlatformGroupFactory)
143-
// case opacity(Float)
159+
case opacity(Float)
144160
// case blendMode(GraphicsBlendMode)
145161
// indirect case clip(Path, FillStyle, _: GraphicsContext.ClipOptions = .init())
146162
// indirect case mask(DisplayList, _: GraphicsContext.ClipOptions = .init())
@@ -151,28 +167,38 @@ extension DisplayList {
151167
// indirect case view(any _DisplayList_ViewFactory)
152168
// indirect case accessibility([AccessibilityNodeAttachment])
153169
// indirect case platform(PlatformEffect)
154-
// indirect case state(StrongHash)
170+
indirect case state(StrongHash)
155171
// indirect case interpolatorRoot(InterpolatorGroup, contentOrigin: CGPoint, contentOffset: CGSize)
156172
// case interpolatorLayer(InterpolatorGroup, serial: UInt32)
157173
// indirect case interpolatorAnimation(InterpolatorAnimation)
158-
// }
159-
// package enum Transform {
160-
// case affine(CGAffineTransform)
161-
// case projection(ProjectionTransform)
162-
// case rotation(_RotationEffect.Data)
163-
// case rotation3D(_Rotation3DEffect.Data)
164-
// }
174+
}
175+
176+
package enum Transform {
177+
#if canImport(Darwin)
178+
case affine(CGAffineTransform)
179+
#endif
180+
case projection(ProjectionTransform)
181+
// case rotation(_RotationEffect.Data)
182+
// case rotation3D(_Rotation3DEffect.Data)
183+
}
184+
165185
// package typealias AnyEffectAnimation = _DisplayList_AnyEffectAnimation
166186
// package typealias AnyEffectAnimator = _DisplayList_AnyEffectAnimator
167-
// package struct ArchiveIDs {
168-
// package var uuid: Foundation.UUID
169-
// package var stableIDs: StableIdentityMap
170-
// package init(uuid: Foundation.UUID, stableIDs: StableIdentityMap)
171-
// }
187+
188+
package struct ArchiveIDs {
189+
package var uuid: UUID
190+
package var stableIDs: StableIdentityMap
191+
package init(uuid: UUID, stableIDs: StableIdentityMap) {
192+
self.uuid = uuid
193+
self.stableIDs = stableIDs
194+
}
195+
}
196+
172197
// package struct InterpolatorAnimation {
173198
// package var value: StrongHash?
174199
// package var animation: Animation?
175200
// }
201+
176202
package struct Version: Comparable, Hashable {
177203
package private(set) var value: Int
178204

@@ -264,13 +290,80 @@ extension DisplayList {
264290
private var restored: RestoreOptions = []
265291

266292
package init() {}
267-
// package mutating func enter(identity: Identity) -> Index
268-
// package mutating func leave(index saved: Index)
269-
// package mutating func updateArchive(entering: Bool)
270-
// package mutating func skip(list: DisplayList)
271-
// package mutating func skip(item: Item)
272-
// package mutating func skip(effect: Effect)
273-
// package func assertItem(_ item: Item)
293+
package mutating func enter(identity: Identity) -> Index {
294+
if identity == .none {
295+
self.serial &+= 1
296+
var copy = self
297+
self.restored = []
298+
return self
299+
} else {
300+
var copy = self
301+
self.identity = identity
302+
self.serial = 0
303+
self.restored = ._1
304+
return copy
305+
}
306+
}
307+
308+
package mutating func leave(index saved: Index) {
309+
if restored.contains(._4) || saved.restored.contains(._8) {
310+
let oldIdentity = identity
311+
let oldSerial = serial
312+
if restored.contains(._4) {
313+
identity = archiveIdentity
314+
serial = archiveSerial
315+
}
316+
if restored.contains(._8) {
317+
archiveIdentity = oldIdentity
318+
archiveSerial = oldSerial
319+
}
320+
}
321+
if restored.contains(._1) {
322+
identity = saved.identity
323+
serial = saved.serial
324+
}
325+
if restored.contains(._2) {
326+
archiveIdentity = saved.archiveIdentity
327+
archiveSerial = saved.archiveSerial
328+
}
329+
restored = saved.restored
330+
}
331+
332+
package mutating func updateArchive(entering: Bool) {
333+
if entering {
334+
archiveIdentity = identity
335+
archiveSerial = serial
336+
identity = .none
337+
serial = .zero
338+
if !restored.contains([._2, ._4]) {
339+
restored = restored.union([._2, ._4])
340+
}
341+
} else {
342+
// false
343+
identity = archiveIdentity
344+
serial = archiveSerial
345+
archiveIdentity = .none
346+
archiveSerial = .zero
347+
if !restored.contains([._1, ._8]) {
348+
restored = restored.union([._1, ._8])
349+
}
350+
}
351+
}
352+
353+
package mutating func skip(list: DisplayList) {
354+
fatalError("TODO")
355+
}
356+
357+
package mutating func skip(item: Item) {
358+
fatalError("TODO")
359+
}
360+
361+
package mutating func skip(effect: Effect) {
362+
363+
fatalError("TODO")
364+
}
365+
366+
package func assertItem(_ item: Item) {}
274367

275368
package var id: ID {
276369
ID(identity: identity, serial: serial, archiveIdentity: archiveIdentity, archiveSerial: archiveSerial)
@@ -285,6 +378,11 @@ extension DisplayList {
285378

286379
private struct RestoreOptions: OptionSet {
287380
let rawValue: UInt8
381+
382+
static let _1 = RestoreOptions(rawValue: 1 << 0)
383+
static let _2 = RestoreOptions(rawValue: 1 << 1)
384+
static let _4 = RestoreOptions(rawValue: 1 << 2)
385+
static let _8 = RestoreOptions(rawValue: 1 << 3)
288386
}
289387
}
290388
}

0 commit comments

Comments
 (0)