Last active
September 1, 2016 09:48
-
-
Save marcpalmer/3413cc0f150ce6e7c00c29ced2c7d5b2 to your computer and use it in GitHub Desktop.
Example of using Swift property change observation to bind models to arguments passed to DSL closures
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
//: 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