diff --git a/Sources/Model/Data Flow/Model.swift b/Sources/Model/Data Flow/Model.swift index 2f82678..5cf0714 100644 --- a/Sources/Model/Data Flow/Model.swift +++ b/Sources/Model/Data Flow/Model.swift @@ -85,7 +85,9 @@ extension Model { setModel(&model) data.storage.value = model data.storage.update = true - StateManager.updateViews(force: data.force) + Task { + await StateManager.updateViews(force: data.force) + } } /// Get the current version of the model. @@ -114,7 +116,9 @@ extension Model where Self: Sendable { } data.storage.value = newValue data.storage.update = true - StateManager.updateViews(force: data.force) + Task { + await StateManager.updateViews(force: data.force) + } } } diff --git a/Sources/Model/Data Flow/State.swift b/Sources/Model/Data Flow/State.swift index cfc3d06..bfb69ec 100644 --- a/Sources/Model/Data Flow/State.swift +++ b/Sources/Model/Data Flow/State.swift @@ -19,7 +19,9 @@ public struct State: StateProtocol, Sendable where Value: Sendable { nonmutating set { rawValue = newValue content.update = true - StateManager.updateViews(force: forceUpdates) + Task { + await StateManager.updateViews(force: forceUpdates) + } } } diff --git a/Sources/Model/Data Flow/StateManager.swift b/Sources/Model/Data Flow/StateManager.swift index 16b3a19..5be74c2 100644 --- a/Sources/Model/Data Flow/StateManager.swift +++ b/Sources/Model/Data Flow/StateManager.swift @@ -8,21 +8,24 @@ import Foundation /// This type manages view updates. +@globalActor public actor StateManager { /// Whether to block updates in general. - public static var blockUpdates = false + @StateManager static var blockAllUpdates = false /// The application identifier. static var appID: String? /// The functions handling view updates. static var updateHandlers: [@Sendable (Bool) async -> Void] = [] + /// The shared instance of the actor. + public static let shared = StateManager() /// Update all of the views. /// - Parameter force: Whether to force all views to update. /// /// Nothing happens if ``StateManager/blockUpdates`` is true. - public static func updateViews(force: Bool = false) { - if !blockUpdates { + public static func updateViews(force: Bool = false) async { + if await !blockAllUpdates { for handler in updateHandlers { Task { await handler(force) @@ -37,4 +40,20 @@ public actor StateManager { updateHandlers.append(handler) } + /// Block all updates. + /// + /// The user interface will not respond to changes. + @StateManager + public static func blockUpdates() { + blockAllUpdates = true + } + + /// Unblock all updates. + /// + /// The user interface will respond to changes. + @StateManager + public static func unblockUpdates() { + blockAllUpdates = false + } + }