Rewrite and move BatchUpdate.swift.

This commit is contained in:
Brent Simmons 2017-10-05 20:34:29 -07:00
parent b53626fc84
commit c258a9da5c
10 changed files with 84 additions and 91 deletions

View File

@ -12,6 +12,7 @@
842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842E45E21ED8C681000A8B52 /* KeyboardDelegateProtocol.swift */; }; 842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842E45E21ED8C681000A8B52 /* KeyboardDelegateProtocol.swift */; };
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */; }; 842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */; };
842E45E71ED8C747000A8B52 /* DB5.plist in Resources */ = {isa = PBXBuildFile; fileRef = 842E45E61ED8C747000A8B52 /* DB5.plist */; }; 842E45E71ED8C747000A8B52 /* DB5.plist in Resources */ = {isa = PBXBuildFile; fileRef = 842E45E61ED8C747000A8B52 /* DB5.plist */; };
846A7BEC1F872C5600FEFD30 /* BatchUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846A7BEB1F872C5600FEFD30 /* BatchUpdate.swift */; };
846E773D1F6EF67A00A165E2 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; }; 846E773D1F6EF67A00A165E2 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; };
846E773E1F6EF67A00A165E2 /* Account.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 846E773E1F6EF67A00A165E2 /* Account.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
846E77411F6EF6A100A165E2 /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846E77211F6EF5D100A165E2 /* Database.framework */; }; 846E77411F6EF6A100A165E2 /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846E77211F6EF5D100A165E2 /* Database.framework */; };
@ -378,6 +379,7 @@
842E45E21ED8C681000A8B52 /* KeyboardDelegateProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardDelegateProtocol.swift; sourceTree = "<group>"; }; 842E45E21ED8C681000A8B52 /* KeyboardDelegateProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardDelegateProtocol.swift; sourceTree = "<group>"; };
842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindowSplitView.swift; sourceTree = "<group>"; }; 842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindowSplitView.swift; sourceTree = "<group>"; };
842E45E61ED8C747000A8B52 /* DB5.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = DB5.plist; path = Evergreen/Resources/DB5.plist; sourceTree = "<group>"; }; 842E45E61ED8C747000A8B52 /* DB5.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = DB5.plist; path = Evergreen/Resources/DB5.plist; sourceTree = "<group>"; };
846A7BEB1F872C5600FEFD30 /* BatchUpdate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BatchUpdate.swift; path = Evergreen/BatchUpdate.swift; sourceTree = "<group>"; };
846E77161F6EF5D000A165E2 /* Database.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Database.xcodeproj; path = Frameworks/Database/Database.xcodeproj; sourceTree = "<group>"; }; 846E77161F6EF5D000A165E2 /* Database.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Database.xcodeproj; path = Frameworks/Database/Database.xcodeproj; sourceTree = "<group>"; };
846E77301F6EF5D600A165E2 /* Account.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Account.xcodeproj; path = Frameworks/Account/Account.xcodeproj; sourceTree = "<group>"; }; 846E77301F6EF5D600A165E2 /* Account.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Account.xcodeproj; path = Frameworks/Account/Account.xcodeproj; sourceTree = "<group>"; };
849A97421ED9EAA9007D329B /* AddFolderWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddFolderWindowController.swift; sourceTree = "<group>"; }; 849A97421ED9EAA9007D329B /* AddFolderWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddFolderWindowController.swift; sourceTree = "<group>"; };
@ -673,6 +675,7 @@
842E45CD1ED8C308000A8B52 /* AppNotifications.swift */, 842E45CD1ED8C308000A8B52 /* AppNotifications.swift */,
84DAEE311F870B390058304B /* DockBadge.swift */, 84DAEE311F870B390058304B /* DockBadge.swift */,
842E45DC1ED8C54B000A8B52 /* Browser.swift */, 842E45DC1ED8C54B000A8B52 /* Browser.swift */,
846A7BEB1F872C5600FEFD30 /* BatchUpdate.swift */,
842E45E11ED8C681000A8B52 /* MainWindow */, 842E45E11ED8C681000A8B52 /* MainWindow */,
842E45E01ED8C587000A8B52 /* Preferences */, 842E45E01ED8C587000A8B52 /* Preferences */,
849A97861ED9ECEF007D329B /* Article Styles */, 849A97861ED9ECEF007D329B /* Article Styles */,
@ -1174,6 +1177,7 @@
849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */, 849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */,
849A97651ED9EB96007D329B /* SidebarTreeControllerDelegate.swift in Sources */, 849A97651ED9EB96007D329B /* SidebarTreeControllerDelegate.swift in Sources */,
849A97671ED9EB96007D329B /* UnreadCountView.swift in Sources */, 849A97671ED9EB96007D329B /* UnreadCountView.swift in Sources */,
846A7BEC1F872C5600FEFD30 /* BatchUpdate.swift in Sources */,
849A975B1ED9EB0D007D329B /* ArticleUtilities.swift in Sources */, 849A975B1ED9EB0D007D329B /* ArticleUtilities.swift in Sources */,
84DAEE301F86CAFE0058304B /* OPMLImporter.swift in Sources */, 84DAEE301F86CAFE0058304B /* OPMLImporter.swift in Sources */,
849A975C1ED9EB0D007D329B /* DefaultFeedsImporter.swift in Sources */, 849A975C1ED9EB0D007D329B /* DefaultFeedsImporter.swift in Sources */,

