Skip to content

Commit b7e86ad

Browse files
committed
Add ReuseTrace and Update Stack
1 parent 5017bdb commit b7e86ad

File tree

3 files changed

+86
-14
lines changed

3 files changed

+86
-14
lines changed

Sources/OpenSwiftUICore/Data/Other/Stack.swift

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// OpenSwiftUICore
44
//
55
// Audited for RELEASE_2024
6-
// Status: Blocked by GraphReusable
6+
// Status: Complete
77

88
package enum Stack<Value>: Sequence, IteratorProtocol {
99
case empty
@@ -104,16 +104,38 @@ extension Stack: Equatable where Value: Equatable {
104104
}
105105
}
106106

107-
//extension Stack: GraphReusable where Value: GraphReusable {
108-
// @inlinable
109-
// package static var isTriviallyReusable: Bool {
110-
// Value.isTriviallyReusable
111-
// }
112-
//
113-
// package mutating func makeReusable(indirectMap: IndirectAttributeMap) {
114-
// guard !isEmpty else { return }
115-
// map { $0.makeReusable(indirectMap: indirectMap) }
116-
// }
117-
//
118-
// package func tryToReuse(by other: Stack<Value>, indirectMap: IndirectAttributeMap, testOnly: Bool) -> Bool
119-
//}
107+
extension Stack: GraphReusable where Value: GraphReusable {
108+
@inlinable
109+
package static var isTriviallyReusable: Bool {
110+
Value.isTriviallyReusable
111+
}
112+
113+
package mutating func makeReusable(indirectMap: IndirectAttributeMap) {
114+
guard !isEmpty else { return }
115+
self = map { value in
116+
var value = value
117+
value.makeReusable(indirectMap: indirectMap)
118+
return value
119+
}
120+
}
121+
122+
package func tryToReuse(by other: Stack<Value>, indirectMap: IndirectAttributeMap, testOnly: Bool) -> Bool {
123+
var nodeA = self
124+
var nodeB = other
125+
repeat {
126+
let valueA = nodeA.pop()
127+
let valueB = nodeB.pop()
128+
if let valueA, let valueB {
129+
guard valueA.tryToReuse(by: valueB, indirectMap: indirectMap, testOnly: testOnly) else {
130+
return false
131+
}
132+
} else if valueA == nil, valueB == nil {
133+
return true
134+
} else {
135+
ReuseTrace.traceReuseViewInputsDifferentFailure()
136+
return false
137+
}
138+
} while true
139+
return false
140+
}
141+
}

Sources/OpenSwiftUICore/Graph/GraphReusable.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ package import OpenGraphShims
1111
#if canImport(Darwin)
1212
// TODO: Move down to OpenGraph Package
1313
package typealias Subgraph = OGSubgraph
14+
package typealias Graph = OGGraph
1415
#endif
1516

1617
package final class IndirectAttributeMap {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// ReuseTrace.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for RELEASE_2024
6+
// Status: WIP
7+
8+
internal import OpenGraphShims
9+
10+
package struct ReuseTrace {
11+
package static func register(graph: Graph) {
12+
recorder = Recorder(graph: graph)
13+
}
14+
15+
@inline(__always)
16+
package static var isEnabled: Bool { recorder != nil }
17+
18+
package static var recorder: ReuseTrace.Recorder?
19+
20+
@inline(__always)
21+
package static func traceReuseFailure(_ name: UnsafePointer<CChar>) {
22+
guard let recorder else { return }
23+
// TODO
24+
// OGGraphAddTraceEvent
25+
// recorder.graph.addTraceEvent(name)
26+
}
27+
28+
@inline(__always)
29+
package static func traceReuseInternalFailure() {
30+
traceReuseFailure("resuse_internal")
31+
}
32+
33+
@inline(__always)
34+
package static func traceReuseViewInputsDifferentFailure() {
35+
traceReuseFailure("reuse_inputsDifferent")
36+
}
37+
38+
// TODO
39+
40+
final package class Recorder {
41+
var graph: Graph
42+
var frameActive: Bool = false
43+
44+
@inline(__always)
45+
init(graph: Graph) {
46+
self.graph = graph
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)