Improves documentations
This commit is contained in:
parent
34cac2aab8
commit
7de73c72a0
|
@ -1,6 +1,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// A unique key used to remove the corresponding element from a bag.
|
/// A unique key used to operate the corresponding element from a bag.
|
||||||
struct BagKey: Equatable {
|
struct BagKey: Equatable {
|
||||||
|
|
||||||
fileprivate let i: UInt64
|
fileprivate let i: UInt64
|
||||||
|
@ -15,7 +15,7 @@ struct BagKey: Equatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A generator can generate a sequence of unique `BagKey`.
|
/// A generator used to generate a sequence of unique `BagKey`.
|
||||||
///
|
///
|
||||||
/// let k1 = gen.next()
|
/// let k1 = gen.next()
|
||||||
/// let k2 = gen.next()
|
/// let k2 = gen.next()
|
||||||
|
@ -26,7 +26,7 @@ struct BagKeyGenerator: Sequence, IteratorProtocol {
|
||||||
|
|
||||||
private var k = BagKey(underlying: 0)
|
private var k = BagKey(underlying: 0)
|
||||||
|
|
||||||
/// Gets next BagKey.
|
/// Advances to the next element and returns it, or nil if no next element exists.
|
||||||
mutating func next() -> Element? {
|
mutating func next() -> Element? {
|
||||||
if k.i == UInt64.max {
|
if k.i == UInt64.max {
|
||||||
return nil
|
return nil
|
||||||
|
@ -95,6 +95,7 @@ struct Bag<Element> {
|
||||||
|
|
||||||
extension Bag: Sequence {
|
extension Bag: Sequence {
|
||||||
|
|
||||||
|
/// Returns an iterator over the elements of this containers.
|
||||||
func makeIterator() -> AnyIterator<Element> {
|
func makeIterator() -> AnyIterator<Element> {
|
||||||
var iterator = entries.makeIterator()
|
var iterator = entries.makeIterator()
|
||||||
return AnyIterator<Element> {
|
return AnyIterator<Element> {
|
||||||
|
|
|
@ -21,7 +21,7 @@ class DeinitObserver {
|
||||||
self.action = action
|
self.action = action
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Installs observation.
|
/// Add observer.
|
||||||
@discardableResult
|
@discardableResult
|
||||||
static func observe(
|
static func observe(
|
||||||
_ object: AnyObject,
|
_ object: AnyObject,
|
||||||
|
@ -35,7 +35,7 @@ class DeinitObserver {
|
||||||
return observer
|
return observer
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Uninstalls observation.
|
/// Remove observer.
|
||||||
func cancel() {
|
func cancel() {
|
||||||
action = nil
|
action = nil
|
||||||
if let o = observed {
|
if let o = observed {
|
||||||
|
|
|
@ -58,7 +58,7 @@ extension Interval: CustomStringConvertible {
|
||||||
|
|
||||||
/// A textual representation of this interval.
|
/// A textual representation of this interval.
|
||||||
///
|
///
|
||||||
/// Interval: 1000 nanoseconds
|
/// "Interval: 1000 nanoseconds"
|
||||||
public var description: String {
|
public var description: String {
|
||||||
return "Interval: \(nanoseconds.clampedToInt()) nanoseconds"
|
return "Interval: \(nanoseconds.clampedToInt()) nanoseconds"
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ extension Interval: CustomDebugStringConvertible {
|
||||||
|
|
||||||
/// A textual representation of this interval for debugging.
|
/// A textual representation of this interval for debugging.
|
||||||
///
|
///
|
||||||
/// Interval: 1000 nanoseconds
|
/// "Interval: 1000 nanoseconds"
|
||||||
public var debugDescription: String {
|
public var debugDescription: String {
|
||||||
return description
|
return description
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,8 @@ extension Interval: Comparable {
|
||||||
|
|
||||||
/// Compares two intervals.
|
/// Compares two intervals.
|
||||||
///
|
///
|
||||||
/// A positive interval is always ordered ascending to a negative interval.
|
/// The comparison is magnitude independent, a positive interval is
|
||||||
|
/// always ordered ascending to a negative interval.
|
||||||
public func compare(_ other: Interval) -> ComparisonResult {
|
public func compare(_ other: Interval) -> ComparisonResult {
|
||||||
let now = Date()
|
let now = Date()
|
||||||
return now.adding(self).compare(now.adding(other))
|
return now.adding(self).compare(now.adding(other))
|
||||||
|
@ -106,26 +107,22 @@ extension Interval: Comparable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the longest interval of the given values.
|
/// Returns the longest interval of the given values.
|
||||||
/// - Note: Returns initialized with `init(nanoseconds: 0)` if given no parameters.
|
|
||||||
public static func longest(_ intervals: Interval...) -> Interval {
|
public static func longest(_ intervals: Interval...) -> Interval {
|
||||||
return longest(intervals)!
|
return longest(intervals)!
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the longest interval of the given values.
|
/// Returns the longest interval of the given values.
|
||||||
/// - Note: Returns initialized with `init(nanoseconds: 0)` if given an empty array.
|
|
||||||
public static func longest(_ intervals: [Interval]) -> Interval? {
|
public static func longest(_ intervals: [Interval]) -> Interval? {
|
||||||
guard !intervals.isEmpty else { return nil }
|
guard !intervals.isEmpty else { return nil }
|
||||||
return intervals.sorted(by: { $0.magnitude > $1.magnitude })[0]
|
return intervals.sorted(by: { $0.magnitude > $1.magnitude })[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the shortest interval of the given values.
|
/// Returns the shortest interval of the given values.
|
||||||
/// - Note: Returns initialized with `init(nanoseconds: 0)` if given no parameters.
|
|
||||||
public static func shortest(_ intervals: Interval...) -> Interval {
|
public static func shortest(_ intervals: Interval...) -> Interval {
|
||||||
return shortest(intervals)!
|
return shortest(intervals)!
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the shortest interval of the given values.
|
/// Returns the shortest interval of the given values.
|
||||||
/// - Note: Returns initialized with `init(nanoseconds: 0)` if given an empty array.
|
|
||||||
public static func shortest(_ intervals: [Interval]) -> Interval? {
|
public static func shortest(_ intervals: [Interval]) -> Interval? {
|
||||||
guard !intervals.isEmpty else { return nil }
|
guard !intervals.isEmpty else { return nil }
|
||||||
return intervals.sorted(by: { $0.magnitude < $1.magnitude })[0]
|
return intervals.sorted(by: { $0.magnitude < $1.magnitude })[0]
|
||||||
|
@ -354,6 +351,7 @@ extension Date {
|
||||||
// MARK: - DispatchSourceTimer
|
// MARK: - DispatchSourceTimer
|
||||||
extension DispatchSourceTimer {
|
extension DispatchSourceTimer {
|
||||||
|
|
||||||
|
/// Schedule this timer later.
|
||||||
func schedule(after timeout: Interval) {
|
func schedule(after timeout: Interval) {
|
||||||
guard !timeout.isNegative else { return }
|
guard !timeout.isNegative else { return }
|
||||||
let ns = timeout.nanoseconds.clampedToInt()
|
let ns = timeout.nanoseconds.clampedToInt()
|
||||||
|
|
|
@ -28,6 +28,7 @@ public struct Period {
|
||||||
|
|
||||||
public private(set) var nanoseconds: Int
|
public private(set) var nanoseconds: Int
|
||||||
|
|
||||||
|
/// Initializes a period value, optional sepcifying values for its fields.
|
||||||
public init(years: Int = 0, months: Int = 0, days: Int = 0,
|
public init(years: Int = 0, months: Int = 0, days: Int = 0,
|
||||||
hours: Int = 0, minutes: Int = 0, seconds: Int = 0,
|
hours: Int = 0, minutes: Int = 0, seconds: Int = 0,
|
||||||
nanoseconds: Int = 0) {
|
nanoseconds: Int = 0) {
|
||||||
|
@ -200,7 +201,7 @@ extension Period: CustomStringConvertible {
|
||||||
|
|
||||||
/// A textual representation of this period.
|
/// A textual representation of this period.
|
||||||
///
|
///
|
||||||
/// Period: 1 year(s) 2 month(s) 3 day(s)
|
/// "Period: 1 year(s) 2 month(s) 3 day(s)"
|
||||||
public var description: String {
|
public var description: String {
|
||||||
let period = tidied(to: .day)
|
let period = tidied(to: .day)
|
||||||
var desc = "Period:"
|
var desc = "Period:"
|
||||||
|
@ -219,7 +220,7 @@ extension Period: CustomDebugStringConvertible {
|
||||||
|
|
||||||
/// A textual representation of this period for debugging.
|
/// A textual representation of this period for debugging.
|
||||||
///
|
///
|
||||||
/// Period: 1 year(s) 2 month(s) 3 day(s)
|
/// "Period: 1 year(s) 2 month(s) 3 day(s)"
|
||||||
public var debugDescription: String {
|
public var debugDescription: String {
|
||||||
return description
|
return description
|
||||||
}
|
}
|
||||||
|
|
|
@ -477,8 +477,10 @@ extension Plan {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Plan {
|
extension Plan {
|
||||||
|
|
||||||
|
/// Returns a Boolean value indicating whether this plan is empty.
|
||||||
public func isNever() -> Bool {
|
public func isNever() -> Bool {
|
||||||
return self.iSeq.makeIterator().next() == nil
|
return iSeq.makeIterator().next() == nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ extension BagKey {
|
||||||
/// `Task` represents a timed task.
|
/// `Task` represents a timed task.
|
||||||
open class Task {
|
open class Task {
|
||||||
|
|
||||||
|
/// The unique id of this task.
|
||||||
public let id = UUID()
|
public let id = UUID()
|
||||||
|
|
||||||
public typealias Action = (Task) -> Void
|
public typealias Action = (Task) -> Void
|
||||||
|
@ -44,9 +45,19 @@ open class Task {
|
||||||
return timer
|
return timer
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
/// The task center which this task currently in.
|
||||||
open internal(set) weak var taskCenter: TaskCenter?
|
open internal(set) weak var taskCenter: TaskCenter?
|
||||||
let taskCenterMutex = NSRecursiveLock()
|
|
||||||
|
|
||||||
|
/// The mutex used to guard task center operations.
|
||||||
|
let taskCenterMutex = NSLock()
|
||||||
|
|
||||||
|
|
||||||
|
/// Initializes a normal task with specified plan and dispatch queue.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - plan: The plan.
|
||||||
|
/// - queue: The dispatch queue to which all actions should be added.
|
||||||
|
/// - onElapse: The action to do when time is out.
|
||||||
init(plan: Plan,
|
init(plan: Plan,
|
||||||
queue: DispatchQueue?,
|
queue: DispatchQueue?,
|
||||||
onElapse: @escaping (Task) -> Void) {
|
onElapse: @escaping (Task) -> Void) {
|
||||||
|
@ -324,8 +335,10 @@ extension Task: CustomStringConvertible {
|
||||||
public var description: String {
|
public var description: String {
|
||||||
return "Task: { " +
|
return "Task: { " +
|
||||||
"\"isCancelled\": \(_timer.isCancelled), " +
|
"\"isCancelled\": \(_timer.isCancelled), " +
|
||||||
"\"countOfActions\": \(_onElapseActions.count), " +
|
"\"countOfElapseActions\": \(_onElapseActions.count), " +
|
||||||
|
"\"countOfDeinitActions\": \(_onDeinitActions.count), " +
|
||||||
"\"countOfExecutions\": \(_countOfExecutions), " +
|
"\"countOfExecutions\": \(_countOfExecutions), " +
|
||||||
|
"\"lifeTime\": \(_lifetime), " +
|
||||||
"\"timeline\": \(_timeline)" +
|
"\"timeline\": \(_timeline)" +
|
||||||
" }"
|
" }"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ extension TaskCenter {
|
||||||
|
|
||||||
weak var task: Task?
|
weak var task: Task?
|
||||||
|
|
||||||
// To find slot
|
// Used to find slot
|
||||||
let hash: Int
|
let hash: Int
|
||||||
|
|
||||||
init(_ task: Task) {
|
init(_ task: Task) {
|
||||||
|
@ -20,16 +20,17 @@ extension TaskCenter {
|
||||||
hasher.combine(hash)
|
hasher.combine(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// To find task
|
// Used to find task
|
||||||
static func == (lhs: TaskBox, rhs: TaskBox) -> Bool {
|
static func == (lhs: TaskBox, rhs: TaskBox) -> Bool {
|
||||||
return lhs.task == rhs.task
|
return lhs.task == rhs.task
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A task mamanger that enables batch tasks operation.
|
||||||
open class TaskCenter {
|
open class TaskCenter {
|
||||||
|
|
||||||
private let mutex = NSRecursiveLock()
|
private let mutex = NSLock()
|
||||||
|
|
||||||
private var taskMap: [String: Set<TaskBox>] = [:]
|
private var taskMap: [String: Set<TaskBox>] = [:]
|
||||||
private var tagMap: [TaskBox: Set<String>] = [:]
|
private var tagMap: [TaskBox: Set<String>] = [:]
|
||||||
|
@ -38,11 +39,11 @@ open class TaskCenter {
|
||||||
return _default
|
return _default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a task to this center.
|
||||||
|
///
|
||||||
|
/// Center won't retain the task.
|
||||||
open func add(_ task: Task) {
|
open func add(_ task: Task) {
|
||||||
task.taskCenterMutex.lock()
|
task.taskCenterMutex.lock()
|
||||||
defer {
|
|
||||||
task.taskCenterMutex.unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
if let center = task.taskCenter {
|
if let center = task.taskCenter {
|
||||||
if center === self { return }
|
if center === self { return }
|
||||||
|
@ -50,6 +51,8 @@ open class TaskCenter {
|
||||||
}
|
}
|
||||||
task.taskCenter = self
|
task.taskCenter = self
|
||||||
|
|
||||||
|
task.taskCenterMutex.unlock()
|
||||||
|
|
||||||
mutex.withLock {
|
mutex.withLock {
|
||||||
let box = TaskBox(task)
|
let box = TaskBox(task)
|
||||||
tagMap[box] = []
|
tagMap[box] = []
|
||||||
|
@ -61,17 +64,17 @@ open class TaskCenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes a task from this center.
|
||||||
open func remove(_ task: Task) {
|
open func remove(_ task: Task) {
|
||||||
task.taskCenterMutex.lock()
|
task.taskCenterMutex.lock()
|
||||||
defer {
|
|
||||||
task.taskCenterMutex.unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
guard task.taskCenter === self else {
|
guard task.taskCenter === self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
task.taskCenter = nil
|
task.taskCenter = nil
|
||||||
|
|
||||||
|
task.taskCenterMutex.unlock()
|
||||||
|
|
||||||
mutex.withLock {
|
mutex.withLock {
|
||||||
let box = TaskBox(task)
|
let box = TaskBox(task)
|
||||||
if let tags = self.tagMap[box] {
|
if let tags = self.tagMap[box] {
|
||||||
|
@ -83,10 +86,16 @@ open class TaskCenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a tag to the task.
|
||||||
|
///
|
||||||
|
/// If the task is not in this center, do nothing.
|
||||||
open func addTag(_ tag: String, to task: Task) {
|
open func addTag(_ tag: String, to task: Task) {
|
||||||
addTags([tag], to: task)
|
addTags([tag], to: task)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds tags to the task.
|
||||||
|
///
|
||||||
|
/// If the task is not in this center, do nothing.
|
||||||
open func addTags(_ tags: [String], to task: Task) {
|
open func addTags(_ tags: [String], to task: Task) {
|
||||||
guard task.taskCenter === self else { return }
|
guard task.taskCenter === self else { return }
|
||||||
|
|
||||||
|
@ -105,10 +114,16 @@ open class TaskCenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes a tag from the task.
|
||||||
|
///
|
||||||
|
/// If the task is not in this center, do nothing.
|
||||||
open func removeTag(_ tag: String, from task: Task) {
|
open func removeTag(_ tag: String, from task: Task) {
|
||||||
removeTags([tag], from: task)
|
removeTags([tag], from: task)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes tags from the task.
|
||||||
|
///
|
||||||
|
/// If the task is not in this center, do nothing.
|
||||||
open func removeTags(_ tags: [String], from task: Task) {
|
open func removeTags(_ tags: [String], from task: Task) {
|
||||||
guard task.taskCenter === self else { return }
|
guard task.taskCenter === self else { return }
|
||||||
|
|
||||||
|
@ -121,6 +136,9 @@ open class TaskCenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns all tags on the task.
|
||||||
|
///
|
||||||
|
/// If the task is not in this center, return an empty array.
|
||||||
open func tagsForTask(_ task: Task) -> [String] {
|
open func tagsForTask(_ task: Task) -> [String] {
|
||||||
guard task.taskCenter === self else { return [] }
|
guard task.taskCenter === self else { return [] }
|
||||||
|
|
||||||
|
@ -129,24 +147,28 @@ open class TaskCenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns all tasks that have the tag.
|
||||||
open func tasksForTag(_ tag: String) -> [Task] {
|
open func tasksForTag(_ tag: String) -> [Task] {
|
||||||
return mutex.withLock {
|
return mutex.withLock {
|
||||||
taskMap[tag]?.compactMap { $0.task } ?? []
|
taskMap[tag]?.compactMap { $0.task } ?? []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns all tasks in this center.
|
||||||
open var allTasks: [Task] {
|
open var allTasks: [Task] {
|
||||||
return mutex.withLock {
|
return mutex.withLock {
|
||||||
tagMap.compactMap { $0.key.task }
|
tagMap.compactMap { $0.key.task }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns all existing tags in this center.
|
||||||
open var allTags: [String] {
|
open var allTags: [String] {
|
||||||
return mutex.withLock {
|
return mutex.withLock {
|
||||||
taskMap.map { $0.key }
|
taskMap.map { $0.key }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes all tasks in this center.
|
||||||
open func clear() {
|
open func clear() {
|
||||||
mutex.withLock {
|
mutex.withLock {
|
||||||
tagMap = [:]
|
tagMap = [:]
|
||||||
|
@ -154,14 +176,17 @@ open class TaskCenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Suspends all tasks that have the tag.
|
||||||
open func suspendByTag(_ tag: String) {
|
open func suspendByTag(_ tag: String) {
|
||||||
tasksForTag(tag).forEach { $0.suspend() }
|
tasksForTag(tag).forEach { $0.suspend() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resumes all tasks that have the tag.
|
||||||
open func resumeByTag(_ tag: String) {
|
open func resumeByTag(_ tag: String) {
|
||||||
tasksForTag(tag).forEach { $0.resume() }
|
tasksForTag(tag).forEach { $0.resume() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cancels all tasks that have the tag.
|
||||||
open func cancelByTag(_ tag: String) {
|
open func cancelByTag(_ tag: String) {
|
||||||
tasksForTag(tag).forEach { $0.cancel() }
|
tasksForTag(tag).forEach { $0.cancel() }
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ extension Weekday: CustomStringConvertible {
|
||||||
|
|
||||||
/// A textual representation of this weekday.
|
/// A textual representation of this weekday.
|
||||||
///
|
///
|
||||||
/// Weekday: Friday
|
/// "Weekday: Friday"
|
||||||
public var description: String {
|
public var description: String {
|
||||||
return "Weekday: \(Calendar.gregorian.weekdaySymbols[rawValue - 1])"
|
return "Weekday: \(Calendar.gregorian.weekdaySymbols[rawValue - 1])"
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ extension Weekday: CustomDebugStringConvertible {
|
||||||
|
|
||||||
/// A textual representation of this weekday for debugging.
|
/// A textual representation of this weekday for debugging.
|
||||||
///
|
///
|
||||||
/// Weekday: Friday
|
/// "Weekday: Friday"
|
||||||
public var debugDescription: String {
|
public var debugDescription: String {
|
||||||
return description
|
return description
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue