Adapt blocking updates to strict concurrency

This commit is contained in:
david-swift 2024-09-29 19:05:29 +02:00
parent ebb68009ee
commit 9a3760b24c
3 changed files with 31 additions and 6 deletions

View File

@ -85,7 +85,9 @@ extension Model {
setModel(&model) setModel(&model)
data.storage.value = model data.storage.value = model
data.storage.update = true data.storage.update = true
StateManager.updateViews(force: data.force) Task {
await StateManager.updateViews(force: data.force)
}
} }
/// Get the current version of the model. /// Get the current version of the model.
@ -114,7 +116,9 @@ extension Model where Self: Sendable {
} }
data.storage.value = newValue data.storage.value = newValue
data.storage.update = true data.storage.update = true
StateManager.updateViews(force: data.force) Task {
await StateManager.updateViews(force: data.force)
}
} }
} }

View File

@ -19,7 +19,9 @@ public struct State<Value>: StateProtocol, Sendable where Value: Sendable {
nonmutating set { nonmutating set {
rawValue = newValue rawValue = newValue
content.update = true content.update = true
StateManager.updateViews(force: forceUpdates) Task {
await StateManager.updateViews(force: forceUpdates)
}
} }
} }

View File

@ -8,21 +8,24 @@
import Foundation import Foundation
/// This type manages view updates. /// This type manages view updates.
@globalActor
public actor StateManager { public actor StateManager {
/// Whether to block updates in general. /// Whether to block updates in general.
public static var blockUpdates = false @StateManager static var blockAllUpdates = false
/// The application identifier. /// The application identifier.
static var appID: String? static var appID: String?
/// The functions handling view updates. /// The functions handling view updates.
static var updateHandlers: [@Sendable (Bool) async -> Void] = [] static var updateHandlers: [@Sendable (Bool) async -> Void] = []
/// The shared instance of the actor.
public static let shared = StateManager()
/// Update all of the views. /// Update all of the views.
/// - Parameter force: Whether to force all views to update. /// - Parameter force: Whether to force all views to update.
/// ///
/// Nothing happens if ``StateManager/blockUpdates`` is true. /// Nothing happens if ``StateManager/blockUpdates`` is true.
public static func updateViews(force: Bool = false) { public static func updateViews(force: Bool = false) async {
if !blockUpdates { if await !blockAllUpdates {
for handler in updateHandlers { for handler in updateHandlers {
Task { Task {
await handler(force) await handler(force)
@ -37,4 +40,20 @@ public actor StateManager {
updateHandlers.append(handler) 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
}
} }