Skip to content

Instantly share code, notes, and snippets.

@jon-cotton
Created January 15, 2016 10:41
Show Gist options
  • Save jon-cotton/dd88c526db2f62c6054b to your computer and use it in GitHub Desktop.
Save jon-cotton/dd88c526db2f62c6054b to your computer and use it in GitHub Desktop.
//: Adventures in generics
import Foundation
protocol MyBaseProtocol {
func didSomething()
func didAnotherThing()
}
protocol MyDataProtocol : MyBaseProtocol {
typealias DataType
func didSomethingWithData(data: DataType)
}
class Thing<DelegateType: MyBaseProtocol> {
var delegate: DelegateType?
func doSomething() {
guard let d = delegate
else { return }
d.didSomething()
}
func doAnotherThing() {
guard let d = delegate
else { return }
d.didAnotherThing()
}
}
protocol DataHandlingThing {
typealias Data
func getSomeData() -> Data
func doSomethingWithData(data: Data)
}
class DataThing<T, DelegateType: MyDataProtocol where DelegateType.DataType == T>: Thing<DelegateType>, DataHandlingThing {
let data: T
init(data: T) {
self.data = data
}
func getSomeData() -> T {
return data
}
override func doSomething() {
super.doSomething()
doSomethingWithData(getSomeData())
}
func doSomethingWithData(data: T) {
delegate?.didSomethingWithData(data)
}
}
class AggregateThing<DelegateType: MyBaseProtocol, ThingObserver: MyBaseProtocol>: Thing<DelegateType> {
var things: [Thing<ThingObserver>] = []
override func doSomething() {
for thing in things {
thing.doSomething()
}
super.doSomething()
}
}
class AggregateDataThing<T, DelegateType: MyDataProtocol, ThingObserver: MyDataProtocol where DelegateType.DataType == [T], ThingObserver.DataType == T>: AggregateThing<DelegateType, ThingObserver>, DataHandlingThing {
typealias Data = [T]
private var dataThings: [DataThing<T, ThingObserver>] = []
init(things: [DataThing<T, ThingObserver>]) {
self.dataThings = things
}
func getSomeData() -> [T] {
var data: [T] = []
for dataThing in dataThings {
data.append(dataThing.getSomeData())
}
return data
}
override func doSomething() {
doSomethingWithData(getSomeData())
super.doSomething()
}
func doSomethingWithData(data: [T]) {
delegate?.didSomethingWithData(data)
}
}
class SimpleStringObserver : MyDataProtocol {
func didSomething() {}
func didAnotherThing() {}
func didSomethingWithData(data: String) {}
}
class SimpleStringCollectionObserver : MyDataProtocol {
func didSomething() {}
func didAnotherThing() {}
func didSomethingWithData(data: [String]) {
for str in data {
print(str)
}
}
}
let stringyThing = DataThing<String, SimpleStringObserver>(data: "A String!")
let anotherStringyThing = DataThing<String, SimpleStringObserver>(data: "Another String!")
let aggregateStringyThing = AggregateDataThing<String, SimpleStringCollectionObserver, SimpleStringObserver>(things:[stringyThing, anotherStringyThing])
let dataObserver = SimpleStringCollectionObserver()
aggregateStringyThing.delegate = dataObserver
aggregateStringyThing.doSomething()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment