Rename schedule to plan to avoid namespace confliction

This commit is contained in:
QuentinJin 2018-09-24 00:34:55 +08:00
parent 289922b445
commit aba3fd69ce
11 changed files with 182 additions and 182 deletions

View File

@ -5,23 +5,23 @@ import Schedule
PlaygroundPage.current.needsIndefiniteExecution = true
Schedule.after(1.second).do {
Plan.after(1.second).do {
print("1 second passed!")
}
Schedule.after(1.minute, repeating: 0.5.seconds).do {
Plan.after(1.minute, repeating: 0.5.seconds).do {
print("Ping!")
}
Schedule.every("one minute and ten seconds").do {
Plan.every("one minute and ten seconds").do {
print("One minute and ten seconds have elapsed!")
}
Schedule.every(.monday, .tuesday, .wednesday, .thursday, .friday).at(6, 30).do {
Plan.every(.monday, .tuesday, .wednesday, .thursday, .friday).at(6, 30).do {
print("Get up!")
}
Schedule.every(.june(14)).at("9:30").do {
Plan.every(.june(14)).at("9:30").do {
print("Happy birthday!")
}

View File

@ -33,7 +33,7 @@
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_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 /* Plan.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* Plan.swift */; };
OBJ_54 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* Task.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 */; };
@ -45,7 +45,7 @@
OBJ_79 /* DateTimeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_28 /* DateTimeTests.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_82 /* SchedulesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* SchedulesTests.swift */; };
OBJ_82 /* PlanTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* PlanTests.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_86 /* XCTestManifests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_35 /* XCTestManifests.swift */; };
@ -82,7 +82,7 @@
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_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 /* Plan.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Plan.swift; sourceTree = "<group>"; };
OBJ_18 /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.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>"; };
@ -93,7 +93,7 @@
OBJ_28 /* DateTimeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimeTests.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_31 /* SchedulesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SchedulesTests.swift; sourceTree = "<group>"; };
OBJ_31 /* PlanTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlanTests.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_35 /* XCTestManifests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestManifests.swift; sourceTree = "<group>"; };
@ -179,7 +179,7 @@
children = (
OBJ_28 /* DateTimeTests.swift */,
OBJ_30 /* Misc.swift */,
OBJ_31 /* SchedulesTests.swift */,
OBJ_31 /* PlanTests.swift */,
OBJ_32 /* TaskHubTests.swift */,
OBJ_33 /* TaskTests.swift */,
OBJ_35 /* XCTestManifests.swift */,
@ -221,7 +221,7 @@
isa = PBXGroup;
children = (
66D9F43221563D7700D9F441 /* RunLoopTask.swift */,
OBJ_17 /* Schedule.swift */,
OBJ_17 /* Plan.swift */,
OBJ_18 /* Task.swift */,
OBJ_19 /* TaskHub.swift */,
OBJ_21 /* Timeline.swift */,
@ -350,7 +350,7 @@
OBJ_49 /* Lock.swift in Sources */,
OBJ_50 /* Monthday.swift in Sources */,
OBJ_52 /* Period.swift in Sources */,
OBJ_53 /* Schedule.swift in Sources */,
OBJ_53 /* Plan.swift in Sources */,
OBJ_54 /* Task.swift in Sources */,
OBJ_55 /* TaskHub.swift in Sources */,
667D2DF72132C5390071DC89 /* DeinitObserver.swift in Sources */,
@ -379,7 +379,7 @@
OBJ_79 /* DateTimeTests.swift in Sources */,
OBJ_80 /* ExtensionsTests.swift in Sources */,
OBJ_81 /* Misc.swift in Sources */,
OBJ_82 /* SchedulesTests.swift in Sources */,
OBJ_82 /* PlanTests.swift in Sources */,
667D2DF92132C95D0071DC89 /* DeinitObserverTests.swift in Sources */,
OBJ_83 /* TaskHubTests.swift in Sources */,
OBJ_84 /* TaskTests.swift in Sources */,

View File

@ -1,17 +1,17 @@
//
// Schedule.swift
// Schedule
// Plan.swift
// Plan
//
// Created by Quentin Jin on 2018/7/2.
//
import Foundation
/// `Schedule` represents a plan that gives the times
/// `Plan` represents a plan that gives the times
/// at which a task should be executed.
///
/// `Schedule` is `Interval` based.
public struct Schedule {
/// `Plan` is `Interval` based.
public struct Plan {
private var sequence: AnySequence<Interval>
private init<S>(_ sequence: S) where S: Sequence, S.Element == Interval {
@ -22,7 +22,7 @@ public struct Schedule {
return sequence.makeIterator()
}
/// Schedules a task with this schedule.
/// Schedules a task with this plan.
///
/// - Parameters:
/// - queue: The queue to which the task will be dispatched.
@ -34,10 +34,10 @@ public struct Schedule {
public func `do`(queue: DispatchQueue,
host: AnyObject? = nil,
onElapse: @escaping (Task) -> Void) -> Task {
return Task(schedule: self, queue: queue, host: host, onElapse: onElapse)
return Task(plan: self, queue: queue, host: host, onElapse: onElapse)
}
/// Schedules a task with this schedule.
/// Schedules a task with this plan.
///
/// - Parameters:
/// - queue: The queue to which the task will be dispatched.
@ -53,23 +53,23 @@ public struct Schedule {
}
}
extension Schedule {
extension Plan {
/// Creates a schedule from a `makeUnderlyingIterator()` method.
/// Creates a plan from a `makeUnderlyingIterator()` method.
///
/// The task will be executed after each interval
/// produced by the iterator that `makeUnderlyingIterator` returns.
///
/// For example:
///
/// let schedule = Schedule.make {
/// let plan = Plan.make {
/// var i = 0
/// return AnyIterator {
/// i += 1
/// return i
/// }
/// }
/// schedule.do {
/// plan.do {
/// print(Date())
/// }
///
@ -78,39 +78,39 @@ extension Schedule {
/// > "2001-01-01 00:00:03"
/// > "2001-01-01 00:00:06"
/// ...
public static func make<I>(_ makeUnderlyingIterator: @escaping () -> I) -> Schedule where I: IteratorProtocol, I.Element == Interval {
return Schedule(AnySequence(makeUnderlyingIterator))
public static func make<I>(_ makeUnderlyingIterator: @escaping () -> I) -> Plan where I: IteratorProtocol, I.Element == Interval {
return Plan(AnySequence(makeUnderlyingIterator))
}
/// Creates a schedule from an interval sequence.
/// Creates a plan from an interval sequence.
/// The task will be executed after each interval in the sequence.
public static func from<S>(_ sequence: S) -> Schedule where S: Sequence, S.Element == Interval {
return Schedule(sequence)
public static func from<S>(_ sequence: S) -> Plan where S: Sequence, S.Element == Interval {
return Plan(sequence)
}
/// Creates a schedule from an interval array.
/// Creates a plan from an interval array.
/// The task will be executed after each interval in the array.
public static func of(_ intervals: Interval...) -> Schedule {
return Schedule(intervals)
public static func of(_ intervals: Interval...) -> Plan {
return Plan(intervals)
}
}
extension Schedule {
extension Plan {
/// Creates a schedule from a `makeUnderlyingIterator()` method.
/// Creates a plan from a `makeUnderlyingIterator()` method.
///
/// The task will be executed at each date
/// produced by the iterator that `makeUnderlyingIterator` returns.
///
/// For example:
///
/// let schedule = Schedule.make {
/// let plan = Plan.make {
/// return AnyIterator {
/// return Date().addingTimeInterval(3)
/// }
/// }
/// print("now:", Date())
/// schedule.do {
/// plan.do {
/// print("task", Date())
/// }
///
@ -120,9 +120,9 @@ extension Schedule {
///
/// You are not supposed to return `Date()` in making interator.
/// If you want to execute a task immediately,
/// use `Schedule.now` then `concat` another schedule instead.
public static func make<I>(_ makeUnderlyingIterator: @escaping () -> I) -> Schedule where I: IteratorProtocol, I.Element == Date {
return Schedule.make { () -> AnyIterator<Interval> in
/// use `Plan.now` then `concat` another plan instead.
public static func make<I>(_ makeUnderlyingIterator: @escaping () -> I) -> Plan where I: IteratorProtocol, I.Element == Date {
return Plan.make { () -> AnyIterator<Interval> in
var iterator = makeUnderlyingIterator()
var last: Date!
return AnyIterator {
@ -134,19 +134,19 @@ extension Schedule {
}
}
/// Creates a schedule from a date sequence.
/// Creates a plan from a date sequence.
/// The task will be executed at each date in the sequence.
public static func from<S>(_ sequence: S) -> Schedule where S: Sequence, S.Element == Date {
return Schedule.make(sequence.makeIterator)
public static func from<S>(_ sequence: S) -> Plan where S: Sequence, S.Element == Date {
return Plan.make(sequence.makeIterator)
}
/// Creates a schedule from a date array.
/// Creates a plan from a date array.
/// The task will be executed at each date in the array.
public static func of(_ dates: Date...) -> Schedule {
return Schedule.from(dates)
public static func of(_ dates: Date...) -> Plan {
return Plan.from(dates)
}
/// A dates sequence corresponding to this schedule.
/// A dates sequence corresponding to this plan.
public var dates: AnySequence<Date> {
return AnySequence { () -> AnyIterator<Date> in
let iterator = self.makeIterator()
@ -162,42 +162,42 @@ extension Schedule {
}
}
extension Schedule {
extension Plan {
/// A schedule with a distant past date.
public static var distantPast: Schedule {
return Schedule.of(Date.distantPast)
/// A plan with a distant past date.
public static var distantPast: Plan {
return Plan.of(Date.distantPast)
}
/// A schedule with a distant future date.
public static var distantFuture: Schedule {
return Schedule.of(Date.distantFuture)
/// A plan with a distant future date.
public static var distantFuture: Plan {
return Plan.of(Date.distantFuture)
}
/// A schedule that is never going to happen.
public static var never: Schedule {
return Schedule.make {
/// A plan that is never going to happen.
public static var never: Plan {
return Plan.make {
AnyIterator<Date> { nil }
}
}
}
extension Schedule {
extension Plan {
/// Returns a new schedule by concatenating a schedule to this schedule.
/// Returns a new plan by concatenating a plan to this plan.
///
/// For example:
///
/// let s0 = Schedule.of(1.second, 2.seconds, 3.seconds)
/// let s1 = Schedule.of(4.seconds, 4.seconds, 4.seconds)
/// let s0 = Plan.of(1.second, 2.seconds, 3.seconds)
/// let s1 = Plan.of(4.seconds, 4.seconds, 4.seconds)
/// let s2 = s0.concat(s1)
///
/// > s2
/// > 1.second, 2.seconds, 3.seconds, 4.seconds, 4.seconds, 4.seconds
public func concat(_ schedule: Schedule) -> Schedule {
return Schedule.make { () -> AnyIterator<Interval> in
public func concat(_ plan: Plan) -> Plan {
return Plan.make { () -> AnyIterator<Interval> in
let i0 = self.makeIterator()
let i1 = schedule.makeIterator()
let i1 = plan.makeIterator()
return AnyIterator {
if let interval = i0.next() { return interval }
return i1.next()
@ -205,19 +205,19 @@ extension Schedule {
}
}
/// Returns a new schedule by merging a schedule to this schedule.
/// Returns a new plan by merging a plan to this plan.
///
/// For example:
///
/// let s0 = Schedule.of(1.second, 3.seconds, 5.seconds)
/// let s1 = Schedule.of(2.seconds, 4.seconds, 6.seconds)
/// let s0 = Plan.of(1.second, 3.seconds, 5.seconds)
/// let s1 = Plan.of(2.seconds, 4.seconds, 6.seconds)
/// let s2 = s0.concat(s1)
/// > s2
/// > 1.second, 1.seconds, 2.seconds, 2.seconds, 3.seconds, 3.seconds
public func merge(_ schedule: Schedule) -> Schedule {
return Schedule.make { () -> AnyIterator<Date> in
public func merge(_ plan: Plan) -> Plan {
return Plan.make { () -> AnyIterator<Date> in
let i0 = self.dates.makeIterator()
let i1 = schedule.dates.makeIterator()
let i1 = plan.dates.makeIterator()
var buffer0: Date!
var buffer1: Date!
return AnyIterator<Date> {
@ -238,16 +238,16 @@ extension Schedule {
}
}
/// Returns a new schedule by only taking the first specific number of this schedule.
/// Returns a new plan by only taking the first specific number of this plan.
///
/// For example:
///
/// let s0 = Schedule.every(1.second)
/// let s0 = Plan.every(1.second)
/// let s1 = s0.first(3)
/// > s1
/// 1.second, 1.second, 1.second
public func first(_ count: Int) -> Schedule {
return Schedule.make { () -> AnyIterator<Interval> in
public func first(_ count: Int) -> Plan {
return Plan.make { () -> AnyIterator<Interval> in
let iterator = self.makeIterator()
var num = 0
return AnyIterator {
@ -258,9 +258,9 @@ extension Schedule {
}
}
/// Returns a new schedule by only taking the part before the date.
public func until(_ date: Date) -> Schedule {
return Schedule.make { () -> AnyIterator<Date> in
/// Returns a new plan by only taking the part before the date.
public func until(_ date: Date) -> Plan {
return Plan.make { () -> AnyIterator<Date> in
let iterator = self.dates.makeIterator()
return AnyIterator {
guard let next = iterator.next(), next < date else {
@ -272,39 +272,39 @@ extension Schedule {
}
}
extension Schedule {
extension Plan {
/// Creates a schedule that executes the task immediately.
public static var now: Schedule {
return Schedule.of(0.nanosecond)
/// Creates a plan that executes the task immediately.
public static var now: Plan {
return Plan.of(0.nanosecond)
}
/// Creates a schedule that executes the task after delay.
public static func after(_ delay: Interval) -> Schedule {
return Schedule.of(delay)
/// Creates a plan that executes the task after delay.
public static func after(_ delay: Interval) -> Plan {
return Plan.of(delay)
}
/// Creates a schedule that executes the task every interval.
public static func every(_ interval: Interval) -> Schedule {
return Schedule.make {
/// Creates a plan that executes the task every interval.
public static func every(_ interval: Interval) -> Plan {
return Plan.make {
AnyIterator { interval }
}
}
/// Creates a schedule that executes the task after delay then repeat
/// Creates a plan that executes the task after delay then repeat
/// every interval.
public static func after(_ delay: Interval, repeating interval: Interval) -> Schedule {
return Schedule.after(delay).concat(Schedule.every(interval))
public static func after(_ delay: Interval, repeating interval: Interval) -> Plan {
return Plan.after(delay).concat(Plan.every(interval))
}
/// Creates a schedule that executes the task at the specific date.
public static func at(_ date: Date) -> Schedule {
return Schedule.of(date)
/// Creates a plan that executes the task at the specific date.
public static func at(_ date: Date) -> Plan {
return Plan.of(date)
}
/// Creates a schedule that executes the task every period.
public static func every(_ period: Period) -> Schedule {
return Schedule.make { () -> AnyIterator<Interval> in
/// Creates a plan that executes the task every period.
public static func every(_ period: Period) -> Plan {
return Plan.make { () -> AnyIterator<Interval> in
let calendar = Calendar.gregorian
var last: Date!
return AnyIterator {
@ -319,32 +319,32 @@ extension Schedule {
}
}
/// Creates a schedule that executes the task every period.
/// Creates a plan that executes the task every period.
///
/// See Period's constructor
public static func every(_ period: String) -> Schedule {
public static func every(_ period: String) -> Plan {
guard let p = Period(period) else {
return Schedule.never
return Plan.never
}
return Schedule.every(p)
return Plan.every(p)
}
}
extension Schedule {
extension Plan {
/// `DateMiddleware` represents a middleware that wraps a schedule
/// `DateMiddleware` represents a middleware that wraps a plan
/// which was only specified date without time.
///
/// You should call `at` method to get the schedule with time specified.
/// You should call `at` method to get the plan with time specified.
public struct DateMiddleware {
fileprivate let schedule: Schedule
fileprivate let plan: Plan
/// Returns a schedule at the specific time.
public func at(_ time: Time) -> Schedule {
/// Returns a plan at the specific time.
public func at(_ time: Time) -> Plan {
var interval = time.intervalSinceZeroClock
return Schedule.make { () -> AnyIterator<Interval> in
let it = self.schedule.makeIterator()
return Plan.make { () -> AnyIterator<Interval> in
let it = self.plan.makeIterator()
return AnyIterator {
if let next = it.next() {
defer { interval = 0.nanoseconds }
@ -355,38 +355,38 @@ extension Schedule {
}
}
/// Returns a schedule at the specific time.
/// Returns a plan at the specific time.
///
/// See Time's constructor
public func at(_ time: String) -> Schedule {
public func at(_ time: String) -> Plan {
guard let time = Time(time) else {
return Schedule.never
return Plan.never
}
return at(time)
}
/// Returns a schedule at the specific time.
/// Returns a plan at the specific time.
///
/// .at(1) => 01
/// .at(1, 2) => 01:02
/// .at(1, 2, 3) => 01:02:03
/// .at(1, 2, 3, 456) => 01:02:03.456
public func at(_ time: Int...) -> Schedule {
public func at(_ time: Int...) -> Plan {
let hour = time[0]
let minute = time.count > 1 ? time[1] : 0
let second = time.count > 2 ? time[2] : 0
let nanosecond = time.count > 3 ? time[3]: 0
guard let time = Time(hour: hour, minute: minute, second: second, nanosecond: nanosecond) else {
return Schedule.never
return Plan.never
}
return at(time)
}
}
/// Creates a schedule that executes the task every specific weekday.
/// Creates a plan that executes the task every specific weekday.
public static func every(_ weekday: Weekday) -> DateMiddleware {
let schedule = Schedule.make { () -> AnyIterator<Date> in
let plan = Plan.make { () -> AnyIterator<Date> in
let calendar = Calendar.gregorian
var date: Date!
return AnyIterator<Date> {
@ -400,23 +400,23 @@ extension Schedule {
return date
}
}
return DateMiddleware(schedule: schedule)
return DateMiddleware(plan: plan)
}
/// Creates a schedule that executes the task every specific weekdays.
/// Creates a plan that executes the task every specific weekdays.
public static func every(_ weekdays: Weekday...) -> DateMiddleware {
var schedule = every(weekdays[0]).schedule
var plan = every(weekdays[0]).plan
if weekdays.count > 1 {
for i in 1..<weekdays.count {
schedule = schedule.merge(Schedule.every(weekdays[i]).schedule)
plan = plan.merge(Plan.every(weekdays[i]).plan)
}
}
return DateMiddleware(schedule: schedule)
return DateMiddleware(plan: plan)
}
/// Creates a schedule that executes the task every specific day in the month.
/// Creates a plan that executes the task every specific day in the month.
public static func every(_ monthday: Monthday) -> DateMiddleware {
let schedule = Schedule.make { () -> AnyIterator<Date> in
let plan = Plan.make { () -> AnyIterator<Date> in
let calendar = Calendar.gregorian
var date: Date!
return AnyIterator<Date> {
@ -430,17 +430,17 @@ extension Schedule {
return date
}
}
return DateMiddleware(schedule: schedule)
return DateMiddleware(plan: plan)
}
/// Creates a schedule that executes the task every specific days in the months.
/// Creates a plan that executes the task every specific days in the months.
public static func every(_ mondays: Monthday...) -> DateMiddleware {
var schedule = every(mondays[0]).schedule
var plan = every(mondays[0]).plan
if mondays.count > 1 {
for i in 1..<mondays.count {
schedule = schedule.merge(Schedule.every(mondays[i]).schedule)
plan = plan.merge(Plan.every(mondays[i]).plan)
}
}
return DateMiddleware(schedule: schedule)
return DateMiddleware(plan: plan)
}
}

View File

@ -7,12 +7,12 @@
import Foundation
extension Schedule {
extension Plan {
/// Schedules a task with this schedule.
/// Schedules a task with this plan.
///
/// - Parameters:
/// - mode: The mode in which to add the schedule.
/// - mode: The mode in which to add the task.
/// - host: The object to be hosted on.
/// - onElapse: The action to do when time is out.
/// - Returns: The task just created.
@ -20,13 +20,13 @@ extension Schedule {
public func `do`(mode: RunLoop.Mode = .default,
host: AnyObject? = nil,
onElapse: @escaping (Task) -> Void) -> Task {
return RunLoopTask(schedule: self, mode: mode, host: host, onElapse: onElapse)
return RunLoopTask(plan: self, mode: mode, host: host, onElapse: onElapse)
}
/// Schedules a task with this schedule.
/// Schedules a task with this plan.
///
/// - Parameters:
/// - mode: The mode in which to add the schedule.
/// - mode: The mode in which to add the task.
/// - host: The object to be hosted on.
/// - onElapse: The action to do when time is out.
/// - Returns: The task just created.
@ -44,7 +44,7 @@ private final class RunLoopTask: Task {
var timer: Timer!
init(schedule: Schedule, mode: RunLoop.Mode, host: AnyObject?, onElapse: @escaping (Task) -> Void) {
init(plan: Plan, mode: RunLoop.Mode, host: AnyObject?, onElapse: @escaping (Task) -> Void) {
var this: Task?
@ -56,7 +56,7 @@ private final class RunLoopTask: Task {
RunLoop.current.add(timer, forMode: mode)
super.init(schedule: schedule, queue: nil, host: host) { (task) in
super.init(plan: plan, queue: nil, host: host) { (task) in
guard let task = task as? RunLoopTask else { return }
task.timer.fireDate = Date()
}

View File

@ -50,12 +50,12 @@ public class Task {
return timer
}()
init(schedule: Schedule,
init(plan: Plan,
queue: DispatchQueue?,
host: AnyObject?,
onElapse: @escaping (Task) -> Void) {
_iterator = schedule.makeIterator()
_iterator = plan.makeIterator()
_timer = DispatchSource.makeTimerSource(queue: queue)
_actions.append(onElapse)
@ -115,7 +115,7 @@ public class Task {
}
}
/// Execute this task now, without disrupting its schedule.
/// Execute this task now, without disrupting its plan.
public func execute() {
let actions = _lock.withLock { () -> Bucket<Task.Action> in
let now = Date()
@ -150,8 +150,8 @@ public class Task {
// MARK: - Manage
/// Reschedules this task with the new schedule.
public func reschedule(_ new: Schedule) {
/// Reschedules this task with the new plan.
public func reschedule(_ new: Plan) {
_lock.withLock {
_iterator = new.makeIterator()
_timeline.estimatedNextExecution = Date()

View File

@ -7,7 +7,7 @@
import Foundation
/// `Timeline` records a task's schedule.
/// `Timeline` records a task's lifecycle.
public struct Timeline {
/// The time of first execution.

View File

@ -59,10 +59,10 @@ extension Sequence where Element == Interval {
}
}
extension Schedule {
extension Plan {
func isAlmostEqual(to schedule: Schedule, leeway: Interval) -> Bool {
return makeIterator().isAlmostEqual(to: schedule.makeIterator(), leeway: leeway)
func isAlmostEqual(to plan: Plan, leeway: Interval) -> Bool {
return makeIterator().isAlmostEqual(to: plan.makeIterator(), leeway: leeway)
}
}

View File

@ -1,15 +1,15 @@
import XCTest
@testable import Schedule
final class SchedulesTests: XCTestCase {
final class PlanTests: XCTestCase {
let leeway = 0.01.seconds
func testMake() {
let intervals = [1.second, 2.hours, 3.days, 4.weeks]
let s0 = Schedule.of(intervals[0], intervals[1], intervals[2], intervals[3])
let s0 = Plan.of(intervals[0], intervals[1], intervals[2], intervals[3])
XCTAssertTrue(s0.makeIterator().isAlmostEqual(to: intervals, leeway: leeway))
let s1 = Schedule.from(intervals)
let s1 = Plan.from(intervals)
XCTAssertTrue(s1.makeIterator().isAlmostEqual(to: intervals, leeway: leeway))
let d0 = Date() + intervals[0]
@ -17,18 +17,18 @@ final class SchedulesTests: XCTestCase {
let d2 = d1 + intervals[2]
let d3 = d2 + intervals[3]
let s2 = Schedule.of(d0, d1, d2, d3)
let s3 = Schedule.from([d0, d1, d2, d3])
let s2 = Plan.of(d0, d1, d2, d3)
let s3 = Plan.from([d0, d1, d2, d3])
XCTAssertTrue(s2.makeIterator().isAlmostEqual(to: intervals, leeway: leeway))
XCTAssertTrue(s3.makeIterator().isAlmostEqual(to: intervals, leeway: leeway))
let longTime = (100 * 365).days
XCTAssertTrue(Schedule.distantPast.makeIterator().next()!.isLonger(than: longTime))
XCTAssertTrue(Schedule.distantFuture.makeIterator().next()!.isLonger(than: longTime))
XCTAssertTrue(Plan.distantPast.makeIterator().next()!.isLonger(than: longTime))
XCTAssertTrue(Plan.distantFuture.makeIterator().next()!.isLonger(than: longTime))
}
func testDates() {
let iterator = Schedule.of(1.days, 2.weeks).dates.makeIterator()
let iterator = Plan.of(1.days, 2.weeks).dates.makeIterator()
var next = iterator.next()
XCTAssertNotNil(next)
XCTAssertTrue(next!.intervalSinceNow.isAlmostEqual(to: 1.days, leeway: leeway))
@ -38,27 +38,27 @@ final class SchedulesTests: XCTestCase {
}
func testNever() {
XCTAssertNil(Schedule.never.makeIterator().next())
XCTAssertNil(Plan.never.makeIterator().next())
}
func testConcat() {
let s0: [Interval] = [1.second, 2.minutes, 3.hours]
let s1: [Interval] = [4.days, 5.weeks]
let s3 = Schedule.from(s0).concat(Schedule.from(s1))
let s4 = Schedule.from(s0 + s1)
let s3 = Plan.from(s0).concat(Plan.from(s1))
let s4 = Plan.from(s0 + s1)
XCTAssertTrue(s3.isAlmostEqual(to: s4, leeway: leeway))
}
func testMerge() {
let intervals0: [Interval] = [1.second, 2.minutes, 1.hour]
let intervals1: [Interval] = [2.seconds, 1.minutes, 1.seconds]
let scheudle0 = Schedule.from(intervals0).merge(Schedule.from(intervals1))
let scheudle1 = Schedule.of(1.second, 1.second, 1.minutes, 1.seconds, 58.seconds, 1.hour)
let scheudle0 = Plan.from(intervals0).merge(Plan.from(intervals1))
let scheudle1 = Plan.of(1.second, 1.second, 1.minutes, 1.seconds, 58.seconds, 1.hour)
XCTAssertTrue(scheudle0.isAlmostEqual(to: scheudle1, leeway: leeway))
}
func testAt() {
let s = Schedule.at(Date() + 1.second)
let s = Plan.at(Date() + 1.second)
let next = s.makeIterator().next()
XCTAssertNotNil(next)
XCTAssertTrue(next!.isAlmostEqual(to: 1.second, leeway: leeway))
@ -66,7 +66,7 @@ final class SchedulesTests: XCTestCase {
func testFirst() {
var count = 10
let s = Schedule.every(1.second).first(count)
let s = Plan.every(1.second).first(count)
let i = s.makeIterator()
while count > 0 {
XCTAssertNotNil(i.next())
@ -77,7 +77,7 @@ final class SchedulesTests: XCTestCase {
func testUntil() {
let until = Date() + 10.seconds
let s = Schedule.every(1.second).until(until).dates
let s = Plan.every(1.second).until(until).dates
let i = s.makeIterator()
while let date = i.next() {
XCTAssertLessThan(date, until)
@ -85,19 +85,19 @@ final class SchedulesTests: XCTestCase {
}
func testNow() {
let s0 = Schedule.now
let s1 = Schedule.of(Date())
let s0 = Plan.now
let s1 = Plan.of(Date())
XCTAssertTrue(s0.isAlmostEqual(to: s1, leeway: leeway))
}
func testAfterAndRepeating() {
let s0 = Schedule.after(1.day, repeating: 1.hour).first(3)
let s1 = Schedule.of(1.day, 1.hour, 1.hour)
let s0 = Plan.after(1.day, repeating: 1.hour).first(3)
let s1 = Plan.of(1.day, 1.hour, 1.hour)
XCTAssertTrue(s0.isAlmostEqual(to: s1, leeway: leeway))
}
func testEveryPeriod() {
let s = Schedule.every("1 year").first(10)
let s = Plan.every("1 year").first(10)
var date = Date()
for i in s.dates {
XCTAssertEqual(i.dateComponents.year!, date.dateComponents.year! + 1)
@ -108,7 +108,7 @@ final class SchedulesTests: XCTestCase {
}
func testEveryWeekday() {
let s = Schedule.every(.friday, .monday).at("11:11:00").first(5)
let s = Plan.every(.friday, .monday).at("11:11:00").first(5)
for i in s.dates {
XCTAssertTrue(i.dateComponents.weekday == 6 || i.dateComponents.weekday == 2)
XCTAssertEqual(i.dateComponents.hour, 11)
@ -116,7 +116,7 @@ final class SchedulesTests: XCTestCase {
}
func testEveryMonthday() {
let s = Schedule.every(.april(1), .october(1)).at(11, 11).first(5)
let s = Plan.every(.april(1), .october(1)).at(11, 11).first(5)
for i in s.dates {
XCTAssertTrue(i.dateComponents.month == 4 || i.dateComponents.month == 10)
XCTAssertEqual(i.dateComponents.day, 1)

View File

@ -12,7 +12,7 @@ final class TaskHubTests: XCTestCase {
@discardableResult
func makeTask() -> Task {
return Schedule.never.do { }
return Plan.never.do { }
}
var shared: TaskHub {

View File

@ -13,7 +13,7 @@ final class TaskTests: XCTestCase {
func testSchedule() {
let e = expectation(description: "testSchedule")
let date = Date()
let task = Schedule.after(0.5.second).do {
let task = Plan.after(0.5.second).do {
XCTAssertTrue(Date().timeIntervalSince(date).isAlmostEqual(to: 0.5, leeway: 0.1))
e.fulfill()
}
@ -24,7 +24,7 @@ final class TaskTests: XCTestCase {
func testRepeat() {
let e = expectation(description: "testRepeat")
var t = 0
let task = Schedule.every(0.2.second).first(3).do {
let task = Plan.every(0.2.second).first(3).do {
t += 1
if t == 3 { e.fulfill() }
}
@ -36,7 +36,7 @@ final class TaskTests: XCTestCase {
let e = expectation(description: "testQueue")
let queue = DispatchQueue(label: "testQueue")
let task = Schedule.after(0.1.second).do(queue: queue) {
let task = Plan.after(0.1.second).do(queue: queue) {
XCTAssertTrue(DispatchQueue.is(queue))
e.fulfill()
}
@ -48,7 +48,7 @@ final class TaskTests: XCTestCase {
let e = expectation(description: "testThread")
DispatchQueue.global().async {
let thread = Thread.current
Schedule.after(0.1.second).do { task in
Plan.after(0.1.second).do { task in
XCTAssertTrue(thread === Thread.current)
e.fulfill()
task.cancel()
@ -61,7 +61,7 @@ final class TaskTests: XCTestCase {
func testSuspendResume() {
let block = {
let task = Schedule.distantFuture.do { }
let task = Plan.distantFuture.do { }
XCTAssertEqual(task.suspensions, 0)
task.suspend()
task.suspend()
@ -73,7 +73,7 @@ final class TaskTests: XCTestCase {
block()
let tag = UUID().uuidString
let task = Schedule.distantFuture.do { }
let task = Plan.distantFuture.do { }
task.addTag(tag)
Task.suspend(byTag: tag)
XCTAssertEqual(task.suspensions, 1)
@ -85,7 +85,7 @@ final class TaskTests: XCTestCase {
func testAddAndRemoveActions() {
let e = expectation(description: "testAddAndRemoveActions")
let task = Schedule.after(0.5.second).do { }
let task = Plan.after(0.5.second).do { }
let date = Date()
let key = task.addAction { _ in
XCTAssertTrue(Date().timeIntervalSince(date).isAlmostEqual(to: 0.5, leeway: 0.1))
@ -102,7 +102,7 @@ final class TaskTests: XCTestCase {
}
func testAddAndRemoveTags() {
let task = Schedule.never.do { }
let task = Plan.never.do { }
let tagA = UUID().uuidString
let tagB = UUID().uuidString
let tagC = UUID().uuidString
@ -121,7 +121,7 @@ final class TaskTests: XCTestCase {
func testReschedule() {
let e = expectation(description: "testReschedule")
var i = 0
let task = Schedule.after(0.1.second).do { (task) in
let task = Plan.after(0.1.second).do { (task) in
i += 1
if task.countOfExecution == 6 && task.timeline.estimatedNextExecution == nil {
e.fulfill()
@ -131,7 +131,7 @@ final class TaskTests: XCTestCase {
}
}
DispatchQueue.global().async(after: 0.5.second) {
task.reschedule(Schedule.every(0.1.second).first(5))
task.reschedule(Plan.every(0.1.second).first(5))
}
waitForExpectations(timeout: 2)
task.cancel()
@ -141,7 +141,7 @@ final class TaskTests: XCTestCase {
let e = expectation(description: "testParasiticTask")
let fn = {
let obj = NSObject()
Schedule.after(0.5.second).do(queue: .main, host: obj, onElapse: {
Plan.after(0.5.second).do(queue: .main, host: obj, onElapse: {
XCTFail("should never come here")
})
}
@ -154,7 +154,7 @@ final class TaskTests: XCTestCase {
func testLifetime() {
let e = expectation(description: "testLifetime")
let task = Schedule.after(1.hour).do { }
let task = Plan.after(1.hour).do { }
task.setLifetime(1.second)
XCTAssertEqual(task.lifetime, 1.second)

View File

@ -4,7 +4,7 @@ import XCTest
public func allTests() -> [XCTestCaseEntry] {
return [
testCase(DateTimeTests.allTests),
testCase(SchedulesTests.allTests),
testCase(PlanTests.allTests),
testCase(TaskHubTests.allTests),
testCase(TaskTests.allTests),
testCase(AtomicTests.allTests),