// // State.swift // Adwaita // // Created by david-swift on 06.08.23. // import Foundation /// A property wrapper for properties in a view that should be stored throughout view updates. @propertyWrapper public struct State: StateProtocol { // swiftlint:disable force_cast /// Access the stored value. This updates the views when being changed. public var wrappedValue: Value { get { content.storage.value as! Value } nonmutating set { content.storage.value = newValue Self.updateViews() } } // swiftlint:enable force_cast /// Get the value as a binding using the `$` prefix. public var projectedValue: Binding { .init { wrappedValue } set: { newValue in self.wrappedValue = newValue } } /// The stored value. public let content: State.Content /// The value with an erased type. public var value: Any { get { wrappedValue } nonmutating set { if let newValue = newValue as? Value { content.storage.value = newValue } } } /// Initialize a property representing a state in the view. /// - Parameters: /// - wrappedValue: The wrapped value. public init(wrappedValue: Value) { content = .init(storage: .init(value: wrappedValue)) } /// A class storing the state's content. public class Content { /// The storage. public var storage: Storage /// Initialize the content. /// - Parameter storage: The storage. public init(storage: Storage) { self.storage = storage } } /// A class storing the value. public class Storage { /// The stored value. public var value: Any /// Initialize the storage. /// - Parameters: /// - value: The value. public init(value: Any) { self.value = value } } /// Update all of the views. public static func updateViews() { for handler in GTUIApp.updateHandlers { handler() } } }