Files
macos-stats/Stats/Modules/CPU/CPUProcessReader.swift
Serhiy Mytrovtsiy 2e718e52cd - fix cpu usage in list;
- fix default widgets in network and battery;
- remove CHANGELOG.md (replaced with git tags);
2020-04-04 16:08:41 +02:00

93 lines
2.6 KiB
Swift

//
// CPUProcessReader.swift
// Stats
//
// Created by Serhiy Mytrovtsiy on 13/01/2020.
// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
//
import Cocoa
struct TopProcess {
var pid: Int = 0
var command: String = ""
var usage: Double = 0
}
class CPUProcessReader: Reader {
public var name: String = "Process"
public var enabled: Bool = false
public var available: Bool = true
public var optional: Bool = true
public var initialized: Bool = false
public var callback: ([TopProcess]) -> Void = {_ in}
private var loadPrevious = host_cpu_load_info()
init(_ updater: @escaping ([TopProcess]) -> Void) {
self.callback = updater
if self.available {
DispatchQueue.global(qos: .default).async {
self.read()
}
}
}
public func toggleEnable(_ value: Bool) {
self.enabled = value
}
public func read() {
if !self.enabled && self.initialized { return }
self.initialized = true
let task = Process()
task.launchPath = "/bin/ps"
task.arguments = ["-Aceo pid,pcpu,comm", "-r"]
let outputPipe = Pipe()
let errorPipe = Pipe()
task.standardOutput = outputPipe
task.standardError = errorPipe
do {
try task.run()
} catch let error {
print(error)
}
let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile()
let output = String(decoding: outputData, as: UTF8.self)
_ = String(decoding: errorData, as: UTF8.self)
if output.isEmpty {
return
}
var index = 0
var processes: [TopProcess] = []
output.enumerateLines { (line, stop) -> () in
if index != 0 {
var str = line.trimmingCharacters(in: .whitespaces)
let pidString = str.findAndCrop(pattern: "^\\d+")
let usageString = str.findAndCrop(pattern: "^[0-9,.]+ ")
let command = str.trimmingCharacters(in: .whitespaces)
let pid = Int(pidString) ?? 0
let usage = Double(usageString.replacingOccurrences(of: ",", with: ".")) ?? 0
processes.append(TopProcess(pid: pid, command: command, usage: usage))
}
if index == 5 { stop = true }
index += 1
}
DispatchQueue.main.async(execute: {
self.callback(processes)
})
}
}