/// Finds the connected screen a `ScreenRef` means. public enum ScreenMatching { /// - Parameter names: names of the connected screens in system order. /// - Returns: index into `names`, or nil if the screen is not connected. public static func index(of ref: ScreenRef, in names: [String]) -> Int? { let sameName = names.indices.filter { names[$0] == ref.name } switch sameName.count { case 1: return sameName[0] case 0: // Renamed or different monitor model: only trust the position if the count still fits. return nil default: // Identical monitors: prefer the remembered position, else the first free match. return sameName.contains(ref.index) ? ref.index : sameName.first } } /// Resolves all assignments; screens claimed twice keep the first assignment. public static func resolve(_ assignments: [VideoAssignment], in names: [String]) -> [Int: Source] { var result: [Int: Source] = [:] for assignment in assignments { guard let index = index(of: assignment.screen, in: names), result[index] == nil else { continue } result[index] = assignment.source } return result } } /// What to stop and start to get from the current state to the desired one. public enum Reconcile { public struct Plan { public var stop: [Key] public var start: [Key: Value] } public static func plan(current: [Key: Value], desired: [Key: Value]) -> Plan { let stop = current.keys.filter { desired[$0] == nil } let start = desired.filter { current[$0.key] != $0.value } return Plan(stop: stop, start: start) } }