Remove `ParasiticTask`, now `host` is a built-in parameter for all tasks.
This commit is contained in:
parent
95ab16f3f7
commit
4242f84f07
|
@ -32,7 +32,6 @@
|
||||||
OBJ_48 /* Interval.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* Interval.swift */; };
|
OBJ_48 /* Interval.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* Interval.swift */; };
|
||||||
OBJ_49 /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* Lock.swift */; };
|
OBJ_49 /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* Lock.swift */; };
|
||||||
OBJ_50 /* Monthday.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* Monthday.swift */; };
|
OBJ_50 /* Monthday.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* Monthday.swift */; };
|
||||||
OBJ_51 /* ParasiticTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* ParasiticTask.swift */; };
|
|
||||||
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 */; };
|
||||||
|
@ -82,7 +81,6 @@
|
||||||
OBJ_12 /* Interval.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Interval.swift; sourceTree = "<group>"; };
|
OBJ_12 /* Interval.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Interval.swift; sourceTree = "<group>"; };
|
||||||
OBJ_13 /* Lock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lock.swift; sourceTree = "<group>"; };
|
OBJ_13 /* Lock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lock.swift; sourceTree = "<group>"; };
|
||||||
OBJ_14 /* Monthday.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Monthday.swift; sourceTree = "<group>"; };
|
OBJ_14 /* Monthday.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Monthday.swift; sourceTree = "<group>"; };
|
||||||
OBJ_15 /* ParasiticTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParasiticTask.swift; sourceTree = "<group>"; };
|
|
||||||
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>"; };
|
||||||
|
@ -222,7 +220,6 @@
|
||||||
OBJ_8 /* Schedule */ = {
|
OBJ_8 /* Schedule */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
OBJ_15 /* ParasiticTask.swift */,
|
|
||||||
66D9F43221563D7700D9F441 /* RunLoopTask.swift */,
|
66D9F43221563D7700D9F441 /* RunLoopTask.swift */,
|
||||||
OBJ_17 /* Schedule.swift */,
|
OBJ_17 /* Schedule.swift */,
|
||||||
OBJ_18 /* Task.swift */,
|
OBJ_18 /* Task.swift */,
|
||||||
|
@ -352,7 +349,6 @@
|
||||||
OBJ_48 /* Interval.swift in Sources */,
|
OBJ_48 /* Interval.swift in Sources */,
|
||||||
OBJ_49 /* Lock.swift in Sources */,
|
OBJ_49 /* Lock.swift in Sources */,
|
||||||
OBJ_50 /* Monthday.swift in Sources */,
|
OBJ_50 /* Monthday.swift in Sources */,
|
||||||
OBJ_51 /* ParasiticTask.swift in Sources */,
|
|
||||||
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 */,
|
||||||
|
|
|
@ -9,24 +9,34 @@ import Foundation
|
||||||
|
|
||||||
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
|
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
|
||||||
|
|
||||||
class DeinitObserver<T: AnyObject> {
|
private var deinitObserverKey: Void = ()
|
||||||
|
|
||||||
private weak var observed: T?
|
class DeinitObserver {
|
||||||
|
|
||||||
private var block: () -> Void
|
private(set) weak var observable: AnyObject?
|
||||||
|
|
||||||
|
private var block: (() -> Void)?
|
||||||
|
|
||||||
private init(_ block: @escaping () -> Void) {
|
private init(_ block: @escaping () -> Void) {
|
||||||
self.block = block
|
self.block = block
|
||||||
}
|
}
|
||||||
|
|
||||||
static func observe(_ observed: T, whenDeinit: @escaping () -> Void) {
|
@discardableResult
|
||||||
let observer = DeinitObserver(whenDeinit)
|
static func observe(_ observable: AnyObject, whenDeinit block: @escaping () -> Void) -> DeinitObserver {
|
||||||
var key: Void = ()
|
let observer = DeinitObserver(block)
|
||||||
objc_setAssociatedObject(observed, &key, observer, .OBJC_ASSOCIATION_RETAIN)
|
objc_setAssociatedObject(observable, &deinitObserverKey, observer, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||||
|
return observer
|
||||||
|
}
|
||||||
|
|
||||||
|
func clear() {
|
||||||
|
block = nil
|
||||||
|
if let o = observable {
|
||||||
|
objc_setAssociatedObject(o, &deinitObserverKey, nil, .OBJC_ASSOCIATION_ASSIGN)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
block()
|
block?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
//
|
|
||||||
// ParasiticTask.swift
|
|
||||||
// Schedule
|
|
||||||
//
|
|
||||||
// Created by Quentin Jin on 2018/7/17.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension Schedule {
|
|
||||||
|
|
||||||
/// Schedules a task with this schedule.
|
|
||||||
///
|
|
||||||
/// This method will receive a `host` object as a parameter,
|
|
||||||
/// the returned task will not retain this object, instead,
|
|
||||||
/// it will observe this object, when this object is dealloced,
|
|
||||||
/// the task will not be scheduled any more, something like parasitism.
|
|
||||||
///
|
|
||||||
/// This feature is very useful when you want a scheduled task live and die
|
|
||||||
/// with a controller.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - queue: The queue to which the task will be dispatched.
|
|
||||||
/// - tag: The tag to be associated to the task.
|
|
||||||
/// - host: The object to be hosted on.
|
|
||||||
/// - onElapse: The action to do when time is out.
|
|
||||||
/// - Returns: The task just created.
|
|
||||||
@discardableResult
|
|
||||||
public func `do`(queue: DispatchQueue,
|
|
||||||
tag: String? = nil,
|
|
||||||
host: AnyObject,
|
|
||||||
onElapse: @escaping (Task) -> Void) -> Task {
|
|
||||||
return ParasiticTask(schedule: self, queue: queue, tag: tag, host: host, onElapse: onElapse)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Schedules a task with this schedule.
|
|
||||||
///
|
|
||||||
/// This method will receive a `host` object as a parameter,
|
|
||||||
/// the returned task will not retain this object, instead,
|
|
||||||
/// it will observe this object, when this object is dealloced,
|
|
||||||
/// the task will not scheduled any more, something like parasitism.
|
|
||||||
///
|
|
||||||
/// This feature is very useful when you want a scheduled task live and die
|
|
||||||
/// with a controller.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - queue: The queue to which the task will be dispatched.
|
|
||||||
/// - tag: The tag to be associated to the task.
|
|
||||||
/// - host: The object to be hosted on.
|
|
||||||
/// - onElapse: The action to do when time is out.
|
|
||||||
/// - Returns: The task just created.
|
|
||||||
@discardableResult
|
|
||||||
public func `do`(queue: DispatchQueue,
|
|
||||||
tag: String? = nil,
|
|
||||||
host: AnyObject,
|
|
||||||
onElapse: @escaping () -> Void) -> Task {
|
|
||||||
return self.do(queue: queue, tag: tag, host: host, onElapse: { (_) in onElapse() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class ParasiticTask: Task {
|
|
||||||
|
|
||||||
weak var parasitifer: AnyObject?
|
|
||||||
|
|
||||||
init(schedule: Schedule, queue: DispatchQueue?, tag: String?, host: AnyObject, onElapse: @escaping (Task) -> Void) {
|
|
||||||
super.init(schedule: schedule, queue: queue, tag: tag) { (task) in
|
|
||||||
guard (task as? ParasiticTask)?.parasitifer != nil else {
|
|
||||||
task.cancel()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
onElapse(task)
|
|
||||||
}
|
|
||||||
self.parasitifer = host
|
|
||||||
|
|
||||||
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
|
|
||||||
DeinitObserver.observe(host) { [weak self] in
|
|
||||||
self?.cancel()
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,48 +11,30 @@ extension Schedule {
|
||||||
|
|
||||||
/// Schedules a task with this schedule.
|
/// Schedules a task with this schedule.
|
||||||
///
|
///
|
||||||
/// This method will receive a `host` object as a parameter,
|
|
||||||
/// the returned task will not retain this object, instead,
|
|
||||||
/// it will observe this object, when this object is dealloced,
|
|
||||||
/// the task will not be scheduled any more, something like parasitism.
|
|
||||||
///
|
|
||||||
/// This feature is very useful when you want a scheduled task live and die
|
|
||||||
/// with a controller.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - queue: The queue to which the task will be dispatched.
|
/// - mode: The mode in which to add the schedule.
|
||||||
/// - tag: The tag to be associated to the task.
|
|
||||||
/// - host: The object to be hosted on.
|
/// - host: The object to be hosted on.
|
||||||
/// - onElapse: The action to do when time is out.
|
/// - onElapse: The action to do when time is out.
|
||||||
/// - Returns: The task just created.
|
/// - Returns: The task just created.
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public func `do`(mode: RunLoop.Mode = .default,
|
public func `do`(mode: RunLoop.Mode = .default,
|
||||||
tag: String? = nil,
|
host: AnyObject? = nil,
|
||||||
onElapse: @escaping (Task) -> Void) -> Task {
|
onElapse: @escaping (Task) -> Void) -> Task {
|
||||||
return RunLoopTask(schedule: self, mode: mode, tag: tag, onElapse: onElapse)
|
return RunLoopTask(schedule: self, mode: mode, host: host, onElapse: onElapse)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Schedules a task with this schedule.
|
/// Schedules a task with this schedule.
|
||||||
///
|
///
|
||||||
/// This method will receive a `host` object as a parameter,
|
|
||||||
/// the returned task will not retain this object, instead,
|
|
||||||
/// it will observe this object, when this object is dealloced,
|
|
||||||
/// the task will not scheduled any more, something like parasitism.
|
|
||||||
///
|
|
||||||
/// This feature is very useful when you want a scheduled task live and die
|
|
||||||
/// with a controller.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - queue: The queue to which the task will be dispatched.
|
/// - mode: The mode in which to add the schedule.
|
||||||
/// - tag: The tag to be associated to the task.
|
|
||||||
/// - host: The object to be hosted on.
|
/// - host: The object to be hosted on.
|
||||||
/// - onElapse: The action to do when time is out.
|
/// - onElapse: The action to do when time is out.
|
||||||
/// - Returns: The task just created.
|
/// - Returns: The task just created.
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public func `do`(mode: RunLoop.Mode = .default,
|
public func `do`(mode: RunLoop.Mode = .default,
|
||||||
tag: String? = nil,
|
host: AnyObject? = nil,
|
||||||
onElapse: @escaping () -> Void) -> Task {
|
onElapse: @escaping () -> Void) -> Task {
|
||||||
return self.do(mode: mode, tag: tag) { (_) in
|
return self.do(mode: mode, host: host) { (_) in
|
||||||
onElapse()
|
onElapse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +44,7 @@ private final class RunLoopTask: Task {
|
||||||
|
|
||||||
var timer: Timer!
|
var timer: Timer!
|
||||||
|
|
||||||
init(schedule: Schedule, mode: RunLoop.Mode, tag: String?, onElapse: @escaping (Task) -> Void) {
|
init(schedule: Schedule, mode: RunLoop.Mode, host: AnyObject?, onElapse: @escaping (Task) -> Void) {
|
||||||
|
|
||||||
var this: Task?
|
var this: Task?
|
||||||
|
|
||||||
|
@ -74,7 +56,7 @@ private final class RunLoopTask: Task {
|
||||||
|
|
||||||
RunLoop.current.add(timer, forMode: mode)
|
RunLoop.current.add(timer, forMode: mode)
|
||||||
|
|
||||||
super.init(schedule: schedule, queue: nil, tag: tag) { (task) in
|
super.init(schedule: schedule, queue: nil, host: host) { (task) in
|
||||||
guard let task = task as? RunLoopTask else { return }
|
guard let task = task as? RunLoopTask else { return }
|
||||||
task.timer.fireDate = Date()
|
task.timer.fireDate = Date()
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,28 +26,30 @@ public struct Schedule {
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - queue: The queue to which the task will be dispatched.
|
/// - queue: The queue to which the task will be dispatched.
|
||||||
/// - tag: The tag to be associated to the task.
|
/// - host: The object to be hosted on. When this object is dealloced,
|
||||||
|
/// the task will not scheduled any more.
|
||||||
/// - onElapse: The action to do when time is out.
|
/// - onElapse: The action to do when time is out.
|
||||||
/// - Returns: The task just created.
|
/// - Returns: The task just created.
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public func `do`(queue: DispatchQueue,
|
public func `do`(queue: DispatchQueue,
|
||||||
tag: String? = nil,
|
host: AnyObject? = nil,
|
||||||
onElapse: @escaping (Task) -> Void) -> Task {
|
onElapse: @escaping (Task) -> Void) -> Task {
|
||||||
return Task(schedule: self, queue: queue, tag: tag, onElapse: onElapse)
|
return Task(schedule: self, queue: queue, host: host, onElapse: onElapse)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Schedules a task with this schedule.
|
/// Schedules a task with this schedule.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - queue: The queue to which the task will be dispatched.
|
/// - queue: The queue to which the task will be dispatched.
|
||||||
/// - tag: The tag to be associated to the task.
|
/// - host: The object to be hosted on. When this object is dealloced,
|
||||||
|
/// the task will not scheduled any more.
|
||||||
/// - onElapse: The action to do when time is out.
|
/// - onElapse: The action to do when time is out.
|
||||||
/// - Returns: The task just created.
|
/// - Returns: The task just created.
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public func `do`(queue: DispatchQueue,
|
public func `do`(queue: DispatchQueue,
|
||||||
tag: String? = nil,
|
host: AnyObject? = nil,
|
||||||
onElapse: @escaping () -> Void) -> Task {
|
onElapse: @escaping () -> Void) -> Task {
|
||||||
return self.do(queue: queue, tag: tag, onElapse: { (_) in onElapse() })
|
return self.do(queue: queue, host: host, onElapse: { (_) in onElapse() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,10 @@ public class Task {
|
||||||
private lazy var _tags: Set<String> = []
|
private lazy var _tags: Set<String> = []
|
||||||
private lazy var _countOfExecutions: Int = 0
|
private lazy var _countOfExecutions: Int = 0
|
||||||
|
|
||||||
|
#if os(Linux)
|
||||||
|
private weak var _host: AnyObject? = TaskHub.shared
|
||||||
|
#endif
|
||||||
|
|
||||||
private lazy var _lifetime: Interval = Int.max.second
|
private lazy var _lifetime: Interval = Int.max.second
|
||||||
private lazy var _lifetimeTimer: DispatchSourceTimer = {
|
private lazy var _lifetimeTimer: DispatchSourceTimer = {
|
||||||
let timer = DispatchSource.makeTimerSource()
|
let timer = DispatchSource.makeTimerSource()
|
||||||
|
@ -47,8 +51,8 @@ public class Task {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
init(schedule: Schedule,
|
init(schedule: Schedule,
|
||||||
queue: DispatchQueue? = nil,
|
queue: DispatchQueue?,
|
||||||
tag: String? = nil,
|
host: AnyObject?,
|
||||||
onElapse: @escaping (Task) -> Void) {
|
onElapse: @escaping (Task) -> Void) {
|
||||||
|
|
||||||
_iterator = schedule.makeIterator()
|
_iterator = schedule.makeIterator()
|
||||||
|
@ -57,6 +61,14 @@ public class Task {
|
||||||
_actions.append(onElapse)
|
_actions.append(onElapse)
|
||||||
|
|
||||||
_timer.setEventHandler { [weak self] in
|
_timer.setEventHandler { [weak self] in
|
||||||
|
|
||||||
|
#if os(Linux)
|
||||||
|
guard self?._host != nil else {
|
||||||
|
self?.cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
self?.elapse()
|
self?.elapse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +77,18 @@ public class Task {
|
||||||
_timer.schedule(after: interval)
|
_timer.schedule(after: interval)
|
||||||
_timeline.estimatedNextExecution = Date().adding(interval)
|
_timeline.estimatedNextExecution = Date().adding(interval)
|
||||||
|
|
||||||
TaskHub.shared.add(self, withTag: tag)
|
#if os(Linux)
|
||||||
|
_host = host
|
||||||
|
#else
|
||||||
|
if let host = host {
|
||||||
|
DeinitObserver.observe(host) { [weak self] in
|
||||||
|
self?.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TaskHub.shared.add(self)
|
||||||
|
|
||||||
_timer.resume()
|
_timer.resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,9 +364,6 @@ public class Task {
|
||||||
public func removeTag(_ tag: String) {
|
public func removeTag(_ tag: String) {
|
||||||
removeTags(tag)
|
removeTags(tag)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
||||||
|
|
Loading…
Reference in New Issue