SessionCtl // Use GCD for certain state tasks.
This commit is contained in:
parent
0f44861440
commit
852eed07e2
|
@ -43,6 +43,9 @@ public class SessionCtl: IMKInputController {
|
||||||
/// 當前副本的客體是否是輸入法本體?
|
/// 當前副本的客體是否是輸入法本體?
|
||||||
public var isServingIMEItself: Bool = false
|
public var isServingIMEItself: Bool = false
|
||||||
|
|
||||||
|
/// 專門用來記錄處理狀態的執行緒記錄槽。
|
||||||
|
public var stateQueueSet = [String]()
|
||||||
|
|
||||||
/// 用以存儲客體的 bundleIdentifier。
|
/// 用以存儲客體的 bundleIdentifier。
|
||||||
/// 由於每次動態獲取都會耗時,所以這裡直接靜態記載之。
|
/// 由於每次動態獲取都會耗時,所以這裡直接靜態記載之。
|
||||||
public var clientBundleIdentifier: String = "" {
|
public var clientBundleIdentifier: String = "" {
|
||||||
|
|
|
@ -12,6 +12,20 @@ import Shared
|
||||||
// MARK: - 狀態調度 (State Handling)
|
// MARK: - 狀態調度 (State Handling)
|
||||||
|
|
||||||
public extension SessionCtl {
|
public extension SessionCtl {
|
||||||
|
private func performStateTask(_ doTask: @escaping () -> Void) {
|
||||||
|
let queueID = UUID().uuidString
|
||||||
|
DispatchQueue.main.async { [self] in
|
||||||
|
stateQueueSet.append(queueID)
|
||||||
|
while stateQueueSet.first != queueID {
|
||||||
|
Thread.sleep(forTimeInterval: 0.001)
|
||||||
|
}
|
||||||
|
doTask()
|
||||||
|
if stateQueueSet.first == queueID {
|
||||||
|
stateQueueSet.removeFirst()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 針對傳入的新狀態進行調度、且將當前會話控制器的狀態切換至新狀態。
|
/// 針對傳入的新狀態進行調度、且將當前會話控制器的狀態切換至新狀態。
|
||||||
///
|
///
|
||||||
/// 先將舊狀態單獨記錄起來,再將新舊狀態作為參數,
|
/// 先將舊狀態單獨記錄起來,再將新舊狀態作為參數,
|
||||||
|
@ -43,11 +57,8 @@ public extension SessionCtl {
|
||||||
switch newState.type {
|
switch newState.type {
|
||||||
case .ofDeactivated:
|
case .ofDeactivated:
|
||||||
// 這裡移除一些處理,轉而交給 commitComposition() 代為執行。
|
// 這裡移除一些處理,轉而交給 commitComposition() 代為執行。
|
||||||
// 這裡不需要 clearInlineDisplay() ,否則會觸發無限迴圈。
|
|
||||||
// 對於 IMK 選字窗的顯示狀態糾正的行為交給 inputMode.didSet() 來處理。
|
// 對於 IMK 選字窗的顯示狀態糾正的行為交給 inputMode.didSet() 來處理。
|
||||||
candidateUI?.visible = false
|
hidePalettes()
|
||||||
popupCompositionBuffer.hide()
|
|
||||||
tooltipInstance.hide()
|
|
||||||
inputHandler?.clear()
|
inputHandler?.clear()
|
||||||
if ![.ofAbortion, .ofEmpty].contains(previous.type), !previous.displayedText.isEmpty {
|
if ![.ofAbortion, .ofEmpty].contains(previous.type), !previous.displayedText.isEmpty {
|
||||||
clearInlineDisplay()
|
clearInlineDisplay()
|
||||||
|
@ -68,23 +79,23 @@ public extension SessionCtl {
|
||||||
commit(text: previous.displayedText)
|
commit(text: previous.displayedText)
|
||||||
}
|
}
|
||||||
// 會在工具提示為空的時候自動消除顯示。
|
// 會在工具提示為空的時候自動消除顯示。
|
||||||
showTooltip(newState.tooltip, duration: newState.tooltipDuration)
|
performStateTask { self.showTooltip(newState.tooltip, duration: newState.tooltipDuration) }
|
||||||
clearInlineDisplay()
|
clearInlineDisplay()
|
||||||
inputHandler?.clear()
|
inputHandler?.clear()
|
||||||
case .ofInputting:
|
case .ofInputting:
|
||||||
candidateUI?.visible = false
|
candidateUI?.visible = false
|
||||||
if !newState.textToCommit.isEmpty { commit(text: newState.textToCommit) }
|
if !newState.textToCommit.isEmpty { commit(text: newState.textToCommit) }
|
||||||
setInlineDisplayWithCursor()
|
|
||||||
// 會在工具提示為空的時候自動消除顯示。
|
// 會在工具提示為空的時候自動消除顯示。
|
||||||
showTooltip(newState.tooltip, duration: newState.tooltipDuration)
|
performStateTask { self.showTooltip(newState.tooltip, duration: newState.tooltipDuration) }
|
||||||
|
setInlineDisplayWithCursor()
|
||||||
case .ofMarking:
|
case .ofMarking:
|
||||||
candidateUI?.visible = false
|
candidateUI?.visible = false
|
||||||
|
performStateTask { self.showTooltip(newState.tooltip) }
|
||||||
setInlineDisplayWithCursor()
|
setInlineDisplayWithCursor()
|
||||||
showTooltip(newState.tooltip)
|
|
||||||
case .ofCandidates, .ofAssociates, .ofSymbolTable:
|
case .ofCandidates, .ofAssociates, .ofSymbolTable:
|
||||||
tooltipInstance.hide()
|
performStateTask { self.showCandidates() }
|
||||||
setInlineDisplayWithCursor()
|
setInlineDisplayWithCursor()
|
||||||
showCandidates()
|
tooltipInstance.hide()
|
||||||
}
|
}
|
||||||
// 浮動組字窗的顯示判定
|
// 浮動組字窗的顯示判定
|
||||||
updatePopupDisplayWithCursor()
|
updatePopupDisplayWithCursor()
|
||||||
|
|
Loading…
Reference in New Issue