mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2024-12-22 23:58:36 +01:00
Go back to CoalescingQueue because it was simpler to use than PostponingBlock.
This commit is contained in:
parent
7dc0d6cb23
commit
308a91cf4f
@ -21,25 +21,18 @@ public protocol DataFileDelegate: AnyObject {
|
||||
private var isDirty = false {
|
||||
didSet {
|
||||
if isDirty {
|
||||
postponingBlock.runInFuture()
|
||||
}
|
||||
else {
|
||||
postponingBlock.cancelRun()
|
||||
saveQueue.add(self, #selector(saveToDiskIfNeeded))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let fileURL: URL
|
||||
|
||||
private lazy var postponingBlock: PostponingBlock = {
|
||||
PostponingBlock(name: "DataFile \(fileURL.absoluteString)", delayInterval: 1.0) { [weak self] in
|
||||
self?.saveToDiskIfNeeded()
|
||||
}
|
||||
}()
|
||||
private let saveQueue: CoalescingQueue
|
||||
|
||||
public init(fileURL: URL) {
|
||||
|
||||
self.fileURL = fileURL
|
||||
self.saveQueue = CoalescingQueue(name: "DataFile \(fileURL.absoluteString)", interval: 1.0, maxInterval: 2.0)
|
||||
}
|
||||
|
||||
public func markAsDirty() {
|
||||
@ -66,7 +59,7 @@ public protocol DataFileDelegate: AnyObject {
|
||||
|
||||
private extension DataFile {
|
||||
|
||||
func saveToDiskIfNeeded() {
|
||||
@objc func saveToDiskIfNeeded() {
|
||||
|
||||
if isDirty {
|
||||
save()
|
||||
|
@ -1,59 +0,0 @@
|
||||
//
|
||||
// PostponingBlock.swift
|
||||
//
|
||||
//
|
||||
// Created by Brent Simmons on 6/9/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import os
|
||||
|
||||
/// Runs a block of code in the future. Each time `runInFuture` is called, the block is postponed again until the future by `delayInterval`.
|
||||
@MainActor public final class PostponingBlock {
|
||||
|
||||
public static let delayIntervalForUI: TimeInterval = 0.05
|
||||
|
||||
private let block: @MainActor () -> Void
|
||||
private let delayInterval: TimeInterval
|
||||
private let name: String // For debugging
|
||||
private var timer: Timer?
|
||||
|
||||
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "PostponingBlock")
|
||||
|
||||
public init(name: String, delayInterval: TimeInterval = PostponingBlock.delayIntervalForUI, block: @MainActor @escaping () -> Void) {
|
||||
|
||||
self.delayInterval = delayInterval
|
||||
self.name = name
|
||||
self.block = block
|
||||
}
|
||||
|
||||
/// Run the block in `delayInterval` seconds, canceling any run about to happen before then.
|
||||
public func runInFuture() {
|
||||
|
||||
invalidateTimer()
|
||||
|
||||
timer = Timer.scheduledTimer(withTimeInterval: delayInterval, repeats: false) { [weak self] timer in
|
||||
MainActor.assumeIsolated {
|
||||
self?.block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Cancel any upcoming run.
|
||||
public func cancelRun() {
|
||||
|
||||
invalidateTimer()
|
||||
}
|
||||
}
|
||||
|
||||
private extension PostponingBlock {
|
||||
|
||||
func invalidateTimer() {
|
||||
|
||||
if let timer, timer.isValid {
|
||||
timer.invalidate()
|
||||
logger.info("Canceling existing timer in PostponingBlock: \(self.name)")
|
||||
}
|
||||
timer = nil
|
||||
}
|
||||
}
|
@ -70,10 +70,6 @@ import Sparkle
|
||||
@IBOutlet var groupArticlesByFeedMenuItem: NSMenuItem!
|
||||
@IBOutlet var checkForUpdatesMenuItem: NSMenuItem!
|
||||
|
||||
private lazy var postponingUpdateDockBadgeBlock: PostponingBlock = {
|
||||
PostponingBlock(name: "Update Dock Badge", delayInterval: 0.05, block: updateDockBadge)
|
||||
}()
|
||||
|
||||
var unreadCount = 0 {
|
||||
didSet {
|
||||
if unreadCount != oldValue {
|
||||
@ -542,10 +538,11 @@ import Sparkle
|
||||
// MARK: - Dock Badge
|
||||
|
||||
func queueUpdateDockBadge() {
|
||||
postponingUpdateDockBadgeBlock.runInFuture()
|
||||
|
||||
CoalescingQueue.standard.add(self, #selector(updateDockBadge))
|
||||
}
|
||||
|
||||
func updateDockBadge() {
|
||||
@objc func updateDockBadge() {
|
||||
let label = unreadCount > 0 ? "\(unreadCount)" : ""
|
||||
NSApplication.shared.dockTile.badgeLabel = label
|
||||
}
|
||||
|
@ -60,12 +60,6 @@ final class MainWindowController : NSWindowController, NSUserInterfaceValidation
|
||||
private var searchSmartFeed: SmartFeed? = nil
|
||||
private var restoreArticleWindowScrollY: CGFloat?
|
||||
|
||||
private lazy var postponingMakeToolbarValidateBlock: PostponingBlock = {
|
||||
PostponingBlock(name: "Make Toolbar Validate") { [weak self] in
|
||||
self?.makeToolbarValidate()
|
||||
}
|
||||
}()
|
||||
|
||||
// MARK: - NSWindowController
|
||||
|
||||
override func windowDidLoad() {
|
||||
@ -203,10 +197,10 @@ final class MainWindowController : NSWindowController, NSUserInterfaceValidation
|
||||
|
||||
func queueMakeToolbarValidate() {
|
||||
|
||||
postponingMakeToolbarValidateBlock.runInFuture()
|
||||
CoalescingQueue.standard.add(self, #selector(makeToolbarValidate))
|
||||
}
|
||||
|
||||
func makeToolbarValidate() {
|
||||
@objc func makeToolbarValidate() {
|
||||
|
||||
window?.toolbar?.validateVisibleItems()
|
||||
}
|
||||
|
@ -23,9 +23,10 @@ final class SidebarStatusBarView: NSView {
|
||||
|
||||
private var progress: CombinedRefreshProgress? = nil {
|
||||
didSet {
|
||||
CoalescingQueue.standard.add(self, #selector(updateUI))
|
||||
queueUpdateUI()
|
||||
}
|
||||
}
|
||||
|
||||
override var isFlipped: Bool {
|
||||
return true
|
||||
}
|
||||
@ -42,6 +43,11 @@ final class SidebarStatusBarView: NSView {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
|
||||
}
|
||||
|
||||
func queueUpdateUI() {
|
||||
|
||||
CoalescingQueue.standard.add(self, #selector(updateUI))
|
||||
}
|
||||
|
||||
@objc func updateUI() {
|
||||
|
||||
guard let progress = progress else {
|
||||
|
@ -48,13 +48,7 @@ import Images
|
||||
}
|
||||
#endif
|
||||
|
||||
private lazy var postponingBlock: PostponingBlock = {
|
||||
PostponingBlock(name: "SmartFeed", delayInterval: 1.0) {
|
||||
Task {
|
||||
try? await self.fetchUnreadCounts()
|
||||
}
|
||||
}
|
||||
}()
|
||||
private let fetchUnreadCountsQueue = CoalescingQueue(name: "SmartFeed", interval: 1.0, maxInterval: 2.0)
|
||||
|
||||
private var fetchUnreadCountsTask: Task<Void, Never>?
|
||||
private let delegate: SmartFeedDelegate
|
||||
@ -71,7 +65,9 @@ import Images
|
||||
queueFetchUnreadCounts()
|
||||
}
|
||||
|
||||
func fetchUnreadCounts() async throws {
|
||||
@objc func fetchUnreadCounts() {
|
||||
|
||||
Task {
|
||||
|
||||
let activeAccounts = AccountManager.shared.activeAccounts
|
||||
|
||||
@ -93,6 +89,7 @@ import Images
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SmartFeed: ArticleFetcher {
|
||||
|
||||
@ -111,7 +108,7 @@ private extension SmartFeed {
|
||||
|
||||
func queueFetchUnreadCounts() {
|
||||
|
||||
postponingBlock.runInFuture()
|
||||
fetchUnreadCountsQueue.add(self, #selector(fetchUnreadCounts))
|
||||
}
|
||||
|
||||
func fetchUnreadCount(for account: Account) async {
|
||||
|
Loading…
Reference in New Issue
Block a user