|
1 |
| -// FIXME |
2 |
| -struct DisplayList {} |
| 1 | +// |
| 2 | +// DisplayList.swift |
| 3 | +// OpenSwiftUICore |
| 4 | +// |
| 5 | +// Audited for RELEASE_2024 |
| 6 | +// Status: WIP |
| 7 | +// ID: F37E3733E490AA5E3BDC045E3D34D9F8 |
| 8 | + |
| 9 | +import Foundation |
| 10 | + |
| 11 | +// MARK: - _DisplayList_Identity |
| 12 | + |
| 13 | +private var lastIdentity: UInt32 = 0 |
| 14 | + |
| 15 | +package struct _DisplayList_Identity: Hashable, Codable, CustomStringConvertible { |
| 16 | + package private(set) var value: UInt32 |
| 17 | + |
| 18 | + init(value: UInt32) { |
| 19 | + self.value = value |
| 20 | + } |
| 21 | + |
| 22 | + package init() { |
| 23 | + lastIdentity += 1 |
| 24 | + self.init(value: lastIdentity) |
| 25 | + } |
| 26 | + |
| 27 | + package init(decodedValue value: UInt32) { |
| 28 | + self.init(value: value) |
| 29 | + } |
| 30 | + |
| 31 | + package static let none = _DisplayList_Identity(value: 0) |
| 32 | + package var description: String { "#\(value)" } |
| 33 | +} |
| 34 | + |
| 35 | +// MARK: - DisplayList |
| 36 | + |
| 37 | +package struct DisplayList: Equatable { |
| 38 | + package private(set) var items: [Item] |
| 39 | + |
| 40 | + package struct Features: OptionSet { |
| 41 | + package let rawValue: UInt16 |
| 42 | + package init(rawValue: UInt16) { |
| 43 | + self.rawValue = rawValue |
| 44 | + } |
| 45 | + package static let required = Features(rawValue: 1 << 0) |
| 46 | + package static let views = Features(rawValue: 1 << 1) |
| 47 | + package static let animations = Features(rawValue: 1 << 2) |
| 48 | + package static let dynamicContent = Features(rawValue: 1 << 3) |
| 49 | + package static let interpolatorLayers = Features(rawValue: 1 << 4) |
| 50 | + package static let interpolatorRoots = Features(rawValue: 1 << 5) |
| 51 | + package static let stateEffects = Features(rawValue: 1 << 6) |
| 52 | + package static let states = Features(rawValue: 1 << 7) |
| 53 | + package static let flattened = Features(rawValue: 1 << 9) |
| 54 | + } |
| 55 | + |
| 56 | + package private(set) var features: Features |
| 57 | + package private(set) var properties: Properties |
| 58 | + |
| 59 | + package init() { |
| 60 | + items = [] |
| 61 | + features = [] |
| 62 | + properties = [] |
| 63 | + } |
| 64 | + |
| 65 | + package init(_ item: Item) { |
| 66 | + fatalError("TODO") |
| 67 | + } |
| 68 | + |
| 69 | + package init(_ items: [Item]) { |
| 70 | + guard !items.isEmpty else { |
| 71 | + self.init() |
| 72 | + return |
| 73 | + } |
| 74 | + fatalError("TODO") |
| 75 | + } |
| 76 | + |
| 77 | + package mutating func append(_ item: Item) { |
| 78 | + fatalError("TODO") |
| 79 | + } |
| 80 | + |
| 81 | + package mutating func append(contentsOf other: DisplayList) { |
| 82 | + fatalError("TODO") |
| 83 | + } |
| 84 | +} |
| 85 | + |
| 86 | +@available(*, unavailable) |
| 87 | +extension DisplayList: Sendable {} |
| 88 | + |
| 89 | +@available(*, unavailable) |
| 90 | +extension DisplayList.Version: Sendable {} |
3 | 91 |
|
4 |
| -// FIXME |
5 | 92 | extension DisplayList {
|
6 |
| - struct Key: PreferenceKey { |
7 |
| - static var defaultValue: Void = () |
| 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 } |
| 123 | + } |
| 124 | + |
| 125 | + package struct Content { |
| 126 | + package var value: Content.Value |
| 127 | + package var seed: Seed |
| 128 | + package enum Value { |
| 129 | +// indirect case backdrop(BackdropEffect) |
| 130 | + indirect case color(Color.Resolved) |
| 131 | +// indirect case chameleonColor(fallback: Color.Resolved, filters: [GraphicsFilter]) |
| 132 | +// indirect case image(GraphicsImage) |
| 133 | +// indirect case shape(Path, AnyResolvedPaint, FillStyle) |
| 134 | +// indirect case shadow(Path, ResolvedShadowStyle) |
| 135 | +// indirect case platformView(any PlatformViewFactory) |
| 136 | +// indirect case platformLayer(any PlatformLayerFactory) |
| 137 | +// indirect case text(StyledTextContentView, CGSize) |
| 138 | +// indirect case flattened(DisplayList, CGPoint, RasterizationOptions) |
| 139 | +// indirect case drawing(any RenderBox.RBDisplayListContents, CGPoint, RasterizationOptions) |
| 140 | +// indirect case view(any _DisplayList_ViewFactory) |
| 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 | + |
| 149 | +// package typealias ViewFactory = _DisplayList_ViewFactory |
| 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) |
| 158 | +// indirect case platformGroup(any PlatformGroupFactory) |
| 159 | + case opacity(Float) |
| 160 | +// case blendMode(GraphicsBlendMode) |
| 161 | +// indirect case clip(Path, FillStyle, _: GraphicsContext.ClipOptions = .init()) |
| 162 | +// indirect case mask(DisplayList, _: GraphicsContext.ClipOptions = .init()) |
| 163 | +// indirect case transform(Transform) |
| 164 | +// indirect case filter(GraphicsFilter) |
| 165 | +// indirect case animation(any _DisplayList_AnyEffectAnimation) |
| 166 | +// indirect case contentTransition(ContentTransition.State) |
| 167 | +// indirect case view(any _DisplayList_ViewFactory) |
| 168 | +// indirect case accessibility([AccessibilityNodeAttachment]) |
| 169 | +// indirect case platform(PlatformEffect) |
| 170 | + indirect case state(StrongHash) |
| 171 | +// indirect case interpolatorRoot(InterpolatorGroup, contentOrigin: CGPoint, contentOffset: CGSize) |
| 172 | +// case interpolatorLayer(InterpolatorGroup, serial: UInt32) |
| 173 | +// indirect case interpolatorAnimation(InterpolatorAnimation) |
| 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 | + |
| 185 | +// package typealias AnyEffectAnimation = _DisplayList_AnyEffectAnimation |
| 186 | +// package typealias AnyEffectAnimator = _DisplayList_AnyEffectAnimator |
| 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 | + |
| 197 | +// package struct InterpolatorAnimation { |
| 198 | +// package var value: StrongHash? |
| 199 | +// package var animation: Animation? |
| 200 | +// } |
| 201 | + |
| 202 | + package struct Version: Comparable, Hashable { |
| 203 | + package private(set) var value: Int |
| 204 | + |
| 205 | + package init() { value = .zero } |
| 206 | + package init(decodedValue value: Int) { self.value = value } |
| 207 | + |
| 208 | + private static var lastValue: Int = .zero |
| 209 | + |
| 210 | + package init(forUpdate: Void) { |
| 211 | + Version.lastValue &+= 1 |
| 212 | + value = Version.lastValue |
| 213 | + } |
| 214 | + |
| 215 | + package mutating func combine(with other: Version) { |
| 216 | + value = max(value, other.value) |
| 217 | + } |
| 218 | + |
| 219 | + package static func < (lhs: Version, rhs: Version) -> Bool { |
| 220 | + lhs.value < rhs.value |
| 221 | + } |
| 222 | + } |
8 | 223 |
|
9 |
| - static func reduce(value _: inout Void, nextValue _: () -> Void) {} |
| 224 | + package struct Seed: Hashable { |
| 225 | + package private(set) var value: UInt16 |
| 226 | + |
| 227 | + init(value: UInt16) { |
| 228 | + self.value = value |
| 229 | + } |
| 230 | + |
| 231 | + package init() { self.init(value: .zero) } |
| 232 | + package init(decodedValue value: UInt16) { self.init(value: value) } |
| 233 | + package init(_ version: Version) { |
| 234 | + if version.value == .zero { |
| 235 | + self.init(value: .zero) |
| 236 | + } else { |
| 237 | + var rawValue = UInt32(bitPattern: Int32(truncatingIfNeeded: version.value >> 16)) |
| 238 | + rawValue += (rawValue << 5) |
| 239 | + rawValue ^= UInt32(bitPattern: Int32(truncatingIfNeeded: version.value)) |
| 240 | + rawValue = 1 | (rawValue << 1) |
| 241 | + self.init(value: UInt16(truncatingIfNeeded: rawValue)) |
| 242 | + } |
| 243 | + } |
| 244 | + |
| 245 | + package mutating func invalidate() { |
| 246 | + guard value != .zero else { return } |
| 247 | + value = (~value | 1) |
| 248 | + } |
| 249 | + |
| 250 | + package static let undefined: Seed = Seed(value: 2) |
| 251 | + } |
| 252 | + package struct Properties: OptionSet { |
| 253 | + package let rawValue: UInt8 |
| 254 | + package init(rawValue: UInt8) { |
| 255 | + self.rawValue = rawValue |
| 256 | + } |
| 257 | + package static let foregroundLayer = Properties(rawValue: 1 << 0) |
| 258 | + package static let ignoresEvents = Properties(rawValue: 1 << 1) |
| 259 | + package static let privacySensitive = Properties(rawValue: 1 << 2) |
| 260 | + package static let archivesInteractiveControls = Properties(rawValue: 1 << 3) |
| 261 | + package static let secondaryForegroundLayer = Properties(rawValue: 1 << 4) |
| 262 | + package static let tertiaryForegroundLayer = Properties(rawValue: 1 << 5) |
| 263 | + package static let quaternaryForegroundLayer = Properties(rawValue: 1 << 6) |
| 264 | + package static let screencaptureProhibited = Properties(rawValue: 1 << 7) |
| 265 | + } |
| 266 | + |
| 267 | + package struct Key : PreferenceKey { |
| 268 | + package static let _includesRemovedValues: Bool = true |
| 269 | + package static let defaultValue = DisplayList() |
| 270 | + package static func reduce(value: inout DisplayList, nextValue: () -> DisplayList) { |
| 271 | + value.append(contentsOf: nextValue()) |
| 272 | + } |
| 273 | + } |
| 274 | + |
| 275 | + package struct Options: OptionSet, ViewInput { |
| 276 | + package let rawValue: UInt8 |
| 277 | + package init(rawValue: UInt8) { |
| 278 | + self.rawValue = rawValue |
| 279 | + } |
10 | 280 |
|
11 |
| - typealias Value = Void |
| 281 | + package static let disableCanonicalization = Options(rawValue: 1 << 0) |
| 282 | + package static let defaultValue: Options = [] |
| 283 | + } |
| 284 | + |
| 285 | + package struct Index { |
| 286 | + package private(set) var identity: _DisplayList_Identity = .none |
| 287 | + package private(set) var serial: UInt32 = .zero |
| 288 | + package private(set) var archiveIdentity: _DisplayList_Identity = .none |
| 289 | + package private(set) var archiveSerial: UInt32 = .zero |
| 290 | + private var restored: RestoreOptions = [] |
| 291 | + |
| 292 | + package init() {} |
| 293 | + package mutating func enter(identity: Identity) -> Index { |
| 294 | + if identity == .none { |
| 295 | + self.serial &+= 1 |
| 296 | + let copy = self |
| 297 | + self.restored = [] |
| 298 | + return copy |
| 299 | + } else { |
| 300 | + let 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) {} |
| 367 | + |
| 368 | + package var id: ID { |
| 369 | + ID(identity: identity, serial: serial, archiveIdentity: archiveIdentity, archiveSerial: archiveSerial) |
| 370 | + } |
| 371 | + |
| 372 | + package struct ID: Hashable { |
| 373 | + var identity: _DisplayList_Identity |
| 374 | + var serial: UInt32 |
| 375 | + var archiveIdentity: _DisplayList_Identity |
| 376 | + var archiveSerial: UInt32 |
| 377 | + } |
| 378 | + |
| 379 | + private struct RestoreOptions: OptionSet { |
| 380 | + 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) |
| 386 | + } |
12 | 387 | }
|
13 | 388 | }
|
0 commit comments