1
1
mirror of https://github.com/danbee/persephone synced 2025-03-04 08:39:11 +00:00

Refactor connection logic

The app would crash when connection settings were changed. This
refactors the connection logic to be consistent with the rest of the
mpdclient command structure. This ultimately fixes the bug.
This commit is contained in:
Daniel Barber 2020-01-13 22:00:47 -05:00
parent d075a06c41
commit b581f297c9
Signed by: danbarber
GPG Key ID: 931D8112E0103DD8
6 changed files with 66 additions and 46 deletions

View File

@ -23,9 +23,6 @@ class AppDelegate: NSObject,
@IBOutlet weak var addSelectedSongToQueueMenuItem: NSMenuItem!
func applicationDidFinishLaunching(_ aNotification: Notification) {
connectToMPDServer()
instantiateControllers()
mediaKeyTap = MediaKeyTap(delegate: self)
mediaKeyTap?.start()
@ -34,22 +31,16 @@ class AppDelegate: NSObject,
$0.uiState
}
}
instantiateControllers()
connectToMPDServer()
}
func connectToMPDServer() {
let mpdServer = App.store.state.preferencesState.mpdServer
App.mpdClient = MPDClient(
host: mpdServer.hostOrDefault,
port: mpdServer.portOrDefault,
withDelegate: App.mpdServerDelegate
)
App.mpdClient.connect()
App.mpdServerController.connect()
}
func instantiateControllers() {
_ = App.mpdServerController
_ = App.userNotificationsController
}

View File

@ -11,9 +11,24 @@ import ReSwift
class MPDServerController {
init() {
// App.store.subscribe(self) {
// $0.select { $0.preferencesState.mpdServer }
// }
App.mpdClient = MPDClient(withDelegate: App.mpdServerDelegate)
App.store.subscribe(self) {
$0.select { $0.preferencesState.mpdServer }
}
}
func connect() {
let mpdServer = App.store.state.preferencesState.mpdServer
App.mpdClient.connect(
host: mpdServer.hostOrDefault,
port: mpdServer.portOrDefault
)
}
func disconnect() {
App.mpdClient.disconnect()
}
}
@ -21,7 +36,9 @@ extension MPDServerController: StoreSubscriber {
typealias StoreSubscriberStateType = MPDServer
func newState(state: MPDServer) {
App.mpdClient.disconnect()
App.mpdClient.connect()
guard App.mpdClient != nil else { return }
disconnect()
connect()
}
}

View File

@ -14,6 +14,14 @@ extension MPDClient {
userData: Dictionary<String, Any> = [:]
) {
switch command {
case .connect:
guard let host = userData["host"] as? String,
let port = userData["port"] as? Int
else { return }
createConnection(host: host, port: port)
case .disconnect:
freeConnection()
// Transport commands
case .prevTrack:

View File

@ -10,40 +10,42 @@ import Foundation
import mpdclient
extension MPDClient {
func makeConnectionOperation(host: String, port: Int) -> BlockOperation {
BlockOperation { [unowned self] in
guard let connection = mpd_connection_new(host, UInt32(port), 10000),
mpd_connection_get_error(connection) == MPD_ERROR_SUCCESS
else { return }
func createConnection(host: String, port: Int) {
guard let connection = mpd_connection_new(host, UInt32(port), 10000),
mpd_connection_get_error(connection) == MPD_ERROR_SUCCESS
else { return }
self.isConnected = true
self.isConnected = true
guard let status = mpd_run_status(connection)
else { return }
guard let status = mpd_run_status(connection)
else { return }
self.connection = connection
self.status = MPDStatus(status)
self.connection = connection
self.status = MPDStatus(status)
self.delegate?.didConnect(mpdClient: self)
self.delegate?.didUpdateStatus(mpdClient: self, status: self.status!)
self.delegate?.didConnect(mpdClient: self)
self.delegate?.didUpdateStatus(mpdClient: self, status: self.status!)
}
func freeConnection() {
guard isConnected else { return }
self.delegate?.willDisconnect(mpdClient: self)
mpd_connection_free(self.connection)
self.isConnected = false
}
func connect(host: String, port: Int) {
let commandOperation = BlockOperation() { [unowned self] in
self.sendCommand(command: .connect, userData: ["host": host, "port": port])
self.idle()
}
commandQueue.addOperation(commandOperation)
}
func connect() {
commandQueue.addOperation(connectionOperation)
}
func disconnect() {
guard isConnected else { return }
noIdle()
commandQueue.addOperation { [unowned self] in
self.delegate?.willDisconnect(mpdClient: self)
mpd_connection_free(self.connection)
self.isConnected = false
}
enqueueCommand(command: .disconnect)
}
}

View File

@ -22,9 +22,8 @@ class MPDClient {
let commandQueue = OperationQueue()
init(host: String, port: Int, withDelegate delegate: MPDClientDelegate?) {
init(withDelegate delegate: MPDClientDelegate?) {
commandQueue.maxConcurrentOperationCount = 1
self.delegate = delegate
self.connectionOperation = makeConnectionOperation(host: host, port: port)
}
}

View File

@ -10,6 +10,9 @@ import Foundation
extension MPDClient {
enum MPDCommand {
case connect
case disconnect
// Transport commands
case prevTrack
case nextTrack