Files
luma/Luma/Engine+LocalNotifier.swift
Ole André Vadla Ravnås 036fcac792 host: Fix data race on pending-action tracker
Hoist seenPending into a @MainActor class so the observation
closure captures a reference instead of a mutable local.
2026-05-23 16:43:24 +02:00

59 lines
2.3 KiB
Swift

#if os(macOS)
import Foundation
import LumaCore
extension Engine {
func attachLocalNotifier() {
let key = ObjectIdentifier(self)
if enginesWithLocalNotifier[key] != nil { return }
let notifier = LocalNotifier()
enginesWithLocalNotifier[key] = notifier
onNotebookChanged = { [weak self] change in
guard case let .added(entry) = change else { return }
guard let self,
let authorID = entry.author?.id,
!self.collaboration.isSelf(authorID)
else { return }
notifier.notifyEntryAdded(entry, labID: self.collaboration.labID)
}
collaboration.onMemberAdded = { [weak self] member in
guard let self,
!self.collaboration.isSelf(member.user.id)
else { return }
notifier.notifyMemberAdded(member, labID: self.collaboration.labID)
}
collaboration.onChatMessageReceived = { [weak self] message in
guard let self, !message.isLocal else { return }
notifier.notifyChatMessage(message, labID: self.collaboration.labID)
}
let seenPending = PendingActionTracker(
initial: Set(((try? store.fetchAllPendingMissionActions()) ?? []).map(\.id))
)
let observation = store.observeAllPendingMissionActions { rows in
Task { @MainActor in
let currentIDs = Set(rows.map(\.id))
let arrivals = rows.filter { !seenPending.ids.contains($0.id) }
seenPending.ids = currentIDs
guard let newest = arrivals.max(by: { $0.requestedAt < $1.requestedAt }) else { return }
notifier.notifyActionAwaitingApproval(newest, additionalPending: arrivals.count - 1)
}
}
pendingActionObservations[key] = observation
}
}
@MainActor
private final class PendingActionTracker {
var ids: Set<UUID>
init(initial: Set<UUID>) { ids = initial }
}
@MainActor
private var enginesWithLocalNotifier: [ObjectIdentifier: LocalNotifier] = [:]
@MainActor
private var pendingActionObservations: [ObjectIdentifier: LumaCore.StoreObservation] = [:]
#endif