From 5b0c80db1b3fffe0b7d563c11d36326e32b39511 Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Sat, 1 Oct 2022 10:42:53 +0800 Subject: [PATCH] NotifierUI // Use extended NSOrderedSet in lieu of array. --- .../Sources/NotifierUI/NotifierUI.swift | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/Packages/vChewing_NotifierUI/Sources/NotifierUI/NotifierUI.swift b/Packages/vChewing_NotifierUI/Sources/NotifierUI/NotifierUI.swift index 24c48da2..36db02ce 100644 --- a/Packages/vChewing_NotifierUI/Sources/NotifierUI/NotifierUI.swift +++ b/Packages/vChewing_NotifierUI/Sources/NotifierUI/NotifierUI.swift @@ -26,14 +26,14 @@ public class Notifier: NSWindowController { // MARK: - Private Declarations - private static var instanceStack: [Notifier] = [] + private static var instanceSet: NSMutableOrderedSet = .init() private let blankValue = "" @discardableResult private init(_ message: String) { currentMessage = message let rawMessage = message.replacingOccurrences(of: "\n", with: "") let isDuplicated: Bool = { - if let firstInstanceExisted = Self.instanceStack.first { + if let firstInstanceExisted = Self.instanceSet.firstNotifier { return message == firstInstanceExisted.currentMessage && firstInstanceExisted.isNew } return false @@ -43,7 +43,12 @@ public class Notifier: NSWindowController { return } // 剔除溢出的副本,讓 Swift 自動回收之。 - while Self.instanceStack.count > 3 { Self.instanceStack.removeLast().close() } + while Self.instanceSet.count > 3 { + if let instanceToRemove = Self.instanceSet.lastNotifier { + instanceToRemove.close() + Self.instanceSet.remove(instanceToRemove) + } + } // 正式進入處理環節。 defer { // 先讓新通知標記自此開始過 0.3 秒自動變為 false。 @@ -141,7 +146,7 @@ public class Notifier: NSWindowController { extension Notifier { private func shiftExistingWindowPositions() { guard let window = window else { return } - Self.instanceStack.compactMap(\.window).forEach { theInstanceWindow in + Self.instanceSet.arrayOfWindows.forEach { theInstanceWindow in var theOrigin = theInstanceWindow.frame theOrigin.origin.y -= (10 + window.frame.height) theInstanceWindow.setFrame(theOrigin, display: true) @@ -159,18 +164,30 @@ extension Notifier { } private func display() { - Self.instanceStack.compactMap(\.window).forEach { + Self.instanceSet.arrayOfWindows.forEach { $0.alphaValue -= 0.1 $0.contentView?.subviews.forEach { $0.alphaValue *= 0.5 } } shiftExistingWindowPositions() fadeIn() - Self.instanceStack.insert(self, at: 0) + Self.instanceSet.insert(self, at: 0) DispatchQueue.main.asyncAfter(deadline: .now() + 1.3) { self.close() - if let idx = Self.instanceStack.firstIndex(where: { $0 === self }) { - Self.instanceStack.remove(at: idx) - } + Self.instanceSet.remove(self) } } } + +extension NSMutableOrderedSet { + fileprivate var arrayOfWindows: [NSWindow] { compactMap { ($0 as? Notifier)?.window } } + + fileprivate var firstNotifier: Notifier? { + for neta in self { if let result = neta as? Notifier { return result } } + return nil + } + + fileprivate var lastNotifier: Notifier? { + for neta in reversed { if let result = neta as? Notifier { return result } } + return nil + } +}