LMInstantiator // Stop duplicating LMCassette.
This commit is contained in:
parent
383a3dd658
commit
15188f0eed
|
@ -74,10 +74,6 @@ extension vChewingLM {
|
||||||
|
|
||||||
// 磁帶資料模組。「currentCassette」對外唯讀,僅用來讀取磁帶本身的中繼資料(Metadata)。
|
// 磁帶資料模組。「currentCassette」對外唯讀,僅用來讀取磁帶本身的中繼資料(Metadata)。
|
||||||
static var lmCassette = LMCassette()
|
static var lmCassette = LMCassette()
|
||||||
public var currentCassette: LMCassette {
|
|
||||||
get { Self.lmCassette }
|
|
||||||
set { Self.lmCassette = newValue }
|
|
||||||
}
|
|
||||||
|
|
||||||
// 聲明使用者語言模組。
|
// 聲明使用者語言模組。
|
||||||
// 使用者語言模組使用多執行緒的話,可能會導致一些問題。有時間再仔細排查看看。
|
// 使用者語言模組使用多執行緒的話,可能會導致一些問題。有時間再仔細排查看看。
|
||||||
|
@ -208,6 +204,7 @@ extension vChewingLM {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var isCassetteDataLoaded: Bool { Self.lmCassette.isLoaded }
|
||||||
public static func loadCassetteData(path: String) {
|
public static func loadCassetteData(path: String) {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
if FileManager.default.isReadableFile(atPath: path) {
|
if FileManager.default.isReadableFile(atPath: path) {
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
|
// ====================
|
||||||
|
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||||
|
// ... with NTL restriction stating that:
|
||||||
|
// No trademark license is granted to use the trade names, trademarks, service
|
||||||
|
// marks, or product names of Contributor, except as required to fulfill notice
|
||||||
|
// requirements defined in MIT License.
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Megrez
|
||||||
|
import Shared
|
||||||
|
|
||||||
|
extension vChewingLM.LMInstantiator {
|
||||||
|
/// 當前磁帶所規定的花牌鍵。
|
||||||
|
public var cassetteWildcardKey: String { Self.lmCassette.wildcardKey }
|
||||||
|
/// 當前磁帶規定的最大碼長。
|
||||||
|
public var maxCassetteKeyLength: Int { Self.lmCassette.maxKeyLength }
|
||||||
|
|
||||||
|
/// 將當前的按鍵轉換成磁帶內定義了的字根。
|
||||||
|
/// - Parameter char: 按鍵字元。
|
||||||
|
/// - Returns: 轉換結果。如果轉換失敗,則返回原始按鍵字元。
|
||||||
|
public func convertCassetteKeyToDisplay(char: String) -> String {
|
||||||
|
Self.lmCassette.convertKeyToDisplay(char: char)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 檢查當前的按鍵是否屬於目前的磁帶規定的允許的字根按鍵。
|
||||||
|
/// - Parameter key: 按鍵字元。
|
||||||
|
/// - Returns: 檢查結果。
|
||||||
|
public func isThisCassetteKeyAllowed(key: String) -> Bool {
|
||||||
|
Self.lmCassette.allowedKeys.contains(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 檢查給定的索引鍵在搭上花牌鍵之後是否有匹配結果。
|
||||||
|
/// - Parameter key: 給定的索引鍵。
|
||||||
|
/// - Returns: 是否有批配結果。
|
||||||
|
public func hasCassetteWildcardResultsFor(key: String) -> Bool {
|
||||||
|
Self.lmCassette.hasUnigramsFor(key: key + Self.lmCassette.wildcard)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 提供磁帶反查結果。
|
||||||
|
/// - Parameter value: 要拿來反查的字詞。
|
||||||
|
/// - Returns: 反查結果字串陣列。
|
||||||
|
public func cassetteReverseLookup(for value: String) -> [String] {
|
||||||
|
var lookupResult = Self.lmCassette.reverseLookupMap[value] ?? []
|
||||||
|
guard !lookupResult.isEmpty else { return [] }
|
||||||
|
lookupResult = lookupResult.map { $0.trimmingCharacters(in: .newlines) }
|
||||||
|
return lookupResult.stableSort(by: { $0.count < $1.count }).stableSort {
|
||||||
|
Self.lmCassette.unigramsFor(key: $0).count
|
||||||
|
< Self.lmCassette.unigramsFor(key: $1).count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -428,11 +428,9 @@ public class InputHandler: InputHandlerProtocol {
|
||||||
return composer.getInlineCompositionForDisplay(isHanyuPinyin: prefs.showHanyuPinyinInCompositionBuffer)
|
return composer.getInlineCompositionForDisplay(isHanyuPinyin: prefs.showHanyuPinyinInCompositionBuffer)
|
||||||
}
|
}
|
||||||
if !prefs.showTranslatedStrokesInCompositionBuffer { return calligrapher }
|
if !prefs.showTranslatedStrokesInCompositionBuffer { return calligrapher }
|
||||||
var result = calligrapher.charComponents
|
return calligrapher.charComponents.map {
|
||||||
for idx in 0..<result.count {
|
currentLM.convertCassetteKeyToDisplay(char: $0)
|
||||||
result[idx] = currentLM.currentCassette.convertKeyToDisplay(char: result[idx])
|
}.joined()
|
||||||
}
|
|
||||||
return result.joined()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Extracted methods and functions (Megrez).
|
// MARK: - Extracted methods and functions (Megrez).
|
||||||
|
|
|
@ -170,7 +170,7 @@ extension InputHandler {
|
||||||
|
|
||||||
let isInputValid: Bool =
|
let isInputValid: Bool =
|
||||||
prefs.cassetteEnabled
|
prefs.cassetteEnabled
|
||||||
? currentLM.currentCassette.allowedKeys.contains(input.text) : composer.inputValidityCheck(key: input.charCode)
|
? currentLM.isThisCassetteKeyAllowed(key: input.text) : composer.inputValidityCheck(key: input.charCode)
|
||||||
|
|
||||||
var shouldAutoSelectCandidate: Bool =
|
var shouldAutoSelectCandidate: Bool =
|
||||||
isInputValid || currentLM.hasUnigramsFor(key: customPunctuation)
|
isInputValid || currentLM.hasUnigramsFor(key: customPunctuation)
|
||||||
|
|
|
@ -181,8 +181,7 @@ extension InputHandler {
|
||||||
/// - Returns: 告知 IMK「該按鍵是否已經被輸入法攔截處理」。
|
/// - Returns: 告知 IMK「該按鍵是否已經被輸入法攔截處理」。
|
||||||
private func handleCassetteComposition(input: InputSignalProtocol) -> Bool? {
|
private func handleCassetteComposition(input: InputSignalProtocol) -> Bool? {
|
||||||
guard let delegate = delegate else { return nil }
|
guard let delegate = delegate else { return nil }
|
||||||
var wildcardKey: String { currentLM.currentCassette.wildcardKey } // 花牌鍵。
|
var wildcardKey: String { currentLM.cassetteWildcardKey } // 花牌鍵。
|
||||||
var wildcard: String { currentLM.currentCassette.wildcard } // 花牌鍵。
|
|
||||||
let isWildcardKeyInput: Bool = (input.text == wildcardKey && !wildcardKey.isEmpty)
|
let isWildcardKeyInput: Bool = (input.text == wildcardKey && !wildcardKey.isEmpty)
|
||||||
|
|
||||||
var keyConsumedByStrokes = false
|
var keyConsumedByStrokes = false
|
||||||
|
@ -193,14 +192,14 @@ extension InputHandler {
|
||||||
|
|
||||||
var isLongestPossibleKeyFormed: Bool {
|
var isLongestPossibleKeyFormed: Bool {
|
||||||
guard !isWildcardKeyInput, prefs.autoCompositeWithLongestPossibleCassetteKey else { return false }
|
guard !isWildcardKeyInput, prefs.autoCompositeWithLongestPossibleCassetteKey else { return false }
|
||||||
return !currentLM.currentCassette.hasUnigramsFor(key: calligrapher + wildcard) && !calligrapher.isEmpty
|
return !currentLM.hasCassetteWildcardResultsFor(key: calligrapher) && !calligrapher.isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
var isStrokesFull: Bool {
|
var isStrokesFull: Bool {
|
||||||
calligrapher.count >= currentLM.currentCassette.maxKeyLength || isLongestPossibleKeyFormed
|
calligrapher.count >= currentLM.maxCassetteKeyLength || isLongestPossibleKeyFormed
|
||||||
}
|
}
|
||||||
|
|
||||||
prehandling: if !skipStrokeHandling && currentLM.currentCassette.allowedKeys.contains(input.text) {
|
prehandling: if !skipStrokeHandling && currentLM.isThisCassetteKeyAllowed(key: input.text) {
|
||||||
if calligrapher.isEmpty, isWildcardKeyInput {
|
if calligrapher.isEmpty, isWildcardKeyInput {
|
||||||
delegate.callError("3606B9C0")
|
delegate.callError("3606B9C0")
|
||||||
var newEmptyState = compositor.isEmpty ? IMEState.ofEmpty() : generateStateOfInputting()
|
var newEmptyState = compositor.isEmpty ? IMEState.ofEmpty() : generateStateOfInputting()
|
||||||
|
|
|
@ -69,14 +69,8 @@ extension SessionCtl: CtlCandidateDelegate {
|
||||||
if isVerticalTyping { return blankResult } // 縱排輸入的場合,選字窗沒有足夠的空間顯示反查結果。
|
if isVerticalTyping { return blankResult } // 縱排輸入的場合,選字窗沒有足夠的空間顯示反查結果。
|
||||||
if value.isEmpty { return blankResult } // 空字串沒有需要反查的東西。
|
if value.isEmpty { return blankResult } // 空字串沒有需要反查的東西。
|
||||||
if value.contains("_") { return blankResult }
|
if value.contains("_") { return blankResult }
|
||||||
guard var lookupResult = LMMgr.currentLM.currentCassette.reverseLookupMap[value] else { return blankResult }
|
// 因為威注音輸入法的反查結果僅由磁帶模組負責,所以相關運算挪至 LMInstantiator 內處理。
|
||||||
for i in 0..<lookupResult.count {
|
return LMMgr.currentLM.cassetteReverseLookup(for: value)
|
||||||
lookupResult[i] = lookupResult[i].trimmingCharacters(in: .newlines)
|
|
||||||
}
|
|
||||||
return lookupResult.stableSort(by: { $0.count < $1.count }).stableSort {
|
|
||||||
LMMgr.currentLM.currentCassette.unigramsFor(key: $0).count
|
|
||||||
< LMMgr.currentLM.currentCassette.unigramsFor(key: $1).count
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var selectionKeys: String {
|
public var selectionKeys: String {
|
||||||
|
|
|
@ -247,7 +247,7 @@ extension SessionCtl {
|
||||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||||
)
|
)
|
||||||
if !LMMgr.currentLM.currentCassette.isLoaded {
|
if !LMMgr.currentLM.isCassetteDataLoaded {
|
||||||
LMMgr.loadCassetteData()
|
LMMgr.loadCassetteData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue