From b6d46ade9419e6685fb1d0ccd1a88fba600719fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 00:01:01 +0000 Subject: [PATCH] Address code review: add debounce constant and thread-safety comment Agent-Logs-Url: https://github.com/meshtastic/Meshtastic-Apple/sessions/9bfe91f2-8ed7-4d2c-bb2e-4ed3dfd3a16c Co-authored-by: garthvh <1795163+garthvh@users.noreply.github.com> --- Meshtastic/Router/Router.swift | 1 + Meshtastic/Views/Nodes/NodeList.swift | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Meshtastic/Router/Router.swift b/Meshtastic/Router/Router.swift index 5af2dfc8..61a599c2 100644 --- a/Meshtastic/Router/Router.swift +++ b/Meshtastic/Router/Router.swift @@ -45,6 +45,7 @@ class Router: ObservableObject { // MARK: Node Object ID Cache /// In-memory cache mapping node numbers to their Core Data `NSManagedObjectID` for O(1) lookups. + /// Thread-safe by virtue of Router's @MainActor isolation — all access is on the main thread. private var nodeObjectIDCache: [Int64: NSManagedObjectID] = [:] /// Updates the node cache from a set of fetched nodes. Call this when the node list changes. diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 5bcf47e7..798e4d6e 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -11,6 +11,9 @@ import CoreData import Foundation struct NodeList: View { + /// Debounce delay for node selection changes (100ms) + private static let nodeSelectionDebounceNs: UInt64 = 100_000_000 + @Environment(\.managedObjectContext) var context @EnvironmentObject var accessoryManager: AccessoryManager @StateObject var router: Router @@ -125,11 +128,11 @@ struct NodeList: View { } } .onChange(of: router.nodeListSelectedNodeNum) { _, newNum in - // Debounce rapid route changes — only process the last selection after 100ms + // Debounce rapid route changes — only process the last selection after a short delay nodeSelectionTask?.cancel() nodeSelectionTask = Task { do { - try await Task.sleep(nanoseconds: 100_000_000) + try await Task.sleep(nanoseconds: Self.nodeSelectionDebounceNs) } catch { return // Cancelled by a newer selection }