Skip to content

Commit f12f96e

Browse files
committed
Implement NSRunLoop
1 parent 387b11f commit f12f96e

File tree

4 files changed

+116
-10
lines changed

4 files changed

+116
-10
lines changed

Foundation.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,13 @@
201201
5BF7AEC11BCD51F9008F214A /* NSValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4C1BCC5DCB00ED97BB /* NSValue.swift */; };
202202
5E5835F41C20C9B500C81317 /* TestNSThread.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E5835F31C20C9B500C81317 /* TestNSThread.swift */; };
203203
612952F91C1B235900BE0FD9 /* TestNSNull.swift in Sources */ = {isa = PBXBuildFile; fileRef = 612952F81C1B235900BE0FD9 /* TestNSNull.swift */; };
204+
61E0117C1C1B554D000037DD /* TestNSRunLoop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E0117B1C1B554D000037DD /* TestNSRunLoop.swift */; };
205+
61E0117D1C1B5590000037DD /* NSRunLoop.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B761BD15DFF00C49C64 /* NSRunLoop.swift */; };
206+
61E0117E1C1B55B9000037DD /* NSTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F481BCC5DCB00ED97BB /* NSTimer.swift */; };
207+
61E0117F1C1B5990000037DD /* CFRunLoop.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88D81BBC9AD800234F36 /* CFRunLoop.c */; };
208+
61E011801C1B5994000037DD /* CFSocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88E01BBC9B0300234F36 /* CFSocket.c */; };
209+
61E011811C1B5998000037DD /* CFMessagePort.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88DC1BBC9AEC00234F36 /* CFMessagePort.c */; };
210+
61E011821C1B599A000037DD /* CFMachPort.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88D01BBC9AAC00234F36 /* CFMachPort.c */; };
204211
61F8AE7D1C180FC600FB62F0 /* TestNSNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F8AE7C1C180FC600FB62F0 /* TestNSNotificationCenter.swift */; };
205212
6E203B8D1C1303BB003B2576 /* TestNSBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E203B8C1C1303BB003B2576 /* TestNSBundle.swift */; };
206213
7A7D6FBB1C16439400957E2E /* TestNSURLResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7D6FBA1C16439400957E2E /* TestNSURLResponse.swift */; };
@@ -542,6 +549,7 @@
542549
5E5835F31C20C9B500C81317 /* TestNSThread.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSThread.swift; sourceTree = "<group>"; };
543550
5EB6A15C1C188FC40037DCB8 /* TestNSJSONSerialization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSJSONSerialization.swift; sourceTree = "<group>"; };
544551
612952F81C1B235900BE0FD9 /* TestNSNull.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSNull.swift; sourceTree = "<group>"; };
552+
61E0117B1C1B554D000037DD /* TestNSRunLoop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSRunLoop.swift; sourceTree = "<group>"; };
545553
61F8AE7C1C180FC600FB62F0 /* TestNSNotificationCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSNotificationCenter.swift; sourceTree = "<group>"; };
546554
6E203B8C1C1303BB003B2576 /* TestNSBundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSBundle.swift; sourceTree = "<group>"; };
547555
7A7D6FBA1C16439400957E2E /* TestNSURLResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSURLResponse.swift; sourceTree = "<group>"; };
@@ -1068,6 +1076,7 @@
10681076
EA66F6401BF1619600136161 /* TestNSPropertyList.swift */,
10691077
E876A73D1C1180E000F279EC /* TestNSRange.swift */,
10701078
844DC3321C17584F005611F9 /* TestNSScanner.swift */,
1079+
61E0117B1C1B554D000037DD /* TestNSRunLoop.swift */,
10711080
EA66F6411BF1619600136161 /* TestNSSet.swift */,
10721081
EA66F6421BF1619600136161 /* TestNSString.swift */,
10731082
5E5835F31C20C9B500C81317 /* TestNSThread.swift */,
@@ -1601,6 +1610,7 @@
16011610
EADE0BA91BD15E0000C49C64 /* NSNull.swift in Sources */,
16021611
EADE0BC01BD15E0000C49C64 /* NSURLProtectionSpace.swift in Sources */,
16031612
5BF7AEAC1BCD51F9008F214A /* NSEnumerator.swift in Sources */,
1613+
61E0117E1C1B55B9000037DD /* NSTimer.swift in Sources */,
16041614
EADE0BCD1BD15E0000C49C64 /* NSXMLParser.swift in Sources */,
16051615
5BDC3FD01BCF17E600ED97BB /* NSCFSet.swift in Sources */,
16061616
EADE0B931BD15DFF00C49C64 /* NSComparisonPredicate.swift in Sources */,
@@ -1668,6 +1678,7 @@
16681678
5BF7AEB41BCD51F9008F214A /* NSObject.swift in Sources */,
16691679
EADE0B521BD09F2F00C49C64 /* NSByteCountFormatter.swift in Sources */,
16701680
EADE0BC11BD15E0000C49C64 /* NSURLProtocol.swift in Sources */,
1681+
61E0117D1C1B5590000037DD /* NSRunLoop.swift in Sources */,
16711682
EADE0BC81BD15E0000C49C64 /* NSXMLDTD.swift in Sources */,
16721683
EADE0BA61BD15E0000C49C64 /* NSMassFormatter.swift in Sources */,
16731684
EADE0BCC1BD15E0000C49C64 /* NSXMLNodeOptions.swift in Sources */,
@@ -1693,6 +1704,7 @@
16931704
buildActionMask = 2147483647;
16941705
files = (
16951706
5B7C8A871BEA7FDB00C5B690 /* CFLocale.c in Sources */,
1707+
61E011801C1B5994000037DD /* CFSocket.c in Sources */,
16961708
5B7C8AB71BEA801700C5B690 /* CFUnicodePrecomposition.c in Sources */,
16971709
5B7C8A721BEA7FCE00C5B690 /* CFBase.c in Sources */,
16981710
5B7C8A951BEA7FEC00C5B690 /* CFXMLTree.c in Sources */,
@@ -1702,6 +1714,7 @@
17021714
5B7C8A7F1BEA7FCE00C5B690 /* CFData.c in Sources */,
17031715
5B7C8A9C1BEA7FF900C5B690 /* CFBundle.c in Sources */,
17041716
5B7C8AB51BEA801700C5B690 /* CFUniChar.c in Sources */,
1717+
61E011811C1B5998000037DD /* CFMessagePort.c in Sources */,
17051718
5B7C8AB61BEA801700C5B690 /* CFUnicodeDecomposition.c in Sources */,
17061719
5B7C8A881BEA7FDB00C5B690 /* CFLocaleIdentifier.c in Sources */,
17071720
5B7C8AB01BEA801700C5B690 /* CFBuiltinConverters.c in Sources */,
@@ -1725,6 +1738,7 @@
17251738
5B7C8A8C1BEA7FE200C5B690 /* CFDate.c in Sources */,
17261739
5B7C8A751BEA7FCE00C5B690 /* CFRuntime.c in Sources */,
17271740
5B7C8A7C1BEA7FCE00C5B690 /* CFBasicHash.c in Sources */,
1741+
61E011821C1B599A000037DD /* CFMachPort.c in Sources */,
17281742
5B7C8A921BEA7FEC00C5B690 /* CFXMLInputStream.c in Sources */,
17291743
5B7C8AAA1BEA800D00C5B690 /* CFBurstTrie.c in Sources */,
17301744
5B7C8A9E1BEA7FF900C5B690 /* CFPlugIn_Instance.c in Sources */,
@@ -1744,6 +1758,7 @@
17441758
5B7C8A971BEA7FF900C5B690 /* CFBundle_Grok.c in Sources */,
17451759
5B7C8ABB1BEA802100C5B690 /* CFURLAccess.c in Sources */,
17461760
5B7C8A901BEA7FEC00C5B690 /* CFOldStylePList.c in Sources */,
1761+
61E0117F1C1B5990000037DD /* CFRunLoop.c in Sources */,
17471762
5B7C8A7B1BEA7FCE00C5B690 /* CFBag.c in Sources */,
17481763
5B7C8AA21BEA800400C5B690 /* CFPreferences.c in Sources */,
17491764
5B7C8A811BEA7FCE00C5B690 /* CFSet.c in Sources */,
@@ -1801,6 +1816,7 @@
18011816
EA66F64C1BF1619600136161 /* TestNSDictionary.swift in Sources */,
18021817
ED58F76F1C134B3A00E6A5BE /* (null) in Sources */,
18031818
EA66F6581BF1619600136161 /* TestNSURL.swift in Sources */,
1819+
61E0117C1C1B554D000037DD /* TestNSRunLoop.swift in Sources */,
18041820
EA66F6441BF1619600136161 /* main.swift in Sources */,
18051821
);
18061822
runOnlyForDeploymentPostprocessing = 0;

Foundation/NSRunLoop.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,51 @@
77
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
88
//
99

10+
import CoreFoundation
1011

11-
public let NSDefaultRunLoopMode: String = "NSDefaultRunLoopMode"
12-
public let NSRunLoopCommonModes: String = "NSRunLoopCommonModes"
12+
public let NSDefaultRunLoopMode: String = kCFRunLoopDefaultMode._swiftObject
13+
public let NSRunLoopCommonModes: String = kCFRunLoopCommonModes._swiftObject
1314

1415
public class NSRunLoop : NSObject {
16+
typealias CFType = CFRunLoopRef
17+
internal var _cfObject : CFType!
18+
internal static var _mainRunLoop : NSRunLoop = {
19+
return NSRunLoop(cfObject: CFRunLoopGetMain())
20+
}()
21+
22+
internal init(cfObject : CFRunLoopRef) {
23+
_cfObject = cfObject
24+
}
1525

1626
public class func currentRunLoop() -> NSRunLoop {
17-
NSUnimplemented()
27+
return NSRunLoop(cfObject: CFRunLoopGetCurrent())
1828
}
1929

2030
public class func mainRunLoop() -> NSRunLoop {
21-
NSUnimplemented()
31+
return _mainRunLoop
2232
}
2333

2434
public var currentMode: String? {
25-
NSUnimplemented()
35+
return CFRunLoopCopyCurrentMode(_cfObject)?._swiftObject
2636
}
2737

2838
public func addTimer(timer: NSTimer, forMode mode: String) {
29-
NSUnimplemented()
39+
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer._cfObject, mode._cfObject)
3040
}
3141

