Last active
August 18, 2017 05:34
-
-
Save andrekandore/f2539a74002d1255cfc3da58faf0f007 to your computer and use it in GitHub Desktop.
Just an idea!
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
actor Downloader { | |
let mainActor : TheMainActor | |
var theList : [URL] = [] | |
init(mainActor: TheMainActor) { self.mainActor = mainActor } | |
actor case .initialized, .ready { | |
actor func setList(list:[String]) -> self.ready? //can only call this from these 2 (initialized and ready) states | |
} | |
actor case .ready { | |
actor func start() -> self.downloading? | |
} | |
actor case .downloading, .finished | |
public var progress : Float | |
} | |
} | |
//If the state was explicit for such an actor, it makes it… | |
// - basically impossible to misuse it (from inside and outside) | |
// - eliminates a lot of boilerplate | |
// - only the actor itself can change its state explicitly | |
// - easier to attach handlers/observers to the actor upon state change (im thinking KVO, wiring up multiple actors etc) | |
// - more clear about the state to the reader and write of the code | |
// - reduces 'var soup' that a lot of classes become when state gets complex since each variable is tied to an explicit state just like an enum | |
// - its possible then to add preconditions (and maybe even automatic errors) for each state like… | |
actor case .finished { | |
precondition { | |
self is [.downloading, .canceled] | |
progress >= 1 | |
} | |
} | |
actor case .ready { | |
precondition { | |
theList.count > 0 | |
} | |
} | |
//How would you access and check state? | |
//Since each state could be returned as an optional, it might be something like this… | |
let aDownloader = Downloader(mainActor:UIActor) | |
//not even possible, since .start() doesn’t exist in the initial state | |
aDownloader.start() | |
//wont call start() because 'ready' returns nil (theList hasnt been set yet) | |
aDownloader.ready?.start() | |
//ok | |
aDownloader.initialized?.setList(list) | |
//you could also chain operations... | |
let download = try aDownloader.initialized?.setList(list)?.start() //ok | |
//check progress | |
let progress = download.progress | |
//or,,, | |
let progress = aDownloader.downloading?.progress | |
//wait until finished | |
let result = await downloading.finished |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment