Skip to content
This repository has been archived by the owner on Aug 29, 2022. It is now read-only.

Commit

Permalink
Merge pull request #216 from bignerdranch/zwaldowski/declutter-future…
Browse files Browse the repository at this point in the history
…-protocol

Declutter Future protocol
  • Loading branch information
zwaldowski committed Apr 9, 2018
2 parents 45ab38d + 707516c commit 1b39f30
Show file tree
Hide file tree
Showing 16 changed files with 265 additions and 147 deletions.
40 changes: 40 additions & 0 deletions Deferred.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,22 @@
DB8A071C2060D38C00639AB3 /* PerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8A071B2060D38C00639AB3 /* PerformanceTests.swift */; };
DB8A071D2060D38C00639AB3 /* PerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8A071B2060D38C00639AB3 /* PerformanceTests.swift */; };
DB8A071E2060D38C00639AB3 /* PerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8A071B2060D38C00639AB3 /* PerformanceTests.swift */; };
DBA01AFE2071E5D300083CD0 /* FutureUpon.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01AFD2071E5D300083CD0 /* FutureUpon.swift */; };
DBA01AFF2071E5D300083CD0 /* FutureUpon.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01AFD2071E5D300083CD0 /* FutureUpon.swift */; };
DBA01B002071E5D300083CD0 /* FutureUpon.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01AFD2071E5D300083CD0 /* FutureUpon.swift */; };
DBA01B012071E5D300083CD0 /* FutureUpon.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01AFD2071E5D300083CD0 /* FutureUpon.swift */; };
DBA01B042071E69100083CD0 /* FutureMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B022071E68F00083CD0 /* FutureMap.swift */; };
DBA01B052071E69100083CD0 /* FutureMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B022071E68F00083CD0 /* FutureMap.swift */; };
DBA01B062071E69100083CD0 /* FutureMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B022071E68F00083CD0 /* FutureMap.swift */; };
DBA01B072071E69100083CD0 /* FutureMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B022071E68F00083CD0 /* FutureMap.swift */; };
DBA01B082071E69100083CD0 /* FutureAndThen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B032071E68F00083CD0 /* FutureAndThen.swift */; };
DBA01B092071E69100083CD0 /* FutureAndThen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B032071E68F00083CD0 /* FutureAndThen.swift */; };
DBA01B0A2071E69100083CD0 /* FutureAndThen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B032071E68F00083CD0 /* FutureAndThen.swift */; };
DBA01B0B2071E69100083CD0 /* FutureAndThen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B032071E68F00083CD0 /* FutureAndThen.swift */; };
DBA01B0D2071E6FF00083CD0 /* FuturePeek.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B0C2071E6FF00083CD0 /* FuturePeek.swift */; };
DBA01B0E2071E6FF00083CD0 /* FuturePeek.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B0C2071E6FF00083CD0 /* FuturePeek.swift */; };
DBA01B0F2071E6FF00083CD0 /* FuturePeek.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B0C2071E6FF00083CD0 /* FuturePeek.swift */; };
DBA01B102071E6FF00083CD0 /* FuturePeek.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA01B0C2071E6FF00083CD0 /* FuturePeek.swift */; };
DBABD0BB203F2E3E00C50896 /* Atomics.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBABD0BA203F2E3E00C50896 /* Atomics.swift */; };
DBABD0BC203F2E3E00C50896 /* Atomics.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBABD0BA203F2E3E00C50896 /* Atomics.swift */; };
DBABD0BD203F2E3E00C50896 /* Atomics.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBABD0BA203F2E3E00C50896 /* Atomics.swift */; };
Expand Down Expand Up @@ -257,6 +273,10 @@
DB55F1FD1D96968E00FC1439 /* TaskWorkItemTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskWorkItemTests.swift; sourceTree = "<group>"; };
DB55F20B1D969A1B00FC1439 /* FutureTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FutureTests.swift; sourceTree = "<group>"; };
DB8A071B2060D38C00639AB3 /* PerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceTests.swift; sourceTree = "<group>"; };
DBA01AFD2071E5D300083CD0 /* FutureUpon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FutureUpon.swift; sourceTree = "<group>"; };
DBA01B022071E68F00083CD0 /* FutureMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FutureMap.swift; sourceTree = "<group>"; };
DBA01B032071E68F00083CD0 /* FutureAndThen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FutureAndThen.swift; sourceTree = "<group>"; };
DBA01B0C2071E6FF00083CD0 /* FuturePeek.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FuturePeek.swift; sourceTree = "<group>"; };
DBABD0BA203F2E3E00C50896 /* Atomics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomics.swift; sourceTree = "<group>"; };
DBC742631DC2F6D4002FB30D /* FutureEveryMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FutureEveryMap.swift; sourceTree = "<group>"; };
EBEB828C1DC4A79A00B7E089 /* TaskComprehensiveTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskComprehensiveTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -375,10 +395,14 @@
DB524C941D85200C00DDF16D /* Executor.swift */,
DB524C951D85200C00DDF16D /* ExistentialFuture.swift */,
DB524C9A1D85200C00DDF16D /* Future.swift */,
DBA01B032071E68F00083CD0 /* FutureAndThen.swift */,
DB524C961D85200C00DDF16D /* FutureCollections.swift */,
DB524C971D85200C00DDF16D /* FutureComposition.swift */,
DBC742631DC2F6D4002FB30D /* FutureEveryMap.swift */,
DB524C9B1D85200C00DDF16D /* FutureIgnore.swift */,
DBA01B022071E68F00083CD0 /* FutureMap.swift */,
DBA01B0C2071E6FF00083CD0 /* FuturePeek.swift */,
DBA01AFD2071E5D300083CD0 /* FutureUpon.swift */,
DB524C9F1D85200C00DDF16D /* Locking.swift */,
DB524C9E1D85200C00DDF16D /* Promise.swift */,
DB524C9C1D85200C00DDF16D /* Protected.swift */,
Expand Down Expand Up @@ -755,6 +779,8 @@
DB126CFD1E5368A100054E95 /* Executor.swift in Sources */,
DB126D2A1E5368A700054E95 /* TaskResult.swift in Sources */,
DB126D021E5368A100054E95 /* FutureEveryMap.swift in Sources */,
DBA01B082071E69100083CD0 /* FutureAndThen.swift in Sources */,
DBA01B0D2071E6FF00083CD0 /* FuturePeek.swift in Sources */,
DB126CFE1E5368A100054E95 /* ExistentialFuture.swift in Sources */,
DBABD0BB203F2E3E00C50896 /* Atomics.swift in Sources */,
DB126D341E5368AD00054E95 /* ExistentialTask.swift in Sources */,
Expand All @@ -768,11 +794,13 @@
DB126D041E5368A100054E95 /* Locking.swift in Sources */,
DB126D361E5368AD00054E95 /* ResultPromise.swift in Sources */,
DB126D3B1E5368AD00054E95 /* TaskMap.swift in Sources */,
DBA01AFE2071E5D300083CD0 /* FutureUpon.swift in Sources */,
DB126D381E5368AD00054E95 /* TaskCollections.swift in Sources */,
DB126D3A1E5368AD00054E95 /* TaskIgnore.swift in Sources */,
DB126D391E5368AD00054E95 /* TaskGroup.swift in Sources */,
DB126CFC1E5368A100054E95 /* Deferred.swift in Sources */,
DB126D051E5368A100054E95 /* Promise.swift in Sources */,
DBA01B042071E69100083CD0 /* FutureMap.swift in Sources */,
DB126D001E5368A100054E95 /* FutureCollections.swift in Sources */,
DB126D011E5368A100054E95 /* FutureComposition.swift in Sources */,
DB126D371E5368AD00054E95 /* TaskAndThen.swift in Sources */,
Expand Down Expand Up @@ -812,6 +840,8 @@
DB126D081E5368A100054E95 /* Executor.swift in Sources */,
DB126D2D1E5368A700054E95 /* TaskResult.swift in Sources */,
DB126D0D1E5368A100054E95 /* FutureEveryMap.swift in Sources */,
DBA01B092071E69100083CD0 /* FutureAndThen.swift in Sources */,
DBA01B0E2071E6FF00083CD0 /* FuturePeek.swift in Sources */,
DB126D091E5368A100054E95 /* ExistentialFuture.swift in Sources */,
DB126D3F1E5368AD00054E95 /* ExistentialTask.swift in Sources */,
DB126D111E5368A100054E95 /* Protected.swift in Sources */,
Expand All @@ -825,11 +855,13 @@
DB126D411E5368AD00054E95 /* ResultPromise.swift in Sources */,
DB126D461E5368AD00054E95 /* TaskMap.swift in Sources */,
DB126D431E5368AD00054E95 /* TaskCollections.swift in Sources */,
DBA01AFF2071E5D300083CD0 /* FutureUpon.swift in Sources */,
DB126D451E5368AD00054E95 /* TaskIgnore.swift in Sources */,
DB126D441E5368AD00054E95 /* TaskGroup.swift in Sources */,
DB126D071E5368A100054E95 /* Deferred.swift in Sources */,
DBABD0BC203F2E3E00C50896 /* Atomics.swift in Sources */,
DB126D101E5368A100054E95 /* Promise.swift in Sources */,
DBA01B052071E69100083CD0 /* FutureMap.swift in Sources */,
DB126D0B1E5368A100054E95 /* FutureCollections.swift in Sources */,
DB126D0C1E5368A100054E95 /* FutureComposition.swift in Sources */,
DB126D421E5368AD00054E95 /* TaskAndThen.swift in Sources */,
Expand Down Expand Up @@ -869,6 +901,8 @@
DB126D131E5368A200054E95 /* Executor.swift in Sources */,
DB126D301E5368A800054E95 /* TaskResult.swift in Sources */,
DB126D181E5368A200054E95 /* FutureEveryMap.swift in Sources */,
DBA01B0A2071E69100083CD0 /* FutureAndThen.swift in Sources */,
DBA01B0F2071E6FF00083CD0 /* FuturePeek.swift in Sources */,
DB126D141E5368A200054E95 /* ExistentialFuture.swift in Sources */,
DB126D4A1E5368AE00054E95 /* ExistentialTask.swift in Sources */,
DB126D1C1E5368A200054E95 /* Protected.swift in Sources */,
Expand All @@ -882,11 +916,13 @@
DB126D4C1E5368AE00054E95 /* ResultPromise.swift in Sources */,
DB126D511E5368AE00054E95 /* TaskMap.swift in Sources */,
DB126D4E1E5368AE00054E95 /* TaskCollections.swift in Sources */,
DBA01B002071E5D300083CD0 /* FutureUpon.swift in Sources */,
DB126D501E5368AE00054E95 /* TaskIgnore.swift in Sources */,
DB126D4F1E5368AE00054E95 /* TaskGroup.swift in Sources */,
DB126D121E5368A200054E95 /* Deferred.swift in Sources */,
DBABD0BD203F2E3E00C50896 /* Atomics.swift in Sources */,
DB126D1B1E5368A200054E95 /* Promise.swift in Sources */,
DBA01B062071E69100083CD0 /* FutureMap.swift in Sources */,
DB126D161E5368A200054E95 /* FutureCollections.swift in Sources */,
DB126D171E5368A200054E95 /* FutureComposition.swift in Sources */,
DB126D4D1E5368AE00054E95 /* TaskAndThen.swift in Sources */,
Expand Down Expand Up @@ -926,6 +962,8 @@
DB126D1E1E5368A200054E95 /* Executor.swift in Sources */,
DB126D331E5368A900054E95 /* TaskResult.swift in Sources */,
DB126D231E5368A200054E95 /* FutureEveryMap.swift in Sources */,
DBA01B0B2071E69100083CD0 /* FutureAndThen.swift in Sources */,
DBA01B102071E6FF00083CD0 /* FuturePeek.swift in Sources */,
DB126D1F1E5368A200054E95 /* ExistentialFuture.swift in Sources */,
DB126D551E5368AE00054E95 /* ExistentialTask.swift in Sources */,
DB126D271E5368A200054E95 /* Protected.swift in Sources */,
Expand All @@ -939,11 +977,13 @@
DB126D571E5368AE00054E95 /* ResultPromise.swift in Sources */,
DB126D5C1E5368AE00054E95 /* TaskMap.swift in Sources */,
DB126D591E5368AE00054E95 /* TaskCollections.swift in Sources */,
DBA01B012071E5D300083CD0 /* FutureUpon.swift in Sources */,
DB126D5B1E5368AE00054E95 /* TaskIgnore.swift in Sources */,
DB126D5A1E5368AE00054E95 /* TaskGroup.swift in Sources */,
DB126D1D1E5368A200054E95 /* Deferred.swift in Sources */,
DBABD0BE203F2E3E00C50896 /* Atomics.swift in Sources */,
DB126D261E5368A200054E95 /* Promise.swift in Sources */,
DBA01B072071E69100083CD0 /* FutureMap.swift in Sources */,
DB126D211E5368A200054E95 /* FutureCollections.swift in Sources */,
DB126D221E5368A200054E95 /* FutureComposition.swift in Sources */,
DB126D581E5368AE00054E95 /* TaskAndThen.swift in Sources */,
Expand Down
6 changes: 0 additions & 6 deletions Sources/Deferred/Deferred.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@ public final class Deferred<Value>: FutureProtocol, PromiseProtocol {

// MARK: PromiseProtocol

public var isFilled: Bool {
return storage.withUnsafeMutablePointers { (_, pointerToReference) in
bnr_atomic_load_relaxed(pointerToReference) != nil
}
}

@discardableResult
public func fill(with value: Value) -> Bool {
let reference = Storage.convertToReference(value)
Expand Down
2 changes: 0 additions & 2 deletions Sources/Deferred/Executor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ extension DispatchQueue: Executor {
}
}

public typealias DefaultExecutor = DispatchQueue

/// An operation queue manages a number of operation objects, making high
/// level features like cancellation and dependencies simple.
///
Expand Down
40 changes: 30 additions & 10 deletions Sources/Deferred/ExistentialFuture.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ in a playground, the following post, and the Swift standard library:
*/

// Abstract class that fake-conforms to `FutureProtocol` for use by `Future`.
private class FutureBox<Value> {
private class Box<Value> {
func upon(_: Future<Value>.PreferredExecutor, execute _: @escaping(Value) -> Void) {
fatalError()
}

func upon(_: Executor, execute _: @escaping(Value) -> Void) {
fatalError()
}

func upon(_: DispatchQueue, execute _: @escaping(Value) -> Void) {
func peek() -> Value? {
fatalError()
}

Expand All @@ -32,33 +36,37 @@ private class FutureBox<Value> {
}

// Concrete future wrapper given an instance of a `FutureProtocol`.
private final class ForwardedTo<Future: FutureProtocol>: FutureBox<Future.Value> {
private final class ForwardedTo<Future: FutureProtocol>: Box<Future.Value> {
let base: Future
init(base: Future) {
self.base = base
}

override func upon(_ executor: DispatchQueue, execute body: @escaping(Future.Value) -> Void) {
override func upon(_ executor: Future.PreferredExecutor, execute body: @escaping(Future.Value) -> Void) {
return base.upon(executor, execute: body)
}

override func upon(_ executor: Executor, execute body: @escaping(Future.Value) -> Void) {
return base.upon(executor, execute: body)
}

override func peek() -> Future.Value? {
return base.peek()
}

override func wait(until time: DispatchTime) -> Future.Value? {
return base.wait(until: time)
}
}

// Concrete future wrapper for an always-filled future.
private final class Always<Value>: FutureBox<Value> {
private final class Always<Value>: Box<Value> {
let value: Value
init(value: Value) {
self.value = value
}

override func upon(_ queue: DispatchQueue, execute body: @escaping(Value) -> Void) {
override func upon(_ queue: Future<Value>.PreferredExecutor, execute body: @escaping(Value) -> Void) {
queue.async { [value] in
body(value)
}
Expand All @@ -70,19 +78,27 @@ private final class Always<Value>: FutureBox<Value> {
}
}

override func peek() -> Value? {
return value
}

override func wait(until _: DispatchTime) -> Value? {
return value
}
}

// Concrete future wrapper that will never get filled.
private final class Never<Value>: FutureBox<Value> {
private final class Never<Value>: Box<Value> {
override init() {}

override func upon(_: DispatchQueue, execute _: @escaping(Value) -> Void) {}
override func upon(_: Future<Value>.PreferredExecutor, execute _: @escaping(Value) -> Void) {}

override func upon(_: Executor, execute _: @escaping(Value) -> Void) {}

override func peek() -> Value? {
return nil
}

override func wait(until _: DispatchTime) -> Value? {
return nil
}
Expand All @@ -101,7 +117,7 @@ private final class Never<Value>: FutureBox<Value> {
/// ensuring that only your implementation can fill the deferred value
/// using the `PromiseProtocol` aspect.
public struct Future<Value>: FutureProtocol {
private let box: FutureBox<Value>
private let box: Box<Value>

/// Create a future whose `upon(_:execute:)` methods forward to `base`.
public init<OtherFuture: FutureProtocol>(_ base: OtherFuture)
Expand All @@ -128,14 +144,18 @@ public struct Future<Value>: FutureProtocol {
self.box = other.box
}

public func upon(_ queue: DispatchQueue, execute body: @escaping(Value) -> Void) {
public func upon(_ queue: PreferredExecutor, execute body: @escaping(Value) -> Void) {
return box.upon(queue, execute: body)
}

public func upon(_ executor: Executor, execute body: @escaping(Value) -> Void) {
return box.upon(executor, execute: body)
}

public func peek() -> Value? {
return box.peek()
}

public func wait(until time: DispatchTime) -> Value? {
return box.wait(until: time)
}
Expand Down
Loading

0 comments on commit 1b39f30

Please sign in to comment.