summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJustin Martin <jaming@protonmail.com>2022-10-15 15:08:48 -0400
committerGitHub <noreply@github.com>2022-10-15 15:08:48 -0400
commitbd35bbdc9c539e035bc4bf91c799d85e566a6921 (patch)
tree7de767f70396f4fb51d1fb2d0d011e8cd6350744 /src
parent41970d9c64ba0a442cd8314456785b4bb6c2f7b7 (diff)
feature: add gpu ram collector for nvidia feature flag (#794)
* add gpu ram collector for nvidia feature flag * add row for TX in basic layout * size gpu point_vec * use vec for mem basic widget drawing * remove to_owned * code review: change mem tuple to struct with cfg fields, rename mem_basic ratio and use vec macro for layout * build on freebsd
Diffstat (limited to 'src')
-rw-r--r--src/app/data_farmer.rs30
-rw-r--r--src/app/data_harvester.rs22
-rw-r--r--src/app/data_harvester/cpu/sysinfo.rs12
-rw-r--r--src/app/data_harvester/memory/general.rs10
-rw-r--r--src/app/data_harvester/memory/general/heim.rs76
-rw-r--r--src/app/data_harvester/memory/general/sysinfo.rs73
-rw-r--r--src/app/data_harvester/nvidia.rs3
-rw-r--r--src/app/data_harvester/temperature/nvidia.rs6
-rw-r--r--src/bin/main.rs5
-rw-r--r--src/canvas.rs24
-rw-r--r--src/canvas/canvas_colours.rs23
-rw-r--r--src/canvas/widgets/mem_basic.rs164
-rw-r--r--src/canvas/widgets/mem_graph.rs59
-rw-r--r--src/constants.rs47
-rw-r--r--src/data_conversion.rs96
-rw-r--r--src/lib.rs4
-rw-r--r--src/options.rs1
17 files changed, 523 insertions, 132 deletions
diff --git a/src/app/data_farmer.rs b/src/app/data_farmer.rs
index e409957f..a89af0a7 100644
--- a/src/app/data_farmer.rs
+++ b/src/app/data_farmer.rs
@@ -43,6 +43,8 @@ pub struct TimedData {
pub swap_data: Option<Value>,
#[cfg(feature = "zfs")]
pub arc_data: Option<Value>,
+ #[cfg(feature = "gpu")]
+ pub gpu_data: Vec<Option<Value>>,
}
#[derive(Clone, Debug, Default)]
@@ -133,6 +135,8 @@ pub struct DataCollection {
pub battery_harvest: Vec<batteries::BatteryHarvest>,
#[cfg(feature = "zfs")]
pub arc_harvest: memory::MemHarvest,
+ #[cfg(feature = "gpu")]
+ pub gpu_harvest: Vec<(String, memory::MemHarvest)>,
}
impl Default for DataCollection {
@@ -155,6 +159,8 @@ impl Default for DataCollection {
battery_harvest: Vec::default(),
#[cfg(feature = "zfs")]
arc_harvest: memory::MemHarvest::default(),
+ #[cfg(feature = "gpu")]
+ gpu_harvest: Vec::default(),
}
}
}
@@ -179,6 +185,10 @@ impl DataCollection {
{
self.arc_harvest = memory::MemHarvest::default();
}
+ #[cfg(feature = "gpu")]
+ {
+ self.gpu_harvest = Vec::default();
+ }
}
pub fn clean_data(&mut self, max_time_millis: u64) {
@@ -222,6 +232,14 @@ impl DataCollection {
self.eat_arc(arc, &mut new_entry);
}
}
+
+ #[cfg(feature = "gpu")]
+ {
+ if let Some(gpu) = harvested_data.gpu {
+ self.eat_gpu(gpu, &mut new_entry);
+ }
+ }
+
// CPU
if let Some(cpu) = harvested_data.cpu {
self.eat_cpu(cpu, &mut new_entry);
@@ -405,8 +423,18 @@ impl DataCollection {
#[cfg(feature = "zfs")]
fn eat_arc(&mut self, arc: memory::MemHarvest, new_entry: &mut TimedData) {
- // Arc
new_entry.arc_data = arc.use_percent;
self.arc_harvest = arc;
}
+
+ #[cfg(feature = "gpu")]
+ fn eat_gpu(&mut self, gpu: Vec<(String, memory::MemHarvest)>, new_entry: &mut TimedData) {
+ // Note this only pre-calculates the data points - the names will be
+ // within the local copy of gpu_harvest. Since it's all sequential
+ // it probably doesn't matter anyways.
+ gpu.iter().for_each(|data| {
+ new_entry.gpu_data.push(data.1.use_percent);
+ });
+ self.gpu_harvest = gpu.to_vec();
+ }
}
diff --git a/src/app/data_harvester.rs b/src/app/data_harvester.rs
index cb02bdb1..4f163755 100644
--- a/src/app/data_harvester.rs
+++ b/src/app/data_harvester.rs
@@ -17,6 +17,9 @@ use futures::join;
use super::DataFilters;
+#[cfg(feature = "nvidia")]
+pub mod nvidia;
+
#[cfg(feature = "battery")]
pub mod batteries;
pub mod cpu;
@@ -42,6 +45,8 @@ pub struct Data {
pub list_of_batteries: Option<Vec<batteries::BatteryHarvest>>,
#[cfg(feature = "zfs")]
pub arc: Option<memory::MemHarvest>,
+ #[cfg(feature = "gpu")]
+ pub gpu: Option<Vec<(String, memory::MemHarvest)>>,
}
impl Default for Data {
@@ -61,6 +66,8 @@ impl Default for Data {
list_of_batteries: None,
#[cfg(feature = "zfs")]
arc: None,
+ #[cfg(feature = "gpu")]
+ gpu: None,
}
}
}
@@ -83,6 +90,10 @@ impl Data {
{
self.arc = None;
}
+ #[cfg(feature = "gpu")]
+ {
+ self.gpu = None;
+ }
}
}
@@ -423,19 +434,24 @@ impl DataCollector {
self.data.network = net_data;
}
- if let Ok(memory) = mem_res.0 {
+ if let Ok(memory) = mem_res.ram {
self.data.memory = memory;
}
- if let Ok(swap) = mem_res.1 {
+ if let Ok(swap) = mem_res.swap {
self.data.swap = swap;
}
#[cfg(feature = "zfs")]
- if let Ok(arc) = mem_res.2 {
+ if let Ok(arc) = mem_res.arc {
self.data.arc = arc;
}
+ #[cfg(feature = "gpu")]
+ if let Ok(gpu) = mem_res.gpus {
+ self.data.gpu = gpu;
+ }
+
if let Ok(disks) = disk_res {
self.data.disks = disks;
}
diff --git a/src/app/data_harvester/cpu/sysinfo.rs b/src/app/data_harvester/cpu/sysinfo.rs
index a5f363b8..54318e1b 100644
--- a/src/app/data_harvester/cpu/sysinfo.rs
+++ b/src/app/data_harvester/cpu/sysinfo.rs
@@ -3,9 +3,9 @@
use std::collections::VecDeque;
-use sysinfo::{LoadAvg, System, SystemExt};
+use sysinfo::{CpuExt, LoadAvg, System, SystemExt};
-use super::{CpuData, CpuHarvest, PastCpuTotal, PastCpuWork};
+use super::{CpuData, CpuDataType, CpuHarvest, PastCpuTotal, PastCpuWork};
use crate::app::data_harvester::cpu::LoadAvgHarvest;
pub async fn get_cpu_data_list(
@@ -14,12 +14,11 @@ pub async fn get_cpu_data_list(
_previous_average_cpu_time: &mut Option<(PastCpuWork, PastCpuTotal)>,
) -> crate::error::Result<CpuHarvest> {
let mut cpu_deque: VecDeque<_> = sys
- .processors()
+ .cpus()
.iter()
.enumerate()
.map(|(i, cpu)| CpuData {
- cpu_prefix: "CPU".to_string(),
- cpu_count: Some(i),
+ data_type: CpuDataType::Cpu(i),
cpu_usage: cpu.cpu_usage() as f64,
})
.collect();
@@ -28,8 +27,7 @@ pub async fn get_cpu_data_list(
let cpu = sys.global_cpu_info();
cpu_deque.push_front(CpuData {
- cpu_prefix: "AVG".to_string(),
- cpu_count: None,
+ data_type: CpuDataType::Avg,
cpu_usage: cpu.cpu_usage() as f64,
})
}
diff --git a/src/app/data_harvester/memory/general.rs b/src/app/data_harvester/memory/general.rs
index 45fb5fdd..84ac1e0d 100644
--- a/src/app/data_harvester/memory/general.rs
+++ b/src/app/data_harvester/memory/general.rs
@@ -14,3 +14,13 @@ pub struct MemHarvest {
pub mem_used_in_kib: u64,
pub use_percent: Option<f64>,
}
+
+#[derive(Debug)]
+pub struct MemCollect {
+ pub ram: crate::utils::error::Result<Option<MemHarvest>>,
+ pub swap: crate::utils::error::Result<Option<MemHarvest>>,
+ #[cfg(feature = "zfs")]
+ pub arc: crate::utils::error::Result<Option<MemHarvest>>,
+ #[cfg(feature = "gpu")]
+ pub gpus: crate::utils::error::Result<Option<Vec<(String, MemHarvest)>>>,
+}
diff --git a/src/app/data_harvester/memory/general/heim.rs b/src/app/data_harvester/memory/general/heim.rs
index 71a68430..83f78ae4 100644
--- a/src/app/data_harvester/memory/general/heim.rs
+++ b/src/app/data_harvester/memory/general/heim.rs
@@ -1,20 +1,26 @@
//! Data collection for memory via heim.
-use crate::data_harvester::memory::MemHarvest;
-
-pub async fn get_mem_data(
- actually_get: bool,
-) -> (
- crate::utils::error::Result<Option<MemHarvest>>,
- crate::utils::error::Result<Option<MemHarvest>>,
- crate::utils::error::Result<Option<MemHarvest>>,
-) {
- use futures::join;
+use crate::data_harvester::memory::{MemCollect, MemHarvest};
+pub async fn get_mem_data(actually_get: bool) -> MemCollect {
if !actually_get {
- (Ok(None), Ok(None), Ok(None))
+ MemCollect {
+ ram: Ok(None),
+ swap: Ok(None),
+ #[cfg(feature = "zfs")]
+ arc: Ok(None),
+ #[cfg(feature = "gpu")]
+ gpus: Ok(None),
+ }
} else {
- join!(get_ram_data(), get_swap_data(), get_arc_data())
+ MemCollect {
+ ram: get_ram_data().await,
+ swap: get_swap_data().await,
+ #[cfg(feature = "zfs")]
+ arc: get_arc_data().await,
+ #[cfg(feature = "gpu")]
+ gpus: get_gpu_data().await,
+ }
}
}
@@ -170,16 +176,15 @@ pub async fn get_swap_data() -> crate::utils::error::Result<Option<MemHarvest>>
}))
}
+#[cfg(feature = "zfs")]
pub async fn get_arc_data() -> crate::utils::error::Result<Option<MemHarvest>> {
- #[cfg(not(feature = "zfs"))]
- let (mem_total_in_kib, mem_used_in_kib) = (0, 0);
-
- #[cfg(feature = "zfs")]
let (mem_total_in_kib, mem_used_in_kib) = {
#[cfg(target_os = "linux")]
{
let mut mem_arc = 0;
let mut mem_total = 0;
+ let mut zfs_keys_read: u8 = 0;
+ const ZFS_KEYS_NEEDED: u8 = 2;
use smol::fs::read_to_string;
let arcinfo = read_to_string("/proc/spl/kstat/zfs/arcstats").await?;
for line in arcinfo.lines() {
@@ -191,8 +196,7 @@ pub async fn get_arc_data() -> crate::utils::error::Result<Option<MemHarvest>> {
continue;
}
};
- let mut zfs_keys_read: u8 = 0;
- const ZFS_KEYS_NEEDED: u8 = 2;
+
if let Some((_type, number)) = value.trim_start().rsplit_once(' ') {
// Parse the value, remember it's in bytes!
if let Ok(number) = number.parse::<u64>() {
@@ -247,3 +251,39 @@ pub async fn get_arc_data() -> crate::utils::error::Result<Option<MemHarvest>> {
},
}))
}
+
+#[cfg(feature = "nvidia")]
+pub async fn get_gpu_data() -> crate::utils::error::Result<Option<Vec<(String, MemHarvest)>>> {
+ use crate::data_harvester::nvidia::NVML_DATA;
+ if let Ok(nvml) = &*NVML_DATA {
+ if let Ok(ngpu) = nvml.device_count() {
+ let mut results = Vec::with_capacity(ngpu as usize);
+ for i in 0..ngpu {
+ if let Ok(device) = nvml.device_by_index(i) {
+ if let (Ok(name), Ok(mem)) = (device.name(), device.memory_info()) {
+ // add device memory in bytes
+ let mem_total_in_kib = mem.total / 1024;
+ let mem_used_in_kib = mem.used / 1024;
+ results.push((
+ name,
+ MemHarvest {
+ mem_total_in_kib,
+ mem_used_in_kib,
+ use_percent: if mem_total_in_kib == 0 {
+ None
+ } else {
+ Some(mem_used_in_kib as f64 / mem_total_in_kib as f64 * 100.0)
+ },
+ },
+ ));
+ }
+ }
+ }
+ Ok(Some(results))
+ } else {
+ Ok(None)
+ }
+ } else {
+ Ok(None)
+ }
+}
diff --git a/src/app/data_harvester/memory/general/sysinfo.rs b/src/app/data_harvester/memory/general/sysinfo.rs
index da4bd812..cf80c206 100644
--- a/src/app/data_harvester/memory/general/sysinfo.rs
+++ b/src/app/data_harvester/memory/general/sysinfo.rs
@@ -1,26 +1,32 @@
//! Data collection for memory via sysinfo.
-use crate::data_harvester::memory::MemHarvest;
+use crate::data_harvester::memory::{MemCollect, MemHarvest};
use sysinfo::{System, SystemExt};
-pub async fn get_mem_data(
- sys: &System, actually_get: bool,
-) -> (
- crate::utils::error::Result<Option<MemHarvest>>,
- crate::utils::error::Result<Option<MemHarvest>>,
- crate::utils::error::Result<Option<MemHarvest>>,
-) {
- use futures::join;
-
+pub async fn get_mem_data(sys: &System, actually_get: bool) -> MemCollect {
if !actually_get {
- (Ok(None), Ok(None), Ok(None))
+ MemCollect {
+ ram: Ok(None),
+ swap: Ok(None),
+ #[cfg(feature = "zfs")]
+ arc: Ok(None),
+ #[cfg(feature = "gpu")]
+ gpus: Ok(None),
+ }
} else {
- join!(get_ram_data(sys), get_swap_data(sys), get_arc_data())
+ MemCollect {
+ ram: get_ram_data(sys).await,
+ swap: get_swap_data(sys).await,
+ #[cfg(feature = "zfs")]
+ arc: get_arc_data().await,
+ #[cfg(feature = "gpu")]
+ gpus: get_gpu_data().await,
+ }
}
}
pub async fn get_ram_data(sys: &System) -> crate::utils::error::Result<Option<MemHarvest>> {
- let (mem_total_in_kib, mem_used_in_kib) = (sys.total_memory() / 1024, sys.used_memory()) / 1024;
+ let (mem_total_in_kib, mem_used_in_kib) = (sys.total_memory() / 1024, sys.used_memory() / 1024);
Ok(Some(MemHarvest {
mem_total_in_kib,
@@ -47,11 +53,8 @@ pub async fn get_swap_data(sys: &System) -> crate::utils::error::Result<Option<M
}))
}
+#[cfg(feature = "zfs")]
pub async fn get_arc_data() -> crate::utils::error::Result<Option<MemHarvest>> {
- #[cfg(not(feature = "zfs"))]
- let (mem_total_in_kib, mem_used_in_kib) = (0, 0);
-
- #[cfg(feature = "zfs")]
let (mem_total_in_kib, mem_used_in_kib) = {
#[cfg(target_os = "freebsd")]
{
@@ -82,3 +85,39 @@ pub async fn get_arc_data() -> crate::utils::error::Result<Option<MemHarvest>> {
},
}))
}
+
+#[cfg(feature = "nvidia")]
+pub async fn get_gpu_data() -> crate::utils::error::Result<Option<Vec<(String, MemHarvest)>>> {
+ use crate::data_harvester::nvidia::NVML_DATA;
+ if let Ok(nvml) = &*NVML_DATA {
+ if let Ok(ngpu) = nvml.device_count() {
+ let mut results = Vec::with_capacity(ngpu as usize);
+ for i in 0..ngpu {
+ if let Ok(device) = nvml.device_by_index(i) {
+ if let (Ok(name), Ok(mem)) = (device.name(), device.memory_info()) {
+ // add device memory in bytes
+ let mem_total_in_kib = mem.total / 1024;
+ let mem_used_in_kib = mem.used / 1024;
+ results.push((
+ name,
+ MemHarvest {
+ mem_total_in_kib,
+ mem_used_in_kib,
+ use_percent: if mem_total_in_kib == 0 {
+ None
+ } else {
+ Some(mem_used_in_kib as f64 / mem_total_in_kib as f64 * 100.0)
+ },
+ },
+ ));
+ }
+ }
+ }
+ Ok(Some(results))
+ } else {
+ Ok(None)
+ }
+ } else {
+ Ok(None)
+ }
+}
diff --git a/src/app/data_harvester/nvidia.rs b/src/app/data_harvester/nvidia.rs
new file mode 100644
index 00000000..72928a7c
--- /dev/null
+++ b/src/app/data_harvester/nvidia.rs
@@ -0,0 +1,3 @@
+use nvml_wrapper::{error::NvmlError, NVML};
+use once_cell::sync::Lazy;
+pub static NVML_DATA: Lazy<Result<NVML, NvmlError>> = Lazy::new(NVML::init);
diff --git a/src/app/data_harvester/temperature/nvidia.rs b/src/app/data_harvester/temperature/nvidia.rs
index c30345ab..049708b7 100644
--- a/src/app/data_harvester/temperature/nvidia.rs
+++ b/src/app/data_harvester/temperature/nvidia.rs
@@ -5,12 +5,14 @@ use super::{
TemperatureType,
};
-use nvml_wrapper::{enum_wrappers::device::TemperatureSensor, NVML};
+use nvml_wrapper::enum_wrappers::device::TemperatureSensor;
+
+use crate::data_harvester::nvidia::NVML_DATA;
pub fn add_nvidia_data(
temperature_vec: &mut Vec<TempHarvest>, temp_type: &TemperatureType, filter: &Option<Filter>,
) -> crate::utils::error::Result<()> {
- if let Ok(nvml) = NVML::init() {
+ if let Ok(nvml) = &*NVML_DATA {
if let Ok(ngpu) = nvml.device_count() {
for i in 0..ngpu {
if let Ok(device) = nvml.device_by_index(i) {
diff --git a/src/bin/main.rs b/src/bin/main.rs
index 4d7a0a34..a5473b00 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -210,6 +210,11 @@ fn main() -> Result<()> {
app.converted_data.arc_data =
convert_arc_data_points(&app.data_collection);
}
+ #[cfg(feature = "gpu")]
+ {
+ app.converted_data.gpu_data =
+ convert_gpu_data(&app.data_collection);
+ }
let (memory_labels, swap_labels) =
convert_mem_labels(&app.data_collection);
diff --git a/src/canvas.rs b/src/canvas.rs
index f171bddd..c9312700 100644
--- a/src/canvas.rs
+++ b/src/canvas.rs
@@ -451,19 +451,29 @@ impl Painter {
}
};
- let mut mem_rows = 0;
+ let mut mem_rows = 1;
+
+ if app_state.converted_data.swap_labels.is_some() {
+ mem_rows += 1; // add row for swap
+ }
#[cfg(feature = "zfs")]
{
- let arc_data = &app_state.converted_data.arc_data;
- if let Some(arc) = arc_data.last() {
- if arc.1 != 0.0 {
- mem_rows += 1; // add row for arc
- }
+ if app_state.converted_data.arc_labels.is_some() {
+ mem_rows += 1; // add row for arc
+ }
+ }
+
+ #[cfg(feature = "gpu")]
+ {
+ if let Some(gpu_data) = &app_state.converted_data.gpu_data {
+ mem_rows += gpu_data.len() as u16; // add row(s) for gpu
}
}
- mem_rows += 2; // add rows for SWAP and MEM
+ if mem_rows == 1 {
+ mem_rows += 1; // need at least 2 rows for RX and TX
+ }
let vertical_chunks = Layout::default()
.direction(Direction::Vertical)
diff --git a/src/canvas/canvas_colours.rs b/src/canvas/canvas_colours.rs
index 9630cc42..ab9b079e 100644
--- a/src/canvas/canvas_colours.rs
+++ b/src/canvas/canvas_colours.rs
@@ -18,6 +18,7 @@ pub struct CanvasColours {
pub ram_style: Style,
pub swap_style: Style,
pub arc_style: Style,
+ pub gpu_colour_styles: Vec<Style>,
pub rx_style: Style,
pub tx_style: Style,
pub total_rx_style: Style,
@@ -51,6 +52,15 @@ impl Default for CanvasColours {
ram_style: Style::default().fg(STANDARD_FIRST_COLOUR),
swap_style: Style::default().fg(STANDARD_SECOND_COLOUR),
arc_style: Style::default().fg(STANDARD_THIRD_COLOUR),
+ gpu_colour_styles: vec![
+ Style::default().fg(STANDARD_FOURTH_COLOUR),
+ Style::default().fg(Color::LightBlue),
+ Style::default().fg(Color::LightRed),
+ Style::default().fg(Color::Cyan),
+ Style::default().fg(Color::Green),
+ Style::default().fg(Color::Blue),
+ Style::default().fg(Color::Red),
+ ],
rx_style: Style::default().fg(STANDARD_FIRST_COLOUR),
tx_style: Style::default().fg(STANDARD_SECOND_COLOUR),
total_rx_style: Style::default().fg(STANDARD_THIRD_COLOUR),
@@ -160,6 +170,11 @@ impl CanvasColours {
.context("Update 'arc_color' in your config file..")?;
}
+ if let Some(gpu_core_colors) = &colours.gpu_core_colors {
+ self.set_gpu_colours(gpu_core_colors)
+ .context("Update 'gpu_core_colors' in your config file..")?;
+ }
+
if let Some(rx_color) = &colours.rx_color {
self.set_rx_colour(rx_color)
.context("Update 'rx_color' in your config file..")?;
@@ -268,6 +283,14 @@ impl CanvasColours {
Ok(())
}
+ pub fn set_gpu_colours(&mut self, colours: &[String]) -> error::Result<()> {
+ self.gpu_colour_styles = colours
+ .iter()
+ .map(|colour| get_style_from_config(colour))
+ .collect::<error::Result<Vec<Style>>>()?;
+ Ok(())
+ }
+
pub fn set_rx_colour(&mut self, colour: &str) -> error::Result<()> {
self.rx_style = get_style_from_config(colour)?;
Ok(())
diff --git a/src/canvas/widgets/mem_basic.rs b/src/canvas/widgets/mem_basic.rs
index 3e5e585d..8f372eff 100644
--- a/src/canvas/widgets/mem_basic.rs
+++ b/src/canvas/widgets/mem_basic.rs
@@ -14,23 +14,7 @@ impl Painter {
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
) {
let mem_data = &app_state.converted_data.mem_data;
- let swap_data = &app_state.converted_data.swap_data;
-
- let margined_loc = Layout::default()
- .constraints({
- #[cfg(feature = "zfs")]
- {
- [Constraint::Length(1); 3]
- }
-
- #[cfg(not(feature = "zfs"))]
- {
- [Constraint::Length(1); 2]
- }
- })
- .direction(Direction::Vertical)
- .horizontal_margin(1)
- .split(draw_loc);
+ let mut draw_widgets: Vec<PipeGauge<'_>> = Vec::new();
if app_state.current_widget.widget_id == widget_id {
f.render_widget(
@@ -41,13 +25,8 @@ impl Painter {
);
}
- let ram_ratio = if let Some(mem) = mem_data.last() {
- mem.1 / 100.0
- } else {
- 0.0
- };
- let swap_ratio = if let Some(swap) = swap_data.last() {
- swap.1 / 100.0
+ let ram_percentage = if let Some(mem) = mem_data.last() {
+ mem.1
} else {
0.0
};
@@ -56,64 +35,129 @@ impl Painter {
let memory_fraction_label =
if let Some((_, label_frac)) = &app_state.converted_data.mem_labels {
- label_frac.trim()
- } else {
- EMPTY_MEMORY_FRAC_STRING
- };
-
- let swap_fraction_label =
- if let Some((_, label_frac)) = &app_state.converted_data.swap_labels {
- label_frac.trim()
+ if app_state.basic_mode_use_percent {
+ format!("{:3.0}%", ram_percentage.round())
+ } else {
+ label_frac.trim().to_string()
+ }
} else {
- EMPTY_MEMORY_FRAC_STRING
+ EMPTY_MEMORY_FRAC_STRING.to_string()
};
- f.render_widget(
+ draw_widgets.push(
PipeGauge::default()
- .ratio(ram_ratio)
+ .ratio(ram_percentage / 100.0)
.start_label("RAM")
.inner_label(memory_fraction_label)
.label_style(self.colours.ram_style)
.gauge_style(self.colours.ram_style),
- margined_loc[0],
);
- f.render_widget(
- PipeGauge::default()
- .ratio(swap_ratio)
- .start_label("SWP")
- .inner_label(swap_fraction_label)
- .label_style(self.colours.swap_style)
- .gauge_style(self.colours.swap_style),
- margined_loc[1],
- );
+ let swap_data = &app_state.converted_data.swap_data;
+
+ let swap_percentage = if let Some(swap) = swap_data.last() {
+ swap.1
+ } else {
+ 0.0
+ };
+
+ if let Some((_, label_frac)) = &app_state.converted_data.swap_labels {
+ let swap_fraction_label = if app_state.basic_mode_use_percent {
+ format!("{:3.0}%", swap_percentage.round())
+ } else {
+ label_frac.trim().to_string()
+ };
+ draw_widgets.push(
+ PipeGauge::default()
+ .ratio(swap_percentage / 100.0)
+ .start_label("SWP")
+ .inner_label(swap_fraction_label)
+ .label_style(self.colours.swap_style)
+ .gauge_style(self.colours.swap_style),
+ );
+ }
#[cfg(feature = "zfs")]
{
let arc_data = &app_state.converted_data.arc_data;
- let arc_ratio = if let Some(arc) = arc_data.last() {
- arc.1 / 100.0
+ let arc_percentage = if let Some(arc) = arc_data.last() {
+ arc.1
} else {
0.0
};
- let arc_fraction_label =
- if let Some((_, label_frac)) = &app_state.converted_data.arc_labels {
- label_frac.trim()
+ if let Some((_, label_frac)) = &app_state.converted_data.arc_labels {
+ let arc_fraction_label = if app_state.basic_mode_use_percent {
+ format!("{:3.0}%", arc_percentage.round())
} else {
- EMPTY_MEMORY_FRAC_STRING
+ label_frac.trim().to_string()
};
+ draw_widgets.push(
+ PipeGauge::default()
+ .ratio(arc_percentage / 100.0)
+ .start_label("ARC")
+ .inner_label(arc_fraction_label)
+ .label_style(self.colours.arc_style)
+ .gauge_style(self.colours.arc_style),
+ );
+ }
+ }
- f.render_widget(
- PipeGauge::default()
- .ratio(arc_ratio)
- .start_label("ARC")
- .inner_label(arc_fraction_label)
- .label_style(self.colours.arc_style)
- .gauge_style(self.colours.arc_style),
- margined_loc[2],
- );
+ #[cfg(feature = "gpu")]
+ {
+ let gpu_styles = &self.colours.gpu_colour_styles;
+ let mut color_index = 0;
+ if let Some(gpu_data) = &app_state.converted_data.gpu_data {
+ gpu_data.iter().for_each(|gpu_data_vec| {
+ let gpu_data = gpu_data_vec.points.as_slice();
+ let gpu_percentage = if let Some(gpu) = gpu_data.last() {
+ gpu.1
+ } else {
+ 0.0
+ };
+ let trimmed_gpu_frac = {
+ if app_state.basic_mode_use_percent {
+ format!("{:3.0}%", gpu_percentage.round())
+ } else {
+ gpu_data_vec.mem_total.trim().to_string()
+ }
+ };
+ let style = {
+ if gpu_styles.is_empty() {
+ tui::style::Style::default()
+ } else if color_index >= gpu_styles.len() {
+ // cycle styles
+ color_index = 1;
+ gpu_styles[color_index - 1]
+ } else {
+ color_index += 1;
+ gpu_styles[color_index - 1]
+ }
+ };
+ draw_widgets.push(
+ PipeGauge::default()
+ .ratio(gpu_percentage / 100.0)
+ .start_label("GPU")
+ .inner_label(trimmed_gpu_frac)
+ .label_style(style)
+ .gauge_style(style),
+ );
+ });
+ }
}
+ let margined_loc = Layout::default()
+ .constraints(vec![Constraint::Length(1); draw_widgets.len()])
+ .direction(Direction::Vertical)
+ .horizontal_margin(1)
+ .split(draw_loc);
+
+ draw_widgets
+ .into_iter()
+ .enumerate()
+ .for_each(|(index, widget)| {
+ f.render_widget(widget, margined_loc[index]);
+ });
+
// Update draw loc in widget map
if app_state.should_get_widget_bounds() {
if let Some(widget) = app_state.widget_map.get_mut(&widget_id) {
diff --git a/src/canvas/widgets/mem_graph.rs b/src/canvas/widgets/mem_graph.rs
index bd959d28..c156fbaa 100644
--- a/src/canvas/widgets/mem_graph.rs
+++ b/src/canvas/widgets/mem_graph.rs
@@ -29,18 +29,22 @@ impl Painter {
draw_loc,
);
let points = {
- let mut size = 0;
+ let mut size = 1;
+ if app_state.converted_data.swap_labels.is_some() {
+ size += 1; // add capacity for SWAP
+ }
#[cfg(feature = "zfs")]
{
- let arc_data = &app_state.converted_data.arc_data;
- if let Some(arc) = arc_data.last() {
- if arc.1 != 0.0 {
- size += 1; // add capacity for ARC
- }
+ if app_state.converted_data.arc_labels.is_some() {
+ size += 1; // add capacity for ARC
+ }
+ }
+ #[cfg(feature = "gpu")]
+ {
+ if let Some(gpu_data) = &app_state.converted_data.gpu_data {
+ size += gpu_data.len(); // add row(s) for gpu
}
}
-
- size += 2; // add capacity for RAM and SWP
let mut points = Vec::with_capacity(size);
if let Some((label_p