From 7b26dce9773c031963a44f30b52b2b97b6b75e16 Mon Sep 17 00:00:00 2001 From: david-swift Date: Tue, 13 Aug 2024 05:52:44 +0200 Subject: [PATCH] Add support for explicit identifiers --- Sources/Model/Data Flow/Model.swift | 2 +- Sources/Model/Data Flow/State.swift | 6 +++-- Sources/Model/Data Flow/StateManager.swift | 25 ++++++++++++--------- Sources/Model/Data Flow/StateProtocol.swift | 2 +- Sources/Model/User Interface/App/App.swift | 1 - Sources/View/StateWrapper.swift | 1 - 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/Sources/Model/Data Flow/Model.swift b/Sources/Model/Data Flow/Model.swift index 5ab11a2..99c79d9 100644 --- a/Sources/Model/Data Flow/Model.swift +++ b/Sources/Model/Data Flow/Model.swift @@ -61,7 +61,7 @@ public protocol Model { public struct ModelData { /// The state value's identifier. - var id: UUID + var id: String /// Whether to force update the views when this value changes. var force: Bool diff --git a/Sources/Model/Data Flow/State.swift b/Sources/Model/Data Flow/State.swift index 4b2f389..8e01763 100644 --- a/Sources/Model/Data Flow/State.swift +++ b/Sources/Model/Data Flow/State.swift @@ -55,7 +55,7 @@ public struct State: StateProtocol { } /// The state's identifier for the stored value. - var id: UUID = .init() + var id: String /// Whether to force update the views when the value changes. var forceUpdates: Bool @@ -66,9 +66,11 @@ public struct State: StateProtocol { /// Initialize a property representing a state in the view with an autoclosure. /// - Parameters: /// - wrappedValue: The wrapped value. + /// - id: An explicit identifier. /// - forceUpdates: Whether to force update all available views when the property gets modified. - public init(wrappedValue: @autoclosure @escaping () -> Value, forceUpdates: Bool = false) { + public init(wrappedValue: @autoclosure @escaping () -> Value, id: String? = nil, forceUpdates: Bool = false) { getInitialValue = wrappedValue + self.id = id ?? UUID().uuidString self.forceUpdates = forceUpdates } diff --git a/Sources/Model/Data Flow/StateManager.swift b/Sources/Model/Data Flow/StateManager.swift index a6b051f..b49e4ae 100644 --- a/Sources/Model/Data Flow/StateManager.swift +++ b/Sources/Model/Data Flow/StateManager.swift @@ -25,9 +25,9 @@ public enum StateManager { struct State { /// The state's identifier. - var id: UUID + var id: String /// Old identifiers of the state which need to be saved. - var oldIDs: [UUID] = [] + var oldIDs: [String] = [] /// The state value. var value: Any? /// Whether to update in the next iteration. @@ -36,13 +36,13 @@ public enum StateManager { /// Whether the state's identifiers contain a certain identifier. /// - Parameter id: The identifier. /// - Returns: Whether the id is contained. - func contains(id: UUID) -> Bool { + func contains(id: String) -> Bool { id == self.id || oldIDs.contains(id) } /// Change the identifier to a new one. /// - Parameter newID: The new identifier. - mutating func changeID(new newID: UUID) { + mutating func changeID(new newID: String) { id = newID } @@ -57,6 +57,9 @@ public enum StateManager { for handler in updateHandlers { handler(force) } + for state in state where state.update { + updatedState(id: state.id) + } } } @@ -70,7 +73,7 @@ public enum StateManager { /// - Parameters: /// - id: The identifier. /// - value: The new value. - static func setState(id: UUID, value: Any?) { + static func setState(id: String, value: Any?) { if saveState { guard let index = state.firstIndex(where: { $0.contains(id: id) }) else { state.append(.init(id: id, value: value)) @@ -83,13 +86,13 @@ public enum StateManager { /// Get the state value for a certain ID. /// - Parameter id: The identifier. /// - Returns: The value. - static func getState(id: UUID) -> Any? { + static func getState(id: String) -> Any? { state[safe: state.firstIndex { $0.contains(id: id) }]?.value } /// Mark the state of a certain id as updated. /// - Parameter id: The identifier. - static func updateState(id: UUID) { + static func updateState(id: String) { if saveState { state[safe: state.firstIndex { $0.contains(id: id) }]?.update = true } @@ -97,7 +100,7 @@ public enum StateManager { /// Mark the state of a certain id as not updated. /// - Parameter id: The identifier. - static func updatedState(id: UUID) { + static func updatedState(id: String) { if saveState { state[safe: state.firstIndex { $0.contains(id: id) }]?.update = false } @@ -106,7 +109,7 @@ public enum StateManager { /// Get whether to update the state of a certain id. /// - Parameter id: The identifier. /// - Returns: Whether to update the state. - static func getUpdateState(id: UUID) -> Bool { + static func getUpdateState(id: String) -> Bool { state[safe: state.firstIndex { $0.contains(id: id) }]?.update ?? false } @@ -114,7 +117,7 @@ public enum StateManager { /// - Parameters: /// - oldID: The old identifier. /// - newID: The new identifier. - static func changeID(old oldID: UUID, new newID: UUID) { + static func changeID(old oldID: String, new newID: String) { if saveState { state[safe: state.firstIndex { $0.contains(id: oldID) }]?.changeID(new: newID) } @@ -122,7 +125,7 @@ public enum StateManager { /// Save a state's identifier until the program ends. /// - Parameter id: The identifier. - static func addConstantID(_ id: UUID) { + static func addConstantID(_ id: String) { state[safe: state.firstIndex { $0.id == id }]?.oldIDs.append(id) } diff --git a/Sources/Model/Data Flow/StateProtocol.swift b/Sources/Model/Data Flow/StateProtocol.swift index a9f0601..cfa6ded 100644 --- a/Sources/Model/Data Flow/StateProtocol.swift +++ b/Sources/Model/Data Flow/StateProtocol.swift @@ -11,6 +11,6 @@ import Foundation protocol StateProtocol { /// The identifier for the state property's value. - var id: UUID { get set } + var id: String { get set } } diff --git a/Sources/Model/User Interface/App/App.swift b/Sources/Model/User Interface/App/App.swift index 944821d..7c9b8d4 100644 --- a/Sources/Model/User Interface/App/App.swift +++ b/Sources/Model/User Interface/App/App.swift @@ -69,7 +69,6 @@ extension App { } if StateManager.getUpdateState(id: property.value.id) { updateProperties = true - StateManager.updatedState(id: property.value.id) } } var removeIndices: [Int] = [] diff --git a/Sources/View/StateWrapper.swift b/Sources/View/StateWrapper.swift index d757816..5365965 100644 --- a/Sources/View/StateWrapper.swift +++ b/Sources/View/StateWrapper.swift @@ -49,7 +49,6 @@ struct StateWrapper: ConvenienceWidget { } if StateManager.getUpdateState(id: property.value.id) { updateProperties = true - StateManager.updatedState(id: property.value.id) } } guard let storage = storage.content[.mainContent]?.first else {