-
-
Save elm4ward/4d5f5a7133eed652dbfbd6292b9878f1 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
import UIKit | |
enum GraphicsCommand { | |
case setColour(colour: UInt32) | |
case moveTo(x: Float, y: Float) | |
case lineTo(x: Float, y: Float) | |
} | |
class GraphicsDSL { | |
var commands = [GraphicsCommand]() | |
var colour: UInt32 = 0xffffff { | |
didSet { | |
if oldValue != colour { | |
commands.append(.setColour(colour: colour)) | |
} | |
} | |
} | |
func moveTo(x: Float, y: Float){ | |
commands.append(.moveTo(x: x, y: y)) | |
} | |
func lineTo(x: Float, y: Float){ | |
commands.append(.lineTo(x: x, y: y)) | |
} | |
} | |
class GraphicsBuilder { | |
/// Called with a closure that can access a special list of functions and properties | |
func build(code: (GraphicsDSL) -> ()) -> [GraphicsCommand] { | |
let dsl = GraphicsDSL() | |
code(dsl) | |
return dsl.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 { b in | |
b.colour = 0xff0000 | |
b.moveTo(x: 50, y: 50) | |
b.colour = 0x00ff00 | |
b.lineTo(x: 100, y: 100) | |
b.colour = 0x0000ff | |
b.lineTo(x: 0, y: 100) | |
b.colour = 0xff00ff | |
b.lineTo(x: 50, y: 50) | |
} | |
print(commands.count) | |
for c in commands { | |
print(c) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment