diff --git a/Kit/module/module.swift b/Kit/module/module.swift index f72b903b..e2008e30 100644 --- a/Kit/module/module.swift +++ b/Kit/module/module.swift @@ -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 diff --git a/Modules/Battery/main.swift b/Modules/Battery/main.swift index de285d53..7d0d2020 100644 --- a/Modules/Battery/main.swift +++ b/Modules/Battery/main.swift @@ -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() { diff --git a/Modules/Battery/popup.swift b/Modules/Battery/popup.swift index 265b7a53..1682ffc5 100644 --- a/Modules/Battery/popup.swift +++ b/Modules/Battery/popup.swift @@ -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, diff --git a/Modules/Battery/portal.swift b/Modules/Battery/portal.swift index 3fb89e13..39eae2e5 100644 --- a/Modules/Battery/portal.swift +++ b/Modules/Battery/portal.swift @@ -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) diff --git a/Modules/Battery/settings.swift b/Modules/Battery/settings.swift index b66fbbae..72809582 100644 --- a/Modules/Battery/settings.swift +++ b/Modules/Battery/settings.swift @@ -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) diff --git a/Modules/Bluetooth/main.swift b/Modules/Bluetooth/main.swift index 62767795..b74fc476 100644 --- a/Modules/Bluetooth/main.swift +++ b/Modules/Bluetooth/main.swift @@ -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]?) { diff --git a/Modules/Bluetooth/readers.swift b/Modules/Bluetooth/readers.swift index a909cea6..e2afc5d1 100644 --- a/Modules/Bluetooth/readers.swift +++ b/Modules/Bluetooth/readers.swift @@ -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) } diff --git a/Modules/CPU/main.swift b/Modules/CPU/main.swift index 106ca5e5..8e8fa1b9 100644 --- a/Modules/CPU/main.swift +++ b/Modules/CPU/main.swift @@ -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?) { diff --git a/Modules/CPU/popup.swift b/Modules/CPU/popup.swift index c7c3b6a4..ca0ff20b 100644 --- a/Modules/CPU/popup.swift +++ b/Modules/CPU/popup.swift @@ -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 { diff --git a/Modules/CPU/settings.swift b/Modules/CPU/settings.swift index 009dd04b..18c75101 100644 --- a/Modules/CPU/settings.swift +++ b/Modules/CPU/settings.swift @@ -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) diff --git a/Modules/Clock/main.swift b/Modules/Clock/main.swift index 4d7fc693..91bad425 100644 --- a/Modules/Clock/main.swift +++ b/Modules/Clock/main.swift @@ -56,12 +56,12 @@ internal class ClockReader: Reader { 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") diff --git a/Modules/Clock/portal.swift b/Modules/Clock/portal.swift index 5980074a..f5aa3f67 100644 --- a/Modules/Clock/portal.swift +++ b/Modules/Clock/portal.swift @@ -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) diff --git a/Modules/Clock/settings.swift b/Modules/Clock/settings.swift index 577861ed..377e8d79 100644 --- a/Modules/Clock/settings.swift +++ b/Modules/Clock/settings.swift @@ -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 diff --git a/Modules/Disk/main.swift b/Modules/Disk/main.swift index 4b3fad3f..36c27f13 100644 --- a/Modules/Disk/main.swift +++ b/Modules/Disk/main.swift @@ -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) } } diff --git a/Modules/Disk/popup.swift b/Modules/Disk/popup.swift index 7c804c37..af6dec54 100644 --- a/Modules/Disk/popup.swift +++ b/Modules/Disk/popup.swift @@ -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) { diff --git a/Modules/Disk/portal.swift b/Modules/Disk/portal.swift index 9849aee2..28916db0 100644 --- a/Modules/Disk/portal.swift +++ b/Modules/Disk/portal.swift @@ -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 diff --git a/Modules/Disk/readers.swift b/Modules/Disk/readers.swift index 7c237559..dcda39ef 100644 --- a/Modules/Disk/readers.swift +++ b/Modules/Disk/readers.swift @@ -187,10 +187,6 @@ internal class CapacityReader: Reader { internal class ActivityReader: Reader { 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() { diff --git a/Modules/Disk/settings.swift b/Modules/Disk/settings.swift index 082293b2..55c55441 100644 --- a/Modules/Disk/settings.swift +++ b/Modules/Disk/settings.swift @@ -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) } } diff --git a/Modules/GPU/main.swift b/Modules/GPU/main.swift index e8895036..a70fa14a 100644 --- a/Modules/GPU/main.swift +++ b/Modules/GPU/main.swift @@ -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?) { diff --git a/Modules/GPU/settings.swift b/Modules/GPU/settings.swift index b7335a7d..a7c561f0 100644 --- a/Modules/GPU/settings.swift +++ b/Modules/GPU/settings.swift @@ -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) diff --git a/Modules/Net/main.swift b/Modules/Net/main.swift index 294e3360..dd03109c 100644 --- a/Modules/Net/main.swift +++ b/Modules/Net/main.swift @@ -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() diff --git a/Modules/Net/popup.swift b/Modules/Net/popup.swift index 20fdf2ff..a765e6a1 100644 --- a/Modules/Net/popup.swift +++ b/Modules/Net/popup.swift @@ -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, diff --git a/Modules/Net/portal.swift b/Modules/Net/portal.swift index f8819bf6..ea76dded 100644 --- a/Modules/Net/portal.swift +++ b/Modules/Net/portal.swift @@ -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) diff --git a/Modules/Net/settings.swift b/Modules/Net/settings.swift index 820203be..29859de4 100644 --- a/Modules/Net/settings.swift +++ b/Modules/Net/settings.swift @@ -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) diff --git a/Modules/RAM/main.swift b/Modules/RAM/main.swift index f4e47b78..cf467f5b 100644 --- a/Modules/RAM/main.swift +++ b/Modules/RAM/main.swift @@ -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?) { diff --git a/Modules/RAM/popup.swift b/Modules/RAM/popup.swift index 5a200f76..309e0811 100644 --- a/Modules/RAM/popup.swift +++ b/Modules/RAM/popup.swift @@ -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, diff --git a/Modules/RAM/settings.swift b/Modules/RAM/settings.swift index 59a748e6..b558edfe 100644 --- a/Modules/RAM/settings.swift +++ b/Modules/RAM/settings.swift @@ -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) diff --git a/Modules/Sensors/main.swift b/Modules/Sensors/main.swift index 834ba50a..6ab3904a 100644 --- a/Modules/Sensors/main.swift +++ b/Modules/Sensors/main.swift @@ -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]) } } diff --git a/Modules/Sensors/readers.swift b/Modules/Sensors/readers.swift index e034f8e7..d4449482 100644 --- a/Modules/Sensors/readers.swift +++ b/Modules/Sensors/readers.swift @@ -25,9 +25,9 @@ internal class SensorsReader: Reader { } 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() } diff --git a/Modules/Sensors/settings.swift b/Modules/Sensors/settings.swift index 0e487b9f..aa5cb0b7 100644 --- a/Modules/Sensors/settings.swift +++ b/Modules/Sensors/settings.swift @@ -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) }