From 1c690a42d3c11195487fbcd1b92fde528eed0c74 Mon Sep 17 00:00:00 2001 From: Tae Won Ha Date: Sun, 31 Mar 2019 17:46:27 +0200 Subject: [PATCH] Remove unnec' observable layer between UiBridge and NvimView --- NvimView/NvimView/NvimView+UiBridge.swift | 24 ++-- NvimView/NvimView/NvimView.swift | 95 +--------------- NvimView/NvimView/UiBridge.swift | 132 ++++++++++------------ 3 files changed, 75 insertions(+), 176 deletions(-) diff --git a/NvimView/NvimView/NvimView+UiBridge.swift b/NvimView/NvimView/NvimView+UiBridge.swift index 035cd915..39ad78e2 100644 --- a/NvimView/NvimView/NvimView+UiBridge.swift +++ b/NvimView/NvimView/NvimView+UiBridge.swift @@ -9,6 +9,14 @@ import MessagePack extension NvimView { + final func initVimError() { + self.eventsSubject.onNext(.initVimError) + } + + final func optionSet(_ value: MessagePackValue) { + + } + final func resize(_ value: MessagePackValue) { guard let array = MessagePackUtils.array( from: value, ofSize: 2, conversion: { $0.intValue } @@ -213,10 +221,10 @@ extension NvimView { } } - final func ipcBecameInvalid(_ reason: String) { - self.bridgeLogger.fault("Bridge became invalid: \(reason)") + final func ipcBecameInvalid(_ error: Swift.Error) { + self.bridgeLogger.fault("Bridge became invalid: \(error)") - self.eventsSubject.onNext(.ipcBecameInvalid(reason)) + self.eventsSubject.onNext(.ipcBecameInvalid(error.localizedDescription)) self.eventsSubject.onCompleted() self.bridgeLogger.fault("Force-closing due to IPC error.") @@ -224,11 +232,11 @@ extension NvimView { .stop() .andThen(self.bridge.forceQuit()) .observeOn(MainScheduler.instance) - .wait(onCompleted: { - self.bridgeLogger.fault("Successfully force-closed the bridge.") - }, onError: { - self.bridgeLogger.fault("There was an error force-closing" + - " the bridge: \($0)") + .wait(onCompleted: { [weak self] in + self?.bridgeLogger.fault("Successfully force-closed the bridge.") + }, onError: { [weak self] in + self?.bridgeLogger.fault("There was an error force-closing" + + " the bridge: \($0)") }) } diff --git a/NvimView/NvimView/NvimView.swift b/NvimView/NvimView/NvimView.swift index d495d30c..a7de93ea 100644 --- a/NvimView/NvimView/NvimView.swift +++ b/NvimView/NvimView/NvimView.swift @@ -9,6 +9,7 @@ import MessagePack import os public class NvimView: NSView, + UiBridgeConsumer, NSUserInterfaceValidations, NSTextInputClient { @@ -129,6 +130,7 @@ public class NvimView: NSView, self.sourceFileUrls = config.sourceFiles super.init(frame: .zero) + self.bridge.consumer = self self.registerForDraggedTypes([NSPasteboard.PasteboardType(String(kUTTypeFileURL))]) self.wantsLayer = true @@ -137,8 +139,6 @@ public class NvimView: NSView, ) self.api.queue = self.queue - - self.subscribeToBridge() } convenience override public init(frame rect: NSRect) { @@ -221,95 +221,4 @@ public class NvimView: NSView, // MARK: - Private private var _linespacing = NvimView.defaultLinespacing - - private func subscribeToBridge() { - self.bridge.stream - .subscribe(onNext: { [weak self] msg in - switch msg { - - case .ready: - self?.log.info("Nvim is ready") - - case .initVimError: - self?.eventsSubject.onNext(.initVimError) - - case .unknown: - self?.bridgeLogger.error("Unknown message from NvimServer") - - case let .resize(value): - self?.resize(value) - - case .clear: - self?.clear() - - case .setMenu: - self?.updateMenu() - - case .busyStart: - self?.busyStart() - - case .busyStop: - self?.busyStop() - - case .mouseOn: - self?.mouseOn() - - case .mouseOff: - self?.mouseOff() - - case let .modeChange(value): - self?.modeChange(value) - - case .bell: - self?.bell() - - case .visualBell: - self?.visualBell() - - case let .flush(value): - self?.flush(value) - - case let .setTitle(value): - self?.setTitle(with: value) - - case .stop: - self?.stop() - - case let .dirtyStatusChanged(value): - self?.setDirty(with: value) - - case let .cwdChanged(value): - self?.cwdChanged(value) - - case let .colorSchemeChanged(value): - self?.colorSchemeChanged(value) - - case let .defaultColorsChanged(value): - self?.defaultColorsChanged(value) - - case let .optionSet(value): - self?.bridgeLogger.debug(value) - break - - case let .autoCommandEvent(value): - self?.autoCommandEvent(value) - - case let .highlightAttrs(value): - self?.setAttr(with: value) - - case .rpcEventSubscribed: - self?.rpcEventSubscribed() - - case let .fatalError(value): - self?.bridgeHasFatalError(value) - - case .debug1: - self?.debug1(nil) - - } - }, onError: { [weak self] error in - self?.bridgeLogger.fault("Error in the bridge stream: \(error)") - }) - .disposed(by: self.disposeBag) - } } diff --git a/NvimView/NvimView/UiBridge.swift b/NvimView/NvimView/UiBridge.swift index d65b2017..7f4648b3 100644 --- a/NvimView/NvimView/UiBridge.swift +++ b/NvimView/NvimView/UiBridge.swift @@ -8,50 +8,38 @@ import RxSwift import MessagePack import os +protocol UiBridgeConsumer: class { + + func initVimError() + func resize(_ value: MessagePackValue) + func clear() + func modeChange(_ value: MessagePackValue) + func flush(_ renderData: [MessagePackValue]) + func setTitle(with value: MessagePackValue) + func stop() + func autoCommandEvent(_ value: MessagePackValue) + func ipcBecameInvalid(_ error: Swift.Error) + func bell() + func cwdChanged(_ value: MessagePackValue) + func colorSchemeChanged(_ value: MessagePackValue) + func defaultColorsChanged(_ value: MessagePackValue) + func optionSet(_ value: MessagePackValue) + func setDirty(with value: MessagePackValue) + func rpcEventSubscribed() + func bridgeHasFatalError(_ value: MessagePackValue?) + func setAttr(with value: MessagePackValue) + func updateMenu() + func busyStart() + func busyStop() + func mouseOn() + func mouseOff() + func visualBell() + func suspend() +} + class UiBridge { - enum Message { - - case ready - - case initVimError - case resize(MessagePackValue) - case clear - case setMenu - case busyStart - case busyStop - case mouseOn - case mouseOff - case modeChange(MessagePackValue) - case bell - case visualBell - case flush([MessagePackValue]) - case setTitle(MessagePackValue) - case stop - case dirtyStatusChanged(MessagePackValue) - case cwdChanged(MessagePackValue) - case colorSchemeChanged(MessagePackValue) - case optionSet(MessagePackValue) - case defaultColorsChanged(MessagePackValue) - case autoCommandEvent(MessagePackValue) - case highlightAttrs(MessagePackValue) - case rpcEventSubscribed - case fatalError(MessagePackValue?) - case debug1 - case unknown - } - - enum Error: Swift.Error { - - case launchNvim - case nvimNotReady - case nvimQuitting - case ipc(Swift.Error) - } - - var stream: Observable { - return self.streamSubject.asObservable() - } + weak var consumer: UiBridgeConsumer? init(uuid: UUID, queue: DispatchQueue, config: NvimView.Config) { self.uuid = uuid @@ -83,7 +71,7 @@ class UiBridge { self?.handleMessage(msgId: message.msgid, data: message.data) }, onError: { [weak self] error in self?.log.error("There was an error on the local message port server: \(error)") - self?.streamSubject.onError(Error.ipc(error)) + self?.consumer?.ipcBecameInvalid(error) }) .disposed(by: self.disposeBag) } @@ -105,8 +93,7 @@ class UiBridge { } func deleteCharacters(_ count: Int, andInputEscapedString string: String) - -> Completable - { + -> Completable { guard let strData = string.data(using: .utf8) else { return .empty() } @@ -158,7 +145,6 @@ class UiBridge { private func handleMessage(msgId: Int32, data: Data?) { guard let msg = NvimServerMsgId(rawValue: Int(msgId)) else { - self.streamSubject.onNext(.unknown) return } @@ -167,8 +153,8 @@ class UiBridge { case .serverReady: self .establishNvimConnection() - .subscribe(onError: { error in - self.streamSubject.onError(Error.ipc(error)) + .subscribe(onError: { [weak self] error in + self?.consumer?.ipcBecameInvalid(error) }) .disposed(by: self.disposeBag) @@ -176,91 +162,88 @@ class UiBridge { self.runLocalServerAndNvimCompletable?(.completed) self.runLocalServerAndNvimCompletable = nil - self.streamSubject.onNext(.ready) - let isInitErrorPresent = MessagePackUtils.value(from: data, conversion: { $0.boolValue }) ?? false if isInitErrorPresent { - self.streamSubject.onNext(.initVimError) + self.consumer?.initVimError() } case .resize: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.resize(v)) - break + self.consumer?.resize(v) case .clear: - self.streamSubject.onNext(.clear) + self.consumer?.clear() case .setMenu: - self.streamSubject.onNext(.setMenu) + self.consumer?.updateMenu() case .busyStart: - self.streamSubject.onNext(.busyStart) + self.consumer?.busyStart() case .busyStop: - self.streamSubject.onNext(.busyStop) + self.consumer?.busyStop() case .modeChange: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.modeChange(v)) + self.consumer?.modeChange(v) case .bell: - self.streamSubject.onNext(.bell) + self.consumer?.bell() case .visualBell: - self.streamSubject.onNext(.visualBell) + self.consumer?.visualBell() case .flush: guard let d = data, let v = (try? unpackAll(d)) else { return } - self.streamSubject.onNext(.flush(v)) + self.consumer?.flush(v) case .setTitle: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.setTitle(v)) + self.consumer?.setTitle(with: v) case .stop: - self.streamSubject.onNext(.stop) + self.consumer?.stop() case .dirtyStatusChanged: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.dirtyStatusChanged(v)) + self.consumer?.setDirty(with: v) case .cwdChanged: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.cwdChanged(v)) + self.consumer?.cwdChanged(v) case .defaultColorsChanged: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.defaultColorsChanged(v)) + self.consumer?.defaultColorsChanged(v) case .colorSchemeChanged: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.colorSchemeChanged(v)) + self.consumer?.colorSchemeChanged(v) case .optionSet: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.optionSet(v)) + self.consumer?.optionSet(v) case .autoCommandEvent: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.autoCommandEvent(v)) + self.consumer?.autoCommandEvent(v) case .debug1: - self.streamSubject.onNext(.debug1) + break case .highlightAttrs: guard let v = MessagePackUtils.value(from: data) else { return } - self.streamSubject.onNext(.highlightAttrs(v)) + self.consumer?.setAttr(with: v) case .rpcEventSubscribed: - self.streamSubject.onNext(.rpcEventSubscribed) + self.consumer?.rpcEventSubscribed() case .fatalError: - self.streamSubject.onNext(.fatalError(MessagePackUtils.value(from: data))) + self.consumer?.bridgeHasFatalError(MessagePackUtils.value(from: data)) @unknown default: self.log.error("Unkonwn msg type from NvimServer") - + } } @@ -353,7 +336,6 @@ class UiBridge { private let scheduler: SerialDispatchQueueScheduler private let queue: DispatchQueue - private let streamSubject = PublishSubject() private let disposeBag = DisposeBag() private var localServerName: String {