feat: basic cpu graph
This commit is contained in:
parent
8f0abd2b78
commit
99c60658fa
4 changed files with 237 additions and 13 deletions
142
Cargo.lock
generated
142
Cargo.lock
generated
|
|
@ -770,6 +770,12 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "float_next_after"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
|
@ -1166,13 +1172,6 @@ dependencies = [
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iced-template"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"iced",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_core"
|
name = "iced_core"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
|
|
@ -1229,6 +1228,7 @@ dependencies = [
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"iced_futures",
|
"iced_futures",
|
||||||
"log",
|
"log",
|
||||||
|
"lyon_path",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"rustc-hash 2.1.3",
|
"rustc-hash 2.1.3",
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
|
|
@ -1303,6 +1303,7 @@ dependencies = [
|
||||||
"iced_debug",
|
"iced_debug",
|
||||||
"iced_graphics",
|
"iced_graphics",
|
||||||
"log",
|
"log",
|
||||||
|
"lyon",
|
||||||
"rustc-hash 2.1.3",
|
"rustc-hash 2.1.3",
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
"wgpu",
|
"wgpu",
|
||||||
|
|
@ -1351,6 +1352,14 @@ dependencies = [
|
||||||
"hashbrown 0.17.1",
|
"hashbrown 0.17.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itop"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"iced",
|
||||||
|
"sysinfo",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jni"
|
name = "jni"
|
||||||
version = "0.22.4"
|
version = "0.22.4"
|
||||||
|
|
@ -1545,6 +1554,58 @@ version = "0.16.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
|
checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lyon"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd0578bdecb7d6d88987b8b2b1e3a4e2f81df9d0ece1078623324a567904e7b7"
|
||||||
|
dependencies = [
|
||||||
|
"lyon_algorithms",
|
||||||
|
"lyon_tessellation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lyon_algorithms"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8575c0d003ae459399623c4def180c63b77f343b1a7fee64f249b349e7699a31"
|
||||||
|
dependencies = [
|
||||||
|
"lyon_path",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lyon_geom"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4336502e29e32af93cf2dad2214ed6003c17ceb5bd499df77b1de663b9042b92"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"euclid",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lyon_path"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c463f9c428b7fc5ec885dcd39ce4aa61e29111d0e33483f6f98c74e89d8621e"
|
||||||
|
dependencies = [
|
||||||
|
"lyon_geom",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lyon_tessellation"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e43b7e44161571868f5c931d12583592c223c5583eef86b08aa02b7048a3552"
|
||||||
|
dependencies = [
|
||||||
|
"float_next_after",
|
||||||
|
"lyon_path",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "malloc_buf"
|
name = "malloc_buf"
|
||||||
version = "0.0.6"
|
version = "0.0.6"
|
||||||
|
|
@ -1674,6 +1735,15 @@ dependencies = [
|
||||||
"jni-sys 0.3.1",
|
"jni-sys 0.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntapi"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
|
|
@ -1950,6 +2020,16 @@ dependencies = [
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-io-kit"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-io-surface"
|
name = "objc2-io-surface"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
|
|
@ -1985,6 +2065,17 @@ dependencies = [
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-open-directory"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb82bed227edf5201dfedf072bba4015a33d3d4a98519837295a90f0a23f676d"
|
||||||
|
dependencies = [
|
||||||
|
"objc2 0.6.4",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"objc2-foundation 0.3.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-quartz-core"
|
name = "objc2-quartz-core"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
@ -2758,6 +2849,21 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sysinfo"
|
||||||
|
version = "0.39.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2071df9448915b71c4fe6d25deaf1c22f12bd234f01540b77312bb8e41361e6"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"memchr",
|
||||||
|
"ntapi",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"objc2-io-kit",
|
||||||
|
"objc2-open-directory",
|
||||||
|
"windows 0.62.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.27.0"
|
version = "3.27.0"
|
||||||
|
|
@ -3402,6 +3508,22 @@ dependencies = [
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.11"
|
version = "0.1.11"
|
||||||
|
|
@ -3411,6 +3533,12 @@ dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "window_clipboard"
|
name = "window_clipboard"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
[package]
|
[package]
|
||||||
name = "iced-template"
|
name = "itop"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
sysinfo = "0.39.6"
|
||||||
|
|
||||||
[dependencies.iced]
|
[dependencies.iced]
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
|
features = [ "canvas" ]
|
||||||
|
|
|
||||||
49
src/app/cpu_graph.rs
Normal file
49
src/app/cpu_graph.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use iced::{Color, Point, Renderer, Theme, mouse, widget::canvas};
|
||||||
|
|
||||||
|
use crate::app;
|
||||||
|
|
||||||
|
const CYAN: Color = Color::from_rgb8(0, 255, 255);
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct CpuGraph {
|
||||||
|
pub cache: canvas::Cache,
|
||||||
|
timeline: VecDeque<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CpuGraph {
|
||||||
|
pub fn update(&mut self, usage: f32) {
|
||||||
|
self.timeline.push_back(usage);
|
||||||
|
if self.timeline.len() > 1000 {
|
||||||
|
self.timeline.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl canvas::Program<app::Message, Theme, Renderer> for CpuGraph {
|
||||||
|
type State = ();
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
_state: &Self::State,
|
||||||
|
renderer: &Renderer,
|
||||||
|
_theme: &Theme,
|
||||||
|
bounds: iced::Rectangle,
|
||||||
|
_cursor: mouse::Cursor,
|
||||||
|
) -> Vec<canvas::Geometry<Renderer>> {
|
||||||
|
let geometry = self.cache.draw_with_bounds(renderer, bounds, |frame| {
|
||||||
|
frame.stroke(
|
||||||
|
&canvas::Path::new(|builder| {
|
||||||
|
for (index, value) in self.timeline.iter().enumerate() {
|
||||||
|
let x = index as f32 / self.timeline.len() as f32 * bounds.width;
|
||||||
|
let y = bounds.height - value / 100. * bounds.height;
|
||||||
|
builder.line_to(Point { x, y })
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
canvas::Stroke::default().with_color(CYAN),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
vec![geometry]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,23 +1,68 @@
|
||||||
use iced::{Color, Element, Renderer, Task, Theme, application, theme, widget};
|
use std::time::Instant;
|
||||||
|
|
||||||
enum Message {}
|
use iced::{
|
||||||
|
Color, Element, Length, Renderer, Subscription, Task, Theme, application, theme, widget, window,
|
||||||
|
};
|
||||||
|
|
||||||
struct State {}
|
use crate::app::cpu_graph::CpuGraph;
|
||||||
|
|
||||||
|
mod cpu_graph;
|
||||||
|
|
||||||
|
enum Message {
|
||||||
|
Frame(Instant),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
sys: sysinfo::System,
|
||||||
|
refreshes: sysinfo::RefreshKind,
|
||||||
|
|
||||||
|
last_refresh: Instant,
|
||||||
|
|
||||||
|
cpu_graph: CpuGraph,
|
||||||
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {}
|
Self {
|
||||||
|
sys: sysinfo::System::new(),
|
||||||
|
refreshes: sysinfo::RefreshKind::nothing()
|
||||||
|
.with_cpu(sysinfo::CpuRefreshKind::nothing().with_cpu_usage()),
|
||||||
|
|
||||||
|
cpu_graph: Default::default(),
|
||||||
|
last_refresh: Instant::now(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn update(&mut self, message: Message) -> Task<Message> {
|
fn update(&mut self, message: Message) -> Task<Message> {
|
||||||
|
match message {
|
||||||
|
Message::Frame(instant) => {
|
||||||
|
if instant.duration_since(self.last_refresh) >= sysinfo::MINIMUM_CPU_UPDATE_INTERVAL
|
||||||
|
{
|
||||||
|
self.sys.refresh_specifics(self.refreshes);
|
||||||
|
self.cpu_graph.update(self.sys.global_cpu_usage());
|
||||||
|
self.cpu_graph.cache.clear();
|
||||||
|
|
||||||
|
self.last_refresh = instant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
fn view(&self) -> Element<'_, Message, Theme, Renderer> {
|
fn view(&self) -> Element<'_, Message, Theme, Renderer> {
|
||||||
widget::text("hiiiiiii").into()
|
widget::Canvas::new(&self.cpu_graph)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subscription(&self) -> Subscription<Message> {
|
||||||
|
window::frames().map(Message::Frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run() -> Result<(), impl std::error::Error> {
|
pub fn run() -> Result<(), impl std::error::Error> {
|
||||||
application(State::new, State::update, State::view)
|
application(State::new, State::update, State::view)
|
||||||
|
.subscription(State::subscription)
|
||||||
.theme(theme::Theme::custom(
|
.theme(theme::Theme::custom(
|
||||||
"high-contrast-dark",
|
"high-contrast-dark",
|
||||||
theme::Palette {
|
theme::Palette {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue