Skip to content

Commit

Permalink
refactor: performance improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
Caldis committed Feb 26, 2021
1 parent 95d9c77 commit c1ade2a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 49 deletions.
9 changes: 6 additions & 3 deletions Mos/ScrollCore/ScrollCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ class ScrollCore {

// MARK: - 滚动事件处理
let scrollEventCallBack: CGEventTapCallBack = { (proxy, type, event, refcon) in
// 滚动事件
let scrollEvent = ScrollEvent(with: event)
// 不处理触控板
// 无法区分黑苹果, 因为黑苹果的触控板驱动直接模拟鼠标输入
if scrollEvent.isTrackpad() { return Unmanaged.passUnretained(event) }
// 无法区分 Magic Mouse, 因为其滚动特征与内置的 Trackpad 一致
if ScrollEvent.isTrackpad(with: event) {
return Unmanaged.passUnretained(event)
}
// 切换目标窗时停止滚动
if ScrollUtils.shared.isTargetChanged(event) {
ScrollPoster.shared.pauseAuto()
Expand Down Expand Up @@ -78,6 +79,8 @@ class ScrollCore {
if ScrollUtils.shared.getLaunchpadActivity(withRunningApplication: targetRunningApplication) {
enableSmooth = false
}
// 滚动事件
let scrollEvent = ScrollEvent(with: event)
// Y轴
if scrollEvent.Y.valid {
// 是否翻转滚动
Expand Down
39 changes: 23 additions & 16 deletions Mos/ScrollCore/ScrollEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,33 @@ class ScrollEvent {
// MARK: - 工具方法
extension ScrollEvent {
// 类型判断
static var isTrackpadCallSamplingRate = 3
static var isTrackpadCallCount = 2
static var isTrackpadCallCache = true
class func isTrackpad(with event: CGEvent) -> Bool {
var result = false
// 根据滚动特征值判定
if (event.getDoubleValueField(.scrollWheelEventMomentumPhase) != 0.0) || (event.getDoubleValueField(.scrollWheelEventScrollPhase) != 0.0) {
// MomentumPhase 或 ScrollPhase 任一不为零, 则为触控板
result = true
} else if event.getDoubleValueField(.scrollWheelEventScrollCount) != 0.0 {
// 累计加速度不为零, 则为触控板
result = true
}
// 根据输入事件源增强判断
if result {
if let specialProcessID = Utils.getRunningApplicationProcessIdentifier(withBundleIdentifier: SPECIAL_EVENT_SOURCE_APPLICATION.logitechOptions)?.processIdentifier {
let sourceProcessID = event.getIntegerValueField(.eventSourceUnixProcessID)
if sourceProcessID == specialProcessID {
result = false
ScrollEvent.isTrackpadCallCount += 1
if isTrackpadCallCount % isTrackpadCallSamplingRate == 0 {
ScrollEvent.isTrackpadCallCache = false
// 根据滚动特征值判定
if (event.getDoubleValueField(.scrollWheelEventMomentumPhase) != 0.0) || (event.getDoubleValueField(.scrollWheelEventScrollPhase) != 0.0) {
// MomentumPhase 或 ScrollPhase 任一不为零, 则为触控板
ScrollEvent.isTrackpadCallCache = true
} else if event.getDoubleValueField(.scrollWheelEventScrollCount) != 0.0 {
// 累计加速度不为零, 则为触控板
ScrollEvent.isTrackpadCallCache = true
}
// 根据输入事件源增强判断
if ScrollEvent.isTrackpadCallCache {
if let specialProcessID = Utils.getRunningApplicationProcessIdentifier(withBundleIdentifier: SPECIAL_EVENT_SOURCE_APPLICATION.logitechOptions)?.processIdentifier {
let sourceProcessID = event.getIntegerValueField(.eventSourceUnixProcessID)
if sourceProcessID == specialProcessID {
ScrollEvent.isTrackpadCallCache = false
}
}
}
ScrollEvent.isTrackpadCallCount = isTrackpadCallSamplingRate - 1
}
return result
return ScrollEvent.isTrackpadCallCache
}

// 初始化轴数据
Expand Down
50 changes: 27 additions & 23 deletions Mos/ScrollCore/ScrollPhase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ScrollPhase.swift
// Mos
//
// Created by 陈标 on 2020/12/19.
// Created by Caldis on 2020/12/19.
// Copyright © 2020 Caldis. All rights reserved.
//

Expand Down Expand Up @@ -45,37 +45,41 @@ class ScrollPhase {
var phase: Phase = Phase.Idle

// MARK: - 滚动阶段更新
let debounceSetPhaseToMomentum = Utils.debounce(delay: 200) {
let syncPhaseValueMapping: [Phase: Phase] = [
Phase.Idle: Phase.Contact,
Phase.Momentum: Phase.Contact,
Phase.PauseAuto: Phase.Contact,
Phase.PauseManual: Phase.Contact,
Phase.Tracing: Phase.Tracing
]
var debounceSetPhaseToMomentumCallSamplingRate = 3
var debounceSetPhaseToMomentumCallCount = 2
let debounceSetPhaseToMomentum = Utils.debounce(delay: 300) {
ScrollPhase.shared.phase = Phase.Momentum
ScrollPhase.shared.debounceSetPhaseToMomentumCallCount = ScrollPhase.shared.debounceSetPhaseToMomentumCallSamplingRate - 1
}
func syncPhase() {
if [Phase.Idle, Phase.Momentum, Phase.PauseAuto, Phase.PauseManual].contains(phase) {
phase = Phase.Contact
} else if (phase == Phase.Tracing) {
phase = Phase.Tracing
if let syncedPhase = syncPhaseValueMapping[phase] {
phase = syncedPhase
}
debounceSetPhaseToMomentumCallCount += 1
if debounceSetPhaseToMomentumCallCount % debounceSetPhaseToMomentumCallSamplingRate == 0 {
debounceSetPhaseToMomentum()
}
debounceSetPhaseToMomentum()
}

// MARK: - 滚动阶段递进
let consumeValueMapping: [Phase: Phase] = [
Phase.Contact: Phase.Tracing,
Phase.PauseAuto: Phase.Idle,
Phase.PauseManual: Phase.Idle,
]
func consume() -> Phase {
switch phase {
case Phase.Idle:
return Phase.Idle
case Phase.Contact:
phase = Phase.Tracing
return Phase.Contact
case Phase.Tracing:
return Phase.Tracing
case Phase.Momentum:
return Phase.Momentum
case Phase.PauseAuto:
phase = Phase.Idle
return Phase.PauseAuto
case Phase.PauseManual:
phase = Phase.Idle
return Phase.PauseManual
let prevPhase = phase
if let nextPhase = consumeValueMapping[phase] {
phase = nextPhase
}
return prevPhase
}

// MARK: - 滚动数据附加
Expand Down
7 changes: 0 additions & 7 deletions Mos/ScrollCore/ScrollPoster.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class ScrollPoster {
static let shared = ScrollPoster()
init() { NSLog("Module initialized: ScrollPoster") }

var ts = Date.currentTimeStamp
// 插值器
private let filler = ScrollFiller()
private let interpolator = Interpolator.lerp
Expand Down Expand Up @@ -85,12 +84,6 @@ extension ScrollPoster {
}
}

extension Date {
static var currentTimeStamp: Int64{
return Int64(Date().timeIntervalSince1970 * 1000)
}
}

// MARK: - 插值数据发送控制
extension ScrollPoster {
// 初始化 CVDisplayLink
Expand Down

0 comments on commit c1ade2a

Please sign in to comment.