feat: moved all modules to the new way of reader mode with a small refactoring

This commit is contained in:
Serhiy Mytrovtsiy
2024-02-10 17:03:47 +01:00
parent 1e9073424b
commit 7e833176d9
30 changed files with 222 additions and 320 deletions

View File

@@ -170,6 +170,7 @@ open class Module: Module_p {
reader.initStoreValues(title: self.config.name)
reader.start()
}
self.menuBar.enable()
}
// disable module
@@ -222,16 +223,8 @@ open class Module: Module_p {
debug("Module disabled", log: self.log)
}
// add reader to module. If module is enabled will fire a read function and start a reader
public func addReader(_ reader: Reader_p) {
self.readers.append(reader)
debug("\(reader.self) was added", log: self.log)
}
// handler for reader, calls when main reader is ready, and return first value
public func readyHandler() {
self.menuBar.enable()
debug("Reader report readiness", log: self.log)
public func setReaders(_ list: [Reader_p?]) {
self.readers = list.filter({ $0 != nil }).map({ $0! as Reader_p })
}
// replace a popup view

View File

@@ -59,9 +59,9 @@ public class Battery: Module {
private var notificationID: String? = nil
public init() {
self.settingsView = Settings("Battery")
self.popupView = Popup("Battery")
self.portalView = Portal("Battery")
self.settingsView = Settings(.battery)
self.popupView = Popup(.battery)
self.portalView = Portal(.battery)
self.notificationsView = Notifications(.battery)
super.init(
@@ -72,8 +72,14 @@ public class Battery: Module {
)
guard self.available else { return }
self.usageReader = UsageReader(.battery)
self.processReader = ProcessReader(.battery)
self.usageReader = UsageReader(.battery) { [weak self] value in
self?.usageCallback(value)
}
self.processReader = ProcessReader(.battery) { [weak self] value in
if let list = value {
self?.popupView.processCallback(list)
}
}
self.settingsView.callback = { [weak self] in
DispatchQueue.global(qos: .background).async {
@@ -87,25 +93,7 @@ public class Battery: Module {
}
}
self.usageReader?.callbackHandler = { [weak self] value in
self?.usageCallback(value)
}
self.usageReader?.readyCallback = { [weak self] in
self?.readyHandler()
}
self.processReader?.callbackHandler = { [weak self] value in
if let list = value {
self?.popupView.processCallback(list)
}
}
if let reader = self.usageReader {
self.addReader(reader)
}
if let reader = self.processReader {
self.addReader(reader)
}
self.setReaders([self.usageReader, self.processReader])
}
public override func willTerminate() {

View File

@@ -64,8 +64,8 @@ internal class Popup: PopupWrapper {
Store.shared.string(key: "\(self.title)_timeFormat", defaultValue: "short")
}
public init(_ title: String) {
self.title = title
public init(_ module: ModuleType) {
self.title = module.rawValue
super.init(frame: NSRect(
x: 0,

View File

@@ -25,8 +25,8 @@ internal class Portal: NSStackView, Portal_p {
Store.shared.string(key: "\(self.name)_timeFormat", defaultValue: "short")
}
init(_ name: String) {
self.name = name
public init(_ module: ModuleType) {
self.name = module.rawValue
super.init(frame: NSRect.zero)

View File

@@ -23,8 +23,8 @@ internal class Settings: NSStackView, Settings_v {
private var numberOfProcesses: Int = 8
private var timeFormat: String = "short"
public init(_ title: String) {
self.title = title
public init(_ module: ModuleType) {
self.title = module.rawValue
self.numberOfProcesses = Store.shared.int(key: "\(self.title)_processes", defaultValue: self.numberOfProcesses)
self.timeFormat = Store.shared.string(key: "\(self.title)_timeFormat", defaultValue: self.timeFormat)

View File

@@ -77,7 +77,7 @@ public struct BLEDevice: Codable {
}
public class Bluetooth: Module {
private var devicesReader: DevicesReader = DevicesReader()
private var devicesReader: DevicesReader?
private let popupView: Popup = Popup()
private let settingsView: Settings = Settings()
@@ -88,18 +88,15 @@ public class Bluetooth: Module {
)
guard self.available else { return }
self.settingsView.callback = { [weak self] in
self?.devicesReader.read()
}
self.devicesReader.callbackHandler = { [weak self] value in
self.devicesReader = DevicesReader { [weak self] value in
self?.batteryCallback(value)
}
self.devicesReader.readyCallback = { [weak self] in
self?.readyHandler()
self.settingsView.callback = { [weak self] in
self?.devicesReader?.read()
}
self.addReader(self.devicesReader)
self.setReaders([self.devicesReader])
}
private func batteryCallback(_ raw: [BLEDevice]?) {

View File

@@ -40,8 +40,8 @@ internal class DevicesReader: Reader<[BLEDevice]>, CBCentralManagerDelegate, CBP
static let batteryServiceUUID = CBUUID(string: "0x180F")
static let batteryCharacteristicsUUID = CBUUID(string: "0x2A19")
init() {
super.init(.bluetooth)
init(callback: @escaping (T?) -> Void = {_ in }) {
super.init(.bluetooth, callback: callback)
self.manager = CBCentralManager(delegate: self, queue: nil)
}

View File

@@ -89,8 +89,8 @@ public class CPU: Module {
}
public init() {
self.settingsView = Settings("CPU")
self.popupView = Popup("CPU")
self.settingsView = Settings(.CPU)
self.popupView = Popup(.CPU)
self.portalView = Portal(.CPU)
self.notificationsView = Notifications(.CPU)
@@ -102,14 +102,26 @@ public class CPU: Module {
)
guard self.available else { return }
self.loadReader = LoadReader(.CPU)
self.processReader = ProcessReader(.CPU)
self.averageReader = AverageReader(.CPU, popup: true)
self.temperatureReader = TemperatureReader(.CPU, popup: true)
self.loadReader = LoadReader(.CPU) { [weak self] value in
self?.loadCallback(value)
}
self.processReader = ProcessReader(.CPU) { [weak self] value in
self?.popupView.processCallback(value)
}
self.averageReader = AverageReader(.CPU, popup: true) { [weak self] value in
self?.popupView.averageCallback(value)
}
self.temperatureReader = TemperatureReader(.CPU, popup: true) { [weak self] value in
self?.popupView.temperatureCallback(value)
}
#if arch(x86_64)
self.limitReader = LimitReader(.CPU, popup: true)
self.frequencyReader = FrequencyReader(.CPU, popup: true)
self.limitReader = LimitReader(.CPU, popup: true) { [weak self] value in
self?.popupView.limitCallback(value)
}
self.frequencyReader = FrequencyReader(.CPU, popup: true) { [weak self] value in
self?.popupView.frequencyCallback(value)
}
#endif
self.settingsView.callback = { [weak self] in
@@ -134,58 +146,14 @@ public class CPU: Module {
self?.popupView.toggleFrequency(state: value)
}
self.loadReader?.callbackHandler = { [weak self] value in
self?.loadCallback(value)
}
self.loadReader?.readyCallback = { [weak self] in
self?.readyHandler()
}
self.processReader?.callbackHandler = { [weak self] value in
if let list = value {
self?.popupView.processCallback(list)
}
}
self.temperatureReader?.callbackHandler = { [weak self] value in
if let v = value {
self?.popupView.temperatureCallback(v)
}
}
self.frequencyReader?.callbackHandler = { [weak self] value in
if let v = value {
self?.popupView.frequencyCallback(v)
}
}
self.limitReader?.callbackHandler = { [weak self] value in
if let v = value {
self?.popupView.limitCallback(v)
}
}
self.averageReader?.callbackHandler = { [weak self] value in
if let v = value {
self?.popupView.averageCallback(v)
}
}
if let reader = self.loadReader {
self.addReader(reader)
}
if let reader = self.processReader {
self.addReader(reader)
}
if let reader = self.temperatureReader {
self.addReader(reader)
}
if let reader = self.frequencyReader {
self.addReader(reader)
}
if let reader = self.limitReader {
self.addReader(reader)
}
if let reader = self.averageReader {
self.addReader(reader)
}
self.setReaders([
self.loadReader,
self.processReader,
self.temperatureReader,
self.frequencyReader,
self.limitReader,
self.averageReader
])
}
private func loadCallback(_ raw: CPU_Load?) {

View File

@@ -89,8 +89,8 @@ internal class Popup: PopupWrapper {
(self.processHeight*CGFloat(self.numberOfProcesses)) + (self.numberOfProcesses == 0 ? 0 : Constants.Popup.separatorHeight + 22)
}
public init(_ title: String) {
self.title = title
public init(_ module: ModuleType) {
self.title = module.rawValue
super.init(frame: NSRect(
x: 0,
@@ -341,7 +341,9 @@ internal class Popup: PopupWrapper {
})
}
public func temperatureCallback(_ value: Double) {
public func temperatureCallback(_ value: Double?) {
guard let value else { return }
DispatchQueue.main.async(execute: {
if (self.window?.isVisible ?? false) || !self.initializedTemperature {
if let view = self.temperatureCircle, (view as NSView).isHidden {
@@ -355,7 +357,9 @@ internal class Popup: PopupWrapper {
})
}
public func frequencyCallback(_ value: Double) {
public func frequencyCallback(_ value: Double?) {
guard let value else { return }
DispatchQueue.main.async(execute: {
if let view = self.frequencyCircle, (view as NSView).isHidden {
view.isHidden = false
@@ -376,7 +380,9 @@ internal class Popup: PopupWrapper {
})
}
public func processCallback(_ list: [TopProcess]) {
public func processCallback(_ list: [TopProcess]?) {
guard let list else { return }
DispatchQueue.main.async(execute: {
if !(self.window?.isVisible ?? false) && self.initializedProcesses {
return
@@ -393,7 +399,9 @@ internal class Popup: PopupWrapper {
})
}
public func limitCallback(_ value: CPU_Limit) {
public func limitCallback(_ value: CPU_Limit?) {
guard let value else { return }
DispatchQueue.main.async(execute: {
if !(self.window?.isVisible ?? false) && self.initializedLimits {
return
@@ -406,10 +414,8 @@ internal class Popup: PopupWrapper {
})
}
public func averageCallback(_ value: [Double]) {
guard value.count == 3 else {
return
}
public func averageCallback(_ value: [Double]?) {
guard let value, value.count == 3 else { return }
DispatchQueue.main.async(execute: {
if !(self.window?.isVisible ?? false) && self.initializedAverage {

View File

@@ -36,8 +36,8 @@ internal class Settings: NSStackView, Settings_v {
private var usagePerCoreView: NSView? = nil
private var groupByClustersView: NSView? = nil
public init(_ title: String) {
self.title = title
public init(_ module: ModuleType) {
self.title = module.rawValue
self.hyperthreadState = Store.shared.bool(key: "\(self.title)_hyperhreading", defaultValue: self.hyperthreadState)
self.usagePerCoreState = Store.shared.bool(key: "\(self.title)_usagePerCore", defaultValue: self.usagePerCoreState)
self.splitValueState = Store.shared.bool(key: "\(self.title)_splitValue", defaultValue: self.splitValueState)

View File

@@ -56,12 +56,12 @@ internal class ClockReader: Reader<Date> {
public class Clock: Module {
private let popupView: Popup = Popup()
private let portalView: Portal
private let settingsView: Settings = Settings()
private let settingsView: Settings = Settings(.clock)
private var reader: ClockReader = ClockReader(.clock)
private var reader: ClockReader?
static var list: [Clock_t] {
if let objects = Store.shared.data(key: "\(Clock.title)_list") {
if let objects = Store.shared.data(key: "\(ModuleType.clock.rawValue)_list") {
let decoder = JSONDecoder()
if let objectsDecoded = try? decoder.decode(Array.self, from: objects) as [Clock_t] {
return objectsDecoded
@@ -71,7 +71,7 @@ public class Clock: Module {
}
public init() {
self.portalView = Portal("Clock", list: Clock.list)
self.portalView = Portal(.clock, list: Clock.list)
super.init(
popup: self.popupView,
@@ -80,18 +80,16 @@ public class Clock: Module {
)
guard self.available else { return }
self.reader.callbackHandler = { [weak self] value in
guard let value else { return }
self.reader = ClockReader(.clock) { [weak self] value in
self?.callback(value)
}
self.addReader(self.reader)
self.reader.readyCallback = { [weak self] in
self?.readyHandler()
}
self.setReaders([self.reader])
}
private func callback(_ value: Date) {
private func callback(_ value: Date?) {
guard let value else { return }
var clocks: [Clock_t] = Clock.list
var widgetList: [Stack_t] = []
@@ -117,7 +115,6 @@ public class Clock: Module {
}
extension Clock {
static let title: String = "Clock"
static let localID: String = UUID().uuidString
static var local: Clock_t {
Clock_t(id: Clock.localID, name: localizedString("Local time"), format: "yyyy-MM-dd HH:mm:ss", tz: "local")

View File

@@ -20,8 +20,8 @@ public class Portal: NSStackView, Portal_p {
private var oneContainer: NSGridView = NSGridView()
private var multiplyContainer: ScrollableStackView = ScrollableStackView(orientation: .horizontal)
init(_ name: String, list: [Clock_t]) {
self.name = name
init(_ module: ModuleType, list: [Clock_t]) {
self.name = module.rawValue
super.init(frame: NSRect.zero)

View File

@@ -22,7 +22,7 @@ internal class Settings: NSStackView, Settings_v, NSTableViewDelegate, NSTableVi
private var list: [Clock_t] {
get {
if let objects = Store.shared.data(key: "\(Clock.title)_list") {
if let objects = Store.shared.data(key: "\(self.title)_list") {
let decoder = JSONDecoder()
if let objectsDecoded = try? decoder.decode(Array.self, from: objects) as [Clock_t] {
return objectsDecoded
@@ -32,16 +32,17 @@ internal class Settings: NSStackView, Settings_v, NSTableViewDelegate, NSTableVi
}
set {
if newValue.isEmpty {
Store.shared.remove("\(Clock.title)_list")
Store.shared.remove("\(self.title)_list")
} else {
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(newValue){
Store.shared.set(key: "\(Clock.title)_list", value: encoded)
Store.shared.set(key: "\(self.title)_list", value: encoded)
}
}
}
}
private var title: String
private var selectedRow: Int = -1
private let scrollView = NSScrollView()
@@ -49,7 +50,9 @@ internal class Settings: NSStackView, Settings_v, NSTableViewDelegate, NSTableVi
private var footerView: NSStackView? = nil
private var deleteButton: NSButton? = nil
public init() {
public init(_ module: ModuleType) {
self.title = module.rawValue
super.init(frame: NSRect.zero)
self.orientation = .vertical

View File

@@ -170,7 +170,7 @@ public class Disks: Codable {
public struct Disk_process: Process_p, Codable {
public var base: DataSizeBase {
DataSizeBase(rawValue: Store.shared.string(key: "\(Disk.name)_base", defaultValue: "byte")) ?? .byte
DataSizeBase(rawValue: Store.shared.string(key: "\(ModuleType.disk.rawValue)_base", defaultValue: "byte")) ?? .byte
}
public var pid: Int
@@ -200,22 +200,18 @@ public struct Disk_process: Process_p, Codable {
}
public class Disk: Module {
public static let name: String = "Disk"
private let popupView: Popup = Popup()
private let settingsView: Settings = Settings()
private let popupView: Popup = Popup(.disk)
private let settingsView: Settings = Settings(.disk)
private let portalView: Portal = Portal(.disk)
private let notificationsView: Notifications
private let notificationsView: Notifications = Notifications(.disk)
private var capacityReader: CapacityReader = CapacityReader(.disk)
private var activityReader: ActivityReader = ActivityReader()
private var processReader: ProcessReader = ProcessReader(.disk)
private var capacityReader: CapacityReader?
private var activityReader: ActivityReader?
private var processReader: ProcessReader?
private var selectedDisk: String = ""
public init() {
self.notificationsView = Notifications(.disk)
super.init(
popup: self.popupView,
settings: self.settingsView,
@@ -224,52 +220,46 @@ public class Disk: Module {
)
guard self.available else { return }
self.selectedDisk = Store.shared.string(key: "\(Disk.name)_disk", defaultValue: self.selectedDisk)
self.capacityReader.callbackHandler = { [weak self] value in
self.capacityReader = CapacityReader(.disk) { [weak self] value in
if let value {
self?.capacityCallback(value)
}
}
self.capacityReader.readyCallback = { [weak self] in
self?.readyHandler()
}
self.activityReader.callbackHandler = { [weak self] value in
self.activityReader = ActivityReader(.disk) { [weak self] value in
if let value {
self?.activityCallback(value)
}
}
self.processReader.callbackHandler = { [weak self] value in
self.processReader = ProcessReader(.disk) { [weak self] value in
if let list = value {
self?.popupView.processCallback(list)
}
}
self.selectedDisk = Store.shared.string(key: "\(ModuleType.disk.rawValue)_disk", defaultValue: self.selectedDisk)
self.settingsView.selectedDiskHandler = { [weak self] value in
self?.selectedDisk = value
self?.capacityReader.read()
self?.capacityReader?.read()
}
self.settingsView.callback = { [weak self] in
self?.capacityReader.read()
self?.capacityReader?.read()
}
self.settingsView.setInterval = { [weak self] value in
self?.capacityReader.setInterval(value)
self?.capacityReader?.setInterval(value)
}
self.settingsView.callbackWhenUpdateNumberOfProcesses = { [weak self] in
self?.popupView.numberOfProcessesUpdated()
DispatchQueue.global(qos: .background).async {
self?.processReader.read()
self?.processReader?.read()
}
}
self.addReader(self.capacityReader)
self.addReader(self.activityReader)
self.addReader(self.processReader)
self.setReaders([self.capacityReader, self.activityReader, self.processReader])
}
public override func widgetDidSet(_ type: widget_t) {
if type == .speed && self.capacityReader.interval != 1 {
if type == .speed && self.capacityReader?.interval != 1 {
self.settingsView.setUpdateInterval(value: 1)
}
}

View File

@@ -38,13 +38,13 @@ internal class Popup: PopupWrapper {
private var processes: ProcessesView? = nil
private var processesView: NSView? = nil
public init() {
self.title = Disk.name
public init(_ module: ModuleType) {
self.title = module.rawValue
super.init(frame: NSRect(x: 0, y: 0, width: Constants.Popup.width, height: 0))
self.readColorState = Color.fromString(Store.shared.string(key: "\(Disk.name)_readColor", defaultValue: self.readColorState.key))
self.writeColorState = Color.fromString(Store.shared.string(key: "\(Disk.name)_writeColor", defaultValue: self.writeColorState.key))
self.readColorState = Color.fromString(Store.shared.string(key: "\(self.title)_readColor", defaultValue: self.readColorState.key))
self.writeColorState = Color.fromString(Store.shared.string(key: "\(self.title)_writeColor", defaultValue: self.writeColorState.key))
self.orientation = .vertical
self.distribution = .fill
@@ -192,7 +192,7 @@ internal class Popup: PopupWrapper {
return
}
self.writeColorState = newValue
Store.shared.set(key: "\(Disk.name)_writeColor", value: key)
Store.shared.set(key: "\(self.title)_writeColor", value: key)
if let color = newValue.additional as? NSColor {
self.processes?.setColor(1, color)
for view in self.disks.subviews.filter({ $0 is DiskView }).map({ $0 as! DiskView }) {
@@ -206,7 +206,7 @@ internal class Popup: PopupWrapper {
return
}
self.readColorState = newValue
Store.shared.set(key: "\(Disk.name)_readColor", value: key)
Store.shared.set(key: "\(self.title)_readColor", value: key)
if let color = newValue.additional as? NSColor {
self.processes?.setColor(0, color)
for view in self.disks.subviews.filter({ $0 is DiskView }).map({ $0 as! DiskView }) {
@@ -297,21 +297,23 @@ internal class DiskView: NSStackView {
internal class NameView: NSStackView {
private let size: Int64
private let uri: URL?
private let finder: URL?
private var ready: Bool = false
private var readState: NSView? = nil
private var writeState: NSView? = nil
private var readColor: NSColor {
Color.fromString(Store.shared.string(key: "\(Disk.name)_readColor", defaultValue: Color.secondBlue.key)).additional as! NSColor
Color.fromString(Store.shared.string(key: "\(ModuleType.disk.rawValue)_readColor", defaultValue: Color.secondBlue.key)).additional as! NSColor
}
private var writeColor: NSColor {
Color.fromString(Store.shared.string(key: "\(Disk.name)_writeColor", defaultValue: Color.secondRed.key)).additional as! NSColor
Color.fromString(Store.shared.string(key: "\(ModuleType.disk.rawValue)_writeColor", defaultValue: Color.secondRed.key)).additional as! NSColor
}
public init(width: CGFloat, name: String, size: Int64, free: Int64, path: URL?) {
self.size = size
self.uri = path
self.finder = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.Finder")
super.init(frame: NSRect(x: 0, y: 0, width: width, height: 16))
@@ -400,8 +402,8 @@ internal class NameView: NSStackView {
}
override func mouseDown(with: NSEvent) {
if let uri = self.uri {
NSWorkspace.shared.openFile(uri.path, withApplication: "Finder")
if let uri = self.uri, let finder = self.finder {
NSWorkspace.shared.open([uri], withApplicationAt: finder, configuration: NSWorkspace.OpenConfiguration())
}
}
}
@@ -411,10 +413,10 @@ internal class ChartView: NSStackView {
private var ready: Bool = false
private var readColor: NSColor {
Color.fromString(Store.shared.string(key: "\(Disk.name)_readColor", defaultValue: Color.secondBlue.key)).additional as! NSColor
Color.fromString(Store.shared.string(key: "\(ModuleType.disk.rawValue)_readColor", defaultValue: Color.secondBlue.key)).additional as! NSColor
}
private var writeColor: NSColor {
Color.fromString(Store.shared.string(key: "\(Disk.name)_writeColor", defaultValue: Color.secondRed.key)).additional as! NSColor
Color.fromString(Store.shared.string(key: "\(ModuleType.disk.rawValue)_writeColor", defaultValue: Color.secondRed.key)).additional as! NSColor
}
public init(width: CGFloat) {

View File

@@ -24,10 +24,10 @@ public class Portal: PortalWrapper {
private var valueColor: NSColor { self.valueColorState.additional as? NSColor ?? NSColor.systemBlue }
private var readColor: NSColor {
Color.fromString(Store.shared.string(key: "\(Disk.name)_readColor", defaultValue: Color.secondBlue.key)).additional as! NSColor
Color.fromString(Store.shared.string(key: "\(self.name)_readColor", defaultValue: Color.secondBlue.key)).additional as! NSColor
}
private var writeColor: NSColor {
Color.fromString(Store.shared.string(key: "\(Disk.name)_writeColor", defaultValue: Color.secondRed.key)).additional as! NSColor
Color.fromString(Store.shared.string(key: "\(self.name)_writeColor", defaultValue: Color.secondRed.key)).additional as! NSColor
}
private var initialized: Bool = false

View File

@@ -187,10 +187,6 @@ internal class CapacityReader: Reader<Disks> {
internal class ActivityReader: Reader<Disks> {
internal var list: Disks = Disks()
init() {
super.init(.disk)
}
override func setup() {
self.setInterval(1)
}
@@ -370,7 +366,7 @@ public class ProcessReader: Reader<[Disk_process]> {
}
private var numberOfProcesses: Int {
Store.shared.int(key: "\(Disk.name)_processes", defaultValue: 5)
Store.shared.int(key: "\(ModuleType.disk.rawValue)_processes", defaultValue: 5)
}
public override func setup() {

View File

@@ -13,6 +13,8 @@ import Cocoa
import Kit
internal class Settings: NSStackView, Settings_v {
private let title: String
private var removableState: Bool = false
private var updateIntervalValue: Int = 10
private var notificationLevel: String = "Disabled"
@@ -30,13 +32,15 @@ internal class Settings: NSStackView, Settings_v {
private var list: [String] = []
public init() {
self.selectedDisk = Store.shared.string(key: "\(Disk.name)_disk", defaultValue: "")
self.removableState = Store.shared.bool(key: "\(Disk.name)_removable", defaultValue: self.removableState)
self.updateIntervalValue = Store.shared.int(key: "\(Disk.name)_updateInterval", defaultValue: self.updateIntervalValue)
self.notificationLevel = Store.shared.string(key: "\(Disk.name)_notificationLevel", defaultValue: self.notificationLevel)
self.numberOfProcesses = Store.shared.int(key: "\(Disk.name)_processes", defaultValue: self.numberOfProcesses)
self.baseValue = Store.shared.string(key: "\(Disk.name)_base", defaultValue: self.baseValue)
public init(_ module: ModuleType) {
self.title = module.rawValue
self.selectedDisk = Store.shared.string(key: "\(self.title)_disk", defaultValue: "")
self.removableState = Store.shared.bool(key: "\(self.title)_removable", defaultValue: self.removableState)
self.updateIntervalValue = Store.shared.int(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue)
self.notificationLevel = Store.shared.string(key: "\(self.title)_notificationLevel", defaultValue: self.notificationLevel)
self.numberOfProcesses = Store.shared.int(key: "\(self.title)_processes", defaultValue: self.numberOfProcesses)
self.baseValue = Store.shared.string(key: "\(self.title)_base", defaultValue: self.baseValue)
super.init(frame: NSRect(x: 0, y: 0, width: 0, height: 0))
@@ -144,7 +148,7 @@ internal class Settings: NSStackView, Settings_v {
@objc private func changeNumberOfProcesses(_ sender: NSMenuItem) {
if let value = Int(sender.title) {
self.numberOfProcesses = value
Store.shared.set(key: "\(Disk.name)_processes", value: value)
Store.shared.set(key: "\(self.title)_processes", value: value)
self.callbackWhenUpdateNumberOfProcesses()
}
}
@@ -152,13 +156,13 @@ internal class Settings: NSStackView, Settings_v {
@objc private func handleSelection(_ sender: NSPopUpButton) {
guard let item = sender.selectedItem else { return }
self.selectedDisk = item.title
Store.shared.set(key: "\(Disk.name)_disk", value: item.title)
Store.shared.set(key: "\(self.title)_disk", value: item.title)
self.selectedDiskHandler(item.title)
}
@objc private func toggleRemovable(_ sender: NSControl) {
self.removableState = controlState(sender)
Store.shared.set(key: "\(Disk.name)_removable", value: self.removableState)
Store.shared.set(key: "\(self.title)_removable", value: self.removableState)
self.callback()
}
@@ -172,21 +176,21 @@ internal class Settings: NSStackView, Settings_v {
guard let key = sender.representedObject as? String else { return }
if key == "Disabled" {
Store.shared.set(key: "\(Disk.name)_notificationLevel", value: key)
Store.shared.set(key: "\(self.title)_notificationLevel", value: key)
} else if let value = Double(key.replacingOccurrences(of: "%", with: "")) {
Store.shared.set(key: "\(Disk.name)_notificationLevel", value: "\(value/100)")
Store.shared.set(key: "\(self.title)_notificationLevel", value: "\(value/100)")
}
}
public func setUpdateInterval(value: Int) {
self.updateIntervalValue = value
Store.shared.set(key: "\(Disk.name)_updateInterval", value: value)
Store.shared.set(key: "\(self.title)_updateInterval", value: value)
self.setInterval(value)
}
@objc private func toggleBase(_ sender: NSMenuItem) {
guard let key = sender.representedObject as? String else { return }
self.baseValue = key
Store.shared.set(key: "\(Disk.name)_base", value: self.baseValue)
Store.shared.set(key: "\(self.title)_base", value: self.baseValue)
}
}

View File

@@ -84,7 +84,7 @@ public class GPU: Module {
public init() {
self.popupView = Popup()
self.settingsView = Settings("GPU")
self.settingsView = Settings(.GPU)
self.portalView = Portal(.GPU)
self.notificationsView = Notifications(.GPU)
@@ -96,15 +96,10 @@ public class GPU: Module {
)
guard self.available else { return }
self.infoReader = InfoReader(.GPU)
self.selectedGPU = Store.shared.string(key: "\(self.config.name)_gpu", defaultValue: self.selectedGPU)
self.infoReader?.callbackHandler = { [weak self] value in
self.infoReader = InfoReader(.GPU) { [weak self] value in
self?.infoCallback(value)
}
self.infoReader?.readyCallback = { [weak self] in
self?.readyHandler()
}
self.selectedGPU = Store.shared.string(key: "\(self.config.name)_gpu", defaultValue: self.selectedGPU)
self.settingsView.selectedGPUHandler = { [weak self] value in
self?.selectedGPU = value
@@ -117,9 +112,7 @@ public class GPU: Module {
self?.infoReader?.read()
}
if let reader = self.infoReader {
self.addReader(reader)
}
self.setReaders([self.infoReader])
}
private func infoCallback(_ raw: GPUs?) {

View File

@@ -26,8 +26,8 @@ internal class Settings: NSStackView, Settings_v {
private var hyperthreadView: NSView? = nil
private var button: NSPopUpButton?
public init(_ title: String) {
self.title = title
public init(_ module: ModuleType) {
self.title = module.rawValue
self.selectedGPU = Store.shared.string(key: "\(self.title)_gpu", defaultValue: "")
self.updateIntervalValue = Store.shared.int(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue)
self.showTypeValue = Store.shared.bool(key: "\(self.title)_showType", defaultValue: self.showTypeValue)

View File

@@ -143,9 +143,9 @@ public class Network: Module {
}
public init() {
self.settingsView = Settings("Network")
self.popupView = Popup("Network")
self.portalView = Portal("Network")
self.settingsView = Settings(.network)
self.popupView = Popup(.network)
self.portalView = Portal(.network)
super.init(
popup: self.popupView,
@@ -154,9 +154,17 @@ public class Network: Module {
)
guard self.available else { return }
self.usageReader = UsageReader(.network)
self.processReader = ProcessReader(.network)
self.connectivityReader = ConnectivityReader(.network)
self.usageReader = UsageReader(.network) { [weak self] value in
self?.usageCallback(value)
}
self.processReader = ProcessReader(.network) { [weak self] value in
if let list = value {
self?.popupView.processCallback(list)
}
}
self.connectivityReader = ConnectivityReader(.network) { [weak self] value in
self?.connectivityCallback(value)
}
self.settingsView.callbackWhenUpdateNumberOfProcesses = {
self.popupView.numberOfProcessesUpdated()
@@ -165,23 +173,6 @@ public class Network: Module {
}
}
self.usageReader?.callbackHandler = { [weak self] value in
self?.usageCallback(value)
}
self.usageReader?.readyCallback = { [weak self] in
self?.readyHandler()
}
self.processReader?.callbackHandler = { [weak self] value in
if let list = value {
self?.popupView.processCallback(list)
}
}
self.connectivityReader?.callbackHandler = { [weak self] value in
self?.connectivityCallback(value)
}
self.settingsView.callback = { [weak self] in
self?.usageReader?.getDetails()
self?.usageReader?.read()
@@ -199,15 +190,7 @@ public class Network: Module {
self?.setIPUpdater()
}
if let reader = self.usageReader {
self.addReader(reader)
}
if let reader = self.processReader {
self.addReader(reader)
}
if let reader = self.connectivityReader {
self.addReader(reader)
}
self.setReaders([self.usageReader, self.processReader, self.connectivityReader])
self.setIPUpdater()
self.setUsageReset()

View File

@@ -91,8 +91,8 @@ internal class Popup: PopupWrapper {
private var latency: [Double] = []
public init(_ title: String) {
self.title = title
public init(_ module: ModuleType) {
self.title = module.rawValue
super.init(frame: NSRect(
x: 0,

View File

@@ -38,8 +38,8 @@ public class Portal: NSStackView, Portal_p {
return value
}
init(_ name: String) {
self.name = name
public init(_ module: ModuleType) {
self.name = module.rawValue
super.init(frame: NSRect.zero)

View File

@@ -42,8 +42,8 @@ internal class Settings: NSStackView, Settings_v, NSTextFieldDelegate {
return false
}
public init(_ title: String) {
self.title = title
public init(_ module: ModuleType) {
self.title = module.rawValue
self.numberOfProcesses = Store.shared.int(key: "\(self.title)_processes", defaultValue: self.numberOfProcesses)
self.readerType = Store.shared.string(key: "\(self.title)_reader", defaultValue: self.readerType)
self.usageReset = Store.shared.string(key: "\(self.title)_usageReset", defaultValue: self.usageReset)

View File

@@ -90,8 +90,8 @@ public class RAM: Module {
}
public init() {
self.settingsView = Settings("RAM")
self.popupView = Popup("RAM")
self.settingsView = Settings(.RAM)
self.popupView = Popup(.RAM)
self.portalView = Portal(.RAM)
self.notificationsView = Notifications(.RAM)
@@ -114,8 +114,14 @@ public class RAM: Module {
self?.processReader?.setInterval(value)
}
self.usageReader = UsageReader(.RAM)
self.processReader = ProcessReader(.RAM)
self.usageReader = UsageReader(.RAM) { [weak self] value in
self?.loadCallback(value)
}
self.processReader = ProcessReader(.RAM) { [weak self] value in
if let list = value {
self?.popupView.processCallback(list)
}
}
self.settingsView.callbackWhenUpdateNumberOfProcesses = { [weak self] in
self?.popupView.numberOfProcessesUpdated()
@@ -124,25 +130,7 @@ public class RAM: Module {
}
}
self.usageReader?.callbackHandler = { [weak self] value in
self?.loadCallback(value)
}
self.usageReader?.readyCallback = { [weak self] in
self?.readyHandler()
}
self.processReader?.callbackHandler = { [weak self] value in
if let list = value {
self?.popupView.processCallback(list)
}
}
if let reader = self.usageReader {
self.addReader(reader)
}
if let reader = self.processReader {
self.addReader(reader)
}
self.setReaders([self.usageReader, self.processReader])
}
private func loadCallback(_ raw: RAM_Usage?) {

View File

@@ -62,8 +62,8 @@ internal class Popup: PopupWrapper {
private var chartColorState: Color = .systemAccent
private var chartColor: NSColor { self.chartColorState.additional as? NSColor ?? NSColor.systemBlue }
public init(_ title: String) {
self.title = title
public init(_ module: ModuleType) {
self.title = module.rawValue
super.init(frame: NSRect(
x: 0,

View File

@@ -26,8 +26,8 @@ internal class Settings: NSStackView, Settings_v {
public var setInterval: ((_ value: Int) -> Void) = {_ in }
public var setTopInterval: ((_ value: Int) -> Void) = {_ in }
public init(_ title: String) {
self.title = title
public init(_ module: ModuleType) {
self.title = module.rawValue
self.updateIntervalValue = Store.shared.int(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue)
self.updateTopIntervalValue = Store.shared.int(key: "\(self.title)_updateTopInterval", defaultValue: self.updateTopIntervalValue)
self.numberOfProcesses = Store.shared.int(key: "\(self.title)_processes", defaultValue: self.numberOfProcesses)

View File

@@ -13,7 +13,7 @@ import Cocoa
import Kit
public class Sensors: Module {
private let sensorsReader: SensorsReader
private var sensorsReader: SensorsReader?
private let popupView: Popup
private let settingsView: Settings
private let portalView: Portal
@@ -24,8 +24,7 @@ public class Sensors: Module {
}
public init() {
self.sensorsReader = SensorsReader()
self.settingsView = Settings("Sensors", list: self.sensorsReader.list.sensors)
self.settingsView = Settings(.sensors)
self.popupView = Popup()
self.portalView = Portal(.sensors)
self.notificationsView = Notifications(.sensors)
@@ -38,53 +37,51 @@ public class Sensors: Module {
)
guard self.available else { return }
self.popupView.setup(self.sensorsReader.list.sensors)
self.portalView.setup(self.sensorsReader.list.sensors)
self.notificationsView.setup(self.sensorsReader.list.sensors)
self.sensorsReader = SensorsReader { [weak self] value in
self?.usageCallback(value)
}
self.settingsView.setList(self.sensorsReader?.list.sensors)
self.popupView.setup(self.sensorsReader?.list.sensors)
self.portalView.setup(self.sensorsReader?.list.sensors)
self.notificationsView.setup(self.sensorsReader?.list.sensors)
self.settingsView.callback = { [weak self] in
self?.sensorsReader.read()
self?.sensorsReader?.read()
}
self.settingsView.setInterval = { [weak self] value in
self?.sensorsReader.setInterval(value)
self?.sensorsReader?.setInterval(value)
}
self.settingsView.HIDcallback = { [weak self] in
DispatchQueue.global(qos: .background).async {
self?.sensorsReader.HIDCallback()
self?.sensorsReader?.HIDCallback()
DispatchQueue.main.async {
self?.popupView.setup(self?.sensorsReader.list.sensors)
self?.portalView.setup(self?.sensorsReader.list.sensors)
self?.settingsView.setList(list: self?.sensorsReader.list.sensors ?? [])
self?.notificationsView.setup(self?.sensorsReader.list.sensors)
self?.popupView.setup(self?.sensorsReader?.list.sensors)
self?.portalView.setup(self?.sensorsReader?.list.sensors)
self?.settingsView.setList(self?.sensorsReader?.list.sensors)
self?.notificationsView.setup(self?.sensorsReader?.list.sensors)
}
}
}
self.settingsView.unknownCallback = { [weak self] in
DispatchQueue.global(qos: .background).async {
self?.sensorsReader.unknownCallback()
self?.sensorsReader?.unknownCallback()
DispatchQueue.main.async {
self?.popupView.setup(self?.sensorsReader.list.sensors)
self?.portalView.setup(self?.sensorsReader.list.sensors)
self?.settingsView.setList(list: self?.sensorsReader.list.sensors ?? [])
self?.notificationsView.setup(self?.sensorsReader.list.sensors)
self?.popupView.setup(self?.sensorsReader?.list.sensors)
self?.portalView.setup(self?.sensorsReader?.list.sensors)
self?.settingsView.setList(self?.sensorsReader?.list.sensors)
self?.notificationsView.setup(self?.sensorsReader?.list.sensors)
}
}
}
self.sensorsReader.callbackHandler = { [weak self] value in
self?.usageCallback(value)
}
self.sensorsReader.readyCallback = { [weak self] in
self?.readyHandler()
}
self.addReader(self.sensorsReader)
self.setReaders([self.sensorsReader])
}
public override func willTerminate() {
guard SMCHelper.shared.isActive() else { return }
guard SMCHelper.shared.isActive(), let reader = self.sensorsReader else { return }
self.sensorsReader.list.sensors.filter({ $0 is Fan }).forEach { (s: Sensor_p) in
reader.list.sensors.filter({ $0 is Fan }).forEach { (s: Sensor_p) in
if let f = s as? Fan, let mode = f.customMode {
if mode != .automatic {
SMCHelper.shared.setFanMode(f.id, mode: FanMode.automatic.rawValue)
@@ -93,12 +90,9 @@ public class Sensors: Module {
}
}
public override func isAvailable() -> Bool {
return !self.sensorsReader.list.sensors.isEmpty
}
private func checkIfNoSensorsEnabled() {
if self.sensorsReader.list.sensors.filter({ $0.state }).isEmpty {
guard let reader = self.sensorsReader else { return }
if reader.list.sensors.filter({ $0.state }).isEmpty {
NotificationCenter.default.post(name: .toggleModule, object: nil, userInfo: ["module": self.config.name, "state": false])
}
}

View File

@@ -25,9 +25,9 @@ internal class SensorsReader: Reader<Sensors_List> {
}
private var unknownSensorsState: Bool
init() {
init(callback: @escaping (T?) -> Void = {_ in }) {
self.unknownSensorsState = Store.shared.bool(key: "Sensors_unknown", defaultValue: false)
super.init(.sensors)
super.init(.sensors, callback: callback)
self.list.sensors = self.sensors()
}

View File

@@ -22,16 +22,15 @@ internal class Settings: NSStackView, Settings_v {
private let title: String
private var button: NSPopUpButton?
private var list: [Sensor_p]
private var list: [Sensor_p] = []
private var widgets: [widget_t] = []
public var callback: (() -> Void) = {}
public var HIDcallback: (() -> Void) = {}
public var unknownCallback: (() -> Void) = {}
public var setInterval: ((_ value: Int) -> Void) = {_ in }
public init(_ title: String, list: [Sensor_p]) {
self.title = title
self.list = list
public init(_ module: ModuleType) {
self.title = module.rawValue
self.hidState = SystemKit.shared.device.platform == .m1 ? true : false
super.init(frame: NSRect(x: 0, y: 0, width: 0, height: 0))
@@ -166,7 +165,8 @@ internal class Settings: NSStackView, Settings_v {
self.widgets = widgets
}
public func setList(list: [Sensor_p]) {
public func setList(_ list: [Sensor_p]?) {
guard let list else { return }
self.list = self.unknownSensorsState ? list : list.filter({ $0.group != .unknown })
self.load(widgets: self.widgets)
}