Skip to content

Commit 75b0f6a

Browse files
authored
Add BodyAccessor Support (#38)
* Update GraphHost * Update GraphValue and GraphInputs * Add BodyAccessor and BodyAccessorRule * Add StaticBody implementation * Complete missing part of StaticBody * Update StaticBody * Add BodyAccessor.makeBody logic * Workaround non-Darwin platform build issue Tracked with #39 * Add scripts and update swift-syntax version
1 parent deb8e9d commit 75b0f6a

17 files changed

+396
-78
lines changed

Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Scripts/demangle.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/zsh
2+
3+
# A `realpath` alternative using the default C implementation.
4+
filepath() {
5+
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
6+
}
7+
8+
OG_ROOT="$(dirname $(dirname $(filepath $0)))"
9+
10+
# Get the language and input file path from the arguments
11+
language=${1:-"swift"}
12+
input_file=${2:-"$(dirname $(filepath $0))/demangle.txt"}
13+
14+
echo "Demangling $input_file using $language mode"
15+
16+
# Read each line of the input file
17+
while IFS= read -r line; do
18+
# Demangle the line using the appropriate tool based on the language
19+
if [[ $language == "swift" ]]; then
20+
xcrun swift-demangle "$line"
21+
elif [[ $language == "c++" ]]; then
22+
c++filt "$line"
23+
else
24+
echo "Invalid language: $language"
25+
echo "Usage: demangle.sh <language> <input file>"
26+
echo "language: swift or c++, [default]: swift"
27+
echo "input file: [default] demangle.txt"
28+
exit 1
29+
fi
30+
done < "$input_file"

Scripts/demangle.txt

Whitespace-only changes.

Scripts/openswiftui_swiftinterface.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/zsh
2+
3+
# A `realpath` alternative using the default C implementation.
4+
filepath() {
5+
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
6+
}
7+
8+
OPENSWIFTUI_ROOT="$(dirname $(dirname $(filepath $0)))"
9+
10+
cd $OPENSWIFTUI_ROOT
11+
12+
export OPENSWIFTUI_SWIFT_TESTING=0
13+
export OPENGRAPH_SWIFT_TESTING=0
14+
swift build -c release -Xswiftc -emit-module-interface -Xswiftc -enable-library-evolution

Sources/OpenSwiftUI/DataAndStorage/ModelData/DynamicProperty/DynamicProperty.swift

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// Created by Kyle on 2023/11/2.
66
// Lastest Version: iOS 15.5
77
// Status: Complete
8+
// ID: 49D2A32E637CD497C6DE29B8E060A506
9+
10+
internal import OpenGraphShims
811

912
/// An interface for a stored variable that updates an external property of a
1013
/// view.
@@ -29,8 +32,209 @@ public protocol DynamicProperty {
2932
mutating func update()
3033
}
3134

35+
// MARK: Default implementation for DynamicProperty
36+
3237
extension DynamicProperty {
38+
public static func _makeProperty<Value>(
39+
in buffer: inout _DynamicPropertyBuffer,
40+
container: _GraphValue<Value>,
41+
fieldOffset: Int,
42+
inputs: inout _GraphInputs
43+
) {
44+
makeEmbeddedProperties(
45+
in: &buffer,
46+
container: container,
47+
fieldOffset: fieldOffset,
48+
inputs: &inputs
49+
)
50+
buffer.append(
51+
EmbeddedDynamicPropertyBox<Self>(),
52+
fieldOffset: fieldOffset
53+
)
54+
}
55+
3356
public static var _propertyBehaviors: UInt32 { 0 }
3457

3558
public mutating func update() {}
3659
}
60+
61+
// MARK: - EmbeddedDynamicPropertyBox
62+
63+
private struct EmbeddedDynamicPropertyBox<Value: DynamicProperty>: DynamicPropertyBox {
64+
typealias Property = Value
65+
func destroy() {}
66+
func reset() {}
67+
func update(property: inout Property, phase _: _GraphInputs.Phase) -> Bool {
68+
property.update()
69+
return false
70+
}
71+
}
72+
73+
extension DynamicProperty {
74+
static func makeEmbeddedProperties<Value>(
75+
in buffer: inout _DynamicPropertyBuffer,
76+
container: _GraphValue<Value>,
77+
fieldOffset: Int,
78+
inputs: inout _GraphInputs
79+
) {
80+
let fields = DynamicPropertyCache.fields(of: self)
81+
buffer.addFields(
82+
fields,
83+
container: container,
84+
inputs: &inputs,
85+
baseOffset: fieldOffset
86+
)
87+
}
88+
}
89+
90+
// FIXME: Compile crash on non-ObjectiveC platform
91+
// https://github.com/OpenSwiftUIProject/OpenSwiftUI/issues/39
92+
#if canImport(Darwin)
93+
extension BodyAccessor {
94+
func makeBody(
95+
container: _GraphValue<Container>,
96+
inputs: inout _GraphInputs,
97+
fields: DynamicPropertyCache.Fields
98+
) -> (_GraphValue<Body>, _DynamicPropertyBuffer?) {
99+
guard Body.self != Never.self else {
100+
fatalError("\(Body.self) may not have Body == Never")
101+
}
102+
return withUnsafeMutablePointer(to: &inputs) { inputsPointer in
103+
func project<Flags: RuleThreadFlags>(flags _: Flags.Type) -> (_GraphValue<Body>, _DynamicPropertyBuffer?) {
104+
let buffer = _DynamicPropertyBuffer(
105+
fields: fields,
106+
container: container,
107+
inputs: &inputsPointer.pointee
108+
)
109+
if buffer._count == 0 {
110+
buffer.destroy()
111+
let body = StaticBody<Self, Flags>(
112+
accessor: self,
113+
container: container.value
114+
)
115+
return (_GraphValue(body), nil)
116+
} else {
117+
let body = DynamicBody<Self, Flags>(
118+
accessor: self,
119+
container: container.value,
120+
phase: inputsPointer.pointee.phase,
121+
links: buffer,
122+
resetSeed: 0
123+
)
124+
return (_GraphValue(body), buffer)
125+
}
126+
}
127+
if fields.behaviors.contains(.asyncThread) {
128+
return project(flags: AsyncThreadFlags.self)
129+
} else {
130+
return project(flags: MainThreadFlags.self)
131+
}
132+
}
133+
}
134+
}
135+
136+
// MARK: - RuleThreadFlags
137+
138+
private protocol RuleThreadFlags {
139+
static var value: OGAttributeTypeFlags { get }
140+
}
141+
142+
private struct AsyncThreadFlags: RuleThreadFlags {
143+
static var value: OGAttributeTypeFlags { .asyncThread }
144+
}
145+
146+
private struct MainThreadFlags: RuleThreadFlags {
147+
static var value: OGAttributeTypeFlags { .mainThread }
148+
}
149+
150+
// MARK: - StaticBody
151+
152+
private struct StaticBody<Accessor: BodyAccessor, ThreadFlags: RuleThreadFlags> {
153+
let accessor: Accessor
154+
@Attribute
155+
var container: Accessor.Container
156+
157+
init(accessor: Accessor, container: Attribute<Accessor.Container>) {
158+
self.accessor = accessor
159+
self._container = container
160+
}
161+
}
162+
163+
extension StaticBody: StatefulRule {
164+
typealias Value = Accessor.Body
165+
166+
func updateValue() {
167+
accessor.updateBody(of: container, changed: true)
168+
}
169+
}
170+
171+
extension StaticBody: _AttributeBody {
172+
static var flags: OGAttributeTypeFlags {
173+
ThreadFlags.value
174+
}
175+
}
176+
177+
extension StaticBody: BodyAccessorRule {
178+
static var container: Any.Type {
179+
Accessor.Container.self
180+
}
181+
182+
static func buffer<Value>(as type: Value.Type, attribute: OGAttribute) -> _DynamicPropertyBuffer? {
183+
nil
184+
}
185+
186+
static func value<Value>(as type: Value.Type, attribute: OGAttribute) -> Value? {
187+
guard container == type else {
188+
return nil
189+
}
190+
return (attribute.info.body.assumingMemoryBound(to: Self.self).pointee.container as! Value)
191+
}
192+
193+
static func metaProperties<Value>(as type: Value.Type, attribute: OGAttribute) -> [(String, OGAttribute)] {
194+
guard container == type else {
195+
return []
196+
}
197+
return [("@self", attribute.info.body.assumingMemoryBound(to: Self.self).pointee._container.identifier)]
198+
}
199+
}
200+
201+
extension StaticBody: CustomStringConvertible {
202+
var description: String { "\(Accessor.Body.self)" }
203+
}
204+
205+
// MARK: - DynamicBody
206+
207+
// TODO
208+
private struct DynamicBody<Accessor: BodyAccessor, ThreadFlags: RuleThreadFlags> {
209+
let accessor: Accessor
210+
@Attribute
211+
var container: Accessor.Container
212+
@Attribute
213+
var phase: _GraphInputs.Phase
214+
var links: _DynamicPropertyBuffer
215+
var resetSeed: UInt32
216+
217+
init(
218+
accessor: Accessor,
219+
container: Attribute<Accessor.Container>,
220+
phase: Attribute<_GraphInputs.Phase>,
221+
links: _DynamicPropertyBuffer,
222+
resetSeed: UInt32
223+
) {
224+
fatalError("TODO")
225+
// self.accessor = accessor
226+
// self._container = container
227+
// self._phase = phase
228+
// self.links = links
229+
// self.resetSeed = resetSeed
230+
}
231+
}
232+
233+
extension DynamicBody: StatefulRule {
234+
typealias Value = Accessor.Body
235+
236+
func updateValue() {
237+
// TODO
238+
}
239+
}
240+
#endif

Sources/OpenSwiftUI/DataAndStorage/ModelData/DynamicProperty/DynamicPropertyBehaviors.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88

99
struct DynamicPropertyBehaviors: OptionSet {
1010
let rawValue: UInt32
11+
static var asyncThread: DynamicPropertyBehaviors { .init(rawValue: 1 << 0) }
1112
}

Sources/OpenSwiftUI/DataAndStorage/ModelData/DynamicProperty/DynamicPropertyBuffer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public struct _DynamicPropertyBuffer {
2626
fields: DynamicPropertyCache.Fields,
2727
container: _GraphValue<Value>,
2828
inputs: inout _GraphInputs,
29-
baseOffset: Int
29+
baseOffset: Int = 0
3030
) {
3131
self.init()
3232
addFields(fields, container: container, inputs: &inputs, baseOffset: baseOffset)

Sources/OpenSwiftUI/DataAndStorage/ModelData/DynamicProperty/DynamicPropertyCache.swift

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -113,50 +113,3 @@ extension DynamicPropertyCache {
113113
var fields: [Field]
114114
}
115115
}
116-
117-
// MARK: - EmbeddedDynamicPropertyBox
118-
119-
private struct EmbeddedDynamicPropertyBox<Value: DynamicProperty>: DynamicPropertyBox {
120-
typealias Property = Value
121-
func destroy() {}
122-
func reset() {}
123-
func update(property: inout Property, phase _: _GraphInputs.Phase) -> Bool {
124-
property.update()
125-
return false
126-
}
127-
}
128-
129-
extension DynamicProperty {
130-
public static func _makeProperty<Value>(
131-
in buffer: inout _DynamicPropertyBuffer,
132-
container: _GraphValue<Value>,
133-
fieldOffset: Int,
134-
inputs: inout _GraphInputs
135-
) {
136-
makeEmbeddedProperties(
137-
in: &buffer,
138-
container: container,
139-
fieldOffset: fieldOffset,
140-
inputs: &inputs
141-
)
142-
buffer.append(
143-
EmbeddedDynamicPropertyBox<Self>(),
144-
fieldOffset: fieldOffset
145-
)
146-
}
147-
148-
static func makeEmbeddedProperties<Value>(
149-
in buffer: inout _DynamicPropertyBuffer,
150-
container: _GraphValue<Value>,
151-
fieldOffset: Int,
152-
inputs: inout _GraphInputs
153-
) -> () {
154-
let fields = DynamicPropertyCache.fields(of: self)
155-
buffer.addFields(
156-
fields,
157-
container: container,
158-
inputs: &inputs,
159-
baseOffset: fieldOffset
160-
)
161-
}
162-
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// BodyAccessor.swift
3+
// OpenSwiftUI
4+
//
5+
// Created by Kyle on 2024/2/21.
6+
// Lastest Version: iOS 15.5
7+
// Status: Complete
8+
9+
protocol BodyAccessor<Container, Body> {
10+
associatedtype Container
11+
associatedtype Body
12+
func updateBody(of: Container, changed: Bool)
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// BodyAccessorRule.swift
3+
// OpenSwiftUI
4+
//
5+
// Created by Kyle on 2024/2/21.
6+
// Lastest Version: iOS 15.5
7+
// Status: Complete
8+
9+
internal import OpenGraphShims
10+
11+
protocol BodyAccessorRule {
12+
static var container: Any.Type { get }
13+
static func value<Value>(as: Value.Type, attribute: OGAttribute) -> Value?
14+
static func buffer<Value>(as: Value.Type, attribute: OGAttribute) -> _DynamicPropertyBuffer?
15+
static func metaProperties<Value>(as: Value.Type, attribute: OGAttribute) -> [(String, OGAttribute)]
16+
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
//
2-
// _Graph.swift
2+
// Graph.swift
33
// OpenSwiftUI
44
//
55
// Created by Kyle on 2023/9/24.
66
// Lastest Version: iOS 15.5
77
// Status: Complete
88

9-
public struct _Graph {
10-
}
9+
public struct _Graph {}

0 commit comments

Comments
 (0)