From 5e53be997d2c8a91bba616f9083e78fd4d158b56 Mon Sep 17 00:00:00 2001 From: Vadym Markov Date: Mon, 6 Aug 2018 09:57:54 +0200 Subject: [PATCH] Add key observation registry --- Cache.xcodeproj/project.pbxproj | 8 ++++ .../Storage/KeyObservationRegistry.swift | 38 +++++++++++++++++++ .../Storage/StorageObservationRegistry.swift | 6 +-- 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 Source/Shared/Storage/KeyObservationRegistry.swift diff --git a/Cache.xcodeproj/project.pbxproj b/Cache.xcodeproj/project.pbxproj index cf44760..eb6d60e 100644 --- a/Cache.xcodeproj/project.pbxproj +++ b/Cache.xcodeproj/project.pbxproj @@ -132,6 +132,9 @@ D511464D2114775100197DCE /* StorageObservationRegistryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D511464A2114775100197DCE /* StorageObservationRegistryTests.swift */; }; D511464F21147B7C00197DCE /* ObservationTokenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D511464E21147B7C00197DCE /* ObservationTokenTests.swift */; }; D511465121147B7C00197DCE /* ObservationTokenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D511464E21147B7C00197DCE /* ObservationTokenTests.swift */; }; + D51146532118337500197DCE /* KeyObservationRegistry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D51146522118337500197DCE /* KeyObservationRegistry.swift */; }; + D51146542118337500197DCE /* KeyObservationRegistry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D51146522118337500197DCE /* KeyObservationRegistry.swift */; }; + D51146552118337500197DCE /* KeyObservationRegistry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D51146522118337500197DCE /* KeyObservationRegistry.swift */; }; D5291D1D1C2837DB00B702C9 /* Cache.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5DC59E01C20593E003BD79B /* Cache.framework */; }; D5291D6A1C283B5400B702C9 /* Cache.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5291D601C283B5300B702C9 /* Cache.framework */; }; D5291D851C283C7C00B702C9 /* TestHelper+OSX.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291D811C283C7000B702C9 /* TestHelper+OSX.swift */; }; @@ -225,6 +228,7 @@ D2D4CC271FA342CA00E4A2D5 /* JSONWrapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONWrapperTests.swift; sourceTree = ""; }; D511464A2114775100197DCE /* StorageObservationRegistryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageObservationRegistryTests.swift; sourceTree = ""; }; D511464E21147B7C00197DCE /* ObservationTokenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservationTokenTests.swift; sourceTree = ""; }; + D51146522118337500197DCE /* KeyObservationRegistry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyObservationRegistry.swift; sourceTree = ""; }; D5291CDF1C28374800B702C9 /* TestHelper+iOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TestHelper+iOS.swift"; sourceTree = ""; }; D5291D181C2837DB00B702C9 /* Cache-iOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Cache-iOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; D5291D231C28380100B702C9 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -369,6 +373,7 @@ D270148720D11040003B45C7 /* Storage+Transform.swift */, D5A9D1BE21134776005DBD3F /* StoreChange.swift */, D5A9D1C221144B65005DBD3F /* StorageObservationRegistry.swift */, + D51146522118337500197DCE /* KeyObservationRegistry.swift */, ); path = Storage; sourceTree = ""; @@ -841,6 +846,7 @@ D5A138C21EB29BFA00881A20 /* UIImage+Extensions.swift in Sources */, D21B66851F6A723C00125DE1 /* DataSerializer.swift in Sources */, D270147A20D1046A003B45C7 /* HybridStorage.swift in Sources */, + D51146552118337500197DCE /* KeyObservationRegistry.swift in Sources */, D270148620D10E76003B45C7 /* AsyncStorage.swift in Sources */, D270149620D125AC003B45C7 /* MemoryCapsule.swift in Sources */, D28897071F8B79B300C61DEE /* JSONDecoder+Extensions.swift in Sources */, @@ -929,6 +935,7 @@ D5A138C41EB29C2100881A20 /* NSImage+Extensions.swift in Sources */, D21B667C1F6A723C00125DE1 /* DataSerializer.swift in Sources */, D270147920D1046A003B45C7 /* HybridStorage.swift in Sources */, + D51146542118337500197DCE /* KeyObservationRegistry.swift in Sources */, D270148520D10E76003B45C7 /* AsyncStorage.swift in Sources */, D270149520D125AC003B45C7 /* MemoryCapsule.swift in Sources */, D28897061F8B79B300C61DEE /* JSONDecoder+Extensions.swift in Sources */, @@ -982,6 +989,7 @@ D270147820D1046A003B45C7 /* HybridStorage.swift in Sources */, D270148420D10E76003B45C7 /* AsyncStorage.swift in Sources */, D28897051F8B79B300C61DEE /* JSONDecoder+Extensions.swift in Sources */, + D51146532118337500197DCE /* KeyObservationRegistry.swift in Sources */, D270148020D10982003B45C7 /* Storage.swift in Sources */, D270149420D125AC003B45C7 /* MemoryCapsule.swift in Sources */, D2CF98611F694FFA00CE8F68 /* MemoryConfig.swift in Sources */, diff --git a/Source/Shared/Storage/KeyObservationRegistry.swift b/Source/Shared/Storage/KeyObservationRegistry.swift new file mode 100644 index 0000000..4b7ac5f --- /dev/null +++ b/Source/Shared/Storage/KeyObservationRegistry.swift @@ -0,0 +1,38 @@ +import Foundation + +public enum KeyChange { + case edit(before: T?, after: T?) + case remove +} + +public final class KeyObservationRegistry { + public typealias Observation = (Storage, KeyChange) -> Void + private(set) var observations = [String: Observation]() + + @discardableResult + public func addObservation(_ observation: @escaping Observation, forKey key: String) -> ObservationToken { + observations[key] = observation + + return ObservationToken { [weak self] in + self?.observations.removeValue(forKey: key) + } + } + + public func removeObservation(forKey key: String) { + observations.removeValue(forKey: key) + } + + public func removeObservation(token: ObservationToken) { + token.cancel() + } + + public func removeAllObservations() { + observations.removeAll() + } + + func notifyObservers(about change: KeyChange, in storage: Storage) { + observations.values.forEach { closure in + closure(storage, change) + } + } +} diff --git a/Source/Shared/Storage/StorageObservationRegistry.swift b/Source/Shared/Storage/StorageObservationRegistry.swift index 568d066..c779df8 100644 --- a/Source/Shared/Storage/StorageObservationRegistry.swift +++ b/Source/Shared/Storage/StorageObservationRegistry.swift @@ -1,7 +1,7 @@ import Foundation -public final class StorageObservationRegistry { - public typealias Observation = (T, StorageChange) -> Void +public final class StorageObservationRegistry { + public typealias Observation = (Storage, StorageChange) -> Void private(set) var observations = [UUID: Observation]() @discardableResult @@ -22,7 +22,7 @@ public final class StorageObservationRegistry { observations.removeAll() } - func notifyObservers(about change: StorageChange, in storage: T) { + func notifyObservers(about change: StorageChange, in storage: Storage) { observations.values.forEach { closure in closure(storage, change) }