Skip to content

Commit 8cc5128

Browse files
committed
Refactor API documentation into separate DocC extension files
- Create dedicated extension files for major APIs: * Attribute.md - Comprehensive property wrapper documentation * Rule.md - Computed attribute protocol documentation * Metadata.md - Runtime type introspection documentation - Simplify source code documentation to brief summaries - Move detailed examples and usage patterns to extension files - Follow OpenSwiftUI documentation organization patterns - Improve documentation discoverability with Topics sections
1 parent 7986436 commit 8cc5128

File tree

6 files changed

+221
-139
lines changed

6 files changed

+221
-139
lines changed

Sources/OpenAttributeGraph/Attribute/Attribute/Attribute.swift

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,6 @@
11
public import OpenAttributeGraphCxx
22

33
/// A reactive property wrapper that automatically tracks dependencies and manages value updates.
4-
///
5-
/// `Attribute` is the core building block of the OpenAttributeGraph reactive system. When you wrap a property
6-
/// with `@Attribute`, it becomes reactive and can automatically track dependencies and propagate changes.
7-
///
8-
/// @Attribute var count: Int = 0
9-
/// @Attribute var doubledCount: Int = count * 2
10-
///
11-
/// count = 5 // doubledCount automatically becomes 10
12-
///
13-
/// ## Key Features
14-
///
15-
/// - **Automatic dependency tracking**: Attributes automatically discover their dependencies
16-
/// - **Efficient updates**: Only affected attributes are recomputed when changes occur
17-
/// - **Type safety**: Full Swift type safety with compile-time checking
18-
/// - **Dynamic member lookup**: Access nested properties as reactive attributes
19-
/// - **Property wrapper syntax**: Clean, declarative syntax using `@Attribute`
20-
///
21-
/// ## Property Wrapper Usage
22-
///
23-
/// Use `@Attribute` to make any Swift value reactive:
24-
///
25-
/// struct CounterView {
26-
/// @Attribute var count: Int = 0
27-
///
28-
/// var body: some View {
29-
/// Button("Count: \(count)") {
30-
/// count += 1
31-
/// }
32-
/// }
33-
/// }
34-
///
35-
/// ## Dynamic Member Lookup
36-
///
37-
/// Access nested properties as separate attributes:
38-
///
39-
/// @Attribute var person: Person = Person(name: "Alice", age: 30)
40-
/// let nameAttribute: Attribute<String> = person.name
41-
/// let ageAttribute: Attribute<Int> = person.age
42-
///
43-
/// ## Integration with Rules
44-
///
45-
/// Create computed attributes using ``Rule`` or ``StatefulRule``:
46-
///
47-
/// struct DoubledRule: Rule {
48-
/// typealias Value = Int
49-
/// let source: Attribute<Int>
50-
///
51-
/// func value() -> Int {
52-
/// source.wrappedValue * 2
53-
/// }
54-
/// }
55-
///
56-
/// let doubled = Attribute(DoubledRule(source: count))
574
@frozen
585
@propertyWrapper
596
@dynamicMemberLookup
@@ -78,11 +25,6 @@ public struct Attribute<Value> {
7825

7926
/// Creates an attribute with an initial value.
8027
///
81-
/// This initializer creates an external attribute that holds the provided value.
82-
/// External attributes are typically used for storing user input or initial state.
83-
///
84-
/// let count = Attribute(value: 42)
85-
///
8628
/// - Parameter value: The initial value for the attribute
8729
public init(value: Value) {
8830
self = withUnsafePointer(to: value) { valuePointer in
@@ -130,15 +72,6 @@ public struct Attribute<Value> {
13072
// MARK: - propertyWrapper
13173

13274
/// The current value of the attribute.
133-
///
134-
/// When used as a property wrapper with `@Attribute`, this provides the underlying value.
135-
/// Getting this value may trigger dependency tracking in the current evaluation context.
136-
/// Setting this value will update the attribute and invalidate any dependents.
137-
///
138-
/// @Attribute var count: Int = 0
139-
///
140-
/// print(count) // Gets wrappedValue, returns 0
141-
/// count = 5 // Sets wrappedValue, triggers updates
14275
public var wrappedValue: Value {
14376
unsafeAddress {
14477
OAGGraphGetValue(identifier, type: Value.self)
@@ -149,15 +82,6 @@ public struct Attribute<Value> {
14982
}
15083

15184
/// The attribute itself when accessed with the `$` prefix.
152-
///
153-
/// This provides access to the attribute object itself rather than its value,
154-
/// allowing you to pass the reactive attribute to other functions or create
155-
/// derived attributes.
156-
///
157-
/// @Attribute var count: Int = 0
158-
///
159-
/// let countAttribute = $count // Gets the Attribute<Int> object
160-
/// let doubled = countAttribute.map { $0 * 2 }
16185
public var projectedValue: Attribute<Value> {
16286
get { self }
16387
set { self = newValue }

Sources/OpenAttributeGraph/Attribute/Rule/Rule.swift

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,65 +8,14 @@
88
public import OpenAttributeGraphCxx
99

1010
/// A protocol for defining computed attributes that automatically update when dependencies change.
11-
///
12-
/// Rules provide a way to create derived attributes that compute their values based on other attributes.
13-
/// When any dependency changes, the rule will automatically recompute its value.
14-
///
15-
/// struct DoubledRule: Rule {
16-
/// typealias Value = Int
17-
/// let source: Attribute<Int>
18-
///
19-
/// var value: Int {
20-
/// source.wrappedValue * 2
21-
/// }
22-
/// }
23-
///
24-
/// @Attribute var count: Int = 5
25-
/// let doubled = Attribute(DoubledRule(source: $count))
26-
/// // doubled.wrappedValue == 10
27-
///
28-
/// count = 10
29-
/// // doubled.wrappedValue automatically becomes 20
30-
///
31-
/// ## Key Features
32-
///
33-
/// - **Automatic dependency tracking**: Dependencies are discovered automatically when accessed
34-
/// - **Lazy evaluation**: Values are only computed when needed
35-
/// - **Caching**: Results are cached until dependencies change
36-
/// - **Efficient updates**: Only recomputes when dependencies actually change
37-
///
38-
/// ## Implementation Requirements
39-
///
40-
/// Types conforming to `Rule` must provide:
41-
/// - `Value`: The type of value produced by the rule
42-
/// - `value`: A computed property that returns the current value
43-
/// - `initialValue`: An optional initial value (defaults to `nil`)
44-
///
45-
/// ## Advanced Usage
46-
///
47-
/// For rules that need to maintain state between evaluations, see ``StatefulRule``.
48-
/// For rules that can be cached based on their content, make your rule type conform to `Hashable`.
4911
public protocol Rule: _AttributeBody {
5012
/// The type of value produced by this rule.
5113
associatedtype Value
5214

5315
/// An optional initial value to use before the rule is first evaluated.
54-
///
55-
/// If `nil`, the rule will be evaluated immediately when the attribute is created.
56-
/// If non-`nil`, this value will be used initially, and the rule will be evaluated
57-
/// on the next update cycle.
5816
static var initialValue: Value? { get }
5917

6018
/// Computes and returns the current value of the rule.
61-
///
62-
/// This property should access any attributes or other dependencies needed to compute
63-
/// the result. The attribute graph will automatically track these dependencies and
64-
/// invalidate this rule when any dependency changes.
65-
///
66-
/// var value: Int {
67-
/// // Dependencies are automatically tracked
68-
/// return source1.wrappedValue + source2.wrappedValue
69-
/// }
7019
var value: Value { get }
7120
}
7221

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# ``Attribute``
2+
3+
A reactive property wrapper that automatically tracks dependencies and manages value updates.
4+
5+
## Overview
6+
7+
`Attribute` is the core building block of the OpenAttributeGraph reactive system. When you wrap a property with `@Attribute`, it becomes reactive and can automatically track dependencies and propagate changes.
8+
9+
@Attribute var count: Int = 0
10+
@Attribute var doubledCount: Int = count * 2
11+
12+
count = 5 // doubledCount automatically becomes 10
13+
14+
## Key Features
15+
16+
- Automatic dependency tracking: Attributes automatically discover their dependencies
17+
- Efficient updates: Only affected attributes are recomputed when changes occur
18+
- Type safety: Full Swift type safety with compile-time checking
19+
- Dynamic member lookup: Access nested properties as reactive attributes
20+
- Property wrapper syntax: Clean, declarative syntax using `@Attribute`
21+
22+
## Property Wrapper Usage
23+
24+
Use `@Attribute` to make any Swift value reactive:
25+
26+
struct CounterView {
27+
@Attribute var count: Int = 0
28+
29+
var body: some View {
30+
Button("Count: \(count)") {
31+
count += 1
32+
}
33+
}
34+
}
35+
36+
## Dynamic Member Lookup
37+
38+
Access nested properties as separate attributes:
39+
40+
@Attribute var person: Person = Person(name: "Alice", age: 30)
41+
let nameAttribute: Attribute<String> = person.name
42+
let ageAttribute: Attribute<Int> = person.age
43+
44+
## Integration with Rules
45+
46+
Create computed attributes using ``Rule`` or ``StatefulRule``:
47+
48+
struct DoubledRule: Rule {
49+
typealias Value = Int
50+
let source: Attribute<Int>
51+
52+
func value() -> Int {
53+
source.wrappedValue * 2
54+
}
55+
}
56+
57+
let doubled = Attribute(DoubledRule(source: count))
58+
59+
## Topics
60+
61+
### Creating Attributes
62+
63+
- ``init(identifier:)``
64+
- ``init(_:)``
65+
- ``init(value:)``
66+
- ``init(type:)``
67+
68+
### Property Wrapper
69+
70+
- ``wrappedValue``
71+
- ``projectedValue``
72+
73+
### Dynamic Member Access
74+
75+
- ``subscript(dynamicMember:)``
76+
- ``subscript(keyPath:)``
77+
- ``subscript(offset:)``
78+
79+
### Type Transformations
80+
81+
- ``unsafeCast(to:)``
82+
- ``unsafeOffset(at:as:)``
83+
- ``applying(offset:)``
84+
85+
### Graph Integration
86+
87+
- ``graph``
88+
- ``subgraph``
89+
90+
### Value Management
91+
92+
- ``value``
93+
- ``valueState``
94+
- ``valueAndFlags(options:)``
95+
- ``changedValue(options:)``
96+
- ``setValue(_:)``
97+
- ``hasValue``
98+
- ``updateValue()``
99+
- ``prefetchValue()``
100+
- ``invalidateValue()``
101+
- ``validate()``
102+
103+
### Input Management
104+
105+
- ``addInput(_:options:token:)-9c3h6``
106+
- ``addInput(_:options:token:)-7u9k3``
107+
108+
### Flags and State
109+
110+
- ``Flags``
111+
- ``flags``
112+
- ``setFlags(_:mask:)``
113+
114+
### Advanced Operations
115+
116+
- ``visitBody(_:)``
117+
- ``mutateBody(as:invalidating:_:)``
118+
- ``breadthFirstSearch(options:_:)``
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# ``Metadata``
2+
3+
Swift runtime type information and reflection capabilities for OpenAttributeGraph.
4+
5+
## Overview
6+
7+
`Metadata` provides access to Swift's runtime type system, enabling type introspection and dynamic operations that power OpenAttributeGraph's reactive system.
8+
9+
let intMetadata = Metadata(Int.self)
10+
let stringMetadata = Metadata(String.self)
11+
12+
let metadata = Metadata(String.self)
13+
let type = metadata.type // Returns String.Type
14+
15+
## Key Features
16+
17+
- Runtime type introspection: Access Swift type metadata at runtime
18+
- Field enumeration: Discover the fields of any Swift type
19+
- Type comparison: Efficient equality checking across different types
20+
- Memory layout: Access memory layout and alignment details
21+
22+
## Usage with Attributes
23+
24+
Metadata enables OpenAttributeGraph to perform type-safe operations on attributes with different value types, supporting features like automatic KeyPath-based attribute access and efficient value comparison.
25+
26+
## Topics
27+
28+
### Creating Metadata
29+
30+
- ``init(_:)``
31+
32+
### Type Information
33+
34+
- ``type``
35+
- ``description``
36+
37+
### Field Introspection
38+
39+
- ``forEachField(options:do:)``
40+
41+
### Global Functions
42+
43+
- ``forEachField(of:do:)``
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# ``Rule``
2+
3+
A protocol for defining computed attributes that automatically update when dependencies change.
4+
5+
## Overview
6+
7+
Rules provide a way to create derived attributes that compute their values based on other attributes. When any dependency changes, the rule will automatically recompute its value.
8+
9+
struct DoubledRule: Rule {
10+
typealias Value = Int
11+
let source: Attribute<Int>
12+
13+
var value: Int {
14+
source.wrappedValue * 2
15+
}
16+
}
17+
18+
@Attribute var count: Int = 5
19+
let doubled = Attribute(DoubledRule(source: $count))
20+
// doubled.wrappedValue == 10
21+
22+
count = 10
23+
// doubled.wrappedValue automatically becomes 20
24+
25+
## Key Features
26+
27+
- Automatic dependency tracking: Dependencies are discovered automatically when accessed
28+
- Lazy evaluation: Values are only computed when needed
29+
- Caching: Results are cached until dependencies change
30+
- Efficient updates: Only recomputes when dependencies actually change
31+
32+
## Implementation Requirements
33+
34+
Types conforming to `Rule` must provide:
35+
- `Value`: The type of value produced by the rule
36+
- `value`: A computed property that returns the current value
37+
- `initialValue`: An optional initial value (defaults to `nil`)
38+
39+
## Advanced Usage
40+
41+
For rules that need to maintain state between evaluations, see ``StatefulRule``.
42+
For rules that can be cached based on their content, make your rule type conform to `Hashable`.
43+
44+
## Topics
45+
46+
### Protocol Requirements
47+
48+
- ``Value``
49+
- ``initialValue``
50+
- ``value``
51+
52+
### Context Access
53+
54+
- ``attribute``
55+
- ``context``
56+
57+
### Cached Evaluation
58+
59+
- ``cachedValue(options:owner:)``
60+
- ``cachedValueIfExists(options:owner:)``

0 commit comments

Comments
 (0)