Skip to content

Commit f610f92

Browse files
committed
Move comprehensive documentation from extension files to Swift source
- Move overview, examples, and usage patterns from DocC extension files to Swift source files - Keep only Topics sections in extension files for API organization - Updated source files with comprehensive documentation: * Attribute.swift - Full property wrapper documentation with examples * Rule.swift - Complete protocol documentation with usage patterns * StatefulRule.swift - Detailed stateful rule documentation * WeakAttribute.swift - Comprehensive weak reference documentation * Focus.swift - Complete KeyPath-based focusing documentation - Simplified extension files to contain only Topics sections: * Attribute.md - Topics organization only * Rule.md - Topics organization only * StatefulRule.md - Topics organization only * WeakAttribute.md - Topics organization only * Focus.md - Topics organization only This provides comprehensive in-source documentation while maintaining clean Topics-based API organization in extension files.
1 parent e1cd7f5 commit f610f92

File tree

10 files changed

+173
-190
lines changed

10 files changed

+173
-190
lines changed

Sources/OpenAttributeGraph/Attribute/Attribute/Attribute.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,58 @@
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 with `@Attribute`, it becomes reactive and can automatically track dependencies and propagate changes.
6+
///
7+
/// @Attribute var count: Int = 0
8+
/// @Attribute var doubledCount: Int = count * 2
9+
///
10+
/// count = 5 // doubledCount automatically becomes 10
11+
///
12+
/// ## Key Features
13+
///
14+
/// - Automatic dependency tracking: Attributes automatically discover their dependencies
15+
/// - Efficient updates: Only affected attributes are recomputed when changes occur
16+
/// - Type safety: Full Swift type safety with compile-time checking
17+
/// - Dynamic member lookup: Access nested properties as reactive attributes
18+
/// - Property wrapper syntax: Clean, declarative syntax using `@Attribute`
19+
///
20+
/// ## Property Wrapper Usage
21+
///
22+
/// Use `@Attribute` to make any Swift value reactive:
23+
///
24+
/// struct CounterView {
25+
/// @Attribute var count: Int = 0
26+
///
27+
/// var body: some View {
28+
/// Button("Count: \(count)") {
29+
/// count += 1
30+
/// }
31+
/// }
32+
/// }
33+
///
34+
/// ## Dynamic Member Lookup
35+
///
36+
/// Access nested properties as separate attributes:
37+
///
38+
/// @Attribute var person: Person = Person(name: "Alice", age: 30)
39+
/// let nameAttribute: Attribute<String> = person.name
40+
/// let ageAttribute: Attribute<Int> = person.age
41+
///
42+
/// ## Integration with Rules
43+
///
44+
/// Create computed attributes using ``Rule`` or ``StatefulRule``:
45+
///
46+
/// struct DoubledRule: Rule {
47+
/// typealias Value = Int
48+
/// let source: Attribute<Int>
49+
///
50+
/// func value() -> Int {
51+
/// source.wrappedValue * 2
52+
/// }
53+
/// }
54+
///
55+
/// let doubled = Attribute(DoubledRule(source: count))
456
@frozen
557
@propertyWrapper
658
@dynamicMemberLookup

Sources/OpenAttributeGraph/Attribute/Rule/Focus.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,34 @@
66
// Status: Complete
77

