0001 // 0002 // VirtualTimeScheduler.swift 0003 // Rx 0004 // 0005 // Created by Krunoslav Zaher on 2/14/15. 0006 // Copyright © 2015 Krunoslav Zaher. All rights reserved. 0007 // 0008 0009 import Foundation 0010 0011 /** 0012 Base class for virtual time schedulers using a priority queue for scheduled items. 0013 */ 0014 public class VirtualTimeScheduler<Converter
HistoricalScheduler.swift:14 public class HistoricalScheduler : VirtualTimeScheduler<HistoricalSchedulerTimeConverter> {VirtualTimeScheduler.swift:249 extension VirtualTimeScheduler {: VirtualTimeConverterType> 0015 : SchedulerType 0016 , CustomDebugStringConvertible { 0017 0018 public typealias VirtualTime
VirtualTimeScheduler.swift:18 public typealias VirtualTime = Converter.VirtualTimeUnitVirtualTimeScheduler.swift:19 public typealias VirtualTimeInterval = Converter.VirtualTimeIntervalUnitVirtualTimeScheduler.swift:26 private var _converter: ConverterVirtualTimeScheduler.swift:49 public init(initialClock: VirtualTime, converter: Converter) {VirtualTimeScheduler.swift:117 public func scheduleAbsoluteVirtual<StateType>(state: StateType, time: Converter.VirtualTimeUnit, action: StateType -> Disposable) -> Disposable {VirtualTimeScheduler.swift:139 public func adjustScheduledTime(time: Converter.VirtualTimeUnit) -> Converter.VirtualTimeUnit {VirtualTimeScheduler.swift:139 public func adjustScheduledTime(time: Converter.VirtualTimeUnit) -> Converter.VirtualTimeUnit {= Converter.VirtualTimeUnit 0019 public typealias VirtualTimeInterval
VirtualTimeScheduler.swift:23 private var _clock: VirtualTimeVirtualTimeScheduler.swift:25 private var _schedulerQueue : PriorityQueue<VirtualSchedulerItem<VirtualTime>>VirtualTimeScheduler.swift:40 public var clock: VirtualTime {VirtualTimeScheduler.swift:49 public init(initialClock: VirtualTime, converter: Converter) {VirtualTimeScheduler.swift:170 func findNext() -> VirtualSchedulerItem<VirtualTime>? {VirtualTimeScheduler.swift:188 public func advanceTo(virtualTime: VirtualTime) {= Converter.VirtualTimeIntervalUnit 0020 0021 private var _running
VirtualTimeScheduler.swift:104 public func scheduleRelativeVirtual<StateType>(state: StateType, dueTime: VirtualTimeInterval, action: StateType -> Disposable) -> Disposable {VirtualTimeScheduler.swift:220 public func sleep(virtualInterval: VirtualTimeInterval) {: Bool 0022 0023 private var _clock
VirtualTimeScheduler.swift:51 _running = falseVirtualTimeScheduler.swift:149 if _running {VirtualTimeScheduler.swift:153 _running = trueVirtualTimeScheduler.swift:165 } while _runningVirtualTimeScheduler.swift:167 _running = falseVirtualTimeScheduler.swift:191 if _running {VirtualTimeScheduler.swift:195 _running = trueVirtualTimeScheduler.swift:211 } while _runningVirtualTimeScheduler.swift:214 _running = falseVirtualTimeScheduler.swift:237 _running = false: VirtualTime 0024 0025 private var _schedulerQueue
VirtualTimeScheduler.swift:41 return _clockVirtualTimeScheduler.swift:50 _clock = initialClockVirtualTimeScheduler.swift:160 _clock = next.timeVirtualTimeScheduler.swift:206 _clock = next.timeVirtualTimeScheduler.swift:213 _clock = virtualTimeVirtualTimeScheduler.swift:228 _clock = sleepTo: PriorityQueue<VirtualSchedulerItem<VirtualTime>> 0026 private var _converter
VirtualTimeScheduler.swift:53 _schedulerQueue = PriorityQueue(hasHigherPriority: {VirtualTimeScheduler.swift:129 _schedulerQueue.enqueue(item)VirtualTimeScheduler.swift:164 _schedulerQueue.remove(next)VirtualTimeScheduler.swift:171 while let front = _schedulerQueue.peek() {VirtualTimeScheduler.swift:173 _schedulerQueue.remove(front)VirtualTimeScheduler.swift:210 _schedulerQueue.remove(next)VirtualTimeScheduler.swift:255 return self._schedulerQueue.debugDescription: Converter 0027 0028 private var _nextId
VirtualTimeScheduler.swift:34 return _converter.convertFromVirtualTime(clock)VirtualTimeScheduler.swift:52 _converter = converterVirtualTimeScheduler.swift:91 let absoluteTime = _converter.convertToVirtualTime(time)VirtualTimeScheduler.swift:105 let time = _converter.offsetVirtualTime(time: self.clock, offset: dueTime)VirtualTimeScheduler.swift:159 if _converter.compareVirtualTime(next.time, self.clock).greaterThan {VirtualTimeScheduler.swift:201 if _converter.compareVirtualTime(next.time, virtualTime).greaterThan {VirtualTimeScheduler.swift:205 if _converter.compareVirtualTime(next.time, self.clock).greaterThan {VirtualTimeScheduler.swift:223 let sleepTo = _converter.offsetVirtualTime(time: clock, offset: virtualInterval)VirtualTimeScheduler.swift:224 if _converter.compareVirtualTime(sleepTo, clock).lessThen {= 0 0029 0030 /** 0031 - returns: Current time. 0032 */ 0033 public var now
VirtualTimeScheduler.swift:125 }, time: time, id: _nextId)VirtualTimeScheduler.swift:127 _nextId += 1: RxTime { 0034 return _converter.convertFromVirtualTime(clock) 0035 } 0036 0037 /** 0038 - returns: Scheduler's absolute time clock value. 0039 */ 0040 public var clock
VirtualTimeScheduler.swift:90 let time = self.now.dateByAddingTimeInterval(dueTime): VirtualTime { 0041 return _clock 0042 } 0043 0044 /** 0045 Creates a new virtual time scheduler. 0046 0047 - parameter initialClock: Initial value for the clock. 0048 */ 0049 public init
VirtualTimeScheduler.swift:34 return _converter.convertFromVirtualTime(clock)VirtualTimeScheduler.swift:105 let time = _converter.offsetVirtualTime(time: self.clock, offset: dueTime)VirtualTimeScheduler.swift:159 if _converter.compareVirtualTime(next.time, self.clock).greaterThan {VirtualTimeScheduler.swift:205 if _converter.compareVirtualTime(next.time, self.clock).greaterThan {VirtualTimeScheduler.swift:223 let sleepTo = _converter.offsetVirtualTime(time: clock, offset: virtualInterval)VirtualTimeScheduler.swift:224 if _converter.compareVirtualTime(sleepTo, clock).lessThen {(initialClock: VirtualTime, converter: Converter) { 0050 _clock = initialClock 0051 _running = false 0052 _converter = converter 0053 _schedulerQueue = PriorityQueue(hasHigherPriority: { 0054 switch converter.compareVirtualTime($0.time, $1.time) { 0055 case .LessThan: 0056 return true 0057 case .Equal: 0058 return $0.id < $1.id 0059 case .GreaterThan: 0060 return false 0061 } 0062 }) 0063 #if TRACE_RESOURCES 0064 AtomicIncrement(&resourceCount) 0065 #endif 0066 } 0067 0068 /** 0069 Schedules an action to be executed immediatelly. 0070 0071 - parameter state: State passed to the action to be executed. 0072 - parameter action: Action to be executed. 0073 - returns: The disposable object used to cancel the scheduled action (best effort). 0074 */ 0075 public func schedule<StateType>(state: StateType, action: StateType -> Disposable) -> Disposable { 0076 return self.scheduleRelative(state, dueTime: 0.0) { a in 0077 return action(a) 0078 } 0079 } 0080 0081 /** 0082 Schedules an action to be executed. 0083 0084 - parameter state: State passed to the action to be executed. 0085 - parameter dueTime: Relative time after which to execute the action. 0086 - parameter action: Action to be executed. 0087 - returns: The disposable object used to cancel the scheduled action (best effort). 0088 */ 0089 public func scheduleRelative
HistoricalScheduler.swift:22 super.init(initialClock: initialClock, converter: HistoricalSchedulerTimeConverter())<StateType>(state: StateType, dueTime: RxTimeInterval, action: StateType -> Disposable) -> Disposable { 0090 let time = self.now.dateByAddingTimeInterval(dueTime) 0091 let absoluteTime = _converter.convertToVirtualTime(time) 0092 let adjustedTime = self.adjustScheduledTime(absoluteTime) 0093 return scheduleAbsoluteVirtual(state, time: adjustedTime, action: action) 0094 } 0095 0096 /** 0097 Schedules an action to be executed after relative time has passed. 0098 0099 - parameter state: State passed to the action to be executed. 0100 - parameter time: Absolute time when to execute the action. If this is less or equal then `now`, `now + 1` will be used. 0101 - parameter action: Action to be executed. 0102 - returns: The disposable object used to cancel the scheduled action (best effort). 0103 */ 0104 public func scheduleRelativeVirtual<StateType>(state: StateType, dueTime: VirtualTimeInterval, action: StateType -> Disposable) -> Disposable { 0105 let time = _converter.offsetVirtualTime(time: self.clock, offset: dueTime) 0106 return scheduleAbsoluteVirtual(state, time: time, action: action) 0107 } 0108 0109 /** 0110 Schedules an action to be executed at absolute virtual time. 0111 0112 - parameter state: State passed to the action to be executed. 0113 - parameter time: Absolute time when to execute the action. 0114 - parameter action: Action to be executed. 0115 - returns: The disposable object used to cancel the scheduled action (best effort). 0116 */ 0117 public func scheduleAbsoluteVirtual
VirtualTimeScheduler.swift:76 return self.scheduleRelative(state, dueTime: 0.0) { a in<StateType>(state: StateType, time: Converter.VirtualTimeUnit, action: StateType -> Disposable) -> Disposable { 0118 MainScheduler.ensureExecutingOnScheduler() 0119 0120 let compositeDisposable = CompositeDisposable() 0121 0122 let item = VirtualSchedulerItem(action: { 0123 let dispose = action(state) 0124 return dispose 0125 }, time: time, id: _nextId) 0126 0127 _nextId += 1 0128 0129 _schedulerQueue.enqueue(item) 0130 0131 compositeDisposable.addDisposable(item) 0132 0133 return compositeDisposable 0134 } 0135 0136 /** 0137 Adjusts time of scheduling before adding item to schedule queue. 0138 */ 0139 public func adjustScheduledTime
VirtualTimeScheduler.swift:93 return scheduleAbsoluteVirtual(state, time: adjustedTime, action: action)VirtualTimeScheduler.swift:106 return scheduleAbsoluteVirtual(state, time: time, action: action)(time: Converter.VirtualTimeUnit) -> Converter.VirtualTimeUnit { 0140 return time 0141 } 0142 0143 /** 0144 Starts the virtual time scheduler. 0145 */ 0146 public func start() { 0147 MainScheduler.ensureExecutingOnScheduler() 0148 0149 if _running { 0150 return 0151 } 0152 0153 _running = true 0154 repeat { 0155 guard let next = findNext() else { 0156 break 0157 } 0158 0159 if _converter.compareVirtualTime(next.time, self.clock).greaterThan { 0160 _clock = next.time 0161 } 0162 0163 next.invoke() 0164 _schedulerQueue.remove(next) 0165 } while _running 0166 0167 _running = false 0168 } 0169 0170 func findNext
VirtualTimeScheduler.swift:92 let adjustedTime = self.adjustScheduledTime(absoluteTime)() -> VirtualSchedulerItem<VirtualTime>? { 0171 while let front = _schedulerQueue.peek() { 0172 if front.disposed { 0173 _schedulerQueue.remove(front) 0174 continue 0175 } 0176 0177 return front 0178 } 0179 0180 return nil 0181 } 0182 0183 /** 0184 Advances the scheduler's clock to the specified time, running all work till that point. 0185 0186 - parameter virtualTime: Absolute time to advance the scheduler's clock to. 0187 */ 0188 public func advanceTo(virtualTime: VirtualTime) { 0189 MainScheduler.ensureExecutingOnScheduler() 0190 0191 if _running { 0192 fatalError("Scheduler is already running") 0193 } 0194 0195 _running = true 0196 repeat { 0197 guard let next = findNext() else { 0198 break 0199 } 0200 0201 if _converter.compareVirtualTime(next.time, virtualTime).greaterThan { 0202 break 0203 } 0204 0205 if _converter.compareVirtualTime(next.time, self.clock).greaterThan { 0206 _clock = next.time 0207 } 0208 0209 next.invoke() 0210 _schedulerQueue.remove(next) 0211 } while _running 0212 0213 _clock = virtualTime 0214 _running = false 0215 } 0216 0217 /** 0218 Advances the scheduler's clock by the specified relative time. 0219 */ 0220 public func sleep(virtualInterval: VirtualTimeInterval) { 0221 MainScheduler.ensureExecutingOnScheduler() 0222 0223 let sleepTo = _converter.offsetVirtualTime(time: clock, offset: virtualInterval) 0224 if _converter.compareVirtualTime(sleepTo, clock).lessThen { 0225 fatalError("Can't sleep to past.") 0226 } 0227 0228 _clock = sleepTo 0229 } 0230 0231 /** 0232 Stops the virtual time scheduler. 0233 */ 0234 public func stop() { 0235 MainScheduler.ensureExecutingOnScheduler() 0236 0237 _running = false 0238 } 0239 0240 #if TRACE_RESOURCES 0241 deinit { 0242 AtomicDecrement(&resourceCount) 0243 } 0244 #endif 0245 } 0246 0247 // MARK: description 0248 0249 extension VirtualTimeScheduler { 0250 /** 0251 A textual representation of `self`, suitable for debugging. 0252 */ 0253 public var debugDescription: String { 0254 get { 0255 return self._schedulerQueue.debugDescription 0256 } 0257 } 0258 } 0259 0260 class VirtualSchedulerItem
VirtualTimeScheduler.swift:155 guard let next = findNext() else {VirtualTimeScheduler.swift:197 guard let next = findNext() else {<Time
VirtualTimeScheduler.swift:25 private var _schedulerQueue : PriorityQueue<VirtualSchedulerItem<VirtualTime>>VirtualTimeScheduler.swift:122 let item = VirtualSchedulerItem(action: {VirtualTimeScheduler.swift:170 func findNext() -> VirtualSchedulerItem<VirtualTime>? {VirtualTimeScheduler.swift:291 extension VirtualSchedulerItem> 0261 : Disposable { 0262 typealias Action
VirtualTimeScheduler.swift:265 let time: TimeVirtualTimeScheduler.swift:276 init(action: Action, time: Time, id: Int) {= () -> Disposable 0263 0264 let action
VirtualTimeScheduler.swift:264 let action: ActionVirtualTimeScheduler.swift:276 init(action: Action, time: Time, id: Int) {: Action 0265 let time
VirtualTimeScheduler.swift:277 self.action = actionVirtualTimeScheduler.swift:283 self.disposable.disposable = action(): Time 0266 let id
VirtualTimeScheduler.swift:54 switch converter.compareVirtualTime($0.time, $1.time) {VirtualTimeScheduler.swift:54 switch converter.compareVirtualTime($0.time, $1.time) {VirtualTimeScheduler.swift:159 if _converter.compareVirtualTime(next.time, self.clock).greaterThan {VirtualTimeScheduler.swift:160 _clock = next.timeVirtualTimeScheduler.swift:201 if _converter.compareVirtualTime(next.time, virtualTime).greaterThan {VirtualTimeScheduler.swift:205 if _converter.compareVirtualTime(next.time, self.clock).greaterThan {VirtualTimeScheduler.swift:206 _clock = next.timeVirtualTimeScheduler.swift:278 self.time = timeVirtualTimeScheduler.swift:294 return "\(time)": Int 0267 0268 var disposed
VirtualTimeScheduler.swift:58 return $0.id < $1.idVirtualTimeScheduler.swift:58 return $0.id < $1.idVirtualTimeScheduler.swift:279 self.id = id: Bool { 0269 get { 0270 return disposable.disposed 0271 } 0272 } 0273 0274 var disposable
VirtualTimeScheduler.swift:172 if front.disposed {= SingleAssignmentDisposable() 0275 0276 init
VirtualTimeScheduler.swift:270 return disposable.disposedVirtualTimeScheduler.swift:283 self.disposable.disposable = action()VirtualTimeScheduler.swift:287 self.disposable.dispose()(action: Action, time: Time, id: Int) { 0277 self.action = action 0278 self.time = time 0279 self.id = id 0280 } 0281 0282 func invoke
VirtualTimeScheduler.swift:122 let item = VirtualSchedulerItem(action: {() { 0283 self.disposable.disposable = action() 0284 } 0285 0286 func dispose() { 0287 self.disposable.dispose() 0288 } 0289 } 0290 0291 extension VirtualSchedulerItem 0292 : CustomDebugStringConvertible { 0293 var debugDescription: String { 0294 return "\(time)" 0295 } 0296 }
VirtualTimeScheduler.swift:163 next.invoke()VirtualTimeScheduler.swift:209 next.invoke()