Skip to content

Instantly share code, notes, and snippets.

@vikingosegundo
Created March 27, 2022 16:47
Show Gist options
  • Save vikingosegundo/8b53c5d20b18783496049968a306e12a to your computer and use it in GitHub Desktop.
Save vikingosegundo/8b53c5d20b18783496049968a306e12a to your computer and use it in GitHub Desktop.
func createRadioFeature(
store s: Store,
player p: AudioPlayer,
output o: @escaping Output) -> Input
{
let loader = StationLoader( store:s, responder:handle(output:o))
let player = Player(audioplayer:p, store:s, responder:handle(output:o))
let visActivater = VisualisationActivator( store:s, responder:handle(output:o))
let visualiser = Visualiser(audioplayer:p, store:s, responder:handle(output:o))
let filter = StationFilter( store:s, responder:handle(output:o))
let favorites = FavoriteManager( store:s, responder:handle(output:o))
let stationsManager = StationManager( store:s, responder:handle(output:o))
func execute(command cmd:Message.Radio) {
if case .load(.all(.stations)) = cmd { loader.request(to:.load(.all(.stations))) }
if case .play(let station ) = cmd { player.request(to:.play(station)) }
if case .pause = cmd { player.request(to:.pause) }
if case .filter(by:.name(let name)) = cmd { filter.request(to:.filter(by:.name(name))) }
if case .clearFilter = cmd { filter.request(to: .clear) }
if case .add (let station, to:.favorites) = cmd { favorites.request(to:.add (.favorite(station))) }
if case .remove(let station,from:.favorites) = cmd { favorites.request(to:.remove(.favorite(station))) }
if case .visualizer(.activate) = cmd { visActivater.request( .activate); visualiser.request(to: .publishLoudness) }
if case .visualizer(.deactivate) = cmd { visActivater.request(.deactivate); visualiser.request(to:.unPublishLoudness) }
if case .visualizer(.start) = cmd { visualiser.request(to: .publishLoudness) }
if case .visualizer(.stop) = cmd { visualiser.request(to:.unPublishLoudness) }
}
func execute(command cmd:Message.Settings) {
if case .fetch(.all(.stations)) = cmd { stationsManager.request(.all(.stations)) }
}
return { // entry point
if case .radio (let c) = $0 { execute(command:c) } // execute if radio feature is command's recipient
if case .settings(let c) = $0 { execute(command:c) } // settings messages
}
}
//MARK: - private handler
private func handle(output: @escaping Output) -> ( StationLoader.Response) -> () { { process(response:$0,output:output) } }
private func handle(output: @escaping Output) -> ( Player.Response) -> () { { process(response:$0,output:output) } }
private func handle(output: @escaping Output) -> ( Visualiser.Response) -> () { { process(response:$0,output:output) } }
private func handle(output: @escaping Output) -> ( StationFilter.Response) -> () { { process(response:$0,output:output) } }
private func handle(output: @escaping Output) -> ( FavoriteManager.Response) -> () { { process(response:$0,output:output) } }
private func handle(output: @escaping Output) -> (VisualisationActivator.Response) -> () { { process(response:$0,output:output) } }
private func handle(output: @escaping Output) -> ( StationManager.Response) -> () { { process(response:$0,output:output) } }
//MARK: - private processing
private func process(response: StationLoader.Response, output: @escaping Output) {
switch response {
case let .all(.stations(stations, loaded:.successfully)): output(.radio(.loaded(.all(.stations(stations), .successfully))))
case .all(.stations(_, loaded:.failed )): output(.radio(.loaded(.all(.stations([] ), .failed ))))
}
}
private func process(response: Player.Response, output: @escaping Output) {
switch response {
case let .playing(song,on:station): output(.radio(.playing(song,on:station)))
case let .paused ( station): output(.radio(.paused ( station)))
case let .waiting( station): output(.radio(.waiting( station)))
}
}
private func process(response: Visualiser.Response, output: @escaping Output) {
switch response {
case let .loudness(interpolated:values): output(.radio(.visualizer(.loudness(interpolated:values))))
}
}
private func process(response: StationFilter.Response, output: @escaping Output) {
switch response {
case let .filtered(by: .name(name, stations: stations)): output(.radio(.filtered(by:.name(name, stations:stations))))
case .filteredCleared : output(.radio(.filterCleard) )
}
}
private func process(response: FavoriteManager.Response, output: @escaping Output) {
switch response {
case .station(let station,.was(.added )): output(.radio(.favorite(.was(.added ),for:station)))
case .station(let station,.was(.removed)): output(.radio(.favorite(.was(.removed),for:station)))
}
}
private func process(response: VisualisationActivator.Response, output: @escaping Output) {
switch response {
case .activation(.succeeded): output(.radio(.visualizer( .activation(.succeeded))))
case .deactivation(.succeeded): output(.radio(.visualizer(.deactivation(.succeeded))))
}
}
private func process(response: StationManager.Response, output: @escaping Output) {
switch response {
case let .all(stations:stations ): output(.settings(.fetched(.all(.stations) , stations)))
case let .filtered( stations, by:.title(filterRule)): output(.settings(.fetched(.stations(filterRule), stations)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment