8000 swift 3 cleanup issues · FutureKit/FutureKit@739674b · GitHub
[go: up one dir, main page]

Skip to content

Commit

Permalink
swift 3 cleanup issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Gray committed Feb 3, 2017
1 parent 538a611 commit 739674b
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@
BlueprintName = "FutureKit iOS Tests"
ReferencedContainer = "container:FutureKit.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "LockPerformanceTests">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
Expand Down
123 changes: 76 additions & 47 deletions FutureKit/Executor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,41 @@ public enum SerialOrConcurrent: Int {

}

internal extension Date {
internal static var now: Date {
return Date()
}
}

internal extension DispatchWallTime {
internal init(_ date: Date) {
let secsSinceEpoch = date.timeIntervalSince1970
let spec = timespec(
tv_sec: __darwin_time_t(secsSinceEpoch),
tv_nsec: Int((secsSinceEpoch - floor(secsSinceEpoch)) * Double(NSEC_PER_SEC))
)
self.init(timespec: spec)
}
}

internal extension DispatchTimeInterval {
internal init(_ interval: TimeInterval) {
let nanoSecs = Int(interval * Double(NSEC_PER_SEC))
self = .nanoseconds(nanoSecs)
}
}

internal extension DispatchQueue {
internal func async(afterDelay interval: TimeInterval, execute block: @escaping @convention(block) () -> Void) {
self.asyncAfter(deadline: DispatchTime.now() + interval, execute: block)
}

internal func async(after date: Date, execute block: @escaping @convention(block) () -> Void) {
self.asyncAfter(wallDeadline: DispatchWallTime(date), execute: block)
}
}


// remove in Swift 2.0

extension qos_class_t {
Expand Down Expand Up @@ -347,6 +382,15 @@ public enum Executor {
executionBlock()
}

@available(*, deprecated: 1.1, message: "renamed to execute(afterDelay:)")
@discardableResult public func executeAfterDelay<__Type>(_ delay: TimeInterval, _ block: @escaping () throws -> __Type) -> Future<__Type> {
return self.execute(afterDelay: delay, block: block)
}
@available(*, deprecated: 1.1, message: "renamed to execute(after:)")
@discardableResult public func executeAt<__Type>(_ date: Date, _ block: @escaping () throws -> __Type) -> Future<__Type> {
return self.execute(after: date, block: block)
}

@discardableResult public func execute<__Type>(_ block: @escaping () throws -> __Type) -> Future<__Type> {
let p = Promise<__Type>()
self.executeBlock { () -> Void in
Expand Down Expand Up @@ -375,95 +419,80 @@ public enum Executor {
return p.future
}

internal func _executeAfterDelay<C:CompletionType>(nanosecs n: Int64, block: @escaping () throws -> C) -> Future<C.T> {
@discardableResult public func execute<C:CompletionType>(afterDelay delay: TimeInterval, block: @escaping () throws -> C) -> Future<C.T> {
let p = Promise<C.T>()
let popTime = DispatchTime.now() + Double(n) / Double(NSEC_PER_SEC)
let q = self.underlyingQueue ?? Executor.defaultQ
q.asyncAfter(deadline: popTime, execute: {
q.async(afterDelay: delay) {
p.completeWithBlock {
return try block()
}
})
return p.future
}
@discardableResult public func executeAfterDelay<C:CompletionType>(_ secs : TimeInterval, block: @escaping () throws -> C) -> Future<C.T> {
let nanosecsDouble = secs * TimeInterval(NSEC_PER_SEC)
let nanosecs = Int64(nanosecsDouble)
let p = Promise<C.T>()
let popTime = dispatch_time(DISPATCH_TIME_NOW, nanosecs)
let q = self.underlyingQueue ?? Executor.defaultQ
dispatch_after(popTime, q, {
p.completeWithBlock {
return try block()
}
})
}
return p.future
}
public func executeAfterDelay<C:CompletionType>(secs : NSTimeInterval, block: () throws -> C) -> Future<C.T> {
return self._executeAfterDelay(secs,block:block)
}

@discardableResult public func executeAfterDelay<__Type>(_ secs : TimeInterval, block: @escaping () throws -> __Type) -> Future<__Type> {
return self.executeAfterDelay(secs) { () -> Completion<__Type> in

@discardableResult public func execute<__Type>(afterDelay secs : TimeInterval, block: @escaping () throws -> __Type) -> Future<__Type> {
return self.execute(afterDelay: secs) { () -> Completion<__Type> in
return .success(try block())
}
}


public func executeAt<C:CompletionType>(date : NSDate, block: () throws -> C) -> Future<C.T> {
return self._executeAt(date,block:block)
public func execute<C:CompletionType>(after date : Date, block: @escaping () throws -> C) -> Future<C.T> {
let p = Promise<C.T>()
let q = self.underlyingQueue ?? Executor.defaultQ
q.async(after: date) {
p.completeWithBlock {
return try block()
}
}
return p.future
}

public func executeAt<__Type>(date : NSDate, block: () throws -> __Type) -> Future<__Type> {
return self.executeAt(date) { () -> Completion<__Type> in
return .Success(try block())
public func execute<__Type>(after date : Date, block: @escaping () throws -> __Type) -> Future<__Type> {
return self.execute(after: date) { () -> Completion<__Type> in
return .success(try block())
}
}

/**
repeatExecution

- parameter date: time to start repeating
- parameter startingAt: date to start repeating
- parameter repeatingEvery: interval to repeat
- parameter action: action to execute

- returns: CancellationToken
*/
public func repeatExecution(date: NSDate, repeatingEvery: NSTimeInterval, action: () -> Void) -> CancellationToken {
return self.repeatExecution(date, repeatingEvery: repeatingEvery, withLeeway: repeatingEvery * 0.1, action: action)
public func repeatExecution(startingAt date: Date = .now, repeatingEvery: TimeInterval, action: @escaping () -> Void) -> CancellationToken {
return self.repeatExecution(startingAt:date, repeatingEvery: repeatingEvery, withLeeway: repeatingEvery * 0.1, action: action)
}


/**
schedule to repeat execution inside this executor

- parameter date: time to start repeatin
- parameter startingAt: date to start repeatin
- parameter repeatingEvery: interval to repeat
- parameter leeway: the 'leeway' execution is allowed. default is 10% of repeatingEvery
- parameter action: action to execute

- returns: CancellationToken that can be used to stop the execution
*/
public func repeatExecution(date: NSDate, repeatingEvery: NSTimeInterval, withLeeway leeway: NSTimeInterval, action: () -> Void) -> CancellationToken {
public func repeatExecution(startingAt date: Date = Date.now, repeatingEvery: TimeInterval, withLeeway leeway: TimeInterval, action: @escaping () -> Void) -> CancellationToken {
precondition(repeatingEvery >= 0)
precondition(leeway >= 0)

let nsecInterval = repeatingEvery * Double(NSEC_PER_SEC)
let nsecLeeway = leeway * Double(NSEC_PER_SEC)

let timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.relatedQueue)
dispatch_source_set_timer(timer, wallTime(date), UInt64(nsecInterval), UInt64(nsecLeeway))

dispatch_source_set_event_handler(timer) { () -> Void in
let timerSource = DispatchSource.makeTimerSource()
timerSource.scheduleRepeating(wallDeadline: DispatchWallTime(date), interval: DispatchTimeInterval(repeatingEvery), leeway: DispatchTimeInterval(leeway))

timerSource.setEventHandler {
self.execute(action)
}
dispatch_resume(timer)


let p = Promise<Void>()

p.onRequestCancel { (options) -> CancelRequestResponse<Void> in
dispatch_source_cancel(timer)
return .Complete(.Cancelled)
timerSource.cancel()
return .complete(.cancelled)
}

return p.future.getCancelToken()
Expand Down Expand Up @@ -511,7 +540,7 @@ public enum Executor {
}
}

public var relatedQueue: dispatch_queue_t {
public var relatedQueue: DispatchQueue {
return self.underlyingQueue ?? Executor.defaultQ
}

Expand Down Expand Up @@ -824,7 +853,7 @@ let example_Of_A_Custom_Executor_That_has_unneeded_dispatches = Executor.custom

let example_Of_A_Custom_Executor_Where_everthing_takes_5_seconds = Executor.custom { (callback) -> Void in

Executor.primary.executeAfterDelay(5.0) { () -> Void in
Executor.primary.execute(afterDelay:5.0) { () -> Void in
callback()
}

Expand Down
10 changes: 5 additions & 5 deletions FutureKit/Future.swift
Original file line number Diff line number Diff line change
Expand Up @@ -637,18 +637,18 @@ open class Future<T> : FutureProtocol {

let p = Promise<T>()
p.automaticallyCancelOnRequestCancel()
executor.executeAfterDelay(delay) { () -> Void in
executor.execute(afterDelay:delay) { () -> Void in
p.complete(completeWith)
}
self.init(completeUsing:p.future)
}

public convenience init(afterDelay:TimeInterval, success:T) { // emits a .Success after delay
public convenience init(afterDelay delay:TimeInterval, success:T) { // emits a .Success after delay
let executor: Executor = .primary

let p = Promise<T>()
p.automaticallyCancelOnRequestCancel()
executor.executeAfterDelay(afterDelay) {
executor.execute(afterDelay:delay) {
p.completeWithSuccess(success)
}
self.init(completeUsing:p.future)
Expand Down Expand Up @@ -1248,7 +1248,7 @@ extension FutureProtocol {
}
.ignoreFailures()

executor.executeAfterDelay(timeout) {
executor.execute(afterDelay:timeout) {
p.completeWithBlock { () -> C in
return try timedOut()
}
Expand Down Expand Up @@ -1285,7 +1285,7 @@ extension FutureProtocol {
p.completeWithSuccess(try didSucceed(result))
}.ignoreFailures()

executor.executeAfterDelay(timeout) {
executor.execute(afterDelay:timeout) {
p.completeWithBlock { () -> C in
return try timedOut()
}
Expand Down
28 changes: 22 additions & 6 deletions FutureKit/Promise.swift
Original file line number Diff line number Diff line change
Expand F438 Up @@ -82,17 +82,17 @@ open class Promise<T> {

public convenience init(automaticallyCancelAfter delay: TimeInterval) {
self.init()
self.automaticallyCancelAfter(delay)
self.automaticallyCancel(afterDelay:delay)
}

public convenience init(automaticallyFailAfter delay: TimeInterval, error:Error ) {
self.init()
self.automaticallyFailAfter(delay,error:error)
self.automaticallyFail(afterDelay:delay,with:error)
}

public convenience init(automaticallyFailAfter delay: TimeInterval, errorMessage:String ) {
self.init()
self.automaticallyFailAfter(delay,error:FutureKitError(genericError: errorMessage))
self.automaticallyFail(afterDelay:delay,with:FutureKitError(genericError: errorMessage))
}

// untestable?
Expand All @@ -101,20 +101,36 @@ open class Promise<T> {
}


@available(*, deprecated: 1.1, message: "renamed to automaticallyCancel(afterDelay:)")
public final func automaticallyCancelAfter(_ delay: TimeInterval) {
self.automaticallyCancelOnRequestCancel()
Executor.default.executeAfterDelay(delay) { () -> Void in
Executor.default.execute(afterDelay:delay) { () -> Void in
self.completeWithCancel()
}
}

public final func automaticallyCancel(afterDelay delay: TimeInterval) {
self.automaticallyCancelOnRequestCancel()
Executor.default.execute(afterDelay:delay) { () -> Void in
self.completeWithCancel()
}
}

@available(*, deprecated: 1.1, message: "renamed to automaticallyFail(afterDelay:with:)")
public final func automaticallyFailAfter(_ delay: TimeInterval, error:Error) {
self.automaticallyCancelOnRequestCancel()
Executor.default.executeAfterDelay(delay) { () -> Void in
Executor.default.execute(afterDelay:delay) { () -> Void in
self.failIfNotCompleted(error)
}
}

public final func automaticallyFail(afterDelay delay: TimeInterval, with:Error) {
self.automaticallyCancelOnRequestCancel()
Executor.default.execute(afterDelay:delay) { () -> Void in
self.failIfNotCompleted(with)
}
}


public final func automaticallyAssertOnFail(_ message:String, file : StaticString = #file, line : Int32 = #line) {
self.future.onFail { (error) -> Void in
Expand Down Expand Up @@ -237,7 +253,7 @@ open class Promise<T> {
return future
}

public final func futureWithFailure(error : ErrorType) -> Future<T>{
public final func futureWithFailure(error : Error) -> Future<T>{
self.completeWithFail(error)
return future
}
Expand Down
2 changes: 2 additions & 0 deletions FutureKit/Synchronization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public extension SynchronizationProtocol {

// modify your container and retrieve a result/element to the same calling thread
// current thread will block until the modifyBlock is done running.
@discardableResult
public final func lockAndModifySync<T>(_ modifyBlock:@escaping () -> T) -> T {

var retVal : T?
Expand Down Expand Up @@ -102,6 +103,7 @@ public extension SynchronizationProtocol {
// perform a readonly query of your shared object and return some value/element T
// current thread may block until the read block is done running.
// do NOT modify your object inside this block
@discardableResult
public final func lockAndReadSync<T>(_ readBlock:@escaping () -> T) -> T {

var retVal : T?
Expand Down
7 changes: 4 additions & 3 deletions FutureKitTests/PromiseTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ extension PromiseFunctionTest {

let blockThatMakesDelayedFuture = { (delay : TimeInterval, completion:Completion<T>) -> Future<T> in
let p = Promise<T>()
promiseExecutor.executeAfterDelay(delay) {
promiseExecutor.execute(afterDelay:delay) {
p.complete(completion)
}
return p.future
Expand Down Expand Up @@ -560,10 +560,10 @@ private enum PromiseFunctions<T : Equatable> {
switch self {

case let .automaticallyCancelAfter(delay):
promise.automaticallyCancelAfter(delay)
promise.automaticallyCancel(afterDelay:delay)

case let .automaticallyFailAfter(delay,error):
promise.automaticallyFailAfter(delay,error:error)
promise.automaticallyFail(afterDelay:delay,with:error)

/* case let .onRequestCancelExecutor(handler):
promise.onRequestCancel(test.promiseExecutor, handler: handler)
Expand Down Expand Up @@ -854,6 +854,7 @@ class PromiseTests: FKTestCase {
}
completeExpectation.fulfill()
}
.ignoreFailures()

// TODO: Can we get this to compile?

Expand Down

0 comments on commit 739674b

Please sign in to comment.
0