Improves documentations
This commit is contained in:
parent
34cac2aab8
commit
7de73c72a0
|
@ -1,6 +1,6 @@
|
|||
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 {
|
||||
|
||||
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 k2 = gen.next()
|
||||
|
@ -26,7 +26,7 @@ struct BagKeyGenerator: Sequence, IteratorProtocol {
|
|||
|
||||
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? {
|
||||
if k.i == UInt64.max {
|
||||
return nil
|
||||
|
@ -95,6 +95,7 @@ struct Bag<Element> {
|
|||
|
||||
extension Bag: Sequence {
|
||||
|
||||
/// Returns an iterator over the elements of this containers.
|
||||
func makeIterator() -> AnyIterator<Element> {
|
||||
var iterator = entries.makeIterator()
|
||||
return AnyIterator<Element> {
|
||||
|
|
|
@ -21,7 +21,7 @@ class DeinitObserver {
|
|||
self.action = action
|
||||
}
|
||||
|
||||
/// Installs observation.
|
||||
/// Add observer.
|
||||
@discardableResult
|
||||
static func observe(
|
||||
_ object: AnyObject,
|
||||
|
@ -35,7 +35,7 @@ class DeinitObserver {
|
|||
return observer
|
||||
}
|
||||
|
||||
/// Uninstalls observation.
|
||||
/// Remove observer.
|
||||
func cancel() {
|
||||
action = nil
|
||||
if let o = observed {
|
||||
|
|
|
@ -58,7 +58,7 @@ extension Interval: CustomStringConvertible {
|
|||
|
||||
/// A textual representation of this interval.
|
||||
///
|
||||
/// Interval: 1000 nanoseconds
|
||||
/// "Interval: 1000 nanoseconds"
|
||||
public var description: String {
|
||||
return "Interval: \(nanoseconds.clampedToInt()) nanoseconds"
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ extension Interval: CustomDebugStringConvertible {
|
|||
|
||||
/// A textual representation of this interval for debugging.
|
||||
///
|
||||
/// Interval: 1000 nanoseconds
|
||||
/// "Interval: 1000 nanoseconds"
|
||||
public var debugDescription: String {
|
||||
return description
|
||||
}
|
||||
|
@ -79,7 +79,8 @@ extension Interval: Comparable {
|
|||
|
||||
/// 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 {
|
||||
let now = Date()
|
||||
return now.adding(self).compare(now.adding(other))
|
||||
|
@ -106,26 +107,22 @@ extension Interval: Comparable {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
return longest(intervals)!
|
||||
}
|
||||
|
||||
/// 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? {
|
||||
guard !intervals.isEmpty else { return nil }
|
||||
return intervals.sorted(by: { $0.magnitude > $1.magnitude })[0]
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
return shortest(intervals)!
|
||||
}
|
||||
|
||||
/// 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? {
|
||||
guard !intervals.isEmpty else { return nil }
|
||||
return intervals.sorted(by: { $0.magnitude < $1.magnitude })[0]
|
||||
|
@ -354,6 +351,7 @@ extension Date {
|
|||
// MARK: - DispatchSourceTimer
|
||||
extension DispatchSourceTimer {
|
||||
|
||||
/// Schedule this timer later.
|
||||
func schedule(after timeout: Interval) {
|
||||
guard !timeout.isNegative else { return }
|
||||
let ns = timeout.nanoseconds.clampedToInt()
|
||||
|
|
|
@ -28,6 +28,7 @@ public struct Period {
|
|||
|
||||
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,
|
||||
hours: Int = 0, minutes: Int = 0, seconds: Int = 0,
|
||||
nanoseconds: Int = 0) {
|
||||
|
@ -200,7 +201,7 @@ extension Period: CustomStringConvertible {
|
|||
|
||||
/// 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 {
|
||||
let period = tidied(to: .day)
|
||||
var desc = "Period:"
|
||||
|
@ -219,7 +220,7 @@ extension Period: CustomDebugStringConvertible {
|
|||
|
||||
/// 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 {
|
||||
return description
|
||||
}
|
||||
|
|
|
@ -477,8 +477,10 @@ extension Plan {
|
|||
}
|
||||
|
||||
extension Plan {
|
||||
|
||||
/// Returns a Boolean value indicating whether this plan is empty.
|
||||
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.
|
||||
open class Task {
|
||||
|
||||
/// The unique id of this task.
|
||||
public let id = UUID()
|
||||
|
||||
public typealias Action = (Task) -> Void
|
||||
|
@ -44,9 +45,19 @@ open class Task {
|
|||
return timer
|
||||
}()
|
||||
|
||||
/// The task center which this task currently in.
|
||||
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,
|
||||
queue: DispatchQueue?,
|
||||
onElapse: @escaping (Task) -> Void) {
|
||||
|
@ -324,8 +335,10 @@ extension Task: CustomStringConvertible {
|
|||
public var description: String {
|
||||
return "Task: { " +
|
||||
"\"isCancelled\": \(_timer.isCancelled), " +
|
||||
"\"countOfActions\": \(_onElapseActions.count), " +
|
||||
"\"countOfElapseActions\": \(_onElapseActions.count), " +
|
||||
"\"countOfDeinitActions\": \(_onDeinitActions.count), " +
|
||||
"\"countOfExecutions\": \(_countOfExecutions), " +
|
||||
"\"lifeTime\": \(_lifetime), " +
|
||||
"\"timeline\": \(_timeline)" +
|
||||
" }"
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ extension TaskCenter {
|
|||
|
||||
weak var task: Task?
|
||||
|
||||
// To find slot
|
||||
// Used to find slot
|
||||
let hash: Int
|
||||
|
||||
init(_ task: Task) {
|
||||
|
@ -20,16 +20,17 @@ extension TaskCenter {
|
|||
hasher.combine(hash)
|
||||
}
|
||||
|
||||
// To find task
|
||||
// Used to find task
|
||||
static func == (lhs: TaskBox, rhs: TaskBox) -> Bool {
|
||||
return lhs.task == rhs.task
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A task mamanger that enables batch tasks operation.
|
||||
open class TaskCenter {
|
||||
|
||||
private let mutex = NSRecursiveLock()
|
||||
private let mutex = NSLock()
|
||||
|
||||
private var taskMap: [String: Set<TaskBox>] = [:]
|
||||
private var tagMap: [TaskBox: Set<String>] = [:]
|
||||
|
@ -38,11 +39,11 @@ open class TaskCenter {
|
|||
return _default
|
||||
}
|
||||
|
||||
/// Adds a task to this center.
|
||||
///
|
||||
/// Center won't retain the task.
|
||||
open func add(_ task: Task) {
|
||||
task.taskCenterMutex.lock()
|
||||
defer {
|
||||
task.taskCenterMutex.unlock()
|
||||
}
|
||||
|
||||
if let center = task.taskCenter {
|
||||
if center === self { return }
|
||||
|
@ -50,6 +51,8 @@ open class TaskCenter {
|
|||
}
|
||||
task.taskCenter = self
|
||||
|
||||
task.taskCenterMutex.unlock()
|
||||
|
||||
mutex.withLock {
|
||||
let box = TaskBox(task)
|
||||
tagMap[box] = []
|
||||
|
@ -61,17 +64,17 @@ open class TaskCenter {
|
|||
}
|
||||
}
|
||||
|
||||
/// Removes a task from this center.
|
||||
open func remove(_ task: Task) {
|
||||
task.taskCenterMutex.lock()
|
||||
defer {
|
||||
task.taskCenterMutex.unlock()
|
||||
}
|
||||
|
||||
guard task.taskCenter === self else {
|
||||
return
|
||||
}
|
||||
task.taskCenter = nil
|
||||
|
||||
task.taskCenterMutex.unlock()
|
||||
|
||||
mutex.withLock {
|
||||
let box = TaskBox(task)
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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] {
|
||||
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] {
|
||||
return mutex.withLock {
|
||||
taskMap[tag]?.compactMap { $0.task } ?? []
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all tasks in this center.
|
||||
open var allTasks: [Task] {
|
||||
return mutex.withLock {
|
||||
tagMap.compactMap { $0.key.task }
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all existing tags in this center.
|
||||
open var allTags: [String] {
|
||||
return mutex.withLock {
|
||||
taskMap.map { $0.key }
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes all tasks in this center.
|
||||
open func clear() {
|
||||
mutex.withLock {
|
||||
tagMap = [:]
|
||||
|
@ -154,14 +176,17 @@ open class TaskCenter {
|
|||
}
|
||||
}
|
||||
|
||||
/// Suspends all tasks that have the tag.
|
||||
open func suspendByTag(_ tag: String) {
|
||||
tasksForTag(tag).forEach { $0.suspend() }
|
||||
}
|
||||
|
||||
/// Resumes all tasks that have the tag.
|
||||
open func resumeByTag(_ tag: String) {
|
||||
tasksForTag(tag).forEach { $0.resume() }
|
||||
}
|
||||
|
||||
/// Cancels all tasks that have the tag.
|
||||
open func cancelByTag(_ tag: String) {
|
||||
tasksForTag(tag).forEach { $0.cancel() }
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ extension Weekday: CustomStringConvertible {
|
|||
|
||||
/// A textual representation of this weekday.
|
||||
///
|
||||
/// Weekday: Friday
|
||||
/// "Weekday: Friday"
|
||||
public var description: String {
|
||||
return "Weekday: \(Calendar.gregorian.weekdaySymbols[rawValue - 1])"
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ extension Weekday: CustomDebugStringConvertible {
|
|||
|
||||
/// A textual representation of this weekday for debugging.
|
||||
///
|
||||
/// Weekday: Friday
|
||||
/// "Weekday: Friday"
|
||||
public var debugDescription: String {
|
||||
return description
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue