Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Example of using Swift property change observation to bind models to arguments passed to DSL closures
//: Playground - show possible simple DSL mechanism using mutable local vars
import UIKit
typealias MoveToFunction = (x: Float, y: Float) -> ()
typealias LineToFunction = (x: Float, y: Float) -> ()
typealias DSLClosure = (inout colour: UInt32, moveTo: MoveToFunction, lineTo: LineToFunction) -> ()
enum GraphicsCommand {
case setColour(colour: UInt32)
case moveTo(x: Float, y: Float)
case lineTo(x: Float, y: Float)
}
class GraphicsBuilder {
/// Called with a closure that can access a special list of functions and properties
func build(code: DSLClosure) -> [GraphicsCommand] {
var commands = [GraphicsCommand]()
var colour: UInt32 = 0xffffff {
didSet {
if oldValue != colour {
commands.append( .setColour(colour: colour))
}
}
}
let moveTo = { x, y in
commands.append( .moveTo(x: x, y: y))
}
let lineTo = { x, y in
commands.append( .lineTo(x: x, y: y))
}
code(colour: &colour, moveTo: moveTo, lineTo: lineTo)
return commands
}
}
let dsl = GraphicsBuilder()
/// This is what it looks like to use it. You can see what you can do in the arg list.
/// It is likely that moving these things to a struct is better. This would in itself be a nice pattern,
/// using structs to define the functionality of a DSL. However we're demonstrating the possibilities
/// of mutable, observable local vars here...
let commands = dsl.build { (colour, moveTo, lineTo) in
colour = 0xff0000
moveTo(x: 50, y: 50)
colour = 0x00ff00
lineTo(x: 100, y: 100)
colour = 0x0000ff
lineTo(x: 0, y: 100)
colour = 0xff00ff
lineTo(x: 50, y: 50)
}
print("Command list is \(commands)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment