diff --git a/Stats.xcodeproj/project.pbxproj b/Stats.xcodeproj/project.pbxproj index 86f82044..ed486c80 100755 --- a/Stats.xcodeproj/project.pbxproj +++ b/Stats.xcodeproj/project.pbxproj @@ -15,7 +15,6 @@ 9A426DB822C2B5EE00C064C4 /* macAppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A426DB722C2B5EE00C064C4 /* macAppUpdater.swift */; }; 9A426DBE22C2BE0000C064C4 /* Updates.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A426DBD22C2BE0000C064C4 /* Updates.storyboard */; }; 9A57A18522A1D26D0033E318 /* MenuBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A57A18422A1D26D0033E318 /* MenuBar.swift */; }; - 9A57A19B22A1E1C50033E318 /* Module.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A57A19A22A1E1C50033E318 /* Module.swift */; }; 9A57A19D22A1E3270033E318 /* CPU.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A57A19C22A1E3270033E318 /* CPU.swift */; }; 9A58D1B022C150C800405315 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58D1AF22C150C800405315 /* Network.swift */; }; 9A58D1B222C150D700405315 /* NetworkReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58D1B122C150D700405315 /* NetworkReader.swift */; }; @@ -25,6 +24,9 @@ 9A6CFC0122A1C9F5001E782D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9A6CFC0022A1C9F5001E782D /* Assets.xcassets */; }; 9A74D59422B4315C004FE1FA /* Chart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A74D59322B4315C004FE1FA /* Chart.swift */; }; 9A74D59722B44498004FE1FA /* Mini.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A74D59622B44498004FE1FA /* Mini.swift */; }; + 9A79B36A22D3BEE600BF1C3A /* Widget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A79B36922D3BEE600BF1C3A /* Widget.swift */; }; + 9A79B36C22D3BEF000BF1C3A /* Module.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A79B36B22D3BEF000BF1C3A /* Module.swift */; }; + 9A79B36E22D3BEF900BF1C3A /* Reader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A79B36D22D3BEF900BF1C3A /* Reader.swift */; }; 9A7B8F5E22A2A57600DEB352 /* CPUReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A7B8F5D22A2A57600DEB352 /* CPUReader.swift */; }; 9A7B8F6922A2C3A100DEB352 /* Memory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A7B8F6822A2C3A100DEB352 /* Memory.swift */; }; 9A7B8F6B22A2C3A700DEB352 /* Disk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A7B8F6A22A2C3A700DEB352 /* Disk.swift */; }; @@ -63,7 +65,6 @@ 9A426DB722C2B5EE00C064C4 /* macAppUpdater.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = macAppUpdater.swift; sourceTree = ""; }; 9A426DBD22C2BE0000C064C4 /* Updates.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Updates.storyboard; sourceTree = ""; }; 9A57A18422A1D26D0033E318 /* MenuBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBar.swift; sourceTree = ""; }; - 9A57A19A22A1E1C50033E318 /* Module.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Module.swift; sourceTree = ""; }; 9A57A19C22A1E3270033E318 /* CPU.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPU.swift; sourceTree = ""; }; 9A58D1AF22C150C800405315 /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = ""; }; 9A58D1B122C150D700405315 /* NetworkReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkReader.swift; sourceTree = ""; }; @@ -73,6 +74,9 @@ 9A6CFC0022A1C9F5001E782D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 9A74D59322B4315C004FE1FA /* Chart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Chart.swift; sourceTree = ""; }; 9A74D59622B44498004FE1FA /* Mini.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mini.swift; sourceTree = ""; }; + 9A79B36922D3BEE600BF1C3A /* Widget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Widget.swift; sourceTree = ""; }; + 9A79B36B22D3BEF000BF1C3A /* Module.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Module.swift; sourceTree = ""; }; + 9A79B36D22D3BEF900BF1C3A /* Reader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reader.swift; sourceTree = ""; }; 9A7B8F5D22A2A57600DEB352 /* CPUReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPUReader.swift; sourceTree = ""; }; 9A7B8F6822A2C3A100DEB352 /* Memory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Memory.swift; sourceTree = ""; }; 9A7B8F6A22A2C3A700DEB352 /* Disk.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Disk.swift; sourceTree = ""; }; @@ -178,6 +182,8 @@ 9A7B8F6322A2C17500DEB352 /* Disk */, 9A09C89C22B3A7BB0018426F /* Battery */, 9A58D1AE22C150B800405315 /* Network */, + 9A79B36B22D3BEF000BF1C3A /* Module.swift */, + 9A79B36D22D3BEF900BF1C3A /* Reader.swift */, ); path = Modules; sourceTree = ""; @@ -186,7 +192,6 @@ isa = PBXGroup; children = ( 9A5B1CBE229E78F0008B9D3C /* Observable.swift */, - 9A57A19A22A1E1C50033E318 /* Module.swift */, 9A5B1CC4229E7B40008B9D3C /* Extensions.swift */, 9A426DB722C2B5EE00C064C4 /* macAppUpdater.swift */, ); @@ -200,6 +205,7 @@ 9A74D59322B4315C004FE1FA /* Chart.swift */, 9A74D59622B44498004FE1FA /* Mini.swift */, 9A58D1B322C179B200405315 /* NetworkView.swift */, + 9A79B36922D3BEE600BF1C3A /* Widget.swift */, ); path = Widgets; sourceTree = ""; @@ -362,6 +368,7 @@ files = ( 9A09C8A222B3D94D0018426F /* BatteryView.swift in Sources */, 9A426DB822C2B5EE00C064C4 /* macAppUpdater.swift in Sources */, + 9A79B36E22D3BEF900BF1C3A /* Reader.swift in Sources */, 9A7B8F6F22A2C57000DEB352 /* DiskReader.swift in Sources */, 9A7B8F6922A2C3A100DEB352 /* Memory.swift in Sources */, 9A7B8F5E22A2A57600DEB352 /* CPUReader.swift in Sources */, @@ -369,17 +376,18 @@ 9A58D1B422C179B200405315 /* NetworkView.swift in Sources */, 9A09C89E22B3A7C90018426F /* Battery.swift in Sources */, 9A7B8F6D22A2C3D600DEB352 /* MemoryReader.swift in Sources */, + 9A79B36C22D3BEF000BF1C3A /* Module.swift in Sources */, 9A57A18522A1D26D0033E318 /* MenuBar.swift in Sources */, 9A57A19D22A1E3270033E318 /* CPU.swift in Sources */, 9A58D1B222C150D700405315 /* NetworkReader.swift in Sources */, 9A09C8A022B3A7E20018426F /* BatteryReader.swift in Sources */, 9A58D1B022C150C800405315 /* Network.swift in Sources */, - 9A57A19B22A1E1C50033E318 /* Module.swift in Sources */, 9A5B1CBF229E78F0008B9D3C /* Observable.swift in Sources */, 9A7B8F6B22A2C3A700DEB352 /* Disk.swift in Sources */, 9A1410F9229E721100D29793 /* AppDelegate.swift in Sources */, 9A74D59722B44498004FE1FA /* Mini.swift in Sources */, 9A5B1CC5229E7B40008B9D3C /* Extensions.swift in Sources */, + 9A79B36A22D3BEE600BF1C3A /* Widget.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Stats/Modules/Battery/Battery.swift b/Stats/Modules/Battery/Battery.swift index 6d78bb4d..4b43f5a6 100644 --- a/Stats/Modules/Battery/Battery.swift +++ b/Stats/Modules/Battery/Battery.swift @@ -32,14 +32,14 @@ class Battery: Module { } func start() { - if !self.reader.usage.value.isNaN { - let value = self.reader.usage!.value + if !self.reader.value.value.isNaN { + let value = self.reader.value!.value (self.view as! BatteryView).setCharging(value: value > 0) (self.view as! Widget).value(value: abs(value)) } self.reader.start() - self.reader.usage.subscribe(observer: self) { (value, _) in + self.reader.value.subscribe(observer: self) { (value, _) in if !value.isNaN { (self.view as! BatteryView).setCharging(value: value > 0) (self.view as! Widget).value(value: abs(value)) diff --git a/Stats/Modules/Battery/BatteryReader.swift b/Stats/Modules/Battery/BatteryReader.swift index 092d166b..8a2c89ca 100644 --- a/Stats/Modules/Battery/BatteryReader.swift +++ b/Stats/Modules/Battery/BatteryReader.swift @@ -10,12 +10,12 @@ import Foundation import IOKit.ps class BatteryReader: Reader { - var usage: Observable! + var value: Observable! var available: Bool = false var updateTimer: Timer! init() { - self.usage = Observable(0) + self.value = Observable(0) read() } @@ -49,7 +49,7 @@ class BatteryReader: Reader { cap = 0 - cap } - self.usage << Double(cap) + self.value << Double(cap) } } } diff --git a/Stats/Modules/CPU/CPUReader.swift b/Stats/Modules/CPU/CPUReader.swift index 96f155e3..1cee0c2e 100644 --- a/Stats/Modules/CPU/CPUReader.swift +++ b/Stats/Modules/CPU/CPUReader.swift @@ -9,7 +9,7 @@ import Foundation class CPUReader: Reader { - var usage: Observable! + var value: Observable! var available: Bool = true var cpuInfo: processor_info_array_t! var prevCpuInfo: processor_info_array_t? @@ -21,7 +21,7 @@ class CPUReader: Reader { init() { let mibKeys: [Int32] = [ CTL_HW, HW_NCPU ] - self.usage = Observable(0) + self.value = Observable(0) mibKeys.withUnsafeBufferPointer() { mib in var sizeOfNumCPUs: size_t = MemoryLayout.size let status = sysctl(processor_info_array_t(mutating: mib.baseAddress), 2, &numCPUs, &sizeOfNumCPUs, nil, 0) @@ -77,7 +77,7 @@ class CPUReader: Reader { inUseOnAllCores = inUseOnAllCores + inUse totalOnAllCores = totalOnAllCores + total } - self.usage << (Double(inUseOnAllCores) / Double(totalOnAllCores)) + self.value << (Double(inUseOnAllCores) / Double(totalOnAllCores)) CPUUsageLock.unlock() diff --git a/Stats/Modules/Disk/DiskReader.swift b/Stats/Modules/Disk/DiskReader.swift index 2d69be2f..582c1a16 100644 --- a/Stats/Modules/Disk/DiskReader.swift +++ b/Stats/Modules/Disk/DiskReader.swift @@ -9,12 +9,12 @@ import Foundation class DiskReader: Reader { - var usage: Observable! + var value: Observable! var available: Bool = true var updateTimer: Timer! init() { - self.usage = Observable(0) + self.value = Observable(0) read() } @@ -38,7 +38,7 @@ class DiskReader: Reader { let free = freeDiskSpaceInBytes() let usedSpace = total - free - self.usage << (Double(usedSpace) / Double(total)) + self.value << (Double(usedSpace) / Double(total)) } func totalDiskSpaceInBytes() -> Int64 { diff --git a/Stats/Modules/Memory/MemoryReader.swift b/Stats/Modules/Memory/MemoryReader.swift index fbcffb51..2df61bb5 100644 --- a/Stats/Modules/Memory/MemoryReader.swift +++ b/Stats/Modules/Memory/MemoryReader.swift @@ -9,13 +9,13 @@ import Foundation class MemoryReader: Reader { - var usage: Observable! + var value: Observable! var available: Bool = true var updateTimer: Timer! var totalSize: Float init() { - self.usage = Observable(0) + self.value = Observable(0) var stats = host_basic_info() var count = UInt32(MemoryLayout.size / MemoryLayout.size) @@ -68,7 +68,7 @@ class MemoryReader: Reader { let compressed = Float(stats.compressor_page_count) * Float(PAGE_SIZE) let free = totalSize - (active + wired + compressed) - self.usage << Double((totalSize - free) / totalSize) + self.value << Double((totalSize - free) / totalSize) } else { print("Error with host_statistics64(): " + (String(cString: mach_error_string(kerr), encoding: String.Encoding.ascii) ?? "unknown error")) diff --git a/Stats/libs/Module.swift b/Stats/Modules/Module.swift similarity index 70% rename from Stats/libs/Module.swift rename to Stats/Modules/Module.swift index 3df2257a..d95a77dc 100644 --- a/Stats/libs/Module.swift +++ b/Stats/Modules/Module.swift @@ -2,7 +2,7 @@ // Module.swift // Stats // -// Created by Serhiy Mytrovtsiy on 01.06.2019. +// Created by Serhiy Mytrovtsiy on 08.07.2019. // Copyright © 2019 Serhiy Mytrovtsiy. All rights reserved. // @@ -11,13 +11,14 @@ import Cocoa protocol Module: class { var name: String { get } var shortName: String { get } + var view: NSView { get set } var menu: NSMenuItem { get } - var submenu: NSMenu { get } + var widgetType: WidgetType { get } + var active: Observable { get } var available: Observable { get } var reader: Reader { get } - var widgetType: WidgetType { get } func start() func stop() @@ -41,19 +42,19 @@ extension Module { widget.label = self.shortName self.view = widget break - case Widgets.Dots: + case Widgets.NetworkDots: self.view = NetworkDotsView(frame: NSMakeRect(0, 0, MODULE_WIDTH, MODULE_HEIGHT)) break - case Widgets.Arrows: + case Widgets.NetworkArrows: self.view = NetworkArrowsView(frame: NSMakeRect(0, 0, MODULE_WIDTH, MODULE_HEIGHT)) break - case Widgets.Text: + case Widgets.NetworkText: self.view = NetworkTextView(frame: NSMakeRect(0, 0, MODULE_WIDTH, MODULE_HEIGHT)) break - case Widgets.DotsWithText: + case Widgets.NetworkDotsWithText: self.view = NetworkDotsTextView(frame: NSMakeRect(0, 0, MODULE_WIDTH, MODULE_HEIGHT)) break - case Widgets.ArrowsWithText: + case Widgets.NetworkArrowsWithText: self.view = NetworkArrowsTextView(frame: NSMakeRect(0, 0, MODULE_WIDTH, MODULE_HEIGHT)) break default: @@ -64,15 +65,15 @@ extension Module { } func start() { - if !self.reader.usage.value.isNaN { + if !self.reader.value.value.isNaN { guard let widget = self.view as? Widget else { return } - widget.value(value: self.reader.usage.value) + widget.value(value: self.reader.value.value) } self.reader.start() - self.reader.usage.subscribe(observer: self) { (value, _) in + self.reader.value.subscribe(observer: self) { (value, _) in if !value.isNaN { guard let widget = self.view as? Widget else { return @@ -91,35 +92,7 @@ extension Module { func stop() { self.reader.stop() - self.reader.usage.unsubscribe(observer: self) + self.reader.value.unsubscribe(observer: self) colors.unsubscribe(observer: self) } } - -protocol Reader { - var usage: Observable! { get } - var available: Bool { get } - var updateTimer: Timer! { get set } - func start() - func stop() - func read() -} - -protocol Widget { - func value(value: Double) - func redraw() -} - -typealias WidgetType = Float - -struct Widgets { - static let Mini: WidgetType = 0.0 - static let Chart: WidgetType = 1.0 - static let ChartWithValue: WidgetType = 1.1 - - static let Dots: WidgetType = 2.0 - static let Arrows: WidgetType = 2.1 - static let Text: WidgetType = 2.2 - static let DotsWithText: WidgetType = 2.3 - static let ArrowsWithText: WidgetType = 2.4 -} diff --git a/Stats/Modules/Network/Network.swift b/Stats/Modules/Network/Network.swift index 9924c19e..f5f2b6e2 100644 --- a/Stats/Modules/Network/Network.swift +++ b/Stats/Modules/Network/Network.swift @@ -24,7 +24,7 @@ class Network: Module { init() { self.available = Observable(self.reader.available) self.active = Observable(defaults.object(forKey: name) != nil ? defaults.bool(forKey: name) : true) - self.widgetType = defaults.object(forKey: "\(name)_widget") != nil ? defaults.float(forKey: "\(name)_widget") : Widgets.Dots + self.widgetType = defaults.object(forKey: "\(name)_widget") != nil ? defaults.float(forKey: "\(name)_widget") : Widgets.NetworkDots initMenu() initWidget() } @@ -32,7 +32,7 @@ class Network: Module { func start() { self.reader.start() - self.reader.usage.subscribe(observer: self) { (value, _) in + self.reader.value.subscribe(observer: self) { (value, _) in if !value.isNaN { (self.view as! Widget).value(value: value) } @@ -51,23 +51,23 @@ class Network: Module { menu.target = self let dots = NSMenuItem(title: "Dots", action: #selector(toggleWidget), keyEquivalent: "") - dots.state = self.widgetType == Widgets.Dots ? NSControl.StateValue.on : NSControl.StateValue.off + dots.state = self.widgetType == Widgets.NetworkDots ? NSControl.StateValue.on : NSControl.StateValue.off dots.target = self let arrows = NSMenuItem(title: "Arrows", action: #selector(toggleWidget), keyEquivalent: "") - arrows.state = self.widgetType == Widgets.Arrows ? NSControl.StateValue.on : NSControl.StateValue.off + arrows.state = self.widgetType == Widgets.NetworkArrows ? NSControl.StateValue.on : NSControl.StateValue.off arrows.target = self let text = NSMenuItem(title: "Text", action: #selector(toggleWidget), keyEquivalent: "") - text.state = self.widgetType == Widgets.Text ? NSControl.StateValue.on : NSControl.StateValue.off + text.state = self.widgetType == Widgets.NetworkText ? NSControl.StateValue.on : NSControl.StateValue.off text.target = self let dotsWithText = NSMenuItem(title: "Dots with text", action: #selector(toggleWidget), keyEquivalent: "") - dotsWithText.state = self.widgetType == Widgets.DotsWithText ? NSControl.StateValue.on : NSControl.StateValue.off + dotsWithText.state = self.widgetType == Widgets.NetworkDotsWithText ? NSControl.StateValue.on : NSControl.StateValue.off dotsWithText.target = self let arrowsWithText = NSMenuItem(title: "Arrows with text", action: #selector(toggleWidget), keyEquivalent: "") - arrowsWithText.state = self.widgetType == Widgets.ArrowsWithText ? NSControl.StateValue.on : NSControl.StateValue.off + arrowsWithText.state = self.widgetType == Widgets.NetworkArrowsWithText ? NSControl.StateValue.on : NSControl.StateValue.off arrowsWithText.target = self submenu.addItem(dots) @@ -100,15 +100,15 @@ class Network: Module { switch sender.title { case "Dots": - widgetCode = Widgets.Dots + widgetCode = Widgets.NetworkDots case "Arrows": - widgetCode = Widgets.Arrows + widgetCode = Widgets.NetworkArrows case "Text": - widgetCode = Widgets.Text + widgetCode = Widgets.NetworkText case "Dots with text": - widgetCode = Widgets.DotsWithText + widgetCode = Widgets.NetworkDotsWithText case "Arrows with text": - widgetCode = Widgets.ArrowsWithText + widgetCode = Widgets.NetworkArrowsWithText default: break } diff --git a/Stats/Modules/Network/NetworkReader.swift b/Stats/Modules/Network/NetworkReader.swift index f40cd05d..6e3ad2e2 100644 --- a/Stats/Modules/Network/NetworkReader.swift +++ b/Stats/Modules/Network/NetworkReader.swift @@ -9,7 +9,7 @@ import Cocoa class NetworkReader: Reader { - var usage: Observable! + var value: Observable! var available: Bool = true var updateTimer: Timer! @@ -17,7 +17,7 @@ class NetworkReader: Reader { var pipe: Pipe = Pipe() init() { - self.usage = Observable(0) + self.value = Observable(0) netProcess.launchPath = "/usr/bin/env" netProcess.arguments = ["netstat", "-w1", "-l", "en0"] netProcess.standardOutput = pipe @@ -51,7 +51,7 @@ class NetworkReader: Reader { return } - self.usage << value + self.value << value } } diff --git a/Stats/Modules/Reader.swift b/Stats/Modules/Reader.swift new file mode 100644 index 00000000..18d60b65 --- /dev/null +++ b/Stats/Modules/Reader.swift @@ -0,0 +1,20 @@ +// +// Reader.swift +// Stats +// +// Created by Serhiy Mytrovtsiy on 08.07.2019. +// Copyright © 2019 Serhiy Mytrovtsiy. All rights reserved. +// + +import Foundation + +protocol Reader { + var value: Observable! { get } + + var available: Bool { get } + var updateTimer: Timer! { get set } + + func start() + func stop() + func read() +} diff --git a/Stats/Widgets/Widget.swift b/Stats/Widgets/Widget.swift new file mode 100644 index 00000000..5f9442a5 --- /dev/null +++ b/Stats/Widgets/Widget.swift @@ -0,0 +1,28 @@ +// +// Widget.swift +// Stats +// +// Created by Serhiy Mytrovtsiy on 08.07.2019. +// Copyright © 2019 Serhiy Mytrovtsiy. All rights reserved. +// + +import Foundation + +protocol Widget { + func value(value: Double) + func redraw() +} + +typealias WidgetType = Float + +struct Widgets { + static let Mini: WidgetType = 0.0 + static let Chart: WidgetType = 1.0 + static let ChartWithValue: WidgetType = 1.1 + + static let NetworkDots: WidgetType = 2.0 + static let NetworkArrows: WidgetType = 2.1 + static let NetworkText: WidgetType = 2.2 + static let NetworkDotsWithText: WidgetType = 2.3 + static let NetworkArrowsWithText: WidgetType = 2.4 +}