88
/// A rule that focuses on a specific property of another attribute using KeyPath.
9+
///
10+
/// `Focus` provides a way to create attributes that automatically track a specific property of another attribute. It uses Swift's KeyPath system to create a focused view of part of a larger data structure.
11+
///
12+
/// struct Person {
13+
/// let name: String
14+
/// let age: Int
15+
/// }
16+
///
17+
/// @Attribute var person = Person(name: "Alice", age: 30)
18+
/// let nameAttribute = Attribute(Focus(root: $person, keyPath: \.name))
19+
/// // nameAttribute automatically updates when person.name changes
20+
///
21+
/// Focus is commonly used internally by OpenAttributeGraph's dynamic member lookup system to create property-specific attributes.
22+
///
23+
/// ## Key Features
24+
///
25+
/// - KeyPath-based focusing: Use any Swift KeyPath to focus on specific properties
26+
/// - Automatic updates: Changes to the focused property automatically propagate
27+
/// - Type safety: Full compile-time type checking for focused properties
28+
/// - Efficient tracking: Only tracks changes to the specific focused property
29+
///
30+
/// ## Usage Pattern
31+
///
32+
/// Focus is ideal for:
33+
/// - Creating focused views of complex data structures
34+
/// - Implementing dynamic member lookup for attributes
35+
/// - Breaking down large objects into smaller, more manageable attribute pieces
36+
/// - Selective observation of specific properties
937
@frozen
1038
public struct Focus<Root, Value>: Rule, CustomStringConvertible {
1139
public var root: Attribute<Root>

Sources/OpenAttributeGraph/Attribute/Rule/Rule.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,44 @@
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`.
1149
public protocol Rule: _AttributeBody {
1250
/// The type of value produced by this rule.
1351
associatedtype Value

Sources/OpenAttributeGraph/Attribute/Rule/StatefulRule.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,35 @@
88
public import OpenAttributeGraphCxx
99

1010
/// A protocol for defining computed attributes that maintain state between evaluations.
11+
///
12+
/// `StatefulRule` extends the basic `Rule` concept by allowing rules to maintain mutable state between updates. This is useful for rules that need to track changes over time or maintain internal state.
13+
///
14+
/// struct CounterRule: StatefulRule {
15+
/// typealias Value = Int
16+
/// private var counter = 0
17+
///
18+
/// mutating func updateValue() {
19+
/// counter += 1
20+
/// value = counter
21+
/// }
22+
/// }
23+
///
24+
/// Unlike ``Rule``, `StatefulRule` allows mutation through the `updateValue()` method and provides direct access to the current value through the `value` property.
25+
///
26+
/// ## Key Features
27+
///
28+
/// - Mutable state: Rules can maintain and modify internal state
29+
/// - Direct value access: Read and write the current value directly
30+
/// - Context access: Access to rule evaluation context and attribute
31+
/// - Lifecycle control: Manual control over when and how values update
32+
///
33+
/// ## Usage Pattern
34+
///
35+
/// StatefulRule is ideal for scenarios where you need to:
36+
/// - Accumulate values over time
37+
/// - Maintain counters or timers
38+
/// - Implement complex state machines
39+
/// - Cache expensive computations with custom invalidation
1140
public protocol StatefulRule: _AttributeBody {
1241
associatedtype Value
1342
static var initialValue: Value? { get }

Sources/OpenAttributeGraph/Attribute/Weak/WeakAttribute.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,32 @@
88
public import OpenAttributeGraphCxx
99

1010
/// A weak reference property wrapper for attributes that prevents retain cycles.
11+
///
12+
/// `WeakAttribute` provides a way to hold weak references to attributes, preventing strong reference cycles in the attribute graph while still allowing access to reactive values.
13+
///
14+
/// @WeakAttribute var parentAttribute: SomeType?
15+
///
16+
/// // Safe access to potentially deallocated attribute
17+
/// if let value = parentAttribute {
18+
/// print("Parent value: \(value)")
19+
/// }
20+
///
21+
/// The weak attribute automatically becomes `nil` when the referenced attribute is deallocated, providing memory-safe access to optional attribute references.
22+
///
23+
/// ## Key Features
24+
///
25+
/// - Weak references: Prevents retain cycles in attribute relationships
26+
/// - Automatic nil assignment: Referenced attributes become nil when deallocated
27+
/// - Dynamic member lookup: Access nested properties through weak references
28+
/// - Optional semantics: All values are optional since references may be deallocated
29+
///
30+
/// ## Usage Pattern
31+
///
32+
/// WeakAttribute is essential for:
33+
/// - Parent-child attribute relationships
34+
/// - Observer patterns that don't own the observed attribute
35+
/// - Breaking potential retain cycles in complex attribute graphs
36+
/// - Optional attribute references in data structures
1137
@frozen
1238
@propertyWrapper
1339
@dynamicMemberLookup

Sources/OpenAttributeGraph/OpenAttributeGraph.docc/Attribute/Attribute/Attribute.md

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,5 @@
11
# ``Attribute``
22

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-
593
## Topics
604

615
### Creating Attributes

Sources/OpenAttributeGraph/OpenAttributeGraph.docc/Attribute/Rule/Focus.md

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,5 @@
11
# ``Focus``
22

3-
## Overview
4-
5-
`Focus` provides a way to create attributes that automatically track a specific property of another attribute. It uses Swift's KeyPath system to create a focused view of part of a larger data structure.
6-
7-
struct Person {
8-
let name: String
9-
let age: Int
10-
}
11-
12-
@Attribute var person = Person(name: "Alice", age: 30)
13-
let nameAttribute = Attribute(Focus(root: $person, keyPath: \.name))
14-
// nameAttribute automatically updates when person.name changes
15-
16-
Focus is commonly used internally by OpenAttributeGraph's dynamic member lookup system to create property-specific attributes.
17-
18-
## Key Features
19-
20-
- KeyPath-based focusing: Use any Swift KeyPath to focus on specific properties
21-
- Automatic updates: Changes to the focused property automatically propagate
22-
- Type safety: Full compile-time type checking for focused properties
23-
- Efficient tracking: Only tracks changes to the specific focused property
24-
25-
## Usage Pattern
26-
27-
Focus is ideal for:
28-
- Creating focused views of complex data structures
29-
- Implementing dynamic member lookup for attributes
30-
- Breaking down large objects into smaller, more manageable attribute pieces
31-
- Selective observation of specific properties
32-
333
## Topics
344

355
### Creating Focus Rules

Sources/OpenAttributeGraph/OpenAttributeGraph.docc/Attribute/Rule/Rule.md

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,5 @@
11
# ``Rule``
22

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-
443
## Topics
454

465
### Protocol Requirements

Sources/OpenAttributeGraph/OpenAttributeGraph.docc/Attribute/Rule/StatefulRule.md

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,5 @@
11
# ``StatefulRule``
22

3-
A protocol for defining computed attributes that maintain state between evaluations.
4-
5-
## Overview
6-
7-
`StatefulRule` extends the basic `Rule` concept by allowing rules to maintain mutable state between updates. This is useful for rules that need to track changes over time or maintain internal state.
8-
9-
struct CounterRule: StatefulRule {
10-
typealias Value = Int
11-
private var counter = 0
12-
13-
mutating func updateValue() {
14-
counter += 1
15-
value = counter
16-
}
17-
}
18-
19-
Unlike ``Rule``, `StatefulRule` allows mutation through the `updateValue()` method and provides direct access to the current value through the `value` property.
20-
21-
## Key Features
22-
23-
- Mutable state: Rules can maintain and modify internal state
24-
- Direct value access: Read and write the current value directly
25-
- Context access: Access to rule evaluation context and attribute
26-
- Lifecycle control: Manual control over when and how values update
27-
28-
## Usage Pattern
29-
30-
StatefulRule is ideal for scenarios where you need to:
31-
- Accumulate values over time
32-
- Maintain counters or timers
33-
- Implement complex state machines
34-
- Cache expensive computations with custom invalidation
35-
363
## Topics
374

385
### Protocol Requirements

0 commit comments

Comments
 (0)