3242
public func addPort(aPort: NSPort, forMode mode: String) {
43+
// CFRunLoopAddSource(CFRunLoopGetCurrent(), aPort._cfObject, mode._cfObject)
3344
NSUnimplemented()
3445
}
3546

3647
public func removePort(aPort: NSPort, forMode mode: String) {
48+
// CFRunLoopRemoveSource(CFRunLoopGetCurrent(), aPort._cfObject, mode._cfObject)
3749
NSUnimplemented()
3850
}
3951

4052
public func limitDateForMode(mode: String) -> NSDate? {
41-
NSUnimplemented()
53+
let nextTimerFireAbsoluteTime = CFRunLoopGetNextTimerFireDate(CFRunLoopGetCurrent(), mode._cfObject)
54+
return NSDate(timeIntervalSinceReferenceDate: nextTimerFireAbsoluteTime)
4255
}
4356

4457
public func acceptInputForMode(mode: String, beforeDate limitDate: NSDate) {
@@ -50,15 +63,17 @@ public class NSRunLoop : NSObject {
5063
extension NSRunLoop {
5164

5265
public func run() {
53-
NSUnimplemented()
66+
runUntilDate(NSDate.distantFuture());
5467
}
5568

5669
public func runUntilDate(limitDate: NSDate) {
57-
NSUnimplemented()
70+
runMode(NSDefaultRunLoopMode, beforeDate: limitDate)
5871
}
5972

6073
public func runMode(mode: String, beforeDate limitDate: NSDate) -> Bool {
61-
NSUnimplemented()
74+
let result: Int32 = CFRunLoopRunSpecific(_cfObject, mode._cfObject, limitDate.timeIntervalSinceNow, false)
75+
let runloopResult = CFRunLoopRunResult(rawValue: result)
76+
return runloopResult == .HandledSource || runloopResult == .TimedOut
6277
}
6378

6479
}

TestFoundation/TestNSRunLoop.swift

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See http://swift.org/LICENSE.txt for license information
7+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
//
9+
10+
11+
#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
12+
import Foundation
13+
import XCTest
14+
#else
15+
import SwiftFoundation
16+
import SwiftXCTest
17+
#endif
18+
19+
20+
class TestNSRunLoop : XCTestCase {
21+
var allTests : [(String, () -> ())] {
22+
return [
23+
("test_runLoopInit", test_runLoopInit),
24+
("test_runLoopRunMode", test_runLoopRunMode),
25+
("test_runLoopLimitDate", test_runLoopLimitDate),
26+
]
27+
}
28+
29+
func test_runLoopInit() {
30+
let mainRunLoop = NSRunLoop.mainRunLoop()
31+
XCTAssertNotNil(mainRunLoop)
32+
let currentRunLoop = NSRunLoop.currentRunLoop()
33+
XCTAssertNotNil(currentRunLoop)
34+
}
35+
36+
func test_runLoopRunMode() {
37+
let runLoop = NSRunLoop.currentRunLoop()
38+
let timeInterval = NSTimeInterval(0.05)
39+
let endDate = NSDate(timeInterval: timeInterval, sinceDate: NSDate())
40+
var flag = false
41+
42+
let dummyTimer = NSTimer.scheduledTimer(0.01, repeats: false) { _ in
43+
flag = true
44+
guard let runLoopMode = runLoop.currentMode else {
45+
XCTFail("Run loop mode is not defined")
46+
return
47+
}
48+
49+
XCTAssertEqual(runLoopMode, NSDefaultRunLoopMode)
50+
}
51+
runLoop.addTimer(dummyTimer, forMode: NSDefaultRunLoopMode)
52+
let result = runLoop.runMode(NSDefaultRunLoopMode, beforeDate: endDate)
53+
54+
XCTAssertFalse(result) // should be .Finished
55+
XCTAssertTrue(flag)
56+
}
57+
58+
func test_runLoopLimitDate() {
59+
let runLoop = NSRunLoop.currentRunLoop()
60+
let timeInterval = NSTimeInterval(1)
61+
let expectedTimeInterval = NSDate(timeInterval: timeInterval, sinceDate: NSDate()).timeIntervalSince1970
62+
63+
let dummyTimer = NSTimer.scheduledTimer(timeInterval, repeats: false) { _ in }
64+
runLoop.addTimer(dummyTimer, forMode: NSDefaultRunLoopMode)
65+
66+
guard let timerTickInterval = runLoop.limitDateForMode(NSDefaultRunLoopMode)?.timeIntervalSince1970 else {
67+
XCTFail()
68+
return
69+
}
70+
71+
XCTAssertLessThan(abs(timerTickInterval - expectedTimeInterval), 0.01)
72+
}
73+
74+
}

TestFoundation/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ XCTMain([
4242
TestNSProcessInfo(),
4343
TestNSPropertyList(),
4444
TestNSRange(),
45+
TestNSRunLoop(),
4546
TestNSScanner(),
4647
TestNSSet(),
4748
TestNSString(),

0 commit comments

Comments
 (0)