Skip to content

Commit 15a223b

Browse files
committed
Update ViewRenderer
1 parent 7077eb3 commit 15a223b

File tree

2 files changed

+125
-2
lines changed

2 files changed

+125
-2
lines changed

Sources/OpenSwiftUICore/Render/DisplayList.ViewRenderer.swift

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,20 @@
33
// OpenSwiftUICore
44
//
55
// Audited for RELEASE_2024
6-
// Status: WIP
6+
// Status: Blocked by ViewUpdater and ViewRasterizer
7+
// ID: 21FFA3C7D88AC65BB559906758271BFC
78

89
import Foundation
910

11+
protocol ViewRendererBase {
12+
var platform: DisplayList.ViewUpdater.Platform { get }
13+
var exportedObject: AnyObject? { get }
14+
func render(rootView: AnyObject, from list: DisplayList, time: Time, version: DisplayList.Version, maxVersion: DisplayList.Version, environment: DisplayList.ViewRenderer.Environment) -> Time
15+
func renderAsync(to list: DisplayList, time: Time, targetTimestamp: Time?, version: DisplayList.Version, maxVersion: DisplayList.Version) -> Time?
16+
func destroy(rootView: AnyObject)
17+
var viewCacheIsEmpty: Bool { get }
18+
}
19+
1020
@_spi(ForOpenSwiftUIOnly)
1121
extension DisplayList {
1222
final public class ViewRenderer {
@@ -18,5 +28,91 @@ extension DisplayList {
1828
self.contentScale = contentScale
1929
}
2030
}
31+
32+
private enum State {
33+
case none
34+
case updating
35+
case rasterizing
36+
}
37+
38+
let platform: DisplayList.ViewUpdater.Platform
39+
package var configuration: _RendererConfiguration = .init()
40+
package weak var host: ViewRendererHost? = nil
41+
private var state: State = .none
42+
var renderer: (any ViewRendererBase)? = nil
43+
var configChanged: Bool = true
44+
45+
package init(platform: DisplayList.ViewUpdater.Platform) {
46+
self.platform = platform
47+
}
48+
49+
private func updateRenderer(rootView: AnyObject) -> any ViewRendererBase {
50+
guard configChanged else {
51+
return renderer!
52+
}
53+
configChanged = false
54+
let renderStateMatchCheck = switch configuration.renderer {
55+
case .default: state == .updating
56+
case .rasterized: state == .rasterizing
57+
}
58+
if !renderStateMatchCheck {
59+
if let renderer {
60+
renderer.destroy(rootView: rootView)
61+
}
62+
renderer = nil
63+
state = .none
64+
}
65+
if let renderer {
66+
switch configuration.renderer {
67+
case .default:
68+
return renderer
69+
case .rasterized(let options):
70+
fatalError("Blocked by ViewRasterizer")
71+
return renderer
72+
}
73+
} else {
74+
switch configuration.renderer {
75+
case .default:
76+
let updater = ViewUpdater()
77+
// TODO: ViewUpdater
78+
renderer = updater
79+
state = .updating
80+
return renderer!
81+
case .rasterized(let options):
82+
fatalError("Blocked by ViewRasterizer")
83+
}
84+
}
85+
}
86+
87+
package func exportedObject(rootView: AnyObject) -> AnyObject? {
88+
let renderer = updateRenderer(rootView: rootView)
89+
return renderer.exportedObject
90+
}
91+
92+
package func render(rootView: AnyObject, from list: DisplayList, time: Time, nextTime: Time, version: DisplayList.Version, maxVersion: DisplayList.Version, environment: DisplayList.ViewRenderer.Environment) -> Time {
93+
let renderer = updateRenderer(rootView: rootView)
94+
let result = renderer.render(rootView: rootView, from: list, time: time, version: version, maxVersion: maxVersion, environment: environment)
95+
let interval = min(nextTime, result) - time
96+
let maxInterval = max(interval, configuration.minFrameInterval)
97+
return time + maxInterval
98+
}
99+
100+
package func renderAsync(to list: DisplayList, time: Time, nextTime: Time, targetTimestamp: Time?, version: DisplayList.Version, maxVersion: DisplayList.Version) -> Time? {
101+
guard !configChanged, let renderer else {
102+
return nil
103+
}
104+
let result = renderer.renderAsync(to: list, time: time, targetTimestamp: targetTimestamp, version: version, maxVersion: maxVersion)
105+
if let result {
106+
let interval = min(nextTime, result) - time
107+
let maxInterval = max(interval, configuration.minFrameInterval)
108+
return time + maxInterval
109+
} else {
110+
return nil
111+
}
112+
}
113+
114+
package var viewCacheIsEmpty: Bool {
115+
renderer?.viewCacheIsEmpty ?? true
116+
}
21117
}
22118
}

Sources/OpenSwiftUICore/Render/DisplayList.ViewUpdater.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,33 @@
66
// Status: WIP
77

88
extension DisplayList {
9-
final package class ViewUpdater {
9+
// FIXME
10+
final package class ViewUpdater: ViewRendererBase {
11+
init() {
12+
fatalError()
13+
}
14+
15+
init(platform: Platform, exportedObject: AnyObject? = nil, viewCacheIsEmpty: Bool) {
16+
self.platform = platform
17+
self.exportedObject = exportedObject
18+
self.viewCacheIsEmpty = viewCacheIsEmpty
19+
}
20+
21+
var platform: Platform
22+
23+
var exportedObject: AnyObject?
24+
25+
func render(rootView: AnyObject, from list: DisplayList, time: Time, version: DisplayList.Version, maxVersion: DisplayList.Version, environment: DisplayList.ViewRenderer.Environment) -> Time {
26+
.zero
27+
}
28+
29+
func renderAsync(to list: DisplayList, time: Time, targetTimestamp: Time?, version: DisplayList.Version, maxVersion: DisplayList.Version) -> Time? {
30+
nil
31+
}
32+
33+
func destroy(rootView: AnyObject) {
34+
}
35+
36+
var viewCacheIsEmpty: Bool
1037
}
1138
}

0 commit comments

Comments
 (0)