Skip to content

Instantly share code, notes, and snippets.

@iThinker
Last active January 17, 2018 14:05
Show Gist options
  • Save iThinker/4faf106c8ce3b59c4c480b9fbd2c4dbb to your computer and use it in GitHub Desktop.
Save iThinker/4faf106c8ce3b59c4c480b9fbd2c4dbb to your computer and use it in GitHub Desktop.
class TrackSelectionStrategy {
static let straight: TrackSelectionStrategy = Straight()
static let shuffle: TrackSelectionStrategy = Shuffle()
fileprivate init() {}
func nextItem(_ sender: AudioPlayerImpl) -> AudioPlayerItem? {
return self.nextItemIndex(sender).map({ sender._items[$0] })
}
func previousItem(_ sender: AudioPlayerImpl) -> AudioPlayerItem? {
return self.previousItemIndex(sender).map({ sender._items[$0] })
}
func canGoForward(_ sender: AudioPlayerImpl) -> Bool {
return self.nextItemIndex(sender) != nil
}
func canGoBack(_ sender: AudioPlayerImpl) -> Bool {
return self.previousItemIndex(sender) != nil
}
private func nextItemIndex(_ sender: AudioPlayerImpl) -> Int? {
return nil
}
private func previousItemIndex(_ sender: AudioPlayerImpl) -> Int? {
return nil
}
private func currentItemIndex(_ sender: AudioPlayerImpl) -> Int? {
let items = sender._items
return sender.currentItem
.flatMap({ items.index(of: $0) })
}
private class Straight: TrackSelectionStrategy {
override func nextItemIndex(_ sender: AudioPlayerImpl) -> Int? {
let items = sender._items
return self.currentItemIndex(sender)
.map({ $0.advanced(by: 1) })
.flatMap({ $0 < items.count ? $0 : nil })
}
override func previousItemIndex(_ sender: AudioPlayerImpl) -> Int? {
return self.currentItemIndex(sender)
.map({ $0.advanced(by: -1) })
.flatMap({ $0 >= 0 ? $0 : nil })
}
}
private class Shuffle: TrackSelectionStrategy {
override func nextItemIndex(_ sender: AudioPlayerImpl) -> Int? {
return self.randomItemIndex(sender)
}
override func previousItemIndex(_ sender: AudioPlayerImpl) -> Int? {
return self.randomItemIndex(sender)
}
private func randomItemIndex(_ sender: AudioPlayerImpl) -> Int? {
let items = sender._items
guard items.count > 1 else {
return nil
}
return self.currentItemIndex(sender)
.map({ self.generateRandomNumber(upperBound: items.count, excluding: $0) })
}
private func generateRandomNumber(upperBound: Int, excluding: Int) -> Int {
let result = Int(arc4random_uniform(UInt32(upperBound)))
return result != excluding ? result : generateRandomNumber(upperBound: upperBound, excluding: excluding)
}
}
}
var nextItem: AudioPlayerItem? {
return self.trackSelectionStrategy.nextItem(self)
}
var previousItem: AudioPlayerItem? {
return self.trackSelectionStrategy.previousItem(self)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment