- 菜单栏:CPU/GPU/内存多样式、网速两行、温度、风扇 - 面板:概览仪表盘、进程、散热、防休眠,液态玻璃与浅色/深色主题 - 采集层:CPU/内存/网络/GPU/磁盘/电池/进程/SMC 温度与风扇,按界面分级采样 - root 辅助工具:风扇调速、合盖不睡眠,断开时自动恢复 - XcodeGen 工程、单元测试、截图模式
81 lines
3.2 KiB
Swift
81 lines
3.2 KiB
Swift
import Foundation
|
|
import Metrics
|
|
import Observation
|
|
import SMC
|
|
|
|
/// 主线程上的最新指标与短历史,只保留界面需要的数据
|
|
@MainActor
|
|
@Observable
|
|
public final class MetricsStore {
|
|
public static let historyCapacity = 60
|
|
|
|
public let topology = CPUSampler.topology()
|
|
public private(set) var system = SystemInfoReader.read()
|
|
|
|
public private(set) var cpu: CPULoad?
|
|
public private(set) var cpuUser = History<Double>(capacity: historyCapacity)
|
|
public private(set) var cpuSystem = History<Double>(capacity: historyCapacity)
|
|
public private(set) var cpuTotal = History<Double>(capacity: historyCapacity)
|
|
|
|
public private(set) var memory: MemoryUsage?
|
|
public private(set) var memoryHistory = History<Double>(capacity: historyCapacity)
|
|
public private(set) var network: NetworkRate?
|
|
public private(set) var downloadHistory = History<Double>(capacity: historyCapacity)
|
|
public private(set) var uploadHistory = History<Double>(capacity: historyCapacity)
|
|
public private(set) var networkInterface: NetworkInterfaceInfo?
|
|
|
|
public private(set) var gpu: GPUUsage?
|
|
public private(set) var gpuHistory = History<Double>(capacity: historyCapacity)
|
|
public private(set) var disk: DiskUsage?
|
|
public private(set) var battery: BatteryStatus?
|
|
public private(set) var processes: [ProcessUsage] = []
|
|
public private(set) var sensors: SensorReadings?
|
|
public private(set) var lastUpdate: Date?
|
|
|
|
public init() {}
|
|
|
|
public func apply(_ snapshot: MetricsSnapshot) {
|
|
lastUpdate = snapshot.date
|
|
if let cpu = snapshot.cpu {
|
|
self.cpu = cpu
|
|
cpuUser.append(cpu.user)
|
|
cpuSystem.append(cpu.system)
|
|
cpuTotal.append(cpu.total)
|
|
}
|
|
if let memory = snapshot.memory {
|
|
self.memory = memory
|
|
memoryHistory.append(memory.usedFraction)
|
|
}
|
|
if let network = snapshot.network {
|
|
self.network = network
|
|
downloadHistory.append(network.downloadBytesPerSecond)
|
|
uploadHistory.append(network.uploadBytesPerSecond)
|
|
}
|
|
if let interface = snapshot.networkInterface { networkInterface = interface }
|
|
if let gpu = snapshot.gpu {
|
|
self.gpu = gpu
|
|
gpuHistory.append(gpu.utilization)
|
|
}
|
|
if let disk = snapshot.disk { self.disk = disk }
|
|
if let battery = snapshot.battery { self.battery = battery }
|
|
if let processes = snapshot.processes { self.processes = processes }
|
|
if let sensors = snapshot.sensors { mergeSensors(sensors) }
|
|
}
|
|
|
|
/// 不同页面采集的温度分组不同,按组合并,避免切页时数据闪烁
|
|
private func mergeSensors(_ new: SensorReadings) {
|
|
guard let old = sensors else {
|
|
sensors = new
|
|
return
|
|
}
|
|
var byGroup = Dictionary(uniqueKeysWithValues: old.temperatures.map { ($0.group, $0) })
|
|
for summary in new.temperatures { byGroup[summary.group] = summary }
|
|
let ordered = TemperatureGroup.allCases.compactMap { byGroup[$0] }
|
|
sensors = SensorReadings(temperatures: ordered, fans: new.fans.isEmpty ? old.fans : new.fans)
|
|
}
|
|
|
|
var fastestFan: FanState? {
|
|
sensors?.fans.max { $0.current < $1.current }
|
|
}
|
|
}
|