Remove WeakSet, rename TaskCenter to TaskHub
This commit is contained in:
parent
05617caee6
commit
3de74c73a2
|
@ -31,10 +31,9 @@
|
||||||
OBJ_52 /* Period.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* Period.swift */; };
|
OBJ_52 /* Period.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* Period.swift */; };
|
||||||
OBJ_53 /* Schedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* Schedule.swift */; };
|
OBJ_53 /* Schedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* Schedule.swift */; };
|
||||||
OBJ_54 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* Task.swift */; };
|
OBJ_54 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* Task.swift */; };
|
||||||
OBJ_55 /* TaskCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* TaskCenter.swift */; };
|
OBJ_55 /* TaskHub.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* TaskHub.swift */; };
|
||||||
OBJ_56 /* Time.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* Time.swift */; };
|
OBJ_56 /* Time.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* Time.swift */; };
|
||||||
OBJ_57 /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* Timeline.swift */; };
|
OBJ_57 /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* Timeline.swift */; };
|
||||||
OBJ_58 /* WeakSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* WeakSet.swift */; };
|
|
||||||
OBJ_59 /* Weekday.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_23 /* Weekday.swift */; };
|
OBJ_59 /* Weekday.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_23 /* Weekday.swift */; };
|
||||||
OBJ_66 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; };
|
OBJ_66 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; };
|
||||||
OBJ_77 /* AtomicTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* AtomicTests.swift */; };
|
OBJ_77 /* AtomicTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* AtomicTests.swift */; };
|
||||||
|
@ -43,9 +42,8 @@
|
||||||
OBJ_80 /* ExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_29 /* ExtensionsTests.swift */; };
|
OBJ_80 /* ExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_29 /* ExtensionsTests.swift */; };
|
||||||
OBJ_81 /* Misc.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_30 /* Misc.swift */; };
|
OBJ_81 /* Misc.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_30 /* Misc.swift */; };
|
||||||
OBJ_82 /* SchedulesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* SchedulesTests.swift */; };
|
OBJ_82 /* SchedulesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* SchedulesTests.swift */; };
|
||||||
OBJ_83 /* TaskCenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_32 /* TaskCenterTests.swift */; };
|
OBJ_83 /* TaskHubTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_32 /* TaskHubTests.swift */; };
|
||||||
OBJ_84 /* TaskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* TaskTests.swift */; };
|
OBJ_84 /* TaskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* TaskTests.swift */; };
|
||||||
OBJ_85 /* WeakSetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_34 /* WeakSetTests.swift */; };
|
|
||||||
OBJ_86 /* XCTestManifests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_35 /* XCTestManifests.swift */; };
|
OBJ_86 /* XCTestManifests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_35 /* XCTestManifests.swift */; };
|
||||||
OBJ_88 /* Schedule.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Schedule::Schedule::Product" /* Schedule.framework */; };
|
OBJ_88 /* Schedule.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Schedule::Schedule::Product" /* Schedule.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
@ -85,10 +83,9 @@
|
||||||
OBJ_16 /* Period.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Period.swift; sourceTree = "<group>"; };
|
OBJ_16 /* Period.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Period.swift; sourceTree = "<group>"; };
|
||||||
OBJ_17 /* Schedule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Schedule.swift; sourceTree = "<group>"; };
|
OBJ_17 /* Schedule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Schedule.swift; sourceTree = "<group>"; };
|
||||||
OBJ_18 /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = "<group>"; };
|
OBJ_18 /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = "<group>"; };
|
||||||
OBJ_19 /* TaskCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskCenter.swift; sourceTree = "<group>"; };
|
OBJ_19 /* TaskHub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskHub.swift; sourceTree = "<group>"; };
|
||||||
OBJ_20 /* Time.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Time.swift; sourceTree = "<group>"; };
|
OBJ_20 /* Time.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Time.swift; sourceTree = "<group>"; };
|
||||||
OBJ_21 /* Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timeline.swift; sourceTree = "<group>"; };
|
OBJ_21 /* Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timeline.swift; sourceTree = "<group>"; };
|
||||||
OBJ_22 /* WeakSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakSet.swift; sourceTree = "<group>"; };
|
|
||||||
OBJ_23 /* Weekday.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Weekday.swift; sourceTree = "<group>"; };
|
OBJ_23 /* Weekday.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Weekday.swift; sourceTree = "<group>"; };
|
||||||
OBJ_26 /* AtomicTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicTests.swift; sourceTree = "<group>"; };
|
OBJ_26 /* AtomicTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicTests.swift; sourceTree = "<group>"; };
|
||||||
OBJ_27 /* BucketTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BucketTests.swift; sourceTree = "<group>"; };
|
OBJ_27 /* BucketTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BucketTests.swift; sourceTree = "<group>"; };
|
||||||
|
@ -96,9 +93,8 @@
|
||||||
OBJ_29 /* ExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionsTests.swift; sourceTree = "<group>"; };
|
OBJ_29 /* ExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionsTests.swift; sourceTree = "<group>"; };
|
||||||
OBJ_30 /* Misc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Misc.swift; sourceTree = "<group>"; };
|
OBJ_30 /* Misc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Misc.swift; sourceTree = "<group>"; };
|
||||||
OBJ_31 /* SchedulesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SchedulesTests.swift; sourceTree = "<group>"; };
|
OBJ_31 /* SchedulesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SchedulesTests.swift; sourceTree = "<group>"; };
|
||||||
OBJ_32 /* TaskCenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskCenterTests.swift; sourceTree = "<group>"; };
|
OBJ_32 /* TaskHubTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskHubTests.swift; sourceTree = "<group>"; };
|
||||||
OBJ_33 /* TaskTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskTests.swift; sourceTree = "<group>"; };
|
OBJ_33 /* TaskTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskTests.swift; sourceTree = "<group>"; };
|
||||||
OBJ_34 /* WeakSetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakSetTests.swift; sourceTree = "<group>"; };
|
|
||||||
OBJ_35 /* XCTestManifests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestManifests.swift; sourceTree = "<group>"; };
|
OBJ_35 /* XCTestManifests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestManifests.swift; sourceTree = "<group>"; };
|
||||||
OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
|
OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
|
||||||
OBJ_9 /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = "<group>"; };
|
OBJ_9 /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = "<group>"; };
|
||||||
|
@ -146,7 +142,6 @@
|
||||||
OBJ_10 /* Bucket.swift */,
|
OBJ_10 /* Bucket.swift */,
|
||||||
OBJ_11 /* Extensions.swift */,
|
OBJ_11 /* Extensions.swift */,
|
||||||
OBJ_13 /* Lock.swift */,
|
OBJ_13 /* Lock.swift */,
|
||||||
OBJ_22 /* WeakSet.swift */,
|
|
||||||
);
|
);
|
||||||
name = Utils;
|
name = Utils;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -166,7 +161,6 @@
|
||||||
6695C99A21329DDB00934290 /* UtilsTests */ = {
|
6695C99A21329DDB00934290 /* UtilsTests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
OBJ_34 /* WeakSetTests.swift */,
|
|
||||||
OBJ_26 /* AtomicTests.swift */,
|
OBJ_26 /* AtomicTests.swift */,
|
||||||
OBJ_27 /* BucketTests.swift */,
|
OBJ_27 /* BucketTests.swift */,
|
||||||
OBJ_29 /* ExtensionsTests.swift */,
|
OBJ_29 /* ExtensionsTests.swift */,
|
||||||
|
@ -188,7 +182,7 @@
|
||||||
OBJ_28 /* DateTimeTests.swift */,
|
OBJ_28 /* DateTimeTests.swift */,
|
||||||
OBJ_30 /* Misc.swift */,
|
OBJ_30 /* Misc.swift */,
|
||||||
OBJ_31 /* SchedulesTests.swift */,
|
OBJ_31 /* SchedulesTests.swift */,
|
||||||
OBJ_32 /* TaskCenterTests.swift */,
|
OBJ_32 /* TaskHubTests.swift */,
|
||||||
OBJ_33 /* TaskTests.swift */,
|
OBJ_33 /* TaskTests.swift */,
|
||||||
OBJ_35 /* XCTestManifests.swift */,
|
OBJ_35 /* XCTestManifests.swift */,
|
||||||
6695C99A21329DDB00934290 /* UtilsTests */,
|
6695C99A21329DDB00934290 /* UtilsTests */,
|
||||||
|
@ -232,7 +226,7 @@
|
||||||
OBJ_15 /* ParasiticTask.swift */,
|
OBJ_15 /* ParasiticTask.swift */,
|
||||||
OBJ_17 /* Schedule.swift */,
|
OBJ_17 /* Schedule.swift */,
|
||||||
OBJ_18 /* Task.swift */,
|
OBJ_18 /* Task.swift */,
|
||||||
OBJ_19 /* TaskCenter.swift */,
|
OBJ_19 /* TaskHub.swift */,
|
||||||
OBJ_21 /* Timeline.swift */,
|
OBJ_21 /* Timeline.swift */,
|
||||||
668685F5210DD226009305C3 /* DateTime */,
|
668685F5210DD226009305C3 /* DateTime */,
|
||||||
668685F4210DD21A009305C3 /* Utils */,
|
668685F4210DD21A009305C3 /* Utils */,
|
||||||
|
@ -352,10 +346,9 @@
|
||||||
OBJ_52 /* Period.swift in Sources */,
|
OBJ_52 /* Period.swift in Sources */,
|
||||||
OBJ_53 /* Schedule.swift in Sources */,
|
OBJ_53 /* Schedule.swift in Sources */,
|
||||||
OBJ_54 /* Task.swift in Sources */,
|
OBJ_54 /* Task.swift in Sources */,
|
||||||
OBJ_55 /* TaskCenter.swift in Sources */,
|
OBJ_55 /* TaskHub.swift in Sources */,
|
||||||
OBJ_56 /* Time.swift in Sources */,
|
OBJ_56 /* Time.swift in Sources */,
|
||||||
OBJ_57 /* Timeline.swift in Sources */,
|
OBJ_57 /* Timeline.swift in Sources */,
|
||||||
OBJ_58 /* WeakSet.swift in Sources */,
|
|
||||||
OBJ_59 /* Weekday.swift in Sources */,
|
OBJ_59 /* Weekday.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -378,9 +371,8 @@
|
||||||
OBJ_80 /* ExtensionsTests.swift in Sources */,
|
OBJ_80 /* ExtensionsTests.swift in Sources */,
|
||||||
OBJ_81 /* Misc.swift in Sources */,
|
OBJ_81 /* Misc.swift in Sources */,
|
||||||
OBJ_82 /* SchedulesTests.swift in Sources */,
|
OBJ_82 /* SchedulesTests.swift in Sources */,
|
||||||
OBJ_83 /* TaskCenterTests.swift in Sources */,
|
OBJ_83 /* TaskHubTests.swift in Sources */,
|
||||||
OBJ_84 /* TaskTests.swift in Sources */,
|
OBJ_84 /* TaskTests.swift in Sources */,
|
||||||
OBJ_85 /* WeakSetTests.swift in Sources */,
|
|
||||||
OBJ_86 /* XCTestManifests.swift in Sources */,
|
OBJ_86 /* XCTestManifests.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
|
@ -34,6 +34,12 @@ public enum Monthday {
|
||||||
|
|
||||||
case december(Int)
|
case december(Int)
|
||||||
|
|
||||||
|
var isToday: Bool {
|
||||||
|
let lhs = Calendar.gregorian.dateComponents(in: TimeZone.autoupdatingCurrent, from: Date())
|
||||||
|
let rhs = toDateComponents()
|
||||||
|
return lhs.month == rhs.month && lhs.day == rhs.day
|
||||||
|
}
|
||||||
|
|
||||||
func toDateComponents() -> DateComponents {
|
func toDateComponents() -> DateComponents {
|
||||||
var month, day: Int
|
var month, day: Int
|
||||||
switch self {
|
switch self {
|
||||||
|
@ -55,10 +61,4 @@ public enum Monthday {
|
||||||
month: month,
|
month: month,
|
||||||
day: day)
|
day: day)
|
||||||
}
|
}
|
||||||
|
|
||||||
var isToday: Bool {
|
|
||||||
let lhs = Calendar.gregorian.dateComponents(in: TimeZone.autoupdatingCurrent, from: Date())
|
|
||||||
let rhs = toDateComponents()
|
|
||||||
return lhs.month == rhs.month && lhs.day == rhs.day
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class Task {
|
||||||
_timer.schedule(after: interval)
|
_timer.schedule(after: interval)
|
||||||
_timeline.estimatedNextExecution = Date().adding(interval)
|
_timeline.estimatedNextExecution = Date().adding(interval)
|
||||||
|
|
||||||
TaskCenter.shared.add(self, withTag: tag)
|
TaskHub.shared.add(self, withTag: tag)
|
||||||
_timer.resume()
|
_timer.resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ public class Task {
|
||||||
_lock.withLock {
|
_lock.withLock {
|
||||||
_timer.cancel()
|
_timer.cancel()
|
||||||
}
|
}
|
||||||
TaskCenter.shared.remove(self)
|
TaskHub.shared.remove(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
|
@ -298,7 +298,7 @@ public class Task {
|
||||||
_lock.unlock()
|
_lock.unlock()
|
||||||
|
|
||||||
for tag in set {
|
for tag in set {
|
||||||
TaskCenter.shared.add(tag: tag, to: self)
|
TaskHub.shared.add(tag: tag, to: self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +325,7 @@ public class Task {
|
||||||
_lock.unlock()
|
_lock.unlock()
|
||||||
|
|
||||||
for tag in set {
|
for tag in set {
|
||||||
TaskCenter.shared.remove(tag: tag, from: self)
|
TaskHub.shared.remove(tag: tag, from: self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,17 +344,17 @@ extension Task {
|
||||||
|
|
||||||
/// Suspends all tasks that have the tag.
|
/// Suspends all tasks that have the tag.
|
||||||
public static func suspend(byTag tag: String) {
|
public static func suspend(byTag tag: String) {
|
||||||
TaskCenter.shared.tasks(forTag: tag).forEach { $0.suspend() }
|
TaskHub.shared.tasks(forTag: tag).forEach { $0.suspend() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resumes all tasks that have the tag.
|
/// Resumes all tasks that have the tag.
|
||||||
public static func resume(byTag tag: String) {
|
public static func resume(byTag tag: String) {
|
||||||
TaskCenter.shared.tasks(forTag: tag).forEach { $0.resume() }
|
TaskHub.shared.tasks(forTag: tag).forEach { $0.resume() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cancels all tasks that have the tag.
|
/// Cancels all tasks that have the tag.
|
||||||
public static func cancel(byTag tag: String) {
|
public static func cancel(byTag tag: String) {
|
||||||
TaskCenter.shared.tasks(forTag: tag).forEach { $0.cancel() }
|
TaskHub.shared.tasks(forTag: tag).forEach { $0.cancel() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// TaskCenter.swift
|
// TaskHub.swift
|
||||||
// Schedule
|
// Schedule
|
||||||
//
|
//
|
||||||
// Created by Quentin Jin on 2018/7/17.
|
// Created by Quentin Jin on 2018/7/17.
|
||||||
|
@ -7,21 +7,21 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
final class TaskCenter {
|
final class TaskHub {
|
||||||
|
|
||||||
static let shared = TaskCenter()
|
static let shared = TaskHub()
|
||||||
|
|
||||||
private init() { }
|
private init() { }
|
||||||
private let lock = Lock()
|
private let lock = Lock()
|
||||||
private var tasks: Set<Task> = []
|
private var tasks: Set<Task> = []
|
||||||
private var registry: [String: WeakSet<Task>] = [:]
|
private var registry: [String: Set<Task>] = [:]
|
||||||
|
|
||||||
func add(_ task: Task, withTag tag: String? = nil) {
|
func add(_ task: Task, withTag tag: String? = nil) {
|
||||||
lock.withLock {
|
lock.withLock {
|
||||||
tasks.insert(task)
|
tasks.insert(task)
|
||||||
if let tag = tag {
|
if let tag = tag {
|
||||||
if registry[tag] == nil {
|
if registry[tag] == nil {
|
||||||
registry[tag] = WeakSet()
|
registry[tag] = []
|
||||||
}
|
}
|
||||||
registry[tag]?.insert(task)
|
registry[tag]?.insert(task)
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,11 @@ final class TaskCenter {
|
||||||
func remove(_ task: Task) {
|
func remove(_ task: Task) {
|
||||||
lock.withLock {
|
lock.withLock {
|
||||||
_ = tasks.remove(task)
|
_ = tasks.remove(task)
|
||||||
|
|
||||||
|
let tags = task.tags
|
||||||
|
for tag in tags {
|
||||||
|
registry[tag]?.remove(task)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +43,7 @@ final class TaskCenter {
|
||||||
lock.withLock {
|
lock.withLock {
|
||||||
guard tasks.contains(task) else { return }
|
guard tasks.contains(task) else { return }
|
||||||
if registry[tag] == nil {
|
if registry[tag] == nil {
|
||||||
registry[tag] = WeakSet()
|
registry[tag] = []
|
||||||
}
|
}
|
||||||
registry[tag]?.insert(task)
|
registry[tag]?.insert(task)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +57,8 @@ final class TaskCenter {
|
||||||
|
|
||||||
func tasks(forTag tag: String) -> [Task] {
|
func tasks(forTag tag: String) -> [Task] {
|
||||||
return lock.withLock {
|
return lock.withLock {
|
||||||
registry[tag]?.objects ?? []
|
guard let tasks = registry[tag] else { return [] }
|
||||||
|
return Array(tasks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,4 +73,15 @@ final class TaskCenter {
|
||||||
tasks.count
|
tasks.count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func clear() -> [Task] {
|
||||||
|
var holder: [Task] = []
|
||||||
|
lock.withLock {
|
||||||
|
holder = Array(tasks)
|
||||||
|
tasks = []
|
||||||
|
registry = [:]
|
||||||
|
}
|
||||||
|
return holder
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,69 +0,0 @@
|
||||||
//
|
|
||||||
// WeakSet.swift
|
|
||||||
// Schedule
|
|
||||||
//
|
|
||||||
// Created by Quentin Jin on 2018/7/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
private struct WeakBox<T: AnyObject> {
|
|
||||||
weak var object: T?
|
|
||||||
init(_ object: T?) {
|
|
||||||
self.object = object
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension WeakBox: Hashable {
|
|
||||||
|
|
||||||
var hashValue: Int {
|
|
||||||
guard let object = object else { return 0 }
|
|
||||||
return ObjectIdentifier(object).hashValue
|
|
||||||
}
|
|
||||||
|
|
||||||
static func == (lhs: WeakBox<T>, rhs: WeakBox<T>) -> Bool {
|
|
||||||
return lhs.hashValue == rhs.hashValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An alternative to `NSHashTable`, since `NSHashTable` is unavailable on linux.
|
|
||||||
struct WeakSet<T: AnyObject> {
|
|
||||||
|
|
||||||
private var set = Set<WeakBox<T>>()
|
|
||||||
|
|
||||||
mutating func insert(_ object: T) {
|
|
||||||
set.insert(WeakBox(object))
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
mutating func remove(_ object: T) -> T? {
|
|
||||||
return set.remove(WeakBox(object))?.object
|
|
||||||
}
|
|
||||||
|
|
||||||
func contains(_ object: T) -> Bool {
|
|
||||||
return set.contains(WeakBox(object))
|
|
||||||
}
|
|
||||||
|
|
||||||
func containsNil() -> Bool {
|
|
||||||
return set.contains(where: { $0.object == nil })
|
|
||||||
}
|
|
||||||
|
|
||||||
mutating func purify() {
|
|
||||||
set = set.filter({ $0.object != nil })
|
|
||||||
}
|
|
||||||
|
|
||||||
var objects: [T] {
|
|
||||||
return set.compactMap({ $0.object })
|
|
||||||
}
|
|
||||||
|
|
||||||
var count: Int {
|
|
||||||
return objects.count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension WeakSet: Sequence {
|
|
||||||
|
|
||||||
func makeIterator() -> AnyIterator<T> {
|
|
||||||
return AnyIterator(objects.makeIterator())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,14 +12,14 @@ public enum Weekday: Int {
|
||||||
|
|
||||||
case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday
|
case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday
|
||||||
|
|
||||||
|
var isToday: Bool {
|
||||||
|
return Calendar.gregorian
|
||||||
|
.dateComponents(in: .autoupdatingCurrent, from: Date()).weekday == rawValue
|
||||||
|
}
|
||||||
|
|
||||||
func toDateComponents() -> DateComponents {
|
func toDateComponents() -> DateComponents {
|
||||||
return DateComponents(calendar: Calendar.gregorian,
|
return DateComponents(calendar: Calendar.gregorian,
|
||||||
timeZone: TimeZone.autoupdatingCurrent,
|
timeZone: TimeZone.autoupdatingCurrent,
|
||||||
weekday: rawValue)
|
weekday: rawValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
var isToday: Bool {
|
|
||||||
return Calendar.gregorian
|
|
||||||
.dateComponents(in: .autoupdatingCurrent, from: Date()).weekday == rawValue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
//
|
|
||||||
// TaskCenterTests.swift
|
|
||||||
// Schedule
|
|
||||||
//
|
|
||||||
// Created by Quentin Jin on 2018/7/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import XCTest
|
|
||||||
@testable import Schedule
|
|
||||||
|
|
||||||
final class TaskCenterTests: XCTestCase {
|
|
||||||
|
|
||||||
func makeTask() -> Task {
|
|
||||||
return Schedule.never.do { }
|
|
||||||
}
|
|
||||||
|
|
||||||
var center: TaskCenter {
|
|
||||||
return TaskCenter.shared
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAdd() {
|
|
||||||
let task = makeTask()
|
|
||||||
center.add(task)
|
|
||||||
XCTAssertTrue(center.contains(task))
|
|
||||||
}
|
|
||||||
|
|
||||||
func testRemove() {
|
|
||||||
let task = makeTask()
|
|
||||||
center.add(task)
|
|
||||||
center.remove(task)
|
|
||||||
XCTAssertFalse(center.contains(task))
|
|
||||||
}
|
|
||||||
|
|
||||||
func testTag() {
|
|
||||||
let task = makeTask()
|
|
||||||
let tag0 = UUID().uuidString
|
|
||||||
center.add(task, withTag: tag0)
|
|
||||||
XCTAssertTrue(center.tasks(forTag: tag0).contains(task))
|
|
||||||
|
|
||||||
let tag1 = UUID().uuidString
|
|
||||||
center.add(tag: tag1, to: task)
|
|
||||||
XCTAssertTrue(center.tasks(forTag: tag1).contains(task))
|
|
||||||
|
|
||||||
center.remove(tag: tag0, from: task)
|
|
||||||
XCTAssertFalse(center.tasks(forTag: tag0).contains(task))
|
|
||||||
}
|
|
||||||
|
|
||||||
static var allTests = [
|
|
||||||
("testAdd", testAdd),
|
|
||||||
("testRemove", testRemove),
|
|
||||||
("testTag", testTag)
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
//
|
||||||
|
// TaskHubTests.swift
|
||||||
|
// Schedule
|
||||||
|
//
|
||||||
|
// Created by Quentin Jin on 2018/7/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import Schedule
|
||||||
|
|
||||||
|
final class TaskHubTests: XCTestCase {
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func makeTask() -> Task {
|
||||||
|
return Schedule.never.do { }
|
||||||
|
}
|
||||||
|
|
||||||
|
var shared: TaskHub {
|
||||||
|
return TaskHub.shared
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAdd() {
|
||||||
|
let task = makeTask()
|
||||||
|
XCTAssertTrue(shared.contains(task))
|
||||||
|
shared.add(task)
|
||||||
|
XCTAssertEqual(shared.countOfTasks, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRemove() {
|
||||||
|
let task = makeTask()
|
||||||
|
shared.remove(task)
|
||||||
|
XCTAssertFalse(shared.contains(task))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTag() {
|
||||||
|
|
||||||
|
let task = makeTask()
|
||||||
|
let tag0 = UUID().uuidString
|
||||||
|
shared.add(task, withTag: tag0)
|
||||||
|
XCTAssertTrue(shared.tasks(forTag: tag0).contains(task))
|
||||||
|
|
||||||
|
let tag1 = UUID().uuidString
|
||||||
|
shared.add(tag: tag1, to: task)
|
||||||
|
XCTAssertTrue(shared.tasks(forTag: tag1).contains(task))
|
||||||
|
|
||||||
|
shared.remove(tag: tag0, from: task)
|
||||||
|
XCTAssertFalse(shared.tasks(forTag: tag0).contains(task))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCount() {
|
||||||
|
shared.clear()
|
||||||
|
XCTAssertEqual(shared.countOfTasks, 0)
|
||||||
|
makeTask()
|
||||||
|
XCTAssertEqual(shared.countOfTasks, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var allTests = [
|
||||||
|
("testAdd", testAdd),
|
||||||
|
("testRemove", testRemove),
|
||||||
|
("testTag", testTag)
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,107 +0,0 @@
|
||||||
//
|
|
||||||
// WeakSetTests.swift
|
|
||||||
// Schedule
|
|
||||||
//
|
|
||||||
// Created by Quentin Jin on 2018/7/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import XCTest
|
|
||||||
@testable import Schedule
|
|
||||||
|
|
||||||
private class Object { }
|
|
||||||
|
|
||||||
final class WeakSetTests: XCTestCase {
|
|
||||||
|
|
||||||
func testInsert() {
|
|
||||||
var set = WeakSet<Object>()
|
|
||||||
|
|
||||||
let block = {
|
|
||||||
let obj = Object()
|
|
||||||
set.insert(obj)
|
|
||||||
}
|
|
||||||
block()
|
|
||||||
XCTAssertEqual(set.count, 0)
|
|
||||||
|
|
||||||
let obj = Object()
|
|
||||||
set.insert(obj)
|
|
||||||
set.insert(obj)
|
|
||||||
XCTAssertEqual(set.count, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testRemove() {
|
|
||||||
var set = WeakSet<Object>()
|
|
||||||
let obj = Object()
|
|
||||||
set.insert(obj)
|
|
||||||
set.remove(obj)
|
|
||||||
XCTAssertEqual(set.count, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testContains() {
|
|
||||||
var set = WeakSet<Object>()
|
|
||||||
|
|
||||||
let block = {
|
|
||||||
let obj = Object()
|
|
||||||
set.insert(obj)
|
|
||||||
}
|
|
||||||
block()
|
|
||||||
XCTAssertTrue(set.containsNil())
|
|
||||||
|
|
||||||
let obj = Object()
|
|
||||||
set.insert(obj)
|
|
||||||
XCTAssertTrue(set.contains(obj))
|
|
||||||
}
|
|
||||||
|
|
||||||
func testObjects() {
|
|
||||||
var set = WeakSet<Object>()
|
|
||||||
|
|
||||||
let obj0 = Object()
|
|
||||||
let obj1 = Object()
|
|
||||||
set.insert(obj0)
|
|
||||||
set.insert(obj1)
|
|
||||||
|
|
||||||
let objs = set.objects
|
|
||||||
XCTAssertEqual(objs.count, 2)
|
|
||||||
XCTAssertTrue(objs.contains(where: { $0 === obj0 }))
|
|
||||||
XCTAssertTrue(objs.contains(where: { $0 === obj1 }))
|
|
||||||
}
|
|
||||||
|
|
||||||
func testIterator() {
|
|
||||||
var set = WeakSet<Object>()
|
|
||||||
|
|
||||||
let obj0 = Object()
|
|
||||||
let obj1 = Object()
|
|
||||||
set.insert(obj0)
|
|
||||||
set.insert(obj1)
|
|
||||||
|
|
||||||
let it = set.makeIterator()
|
|
||||||
XCTAssertNotNil(it.next())
|
|
||||||
XCTAssertNotNil(it.next())
|
|
||||||
XCTAssertNil(it.next())
|
|
||||||
}
|
|
||||||
|
|
||||||
func testPurify() {
|
|
||||||
var set = WeakSet<Object>()
|
|
||||||
|
|
||||||
let block = {
|
|
||||||
let obj = Object()
|
|
||||||
set.insert(obj)
|
|
||||||
}
|
|
||||||
autoreleasepool {
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
|
|
||||||
let obj = Object()
|
|
||||||
set.insert(obj)
|
|
||||||
|
|
||||||
set.purify()
|
|
||||||
XCTAssertFalse(set.containsNil())
|
|
||||||
}
|
|
||||||
|
|
||||||
static var allTests = [
|
|
||||||
("testInsert", testInsert),
|
|
||||||
("testRemove", testRemove),
|
|
||||||
("testContains", testContains),
|
|
||||||
("testObjects", testObjects),
|
|
||||||
("testIterator", testIterator)
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -5,13 +5,11 @@ public func allTests() -> [XCTestCaseEntry] {
|
||||||
return [
|
return [
|
||||||
testCase(DateTimeTests.allTests),
|
testCase(DateTimeTests.allTests),
|
||||||
testCase(SchedulesTests.allTests),
|
testCase(SchedulesTests.allTests),
|
||||||
testCase(TaskCenterTests.allTests),
|
testCase(TaskHubTests.allTests),
|
||||||
testCase(ExtensionsTests.allTests),
|
|
||||||
testCase(BucketTests.allTests),
|
|
||||||
testCase(WeakSetTests.allTests),
|
|
||||||
testCase(TaskTests.allTests),
|
testCase(TaskTests.allTests),
|
||||||
testCase(TaskCenterTests.allTests),
|
testCase(AtomicTests.allTests),
|
||||||
testCase(AtomicTests.allTests)
|
testCase(BucketTests.allTests),
|
||||||
|
testCase(ExtensionsTests.allTests)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue