Skip to content

Commit 0d22c7e

Browse files
authored
Add ChangedBodyProperty implementation (#78)
1 parent 2da57e3 commit 0d22c7e

File tree

4 files changed

+105
-24
lines changed

4 files changed

+105
-24
lines changed

Package.resolved

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"location" : "https://github.com/OpenSwiftUIProject/OpenGraph",
88
"state" : {
99
"branch" : "main",
10-
"revision" : "036b8d28a8a1220a768a81bbc20624759094137c"
10+
"revision" : "acbee3c7c30cac49d64a8f619f3e3856a4e943f8"
1111
}
1212
},
1313
{

Sources/OpenSwiftUI/Data/Model/DynamicProperty/DynamicPropertyBuffer.swift

+13
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,19 @@ public struct _DynamicPropertyBuffer {
217217
func traceMountedProperties<Value>(to value: _GraphValue<Value>, fields: DynamicPropertyCache.Fields) {
218218
// TODO: Signpost related
219219
}
220+
221+
func applyChanged(to body: (Int) -> Void) {
222+
var index = 0
223+
var pointer = buf
224+
while index < _count {
225+
let itemPointer = pointer.assumingMemoryBound(to: Item.self)
226+
if itemPointer.pointee.lastChanged {
227+
body(Int(itemPointer.pointee.fieldOffset))
228+
}
229+
index &+= 1
230+
pointer += Int(itemPointer.pointee.size)
231+
}
232+
}
220233
}
221234

222235
extension _DynamicPropertyBuffer {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//
2+
// ChangedBodyProperty.swift
3+
// OpenSwiftUI
4+
//
5+
// Audited for RELEASE_2021
6+
// Status: Complete
7+
8+
#if canImport(Darwin)
9+
internal import OpenGraphShims
10+
import Foundation
11+
12+
extension View {
13+
public static func _printChanges() {
14+
printChangedBodyProperties(of: Self.self)
15+
}
16+
}
17+
18+
extension ViewModifier {
19+
public static func _printChanges() {
20+
printChangedBodyProperties(of: Self.self)
21+
}
22+
}
23+
24+
func printChangedBodyProperties<Body>(of type: Body.Type) {
25+
let properties = changedBodyProperties(of: type)
26+
var result = OGTypeID(type).description
27+
if properties.isEmpty {
28+
result.append(": unchanged.")
29+
} else {
30+
result.append(": \(properties.joined(separator: " ,")) changed.")
31+
}
32+
print(result)
33+
}
34+
35+
func changedBodyProperties<Body>(of type: Body.Type) -> [String] {
36+
var index = 0
37+
repeat {
38+
let options = [
39+
OGGraph.descriptionFormat.takeUnretainedValue(): "stack/frame",
40+
"frame_index": index
41+
] as NSDictionary
42+
guard let description = OGGraph.description(nil, options: options),
43+
let dict = description.takeUnretainedValue() as? [String: Any],
44+
let nodeID = dict["node-id"] as? UInt32,
45+
let selfType = dict["self-type"] as? BodyAccessorRule.Type,
46+
selfType.container == Body.self
47+
else {
48+
index &+= 1
49+
continue
50+
}
51+
var properties: [String] = []
52+
let attribute = OGAttribute(rawValue: nodeID)
53+
let metaProperties = selfType.metaProperties(as: type, attribute: attribute)
54+
if !metaProperties.isEmpty, let inputs = dict["inputs"] as? [[String: Any]] {
55+
for metaProperty in metaProperties {
56+
for input in inputs {
57+
guard let id = input["id"] as? UInt32,
58+
id == metaProperty.1.rawValue,
59+
let changed = input["changed"] as? Bool,
60+
changed
61+
else {
62+
continue
63+
}
64+
properties.append(metaProperty.0)
65+
}
66+
}
67+
}
68+
if let buffer = selfType.buffer(as: type, attribute: attribute) {
69+
let fields = DynamicPropertyCache.fields(of: Body.self)
70+
buffer.applyChanged { offset in
71+
switch fields.layout {
72+
case .product(let fields):
73+
guard let field = fields.first(where: { $0.offset == offset }),
74+
let name = field.name,
75+
let property = String(cString: name, encoding: .utf8) else {
76+
properties.append("@\(offset)")
77+
return
78+
}
79+
properties.append(property)
80+
break
81+
case .sum(_, _):
82+
properties.append("@\(offset)")
83+
break
84+
}
85+
}
86+
}
87+
return properties
88+
} while (index != 32)
89+
return []
90+
}
91+
#endif

Sources/OpenSwiftUI/View/Debug/TODO/printChange.swift

-23
This file was deleted.

0 commit comments

Comments
 (0)