View File

@ -16,6 +16,7 @@ import Account
let appName = "Evergreen" let appName = "Evergreen"
var currentTheme: VSTheme! var currentTheme: VSTheme!
let batchUpdate = BatchUpdate()
@NSApplicationMain @NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations { class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations {

View File

@ -0,0 +1,63 @@
//
// BatchUpdates.swift
// DataModel
//
// Created by Brent Simmons on 9/12/16.
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
//
import Foundation
public typealias BatchUpdateBlock = () -> Void
public extension Notification.Name {
public static let BatchUpdateDidPerform = Notification.Name(rawValue: "BatchUpdateDidPerform")
}
final class BatchUpdate {
private var count = 0
var isPerforming: Bool {
get {
return count > 0
}
}
func perform(_ batchUpdateBlock: BatchUpdateBlock) {
incrementCount()
batchUpdateBlock()
decrementCount()
}
}
private extension BatchUpdate {
func incrementCount() {
count = count + 1
}
func decrementCount() {
count = count - 1
if count < 1 {
if count < 0 {
assertionFailure("Batch updates count should never be below 0.")
count = 0
}
count = 0
postBatchUpdateDidPerform()
}
}
func postBatchUpdateDidPerform() {
NotificationCenter.default.post(name: .BatchUpdateDidPerform, object: nil, userInfo: nil)
}
}

View File

@ -8,10 +8,10 @@
import Cocoa import Cocoa
private let splitViewDividerColor = NSColor(calibratedWhite: 0.8, alpha: 1.0)
class MainWindowSplitView: NSSplitView { class MainWindowSplitView: NSSplitView {
private let splitViewDividerColor = NSColor(calibratedWhite: 0.8, alpha: 1.0)
override var dividerColor: NSColor { override var dividerColor: NSColor {
get { get {
return splitViewDividerColor return splitViewDividerColor

View File

@ -73,7 +73,7 @@ import Account
outlineView.removeItems(at: selectedRows, inParent: nil, withAnimation: [.slideDown]) outlineView.removeItems(at: selectedRows, inParent: nil, withAnimation: [.slideDown])
outlineView.endUpdates() outlineView.endUpdates()
performDataModelBatchUpdates { batchUpdate.perform {
deleteItemsForNodes(nodesToDelete) deleteItemsForNodes(nodesToDelete)
} }
@ -164,7 +164,7 @@ private extension SidebarViewController {
func rebuildTreeAndReloadDataIfNeeded() { func rebuildTreeAndReloadDataIfNeeded() {
if !dataModelIsPerformingBatchUpdates() { if !batchUpdate.isPerforming {
treeController.rebuild() treeController.rebuild()
outlineView.reloadData() outlineView.reloadData()
} }

View File

@ -1,76 +0,0 @@
//
// BatchUpdates.swift
// DataModel
//
// Created by Brent Simmons on 9/12/16.
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
//
import Foundation
private final class BatchUpdatesTracker {
private var batchUpdatesCount = 0
var isPerformingBatchUpdates: Bool {
get {
return batchUpdatesCount > 0
}
}
func incrementBatchUpdatesCount() {
batchUpdatesCount = batchUpdatesCount + 1
}
func decrementBatchUpdatesCount() {
batchUpdatesCount = batchUpdatesCount - 1
if batchUpdatesCount < 1 {
if batchUpdatesCount < 0 {
assertionFailure("Batch updates count should never be below 0.")
batchUpdatesCount = 0
}
batchUpdatesCount = 0
postDataModelDidPerformBatchUpdates()
}
}
func postDataModelDidPerformBatchUpdates() {
NotificationCenter.default.post(name: .DataModelDidPerformBatchUpdates, object: nil)
}
}
fileprivate let batchUpdatesTracker = BatchUpdatesTracker()
public func dataModelIsPerformingBatchUpdates() -> Bool {
return batchUpdatesTracker.isPerformingBatchUpdates
}
public typealias BatchUpdatesBlock = () -> Void
public func performDataModelBatchUpdates(_ batchUpdatesBlock: BatchUpdatesBlock) {
startDataModelBatchUpdates()
batchUpdatesBlock()
endDataModelBatchUpdates()
}
private func startDataModelBatchUpdates() {
batchUpdatesTracker.incrementBatchUpdatesCount()
}
private func endDataModelBatchUpdates() {
batchUpdatesTracker.decrementBatchUpdatesCount()
}

View File

@ -19,7 +19,6 @@
844BEE811F0AB4D0004AB7CD /* Author.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE801F0AB4D0004AB7CD /* Author.swift */; }; 844BEE811F0AB4D0004AB7CD /* Author.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE801F0AB4D0004AB7CD /* Author.swift */; };
844BEE831F0AB4D6004AB7CD /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE821F0AB4D6004AB7CD /* Attachment.swift */; }; 844BEE831F0AB4D6004AB7CD /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE821F0AB4D6004AB7CD /* Attachment.swift */; };
844BEE851F0AB4DB004AB7CD /* ArticleStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */; }; 844BEE851F0AB4DB004AB7CD /* ArticleStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */; };
844BEE871F0AB4E3004AB7CD /* BatchUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE861F0AB4E3004AB7CD /* BatchUpdates.swift */; };
844BEE891F0AB4E7004AB7CD /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE881F0AB4E7004AB7CD /* Notifications.swift */; }; 844BEE891F0AB4E7004AB7CD /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE881F0AB4E7004AB7CD /* Notifications.swift */; };
84C490F41F705D5F003131D2 /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C490F51F705D5F003131D2 /* RSWeb.framework */; }; 84C490F41F705D5F003131D2 /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C490F51F705D5F003131D2 /* RSWeb.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -70,7 +69,6 @@
844BEE801F0AB4D0004AB7CD /* Author.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Author.swift; sourceTree = "<group>"; }; 844BEE801F0AB4D0004AB7CD /* Author.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Author.swift; sourceTree = "<group>"; };
844BEE821F0AB4D6004AB7CD /* Attachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = "<group>"; }; 844BEE821F0AB4D6004AB7CD /* Attachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = "<group>"; };
844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticleStatus.swift; sourceTree = "<group>"; }; 844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticleStatus.swift; sourceTree = "<group>"; };
844BEE861F0AB4E3004AB7CD /* BatchUpdates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BatchUpdates.swift; sourceTree = "<group>"; };
844BEE881F0AB4E7004AB7CD /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; }; 844BEE881F0AB4E7004AB7CD /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = "<group>"; }; 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = "<group>"; };
84C490F51F705D5F003131D2 /* RSWeb.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSWeb.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84C490F51F705D5F003131D2 /* RSWeb.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSWeb.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -106,7 +104,6 @@
844BEE821F0AB4D6004AB7CD /* Attachment.swift */, 844BEE821F0AB4D6004AB7CD /* Attachment.swift */,
844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */, 844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */,
840405C91F1A8E4300DF0296 /* DatabaseID.swift */, 840405C91F1A8E4300DF0296 /* DatabaseID.swift */,
844BEE861F0AB4E3004AB7CD /* BatchUpdates.swift */,
844BEE881F0AB4E7004AB7CD /* Notifications.swift */, 844BEE881F0AB4E7004AB7CD /* Notifications.swift */,
8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */, 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */,
8419741F1F6DD672006346C4 /* DisplayNameProvider.swift */, 8419741F1F6DD672006346C4 /* DisplayNameProvider.swift */,
@ -304,7 +301,6 @@
844BEE831F0AB4D6004AB7CD /* Attachment.swift in Sources */, 844BEE831F0AB4D6004AB7CD /* Attachment.swift in Sources */,
8419741C1F6DD613006346C4 /* UnreadCountProvider.swift in Sources */, 8419741C1F6DD613006346C4 /* UnreadCountProvider.swift in Sources */,
841974201F6DD672006346C4 /* DisplayNameProvider.swift in Sources */, 841974201F6DD672006346C4 /* DisplayNameProvider.swift in Sources */,
844BEE871F0AB4E3004AB7CD /* BatchUpdates.swift in Sources */,
844BEE811F0AB4D0004AB7CD /* Author.swift in Sources */, 844BEE811F0AB4D0004AB7CD /* Author.swift in Sources */,
840405CA1F1A8E4300DF0296 /* DatabaseID.swift in Sources */, 840405CA1F1A8E4300DF0296 /* DatabaseID.swift in Sources */,
844BEE851F0AB4DB004AB7CD /* ArticleStatus.swift in Sources */, 844BEE851F0AB4DB004AB7CD /* ArticleStatus.swift in Sources */,

View File

@ -587,7 +587,7 @@
INFOPLIST_FILE = RSDatabase/Info.plist; INFOPLIST_FILE = RSDatabase/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=200"; OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=300";
PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSDatabase; PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSDatabase;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
@ -608,7 +608,7 @@
INFOPLIST_FILE = RSDatabase/Info.plist; INFOPLIST_FILE = RSDatabase/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=200"; OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-function-bodies=300";
PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSDatabase; PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSDatabase;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;

View File

@ -41,13 +41,16 @@ struct FeedsImporter {
static func importFeeds(_ feedDictionaries: [DiskFeedDictionary], account: Account) { static func importFeeds(_ feedDictionaries: [DiskFeedDictionary], account: Account) {
let feedsToImport = feeds(with: feedDictionaries, accountID: account.accountID) let feedsToImport = feeds(with: feedDictionaries, accountID: account.accountID)
for feed in feedsToImport {
if !account.hasFeed(with: feed.feedID) { batchUpdate.perform {
let _ = account.addFeed(feed, to: nil) for feed in feedsToImport {
if !account.hasFeed(with: feed.feedID) {
let _ = account.addFeed(feed, to: nil)
}
} }
} }
} }
private static func feeds(with feedDictionaries: [DiskFeedDictionary], accountID: String) -> Set<Feed> { private static func feeds(with feedDictionaries: [DiskFeedDictionary], accountID: String) -> Set<Feed> {
let feedArray = feedDictionaries.flatMap { Feed(accountID: accountID, dictionary: $0) } let feedArray = feedDictionaries.flatMap { Feed(accountID: accountID, dictionary: $0) }

View File

@ -38,7 +38,9 @@ struct OPMLImporter {
} }
if let opmlDocument = opmlDocument { if let opmlDocument = opmlDocument {
account.importOPML(opmlDocument) batchUpdate.perform {
account.importOPML(opmlDocument)
}
} }
} }
} }