diff --git a/Persephone/AppDelegate.swift b/Persephone/AppDelegate.swift index cf46953..95879b4 100644 --- a/Persephone/AppDelegate.swift +++ b/Persephone/AppDelegate.swift @@ -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 } diff --git a/Persephone/Components/Shared/MPDServerController.swift b/Persephone/Components/Shared/MPDServerController.swift index a21e940..f4ae753 100644 --- a/Persephone/Components/Shared/MPDServerController.swift +++ b/Persephone/Components/Shared/MPDServerController.swift @@ -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() } } diff --git a/Persephone/MPDClient/Extensions/MPDClient+Command.swift b/Persephone/MPDClient/Extensions/MPDClient+Command.swift index 049d443..af1ff43 100644 --- a/Persephone/MPDClient/Extensions/MPDClient+Command.swift +++ b/Persephone/MPDClient/Extensions/MPDClient+Command.swift @@ -14,6 +14,14 @@ extension MPDClient { userData: Dictionary = [:] ) { 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: diff --git a/Persephone/MPDClient/Extensions/MPDClient+Connection.swift b/Persephone/MPDClient/Extensions/MPDClient+Connection.swift index d219fd0..b18295b 100644 --- a/Persephone/MPDClient/Extensions/MPDClient+Connection.swift +++ b/Persephone/MPDClient/Extensions/MPDClient+Connection.swift @@ -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) } } diff --git a/Persephone/MPDClient/MPDClient.swift b/Persephone/MPDClient/MPDClient.swift index 75c8d36..9decfd8 100644 --- a/Persephone/MPDClient/MPDClient.swift +++ b/Persephone/MPDClient/MPDClient.swift @@ -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) } } diff --git a/Persephone/MPDClient/Models/MPDCommand.swift b/Persephone/MPDClient/Models/MPDCommand.swift index f3dee72..8c3d1ec 100644 --- a/Persephone/MPDClient/Models/MPDCommand.swift +++ b/Persephone/MPDClient/Models/MPDCommand.swift @@ -10,6 +10,9 @@ import Foundation extension MPDClient { enum MPDCommand { + case connect + case disconnect + // Transport commands case prevTrack case nextTrack