Efficiency: Release builds by default, only the visible island screen is built, character at 30 fps, adaptive mouse polling (60/30/10 Hz), hex colours parsed once
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -217,16 +217,33 @@ final class IslandWindowController: NSWindowController {
|
||||
|
||||
// MARK: - 60 Hz polling loop
|
||||
|
||||
private func startPolling() {
|
||||
frameTimer = Timer.scheduledTimer(withTimeInterval: 1.0/60.0, repeats: true) { [weak self] _ in
|
||||
private var pollInterval: TimeInterval = 0
|
||||
|
||||
/// Mouse polling rate follows what's on screen: 60 Hz only while dragging (ghost,
|
||||
/// chat handle), 30 Hz with the island open (the character draws at 30 fps),
|
||||
/// 10 Hz when folded (hover still reacts within 0.1 s).
|
||||
private var desiredPollInterval: TimeInterval {
|
||||
if inAttachDrag || attachDragStart != nil || state.chatDragHeight != nil { return 1.0 / 60.0 }
|
||||
return state.mode == .expanded ? 1.0 / 30.0 : 1.0 / 10.0
|
||||
}
|
||||
|
||||
private func startPolling(interval: TimeInterval = 1.0 / 10.0) {
|
||||
frameTimer?.invalidate()
|
||||
pollInterval = interval
|
||||
let t = Timer(timeInterval: interval, repeats: true) { [weak self] _ in
|
||||
guard let self else { return }
|
||||
Task { @MainActor in self.pollFrame() }
|
||||
}
|
||||
RunLoop.main.add(frameTimer!, forMode: .common)
|
||||
// Let macOS coalesce wakeups with other timers.
|
||||
t.tolerance = interval * 0.2
|
||||
RunLoop.main.add(t, forMode: .common)
|
||||
frameTimer = t
|
||||
}
|
||||
|
||||
private func pollFrame() {
|
||||
guard let panel = window as? IslandPanel else { return }
|
||||
let want = desiredPollInterval
|
||||
if abs(want - pollInterval) > 0.001 { startPolling(interval: want) }
|
||||
|
||||
let mouse = NSEvent.mouseLocation
|
||||
|
||||
|
||||
Reference in New Issue
Block a user