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

View File

@ -11,9 +11,24 @@ import ReSwift
class MPDServerController { class MPDServerController {
init() { init() {
// App.store.subscribe(self) { App.mpdClient = MPDClient(withDelegate: App.mpdServerDelegate)
// $0.select { $0.preferencesState.mpdServer }
// } 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 typealias StoreSubscriberStateType = MPDServer
func newState(state: MPDServer) { func newState(state: MPDServer) {
App.mpdClient.disconnect() guard App.mpdClient != nil else { return }
App.mpdClient.connect()
disconnect()
connect()
} }
} }

View File

@ -15,6 +15,14 @@ extension MPDClient {
) { ) {
switch command { 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 // Transport commands
case .prevTrack: case .prevTrack:
sendPreviousTrack() sendPreviousTrack()

View File

@ -10,8 +10,7 @@ import Foundation
import mpdclient import mpdclient
extension MPDClient { extension MPDClient {
func makeConnectionOperation(host: String, port: Int) -> BlockOperation { func createConnection(host: String, port: Int) {
BlockOperation { [unowned self] in
guard let connection = mpd_connection_new(host, UInt32(port), 10000), guard let connection = mpd_connection_new(host, UInt32(port), 10000),
mpd_connection_get_error(connection) == MPD_ERROR_SUCCESS mpd_connection_get_error(connection) == MPD_ERROR_SUCCESS
else { return } else { return }
@ -26,24 +25,27 @@ extension MPDClient {
self.delegate?.didConnect(mpdClient: self) self.delegate?.didConnect(mpdClient: self)
self.delegate?.didUpdateStatus(mpdClient: self, status: self.status!) self.delegate?.didUpdateStatus(mpdClient: self, status: self.status!)
self.idle()
}
} }
func connect() { func freeConnection() {
commandQueue.addOperation(connectionOperation)
}
func disconnect() {
guard isConnected else { return } guard isConnected else { return }
noIdle()
commandQueue.addOperation { [unowned self] in
self.delegate?.willDisconnect(mpdClient: self) self.delegate?.willDisconnect(mpdClient: self)
mpd_connection_free(self.connection) mpd_connection_free(self.connection)
self.isConnected = false 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 disconnect() {
enqueueCommand(command: .disconnect)
} }
} }

View File

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

View File

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