From efaf0b71be8e2f12689f624b8ba287f9d4f12da7 Mon Sep 17 00:00:00 2001 From: James Moschou Date: Sun, 24 Aug 2025 16:43:16 +0200 Subject: [PATCH 1/5] Support initializing Attribute with rule and initial value --- .../Attribute/Attribute/Attribute.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Sources/OpenAttributeGraph/Attribute/Attribute/Attribute.swift b/Sources/OpenAttributeGraph/Attribute/Attribute/Attribute.swift index 716eb10..688bc02 100644 --- a/Sources/OpenAttributeGraph/Attribute/Attribute/Attribute.swift +++ b/Sources/OpenAttributeGraph/Attribute/Attribute/Attribute.swift @@ -289,11 +289,27 @@ extension Attribute { } } + public init(_ rule: R, initialValue: Value) where R.Value == Value { + self = withUnsafePointer(to: rule) { pointer in + withUnsafePointer(to: initialValue) { initialValuePointer in + Attribute(body: pointer, value: initialValuePointer) { R._update } + } + } + } + public init(_ rule: R) where R.Value == Value { self = withUnsafePointer(to: rule) { pointer in Attribute(body: pointer, value: nil) { R._update } } } + + public init(_ rule: R, initialValue: Value) where R.Value == Value { + self = withUnsafePointer(to: rule) { pointer in + withUnsafePointer(to: initialValue) { initialValuePointer in + Attribute(body: pointer, value: initialValuePointer) { R._update } + } + } + } } @_silgen_name("OAGGraphCreateAttribute") From 6de55f4c2c53b80dbf6903280a656196094b7be5 Mon Sep 17 00:00:00 2001 From: James Moschou Date: Sun, 24 Aug 2025 16:43:25 +0200 Subject: [PATCH 2/5] Make AttributeBodyVisitor visit method mutating --- .../Attribute/Body/AttributeBodyVisitor.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/OpenAttributeGraph/Attribute/Body/AttributeBodyVisitor.swift b/Sources/OpenAttributeGraph/Attribute/Body/AttributeBodyVisitor.swift index d85fbf4..e7b825d 100644 --- a/Sources/OpenAttributeGraph/Attribute/Body/AttributeBodyVisitor.swift +++ b/Sources/OpenAttributeGraph/Attribute/Body/AttributeBodyVisitor.swift @@ -5,5 +5,5 @@ // Status: WIP public protocol AttributeBodyVisitor { - func visit(body: UnsafePointer) + mutating func visit(body: UnsafePointer) } From a8028a796998256add7344727a441c3dd0fbb768 Mon Sep 17 00:00:00 2001 From: James Moschou Date: Sun, 24 Aug 2025 16:43:58 +0200 Subject: [PATCH 3/5] Add attribute and resetSource() to IndirectAttribute # Conflicts: # Sources/OpenGraphCxx/Attribute/OGAttribute.cpp # Sources/OpenGraphCxx/include/OpenGraph/OGAttribute.h --- .../Attribute/Indirect/IndirectAttribute.swift | 8 ++++++++ Sources/OpenAttributeGraphCxx/Attribute/OAGAttribute.cpp | 4 ++++ .../include/OpenAttributeGraph/OAGAttribute.h | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/Sources/OpenAttributeGraph/Attribute/Indirect/IndirectAttribute.swift b/Sources/OpenAttributeGraph/Attribute/Indirect/IndirectAttribute.swift index ceb3ba6..81c5e41 100644 --- a/Sources/OpenAttributeGraph/Attribute/Indirect/IndirectAttribute.swift +++ b/Sources/OpenAttributeGraph/Attribute/Indirect/IndirectAttribute.swift @@ -15,11 +15,19 @@ public struct IndirectAttribute { identifier = source.identifier.createIndirect(size: UInt64(MemoryLayout.size)) } + public var attribute: Attribute { + Attribute(identifier: identifier) + } + public var source: Attribute { get { Attribute(identifier: identifier.source) } nonmutating set { identifier.source = newValue.identifier } } + public func resetSource() { + __OAGGraphResetIndirectAttribute(identifier, false) + } + public var dependency: AnyAttribute? { get { let dependency = identifier._indirectDependency diff --git a/Sources/OpenAttributeGraphCxx/Attribute/OAGAttribute.cpp b/Sources/OpenAttributeGraphCxx/Attribute/OAGAttribute.cpp index 5042935..38fefd4 100644 --- a/Sources/OpenAttributeGraphCxx/Attribute/OAGAttribute.cpp +++ b/Sources/OpenAttributeGraphCxx/Attribute/OAGAttribute.cpp @@ -103,6 +103,10 @@ void OAGGraphSetIndirectAttribute(OAGAttribute attribute1, OAGAttribute attribut // TODO } +void OAGGraphResetIndirectAttribute(OAGAttribute attribute, bool non_nil) { + // TODO +} + OAGAttribute OAGGraphCreateAttribute(long index, const void *body, const void * value) { // TODO return OAGAttributeNil; diff --git a/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGAttribute.h b/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGAttribute.h index 4431295..9eb3ed4 100644 --- a/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGAttribute.h +++ b/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGAttribute.h @@ -89,6 +89,10 @@ OAG_EXPORT OAG_REFINED_FOR_SWIFT void OAGGraphSetIndirectAttribute(OAGAttribute attribute1, OAGAttribute attribute2) OAG_SWIFT_NAME(setter:OAGAttribute.source(self:_:)); +OAG_EXPORT +OAG_REFINED_FOR_SWIFT +void OAGGraphResetIndirectAttribute(OAGAttribute attribute, bool non_nil); + OAG_EXPORT OAG_REFINED_FOR_SWIFT OAGAttribute OAGGraphCreateAttribute(long index, const void *body, const void * _Nullable value); From 9839901d62c56c4b3522d6fe50a9370b8a1dea93 Mon Sep 17 00:00:00 2001 From: James Moschou Date: Sun, 7 Sep 2025 16:48:33 +0200 Subject: [PATCH 4/5] Add compatibility tests for initializing Attribute with Rule/StatefuleRule and initial value --- .../AttributeCompatibilityTests.swift | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Tests/OpenAttributeGraphCompatibilityTests/Attribute/Attribute/AttributeCompatibilityTests.swift b/Tests/OpenAttributeGraphCompatibilityTests/Attribute/Attribute/AttributeCompatibilityTests.swift index 9405c9e..3594595 100644 --- a/Tests/OpenAttributeGraphCompatibilityTests/Attribute/Attribute/AttributeCompatibilityTests.swift +++ b/Tests/OpenAttributeGraphCompatibilityTests/Attribute/Attribute/AttributeCompatibilityTests.swift @@ -14,6 +14,37 @@ struct AttributeCompatibilityTests { #expect(intAttribute.value == 0) } + @Test + func initWithRule() { + struct TestRule: Rule { + var value: Int { + return 0 + } + } + let attribute1 = Attribute(TestRule()) + #expect(attribute1.value == 0) + + let attribute2 = Attribute(TestRule(), initialValue: 1) + #expect(attribute2.value == 1) + } + + @Test + func initWithStatefulRule() { + struct TestStatefuleRule: StatefulRule { + typealias Value = Int + func updateValue() { + withUnsafePointer(to: 0) { ptr in + Graph.setOutputValue(ptr) + } + } + } + let attribute1 = Attribute(TestStatefuleRule()) + #expect(attribute1.value == 0) + + let attribute2 = Attribute(TestStatefuleRule(), initialValue: 1) + #expect(attribute2.value == 1) + } + @Test func hashableAndEquatable() { let a = Attribute(identifier: .nil) From f87f3f5f48ebc073f4b75abc8f80fd18902df0aa Mon Sep 17 00:00:00 2001 From: James Moschou Date: Sun, 7 Sep 2025 16:49:02 +0200 Subject: [PATCH 5/5] Add compatibility tests for IndirectAttribute attribute and resetSource() --- .../IndirectAttributeCompatibilityTests.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Tests/OpenAttributeGraphCompatibilityTests/Attribute/Indirect/IndirectAttributeCompatibilityTests.swift b/Tests/OpenAttributeGraphCompatibilityTests/Attribute/Indirect/IndirectAttributeCompatibilityTests.swift index a907746..21c6bd7 100644 --- a/Tests/OpenAttributeGraphCompatibilityTests/Attribute/Indirect/IndirectAttributeCompatibilityTests.swift +++ b/Tests/OpenAttributeGraphCompatibilityTests/Attribute/Indirect/IndirectAttributeCompatibilityTests.swift @@ -12,9 +12,24 @@ struct IndirectAttributeCompatibilityTests { func basic() { let source = Attribute(value: 0) let indirect = IndirectAttribute(source: source) + #expect(indirect.attribute.identifier == indirect.identifier) #expect(indirect.identifier != source.identifier) #expect(indirect.source.identifier == source.identifier) #expect(indirect.dependency == .init(rawValue: 0)) } + + @Test + func resetSource() { + let source1 = Attribute(value: 0) + let indirect = IndirectAttribute(source: source1) + #expect(indirect.source.identifier == source1.identifier) + + let source2 = Attribute(value: 0) + indirect.source = source2 + #expect(indirect.source.identifier == source2.identifier) + + indirect.resetSource() + #expect(indirect.source.identifier == source1.identifier) + } } #endif