diff --git a/Sources/Model/User Interface/View/Properties/BindingProperty.swift b/Sources/Model/User Interface/View/Properties/BindingProperty.swift index efb64c4..156a583 100644 --- a/Sources/Model/User Interface/View/Properties/BindingProperty.swift +++ b/Sources/Model/User Interface/View/Properties/BindingProperty.swift @@ -74,3 +74,23 @@ protocol BindingPropertyProtocol { var setValue: (Pointer, Value, ViewStorage) -> Void { get } } + +extension Widget { + + /// Apply a binding property to the framework. + /// - Parameters: + /// - property: The property. + /// - storage: The view storage. + func setBindingProperty( + property: Property, + storage: ViewStorage + ) where Property: BindingPropertyProtocol { + if let optional = property.wrappedValue.wrappedValue as? any OptionalProtocol, optional.optionalValue == nil { + return + } + if let pointer = storage.pointer as? Property.Pointer { + property.setValue(pointer, property.wrappedValue.wrappedValue, storage) + } + } + +} diff --git a/Sources/Model/User Interface/View/Properties/Property.swift b/Sources/Model/User Interface/View/Properties/Property.swift index a99a8d3..719ebfe 100644 --- a/Sources/Model/User Interface/View/Properties/Property.swift +++ b/Sources/Model/User Interface/View/Properties/Property.swift @@ -211,7 +211,18 @@ extension Widget { /// - parent: The view storage. func initBindingProperty(_ value: Property, parent: ViewStorage) where Property: BindingPropertyProtocol { if let view = parent.pointer as? Property.Pointer { - value.observe(view, value.wrappedValue, parent) + value.observe( + view, + .init { + value.wrappedValue.wrappedValue + } set: { newValue in + if let compareValue = newValue as? any Equatable, + !equal(value.wrappedValue.wrappedValue, compareValue) { + value.wrappedValue.wrappedValue = newValue + } + }, + parent + ) } } @@ -321,8 +332,20 @@ extension Widget { _ property: Property, _ value: Value ) -> Bool where Property: PropertyProtocol, Value: Equatable { - if let propertyValue = property.wrappedValue as? Value { - return propertyValue == value + equal(property.wrappedValue, value) + } + + /// Check whether a value is equal to another value. + /// - Parameters: + /// - value1: The first value. + /// - value2: The second value. + /// - Returns: Whether the values are equal. + func equal( + _ value1: Value1, + _ value2: Value2 + ) -> Bool where Value2: Equatable { + if let value1 = value1 as? Value2 { + return value1 == value2 } return false } @@ -340,22 +363,6 @@ extension Widget { } } - /// Apply a binding property to the framework. - /// - Parameters: - /// - property: The property. - /// - storage: The view storage. - func setBindingProperty( - property: Property, - storage: ViewStorage - ) where Property: BindingPropertyProtocol { - if let optional = property.wrappedValue.wrappedValue as? any OptionalProtocol, optional.optionalValue == nil { - return - } - if let pointer = storage.pointer as? Property.Pointer { - property.setValue(pointer, property.wrappedValue.wrappedValue, storage) - } - } - } /// A protocol for values which can be optional.