@@ -208,12 +208,165 @@ extension RunLoop {
208
208
}
209
209
}
210
210
211
- // SPI for XCTest
212
- #if os(Windows)
211
+ // These exist as SPI for XCTest for now. Do not rely on their contracts or continued existence.
212
+
213
213
extension RunLoop {
214
- public func _stop( ) {
215
- CFRunLoopStop ( getCFRunLoop ( ) )
216
- }
214
+ @available ( * , deprecated, message: " For XCTest use only. " )
215
+ public func _stop( ) {
216
+ CFRunLoopStop ( getCFRunLoop ( ) )
217
+ }
218
+
219
+ @available ( * , deprecated, message: " For XCTest use only. " )
220
+ public func _observe( _ activities: _Activities , in mode: RunLoop . Mode = . default, repeats: Bool = true , order: Int = 0 , handler: @escaping ( _Activity ) -> Void ) -> _Observer {
221
+ let observer = _Observer ( activities: activities, repeats: repeats, order: order, handler: handler)
222
+ CFRunLoopAddObserver ( self . getCFRunLoop ( ) , observer. cfObserver, mode. _cfStringUniquingKnown)
223
+ return observer
224
+ }
225
+
226
+ @available ( * , deprecated, message: " For XCTest use only. " )
227
+ public func _observe( _ activity: _Activity , in mode: RunLoop . Mode = . default, repeats: Bool = true , order: Int = 0 , handler: @escaping ( _Activity ) -> Void ) -> _Observer {
228
+ return _observe ( _Activities ( activity) , in: mode, repeats: repeats, order: order, handler: handler)
229
+ }
230
+
231
+ @available ( * , deprecated, message: " For XCTest use only. " )
232
+ func _add( _ source: _Source , forMode mode: RunLoop . Mode ) {
233
+ CFRunLoopAddSource ( _cfRunLoop, source. cfSource, mode. _cfStringUniquingKnown)
234
+ }
217
235
}
218
- #endif
219
236
237
+ extension RunLoop {
238
+ @available ( * , deprecated, message: " For XCTest use only. " )
239
+ public enum _Activity : UInt {
240
+ // These must match CFRunLoopActivity.
241
+ case entry = 0
242
+ case beforeTimers = 1
243
+ case beforeSources = 2
244
+ case beforeWaiting = 32
245
+ case afterWaiting = 64
246
+ case exit = 128
247
+ }
248
+
249
+ @available ( * , deprecated, message: " For XCTest use only. " )
250
+ public struct _Activities : OptionSet {
251
+ public var rawValue : UInt
252
+ public init ( rawValue: UInt ) {
253
+ self . rawValue = rawValue
254
+ }
255
+
256
+ public init ( _ activity: _Activity ) {
257
+ self . rawValue = activity. rawValue
258
+ }
259
+
260
+ public static let entry = _Activities ( rawValue: _Activity. entry. rawValue)
261
+ public static let beforeTimers = _Activities ( rawValue: _Activity. beforeTimers. rawValue)
262
+ public static let beforeSources = _Activities ( rawValue: _Activity. beforeSources. rawValue)
263
+ public static let beforeWaiting = _Activities ( rawValue: _Activity. beforeWaiting. rawValue)
264
+ public static let afterWaiting = _Activities ( rawValue: _Activity. afterWaiting. rawValue)
265
+ public static let exit = _Activities ( rawValue: _Activity. exit. rawValue)
266
+ public static let allActivities = _Activities ( rawValue: 0x0FFFFFFF )
267
+ }
268
+
269
+ @available ( * , deprecated, message: " For XCTest use only. " )
270
+ public class _Observer {
271
+ fileprivate let cfObserver : CFRunLoopObserver
272
+
273
+ fileprivate init ( activities: _Activities , repeats: Bool , order: Int , handler: @escaping ( _Activity ) -> Void ) {
274
+ self . cfObserver = CFRunLoopObserverCreateWithHandler ( kCFAllocatorSystemDefault, CFOptionFlags ( activities. rawValue) , repeats, CFIndex ( order) , { ( cfObserver, cfActivity) in
275
+ guard let activity = _Activity ( rawValue: UInt ( cfActivity. rawValue) ) else { return }
276
+ handler ( activity)
277
+ } )
278
+ }
279
+
280
+ public func invalidate( ) {
281
+ CFRunLoopObserverInvalidate ( cfObserver)
282
+ }
283
+
284
+ var order : Int {
285
+ Int ( CFRunLoopObserverGetOrder ( cfObserver) )
286
+ }
287
+
288
+ var isValid : Bool {
289
+ CFRunLoopObserverIsValid ( cfObserver)
290
+ }
291
+ }
292
+
293
+ @available ( * , deprecated, message: " For XCTest use only. " )
294
+ open class _Source : NSObject {
295
+ fileprivate var cfSource : CFRunLoopSource !
296
+
297
+ public init ( order: Int = 0 ) {
298
+ super. init ( )
299
+
300
+ var context = CFRunLoopSourceContext (
301
+ version: 0 ,
302
+ info: Unmanaged . passUnretained ( self ) . toOpaque ( ) ,
303
+ retain: nil ,
304
+ release: nil ,
305
+ copyDescription: { ( info) -> Unmanaged < CFString > ? in
306
+ let me = Unmanaged < _Source > . fromOpaque ( info!) . takeUnretainedValue ( )
307
+ return . passRetained( String ( describing: me) . _cfObject)
308
+ } ,
309
+ equal: { ( infoA, infoB) -> DarwinBoolean in
310
+ let a = Unmanaged < _Source > . fromOpaque ( infoA!) . takeUnretainedValue ( )
311
+ let b = Unmanaged < _Source > . fromOpaque ( infoB!) . takeUnretainedValue ( )
312
+ return a == b ? true : false
313
+ } ,
314
+ hash: { ( info) -> CFHashCode in
315
+ let me = Unmanaged < _Source > . fromOpaque ( info!) . takeUnretainedValue ( )
316
+ return CFHashCode ( me. hashValue)
317
+ } ,
318
+ schedule: { ( info, cfRunLoop, cfRunLoopMode) in
319
+ let me = Unmanaged < _Source > . fromOpaque ( info!) . takeUnretainedValue ( )
320
+ var mode : RunLoop . Mode = . default
321
+ if let cfRunLoopMode = cfRunLoopMode {
322
+ mode = RunLoop . Mode ( rawValue: cfRunLoopMode. _swiftObject)
323
+ }
324
+
325
+ me. didSchedule ( in: mode)
326
+ } ,
327
+ cancel: { ( info, cfRunLoop, cfRunLoopMode) in
328
+ let me = Unmanaged < _Source > . fromOpaque ( info!) . takeUnretainedValue ( )
329
+ var mode : RunLoop . Mode = . default
330
+ if let cfRunLoopMode = cfRunLoopMode {
331
+ mode = RunLoop . Mode ( rawValue: cfRunLoopMode. _swiftObject)
332
+ }
333
+
334
+ me. didCancel ( in: mode)
335
+ } ,
336
+ perform: { ( info) in
337
+ let me = Unmanaged < _Source > . fromOpaque ( info!) . takeUnretainedValue ( )
338
+ me. perform ( )
339
+ } )
340
+
341
+ self . cfSource = CFRunLoopSourceCreate ( kCFAllocatorSystemDefault, CFIndex ( order) , & context)
342
+ }
343
+
344
+ open func didSchedule( in mode: RunLoop . Mode ) {
345
+ // Override me.
346
+ }
347
+
348
+ open func didCancel( in mode: RunLoop . Mode ) {
349
+ // Override me.
350
+ }
351
+
352
+ open func perform( ) {
353
+ // Override me.
354
+ }
355
+
356
+ open func invalidate( ) {
357
+ CFRunLoopSourceInvalidate ( cfSource)
358
+ }
359
+
360
+ var order : Int {
361
+ Int ( CFRunLoopSourceGetOrder ( cfSource) )
362
+ }
363
+
364
+ var isValid : Bool {
365
+ CFRunLoopSourceIsValid ( cfSource)
366
+ }
367
+
368
+ open func signal( ) {
369
+ CFRunLoopSourceSignal ( cfSource)
370
+ }
371
+ }
372
+ }
0 commit comments