Last active
May 31, 2016 10:11
-
-
Save charlieMonroe/655f2b5e25cc0b4ba06c0ddafa41c73b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// An argument of the function. | |
struct Argument { | |
var name: String | |
var type: Any.Type | |
} | |
/// Variable captured by the closure. | |
struct CapturedVariable { | |
var name: String | |
var type: Any.Type | |
var value: Any | |
/// Possibly other stuff like weak, etc. | |
} | |
protocol Function { | |
/* associatedtype ReturnType? */ | |
/// Arguments taken by the function. | |
var arguments: [Argument] { get } | |
/// If it's a closure, it contains info about the | |
/// variables captured by the closure. Example: | |
/// | |
/// var x: CGFloat = 0.0 | |
/// let closure = { x = 3.0 } | |
/// | |
/// closure.capturedVariables[0]: | |
/// -name: "x" | |
/// -type: CGFloat.self | |
/// -value: CGFloat(0.0) | |
var capturedVariables: [CapturedVariable] { get } | |
/// Return type of the value. | |
var returnValueType: Any.Type { get } // ReturnType? | |
/// Will execute the function/closure with arguments. | |
/// Since the arguments don't need to be heterogenous, | |
/// it's Any. If a cast to the actual arguments required | |
/// by the function fails, fatalError is called. | |
func executeWithArguments(args: Any...) -> Any /* ReturnType */ | |
} | |
///// Examples of usage: | |
let closure1 = { print("hello") } | |
closure1.arguments // Empty array | |
closure1.capturedVariables // Empty array | |
let myString = "john" | |
let closure2 = { (string: String) -> String in (myString + string).lowercaseString } | |
closure2.arguments // { name: "string", type: String.Type } | |
closure2.capturedVariables // { name: "myString", type: String.Type, value: "john" } | |
let function3 = NSArray.arrayByAddingObjectsFromArray /// (NSArray) -> ([AnyObject] -> [AnyObject]) | |
function3.arguments // { name: "self", type: NSArray.Type } | |
function3.capturedVariables // Empty. | |
function3.returnValueType /// (([AnyObject]) -> [AnyObject]).Type | |
class Invocation<ReturnType> { | |
let function: Function | |
func invokeOnMainThread(args: [Any]) -> ReturnType { | |
let result: ReturnType! = nil | |
dispatch_sync(dispatch_get_main_queue(), { | |
// #splat was discussed in another thread. | |
result = self.function.executeWithArguments(#splat(args)) as! ReturnType | |
}) | |
return result | |
} | |
} | |
func doSomethingWithArgument<T>(arg: T) { | |
if arg is Function { | |
fatalError("You can't pass functions here!") | |
} | |
} | |
doSomethingWithArgument(closure1) // fatalError |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment