1
1
mirror of https://github.com/danbee/persephone synced 2025-03-04 08:39:11 +00:00
persephone/Shared/MPDClient/Extensions/MPDClient+Idle.swift
Dan Barber ff88aa8f5e Move the handle idle command into the command queue
My theory is that it's ok to send the `noidle` synchronously but the
subsequent handling of the idle response should be on the command queue.
My hope is that this fixes issues with less than perfect network
connections (and also very occasionally seen on good networks).
2021-12-05 19:10:12 -06:00

83 lines
2.0 KiB
Swift

//
// Idle.swift
// Persephone
//
// Created by Daniel Barber on 2019/3/15.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Foundation
import mpdclient
extension MPDClient {
func noIdle() {
guard isConnected else { return }
if isIdle {
mpd_send_noidle(connection)
}
}
func idle(_ force: Bool = false) {
guard isConnected else { return }
let shouldIdle: Bool = (!isIdle && commandQueue.operationCount == 1) || force
if shouldIdle {
self.isIdle = true
mpd_send_idle(connection)
let handleIdleOperation = BlockOperation() { [unowned self] in
self.handleIdleResult()
}
handleIdleOperation.queuePriority = .high
commandQueue.addOperation(handleIdleOperation)
}
}
func handleIdleResult() {
let result = mpd_recv_idle(connection, true)
let mpdIdle = MPDIdle(rawValue: result.rawValue)
isIdle = false
if checkError() {
if mpdIdle.contains(.database) {
self.fetchAllAlbums()
}
if mpdIdle.contains(.queue) {
self.fetchQueue()
self.fetchStatus()
self.delegate?.didUpdateQueue(mpdClient: self, queue: self.queue)
if let status = self.status {
self.delegate?.didUpdateQueuePos(mpdClient: self, song: status.song)
}
}
if mpdIdle.contains(.player) ||
mpdIdle.contains(.options) ||
mpdIdle.contains(.mixer) {
self.fetchStatus()
if let status = self.status {
self.delegate?.didUpdateStatus(mpdClient: self, status: status)
self.delegate?.didUpdateQueuePos(mpdClient: self, song: status.song)
}
}
if mpdIdle.contains(.update) {
self.fetchStatus()
if self.status?.updating ?? false {
self.delegate?.willStartDatabaseUpdate(mpdClient: self)
} else {
self.delegate?.didFinishDatabaseUpdate(mpdClient: self)
}
}
if !mpdIdle.isEmpty {
self.idle()
}
}
}
}