Skip to content

Instantly share code, notes, and snippets.

@tjhancocks
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjhancocks/61a9074bdc6213fddc39 to your computer and use it in GitHub Desktop.
Save tjhancocks/61a9074bdc6213fddc39 to your computer and use it in GitHub Desktop.
GCD Stuffs

Dispatch

This is an experimental thing that I'm working on to have a play around with syntactic sugar in Swift. The idea is to make dispatching to threads easier and more obvious.

import Dispatch
import Foundation
/// The thread enumeration acts as a simple way of requesting a thread
/// through out the app.
enum Thread {
case Any
case Main
case Background
case Concurrent(String)
}
/// We produce an extension to thread to allow it to be able to return
/// the actual GCD instances of those threads.
extension Thread {
var queue: dispatch_queue_t {
switch self {
case .Any:
return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)
case .Main:
return dispatch_get_main_queue()
case .Background:
return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
case .Concurrent(let name) where name != "":
return dispatch_queue_create((name as NSString).UTF8String, DISPATCH_QUEUE_CONCURRENT)
default:
fatalError("Invalid thread queue requested.")
}
}
}
/// We can also extend thread to provide a "run" method so that we can submit
/// closures to the queue directly and cut out the middle man.
extension dispatch_queue_t {
func run(closure: dispatch_block_t) {
dispatch_async(self, closure)
}
}
/// Convience functions to make what appear to be language constructs as well.
func mainThread(closure: dispatch_block_t) {
Thread.Main.queue.run(closure)
}
func async(closure: dispatch_block_t) {
Thread.Any.queue.run(closure)
}
func async(named: String, closure: dispatch_block_t) {
Thread.Concurrent(named).queue.run(closure)
}
func background(closure: dispatch_block_t) {
Thread.Background.queue.run(closure)
}
/// Given the new syntax of a block, and the need to commonly dispatch to the
/// main thread, lets create an operator, that returns a closure that
/// automatically dispatches itself to the main thread.
prefix operator ^ {}
prefix func ^ (closure: dispatch_block_t) -> dispatch_block_t {
return { mainThread(closure) }
}
/// We also might want to join the functionality of two closures. This makes
/// makes a new closure that executes the two provided closures in sequence.
func + (lhs: dispatch_block_t, rhs: dispatch_block_t) -> dispatch_block_t {
return { lhs(); rhs() }
}
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(aNotification: NSNotification) {
// We define a new block that will be automatically dispatched to the main
// thread. We can call and use this block safely from any thread!
let updateWindowTitle = ^{ [unowned self] in
self.window.title = "We set the window title from a thread!"
}
// We can define another block to centre the window...
let centerWindow = ^{ [unowned self] in
self.window.center()
}
// And then join them all together like so
let windowActions = updateWindowTitle + centerWindow
// We're going to set up a wait on a background thread, then run all the
// window actions together after a small delay
async("MyBackgroundThread") {
NSThread.sleepForTimeInterval(5)
windowActions()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment