Skip to content

Instantly share code, notes, and snippets.

@plumhead
Created June 6, 2014 22:01
Show Gist options
  • Save plumhead/c4597bdda147073cf791 to your computer and use it in GitHub Desktop.
Save plumhead/c4597bdda147073cf791 to your computer and use it in GitHub Desktop.
Hiding GCD behing Async
//
// Async.swift
// TestSwiftUI
//
// Created by Plumhead on 06/06/2014.
//
// There are many holes in this which will be ironed out over time - put up as a starting point for ideas
//
import Foundation
enum AwaitResult<T> {
case Success(a : T)
case Timeout
}
typealias Ctx = dispatch_group_t
operator infix ! {associativity left precedence 140}
func ! <T> (ctx: Ctx,f: () -> T) -> T {
var result : (() -> T)?
dispatch_group_async(ctx,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
println("pre task")
sleep(5)
result = {f()}
println("post task")
})
dispatch_group_wait(ctx, DISPATCH_TIME_FOREVER)
return result!()
}
class Async {
class func async<T>(f : Ctx -> T)(ctx: Ctx) -> T {
println("Running Async!!!")
return f(ctx)
}
class func Run<T>(f: Ctx -> T) -> AwaitResult<T> {
var result : AwaitResult<T> = .Timeout
let group = dispatch_group_create()
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
println("RunAsync Starting")
sleep(5)
let childgroup = dispatch_group_create()
let r = f(childgroup)
dispatch_group_wait(childgroup, DISPATCH_TIME_FOREVER)
result = AwaitResult.Success(a:r)
println("RunAsync Ending")
})
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
return result
}
class func test() {
func f3(name : String) -> Int {return name.lengthOfBytesUsingEncoding(NSASCIIStringEncoding)}
/*
In FSharp you can do something like the following.
let r = async {
let! a = someFunc1()
let! b = someFunc2(with params)
let c = 123
return a + b + c
}
|> Async.RunAsynchronously
Can we get close to this in Swift?
Lots of gaps in this implementation - still getting to grips with Swift
*/
// No obvious signs of GCD in this bit - trying to bury in the lower level detail
// Timeouts, cancellations TODO
let f1 = async {
(ctx : Ctx) -> Int in
let a = ctx ! {10}
let b = ctx ! {20}
let c = ctx ! {f3("Andy Calderbank")}
println("Finished Running Async Block with result =\(a+b+c)")
return a + b + c
}
let result = Async.Run(f1)
switch result {
case let .Success(a) : println ("Success with result=\(a)")
case .Timeout : println("Timeout") // NOT IMPLEMENTED YET!
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment