From 41410e4e3db83833d93b5e4a8cfd7e46fbfbdfa6 Mon Sep 17 00:00:00 2001 From: Martino Ferrari Date: Sun, 12 Apr 2026 16:20:44 +0200 Subject: [PATCH] Working on better plotting --- Cargo.lock | 2159 +++++++++++++++++--------- Cargo.toml | 33 +- rmon-agent/Cargo.toml | 41 +- rmon-agent/src/server/session.rs | 27 +- rmon-agent/src/storage/continuous.rs | 95 +- rmon-common/Cargo.toml | 19 +- rmon-ui/Cargo.toml | 22 +- rmon-ui/src/app.rs | 632 +++++--- rmon-ui/src/main.rs | 2 +- rmon-ui/src/state/mod.rs | 122 +- 10 files changed, 2088 insertions(+), 1064 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 221ea53..9b3cce6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,72 +20,95 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "accesskit" -version = "0.12.3" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74a4b14f3d99c1255dcba8f45621ab1a2e7540a0009652d33989005a4d0bfc6b" +checksum = "99b76d84ee70e30a4a7e39ab9018e2b17a6a09e31084176cc7c0b2dec036ba45" +dependencies = [ + "enumn", + "serde", +] + +[[package]] +name = "accesskit_atspi_common" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5393c75d4666f580f4cac0a968bc97c36076bb536a129f28210dac54ee127ed" +dependencies = [ + "accesskit", + "accesskit_consumer", + "atspi-common", + "serde", + "thiserror 1.0.69", + "zvariant", +] [[package]] name = "accesskit_consumer" -version = "0.16.1" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c17cca53c09fbd7288667b22a201274b9becaa27f0b91bf52a526db95de45e6" +checksum = "7a12dc159d52233c43d9fe5415969433cbdd52c3d6e0df51bda7d447427b9986" dependencies = [ "accesskit", + "immutable-chunkmap", ] [[package]] name = "accesskit_macos" -version = "0.10.1" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3b6ae1eabbfbced10e840fd3fce8a93ae84f174b3e4ba892ab7bcb42e477a7" +checksum = "bfc6c1ecd82053d127961ad80a8beaa6004fb851a3a5b96506d7a6bd462403f6" dependencies = [ "accesskit", "accesskit_consumer", - "objc2 0.3.0-beta.3.patch-leaks.3", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", "once_cell", ] [[package]] name = "accesskit_unix" -version = "0.6.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f46c18d99ba61ad7123dd13eeb0c104436ab6af1df6a1cd8c11054ed394a08" +checksum = "be7f5cf6165be10a54b2655fa2e0e12b2509f38ed6fc43e11c31fdb7ee6230bb" dependencies = [ "accesskit", - "accesskit_consumer", + "accesskit_atspi_common", "async-channel", - "async-once-cell", + "async-executor", + "async-task", "atspi", - "futures-lite 1.13.0", - "once_cell", + "futures-lite", + "futures-util", "serde", "zbus", ] [[package]] name = "accesskit_windows" -version = "0.15.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcae27ec0974fc7c3b0b318783be89fd1b2e66dd702179fe600166a38ff4a0b" +checksum = "974e96c347384d9133427167fb8a58c340cb0496988dacceebdc1ed27071023b" dependencies = [ "accesskit", "accesskit_consumer", - "once_cell", "paste", "static_assertions", - "windows", + "windows 0.58.0", + "windows-core 0.58.0", ] [[package]] name = "accesskit_winit" -version = "0.15.0" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88e39fcec2e10971e188730b7a76bab60647dacc973d4591855ebebcadfaa738" +checksum = "aea3522719f1c44564d03e9469a8e2f3a98b3a8a880bd66d0789c6b9c4a669dd" dependencies = [ "accesskit", "accesskit_macos", "accesskit_unix", "accesskit_windows", + "raw-window-handle", "winit", ] @@ -102,7 +125,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "getrandom 0.3.4", "once_cell", + "serde", "version_check", "zerocopy", ] @@ -118,20 +143,21 @@ dependencies = [ [[package]] name = "android-activity" -version = "0.4.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64529721f27c2314ced0890ce45e469574a73e5e6fdd6e9da1860eb29285f5e0" +checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" dependencies = [ "android-properties", - "bitflags 1.3.2", + "bitflags 2.11.0", "cc", - "jni-sys 0.3.1", + "jni", "libc", "log", "ndk", "ndk-context", - "ndk-sys", - "num_enum 0.6.1", + "ndk-sys 0.6.0+11769913", + "num_enum", + "thiserror 2.0.18", ] [[package]] @@ -214,8 +240,8 @@ dependencies = [ "clipboard-win", "log", "objc2 0.6.4", - "objc2-app-kit", - "objc2-foundation", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", "parking_lot", "percent-encoding", "windows-sys 0.60.2", @@ -235,13 +261,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] -name = "async-broadcast" -version = "0.5.1" +name = "as-raw-xcb-connection" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" dependencies = [ - "event-listener 2.5.3", + "libloading", +] + +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", "futures-core", + "pin-project-lite", ] [[package]] @@ -264,42 +307,21 @@ checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.4.1", - "futures-lite 2.6.1", + "fastrand", + "futures-lite", "pin-project-lite", "slab", ] [[package]] name = "async-fs" -version = "1.6.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" dependencies = [ - "async-lock 2.8.0", - "autocfg", + "async-lock", "blocking", - "futures-lite 1.13.0", -] - -[[package]] -name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite 1.13.0", - "log", - "parking", - "polling 2.8.0", - "rustix 0.37.28", - "slab", - "socket2 0.4.10", - "waker-fn", + "futures-lite", ] [[package]] @@ -312,55 +334,41 @@ dependencies = [ "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "parking", - "polling 3.11.0", + "polling", "rustix 1.1.4", "slab", "windows-sys 0.61.2", ] -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", -] - [[package]] name = "async-lock" version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ - "event-listener 5.4.1", + "event-listener", "event-listener-strategy", "pin-project-lite", ] -[[package]] -name = "async-once-cell" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a" - [[package]] name = "async-process" -version = "1.8.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", + "async-channel", + "async-io", + "async-lock", "async-signal", + "async-task", "blocking", "cfg-if", - "event-listener 3.1.0", - "futures-lite 1.13.0", - "rustix 0.38.44", - "windows-sys 0.48.0", + "event-listener", + "futures-lite", + "rustix 1.1.4", ] [[package]] @@ -380,8 +388,8 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" dependencies = [ - "async-io 2.6.0", - "async-lock 3.4.2", + "async-io", + "async-lock", "atomic-waker", "cfg-if", "futures-core", @@ -417,9 +425,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atspi" -version = "0.19.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6059f350ab6f593ea00727b334265c4dfc7fd442ee32d264794bd9bdc68e87ca" +checksum = "be534b16650e35237bb1ed189ba2aab86ce65e88cc84c66f4935ba38575cecbf" dependencies = [ "atspi-common", "atspi-connection", @@ -428,39 +436,42 @@ dependencies = [ [[package]] name = "atspi-common" -version = "0.3.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92af95f966d2431f962bc632c2e68eda7777330158bf640c4af4249349b2cdf5" +checksum = "1909ed2dc01d0a17505d89311d192518507e8a056a48148e3598fef5e7bb6ba7" dependencies = [ "enumflags2", "serde", "static_assertions", "zbus", + "zbus-lockstep", + "zbus-lockstep-macros", "zbus_names", "zvariant", ] [[package]] name = "atspi-connection" -version = "0.3.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c65e7d70f86d4c0e3b2d585d9bf3f979f0b19d635a336725a88d279f76b939" +checksum = "430c5960624a4baaa511c9c0fcc2218e3b58f5dbcc47e6190cafee344b873333" dependencies = [ "atspi-common", "atspi-proxies", - "futures-lite 1.13.0", + "futures-lite", "zbus", ] [[package]] name = "atspi-proxies" -version = "0.3.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6495661273703e7a229356dcbe8c8f38223d697aacfaf0e13590a9ac9977bb52" +checksum = "a5e6c5de3e524cf967569722446bcd458d5032348554d9a17d7d72b041ab7496" dependencies = [ "atspi-common", "serde", "zbus", + "zvariant", ] [[package]] @@ -478,6 +489,21 @@ dependencies = [ "serde", ] +[[package]] +name = "bit-set" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" + [[package]] name = "bitflags" version = "1.3.2" @@ -505,23 +531,13 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-sys" -version = "0.1.0-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" -dependencies = [ - "objc-sys", -] - [[package]] name = "block2" -version = "0.2.0-alpha.6" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "block-sys", - "objc2-encode 2.0.0-pre.2", + "objc2 0.5.2", ] [[package]] @@ -533,7 +549,7 @@ dependencies = [ "async-channel", "async-task", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "piper", ] @@ -569,6 +585,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.11.1" @@ -577,16 +599,53 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "calloop" -version = "0.10.6" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.11.0", "log", - "nix 0.25.1", - "slotmap", - "thiserror", - "vec_map", + "polling", + "rustix 0.38.44", + "slab", + "thiserror 1.0.69", +] + +[[package]] +name = "calloop" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" +dependencies = [ + "bitflags 2.11.0", + "polling", + "rustix 1.1.4", + "slab", + "tracing", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop 0.13.0", + "rustix 0.38.44", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" +dependencies = [ + "calloop 0.14.4", + "rustix 1.1.4", + "wayland-backend", + "wayland-client", ] [[package]] @@ -601,12 +660,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - [[package]] name = "cfg-if" version = "1.0.4" @@ -619,6 +672,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "cgl" version = "0.3.2" @@ -637,7 +696,6 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", - "serde", "wasm-bindgen", "windows-link", ] @@ -692,47 +750,52 @@ dependencies = [ ] [[package]] -name = "cocoa" -version = "0.24.1" +name = "codespan-reporting" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation", - "core-foundation", - "core-graphics", - "foreign-types", - "libc", - "objc", + "termcolor", + "unicode-width", ] -[[package]] -name = "cocoa-foundation" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation", - "core-graphics-types", - "libc", - "objc", -] - -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "com" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "combine" version = "4.6.7" @@ -762,6 +825,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -770,12 +843,12 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core-graphics" -version = "0.22.3" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "core-graphics-types", "foreign-types", "libc", @@ -788,7 +861,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "libc", ] @@ -836,15 +909,10 @@ dependencies = [ ] [[package]] -name = "derivative" -version = "2.2.0" +name = "cursor-icon" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" [[package]] name = "digest" @@ -889,7 +957,16 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" dependencies = [ - "libloading 0.8.9", + "libloading", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", ] [[package]] @@ -899,64 +976,99 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] -name = "ecolor" -version = "0.24.1" +name = "dpi" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7637fc2e74d17e52931bac90ff4fc061ac776ada9c7fa272f24cdca5991972" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" + +[[package]] +name = "ecolor" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775cfde491852059e386c4e1deb4aef381c617dc364184c6f6afee99b87c402b" dependencies = [ "bytemuck", + "emath", + "serde", ] [[package]] name = "eframe" -version = "0.24.1" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd73918a828c35a7efb4d7188ea973df4bffc589178ed95f521c917b03ddcfa" +checksum = "8ac2645a9bf4826eb4e91488b1f17b8eaddeef09396706b2f14066461338e24f" dependencies = [ + "ahash", "bytemuck", - "cocoa", + "document-features", "egui", + "egui-wgpu", "egui-winit", "egui_glow", - "glow", + "glow 0.14.2", "glutin", "glutin-winit", "image", "js-sys", "log", - "objc", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", "parking_lot", "percent-encoding", "raw-window-handle", "static_assertions", - "thiserror", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "web-time", "winapi", + "windows-sys 0.52.0", "winit", ] [[package]] name = "egui" -version = "0.24.1" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55bcb864b764eb889515a38b8924757657a250738ad15126637ee2df291ee6b" +checksum = "53eafabcce0cb2325a59a98736efe0bf060585b437763f8c476957fb274bb974" dependencies = [ "accesskit", "ahash", + "emath", "epaint", "log", "nohash-hasher", + "serde", +] + +[[package]] +name = "egui-wgpu" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00fd5d06d8405397e64a928fa0ef3934b3c30273ea7603e3dc4627b1f7a1a82" +dependencies = [ + "ahash", + "bytemuck", + "document-features", + "egui", + "epaint", + "log", + "thiserror 1.0.69", + "type-map", + "web-time", + "wgpu", + "winit", ] [[package]] name = "egui-winit" -version = "0.24.1" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b673606b6606b12b95e3a3194d7882bf5cff302db36a520b8144c7c342e4e84" +checksum = "0a9c430f4f816340e8e8c1b20eec274186b1be6bc4c7dfc467ed50d57abc36c6" dependencies = [ "accesskit_winit", + "ahash", "arboard", "egui", "log", @@ -969,26 +1081,43 @@ dependencies = [ [[package]] name = "egui_glow" -version = "0.24.1" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "262151f9d57c557c02a40a46f27b9e050a6eb0b006b94dced9c6f4519a04d489" +checksum = "0e39bccc683cd43adab530d8f21a13eb91e80de10bcc38c3f1c16601b6f62b26" dependencies = [ + "ahash", "bytemuck", "egui", - "glow", + "glow 0.14.2", "log", - "memoffset 0.7.1", + "memoffset", "wasm-bindgen", "web-sys", + "winit", ] [[package]] name = "egui_plot" -version = "0.24.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29b484821a5b336af40a34151a940f52bef0f1ab56ec0d8cf80f74783eaae412" +checksum = "d8dca4871c15d51aadb79534dcf51a8189e5de3426ee7b465eb7db9a0a81ea67" dependencies = [ + "ahash", "egui", + "emath", +] + +[[package]] +name = "egui_tiles" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e95b957b2db66175ea36f73cb09a1c40e5f2455692347ccfbe79fd3c84907b5b" +dependencies = [ + "ahash", + "egui", + "itertools 0.13.0", + "log", + "serde", ] [[package]] @@ -999,13 +1128,20 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "emath" -version = "0.24.1" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a045c6c0b44b35e98513fc1e9d183ab42881ac27caccb9fa345465601f56cce4" +checksum = "b1fe0049ce51d0fb414d029e668dd72eb30bc2b739bf34296ed97bd33df544f3" dependencies = [ "bytemuck", + "serde", ] +[[package]] +name = "endi" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" + [[package]] name = "enumflags2" version = "0.7.12" @@ -1028,21 +1164,40 @@ dependencies = [ ] [[package]] -name = "epaint" -version = "0.24.1" +name = "enumn" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1b9e000d21bab9b535ce78f9f7745be28b3f777f6c7223936561c5c7fefab8" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "epaint" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a32af8da821bd4f43f2c137e295459ee2e1661d87ca8779dfa0eaf45d870e20f" dependencies = [ "ab_glyph", "ahash", "bytemuck", "ecolor", "emath", + "epaint_default_fonts", "log", "nohash-hasher", "parking_lot", + "serde", ] +[[package]] +name = "epaint_default_fonts" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "483440db0b7993cf77a20314f08311dbe95675092405518c0677aa08c151a3ea" + [[package]] name = "equivalent" version = "1.0.2" @@ -1065,23 +1220,6 @@ version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "event-listener" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - [[package]] name = "event-listener" version = "5.4.1" @@ -1099,19 +1237,10 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "event-listener 5.4.1", + "event-listener", "pin-project-lite", ] -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - [[package]] name = "fastrand" version = "2.4.1" @@ -1162,18 +1291,30 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foreign-types" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ + "foreign-types-macros", "foreign-types-shared", ] [[package]] -name = "foreign-types-shared" -version = "0.1.1" +name = "foreign-types-macros" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" @@ -1241,28 +1382,13 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-lite" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "fastrand 2.4.1", + "fastrand", "futures-core", "futures-io", "parking", @@ -1378,9 +1504,21 @@ dependencies = [ [[package]] name = "glow" -version = "0.12.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0fe580e4b60a8ab24a868bc08e2f03cbcb20d3d676601fa909386713333728" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glow" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483" dependencies = [ "js-sys", "slotmap", @@ -1390,34 +1528,36 @@ dependencies = [ [[package]] name = "glutin" -version = "0.30.10" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc93b03242719b8ad39fb26ed2b01737144ce7bd4bfc7adadcef806596760fe" +checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" dependencies = [ - "bitflags 1.3.2", - "cfg_aliases", + "bitflags 2.11.0", + "cfg_aliases 0.2.1", "cgl", - "core-foundation", - "dispatch", + "dispatch2", "glutin_egl_sys", "glutin_glx_sys", "glutin_wgl_sys", - "libloading 0.7.4", - "objc2 0.3.0-beta.3.patch-leaks.3", + "libloading", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", "once_cell", "raw-window-handle", - "wayland-sys 0.30.1", - "windows-sys 0.45.0", + "wayland-sys", + "windows-sys 0.52.0", "x11-dl", ] [[package]] name = "glutin-winit" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629a873fc04062830bfe8f97c03773bcd7b371e23bcc465d0a61448cd1588fa4" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" dependencies = [ - "cfg_aliases", + "cfg_aliases 0.2.1", "glutin", "raw-window-handle", "winit", @@ -1425,19 +1565,19 @@ dependencies = [ [[package]] name = "glutin_egl_sys" -version = "0.5.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af784eb26c5a68ec85391268e074f0aa618c096eadb5d6330b0911cf34fe57c5" +checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" dependencies = [ "gl_generator", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] name = "glutin_glx_sys" -version = "0.4.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b53cb5fe568964aa066a3ba91eac5ecbac869fb0842cd0dc9e412434f1a1494" +checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" dependencies = [ "gl_generator", "x11-dl", @@ -1445,13 +1585,65 @@ dependencies = [ [[package]] name = "glutin_wgl_sys" -version = "0.4.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef89398e90033fc6bc65e9bd42fd29bbbfd483bda5b56dc5562f455550618165" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" dependencies = [ "gl_generator", ] +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.11.0", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.11.0", +] + +[[package]] +name = "gpu-allocator" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd4240fc91d3433d5e5b0fc5b67672d771850dc19bbee03c1381e19322803d7" +dependencies = [ + "log", + "presser", + "thiserror 1.0.69", + "winapi", + "windows 0.52.0", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" +dependencies = [ + "bitflags 2.11.0", + "gpu-descriptor-types", + "hashbrown 0.15.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.11.0", +] + [[package]] name = "hashbrown" version = "0.15.5" @@ -1467,18 +1659,27 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +[[package]] +name = "hassle-rs" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" +dependencies = [ + "bitflags 2.11.0", + "com", + "libc", + "libloading", + "thiserror 1.0.69", + "widestring", + "winapi", +] + [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "hermit-abi" version = "0.5.2" @@ -1492,13 +1693,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "home" -version = "0.5.12" +name = "hexf-parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" -dependencies = [ - "windows-sys 0.61.2", -] +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "iana-time-zone" @@ -1512,7 +1710,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core", + "windows-core 0.62.2", ] [[package]] @@ -1635,17 +1833,26 @@ dependencies = [ [[package]] name = "image" -version = "0.24.9" +version = "0.25.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" dependencies = [ "bytemuck", - "byteorder", - "color_quant", + "byteorder-lite", + "moxcms", "num-traits", "png", ] +[[package]] +name = "immutable-chunkmap" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3e98b1520e49e252237edc238a39869da9f3241f2ec19dc788c1d24694d1e4" +dependencies = [ + "arrayvec", +] + [[package]] name = "indexmap" version = "2.14.0" @@ -1678,29 +1885,6 @@ dependencies = [ "libc", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1716,6 +1900,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" @@ -1724,18 +1917,32 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jni" -version = "0.21.1" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" dependencies = [ - "cesu8", "cfg-if", "combine", - "jni-sys 0.3.1", + "jni-macros", + "jni-sys 0.4.1", "log", - "thiserror", + "simd_cesu8", + "thiserror 2.0.18", "walkdir", - "windows-sys 0.45.0", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", ] [[package]] @@ -1788,6 +1995,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + [[package]] name = "khronos_api" version = "3.1.0" @@ -1832,16 +2050,6 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - [[package]] name = "libloading" version = "0.8.9" @@ -1864,12 +2072,6 @@ dependencies = [ "redox_syscall 0.7.4", ] -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -1888,6 +2090,12 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + [[package]] name = "lock_api" version = "0.4.14" @@ -1929,31 +2137,13 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" -version = "0.5.10" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.9.1" @@ -1963,6 +2153,21 @@ dependencies = [ "autocfg", ] +[[package]] +name = "metal" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +dependencies = [ + "bitflags 2.11.0", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -1997,17 +2202,49 @@ dependencies = [ ] [[package]] -name = "ndk" -version = "0.7.0" +name = "moxcms" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" dependencies = [ - "bitflags 1.3.2", + "num-traits", + "pxfm", +] + +[[package]] +name = "naga" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd5a652b6faf21496f2cfd88fc49989c8db0825d1f6746b1a71a6ede24a63ad" +dependencies = [ + "arrayvec", + "bit-set", + "bitflags 2.11.0", + "cfg_aliases 0.1.1", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "rustc-hash 1.1.0", + "spirv", + "termcolor", + "thiserror 1.0.69", + "unicode-xid", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.11.0", "jni-sys 0.3.1", - "ndk-sys", - "num_enum 0.5.11", + "log", + "ndk-sys 0.6.0+11769913", + "num_enum", "raw-window-handle", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2018,48 +2255,33 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "ndk-sys" -version = "0.4.1+23.1.7779620" +version = "0.5.0+25.2.9519653" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys 0.3.1", +] + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ "jni-sys 0.3.1", ] [[package]] name = "nix" -version = "0.24.3" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.11.0", "cfg-if", + "cfg_aliases 0.2.1", "libc", - "memoffset 0.6.5", -] - -[[package]] -name = "nix" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.6.5", -] - -[[package]] -name = "nix" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.7.1", + "memoffset", ] [[package]] @@ -2107,39 +2329,19 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.11" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" dependencies = [ - "num_enum_derive 0.5.11", -] - -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", + "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.5.11" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -2158,19 +2360,18 @@ dependencies = [ [[package]] name = "objc-sys" -version = "0.2.0-beta.2" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" [[package]] name = "objc2" -version = "0.3.0-beta.3.patch-leaks.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" dependencies = [ - "block2", "objc-sys", - "objc2-encode 2.0.0-pre.2", + "objc2-encode", ] [[package]] @@ -2179,7 +2380,23 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" dependencies = [ - "objc2-encode 4.1.0", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.11.0", + "block2", + "libc", + "objc2 0.5.2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation 0.2.2", + "objc2-quartz-core", ] [[package]] @@ -2190,8 +2407,45 @@ checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.11.0", "objc2 0.6.4", + "objc2-core-foundation", "objc2-core-graphics", - "objc2-foundation", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.11.0", + "block2", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.11.0", + "block2", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -2219,12 +2473,27 @@ dependencies = [ ] [[package]] -name = "objc2-encode" -version = "2.0.0-pre.2" +name = "objc2-core-image" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "objc-sys", + "block2", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2 0.5.2", + "objc2-contacts", + "objc2-foundation 0.2.2", ] [[package]] @@ -2233,6 +2502,19 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.11.0", + "block2", + "dispatch", + "libc", + "objc2 0.5.2", +] + [[package]] name = "objc2-foundation" version = "0.3.2" @@ -2255,6 +2537,98 @@ dependencies = [ "objc2-core-foundation", ] +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.11.0", + "block2", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.11.0", + "block2", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.11.0", + "block2", + "objc2 0.5.2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation 0.2.2", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.11.0", + "block2", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -2337,6 +2711,26 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pin-project" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -2350,7 +2744,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" dependencies = [ "atomic-waker", - "fastrand 2.4.1", + "fastrand", "futures-io", ] @@ -2368,33 +2762,17 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "png" -version = "0.17.16" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.11.0", "crc32fast", "fdeflate", "flate2", "miniz_oxide", ] -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys 0.48.0", -] - [[package]] name = "polling" version = "3.11.0" @@ -2403,7 +2781,7 @@ checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi 0.5.2", + "hermit-abi", "pin-project-lite", "rustix 1.1.4", "windows-sys 0.61.2", @@ -2427,6 +2805,12 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + [[package]] name = "prettyplease" version = "0.2.37" @@ -2439,12 +2823,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "toml_edit 0.25.11+spec-1.1.0", ] [[package]] @@ -2456,6 +2839,37 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" + +[[package]] +name = "pxfm" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d" + +[[package]] +name = "quick-xml" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quick-xml" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.45" @@ -2509,15 +2923,15 @@ dependencies = [ [[package]] name = "raw-window-handle" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] @@ -2569,23 +2983,28 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + [[package]] name = "rmon-agent" version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "bincode", "byteorder", "bytes", "chrono", "clap", "futures", - "itertools", "notify", "regex", "rmon-common", "serde", + "serde_json", "tempfile", "tokio", "tokio-util", @@ -2601,11 +3020,12 @@ dependencies = [ "anyhow", "bincode", "bytes", - "chrono", + "futures", "serde", - "thiserror", + "serde_json", "tokio", "tokio-util", + "tracing", ] [[package]] @@ -2613,35 +3033,42 @@ name = "rmon-ui" version = "0.1.0" dependencies = [ "anyhow", - "bincode", "bytes", "chrono", "eframe", "egui", "egui_plot", + "egui_tiles", "futures", - "itertools", + "itertools 0.12.1", "libc", "rmon-common", - "serde", "tokio", "tokio-util", "tracing", "tracing-subscriber", + "uuid", ] [[package]] -name = "rustix" -version = "0.37.28" +name = "rustc-hash" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", + "semver", ] [[package]] @@ -2699,14 +3126,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sctk-adwaita" -version = "0.5.4" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" dependencies = [ "ab_glyph", "log", "memmap2", - "smithay-client-toolkit", + "smithay-client-toolkit 0.19.2", "tiny-skia", ] @@ -2821,6 +3248,22 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "slab" version = "0.4.12" @@ -2844,41 +3287,74 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smithay-client-toolkit" -version = "0.16.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 1.3.2", - "calloop", - "dlib", - "lazy_static", + "bitflags 2.11.0", + "calloop 0.13.0", + "calloop-wayland-source 0.3.0", + "cursor-icon", + "libc", "log", "memmap2", - "nix 0.24.3", - "pkg-config", + "rustix 0.38.44", + "thiserror 1.0.69", + "wayland-backend", "wayland-client", + "wayland-csd-frame", "wayland-cursor", "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" +dependencies = [ + "bitflags 2.11.0", + "calloop 0.14.4", + "calloop-wayland-source 0.4.1", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 1.1.4", + "thiserror 2.0.18", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-experimental", + "wayland-protocols-misc", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", ] [[package]] name = "smithay-clipboard" -version = "0.6.6" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" +checksum = "71704c03f739f7745053bde45fa203a46c58d25bc5c4efba1d9a60e9dba81226" dependencies = [ - "smithay-client-toolkit", - "wayland-client", + "libc", + "smithay-client-toolkit 0.20.0", + "wayland-backend", ] [[package]] -name = "socket2" -version = "0.4.10" +name = "smol_str" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" dependencies = [ - "libc", - "winapi", + "serde", ] [[package]] @@ -2891,6 +3367,15 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.11.0", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -2954,20 +3439,38 @@ version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ - "fastrand 2.4.1", + "fastrand", "getrandom 0.4.2", "once_cell", "rustix 1.1.4", "windows-sys 0.61.2", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", ] [[package]] @@ -2981,6 +3484,17 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "thread_local" version = "1.1.9" @@ -2992,23 +3506,23 @@ dependencies = [ [[package]] name = "tiny-skia" -version = "0.8.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" dependencies = [ "arrayref", "arrayvec", "bytemuck", "cfg-if", - "png", + "log", "tiny-skia-path", ] [[package]] name = "tiny-skia-path" -version = "0.8.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" dependencies = [ "arrayref", "bytemuck", @@ -3037,7 +3551,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.3", + "socket2", "tokio-macros", "windows-sys 0.61.2", ] @@ -3074,7 +3588,7 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_edit 0.22.27", ] @@ -3088,14 +3602,12 @@ dependencies = [ ] [[package]] -name = "toml_edit" -version = "0.19.15" +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", + "serde_core", ] [[package]] @@ -3107,11 +3619,32 @@ dependencies = [ "indexmap", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_write", "winnow 0.7.15", ] +[[package]] +name = "toml_edit" +version = "0.25.11+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +dependencies = [ + "indexmap", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.1", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.1", +] + [[package]] name = "toml_write" version = "0.1.2" @@ -3124,6 +3657,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3185,6 +3719,15 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +[[package]] +name = "type-map" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" +dependencies = [ + "rustc-hash 2.1.2", +] + [[package]] name = "typenum" version = "1.19.0" @@ -3197,7 +3740,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ - "memoffset 0.9.1", + "memoffset", "tempfile", "windows-sys 0.61.2", ] @@ -3208,6 +3751,18 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "unicode-segmentation" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -3238,30 +3793,29 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +dependencies = [ + "getrandom 0.4.2", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "waker-fn" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" - [[package]] name = "walkdir" version = "2.5.0" @@ -3386,87 +3940,137 @@ dependencies = [ ] [[package]] -name = "wayland-client" -version = "0.29.5" +name = "wayland-backend" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" +checksum = "2857dd20b54e916ec7253b3d6b4d5c4d7d4ca2c33c2e11c6c76a99bd8744755d" dependencies = [ - "bitflags 1.3.2", + "cc", "downcast-rs", - "libc", - "nix 0.24.3", + "rustix 1.1.4", "scoped-tls", - "wayland-commons", - "wayland-scanner", - "wayland-sys 0.29.5", + "smallvec", + "wayland-sys", ] [[package]] -name = "wayland-commons" -version = "0.29.5" +name = "wayland-client" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ - "nix 0.24.3", - "once_cell", - "smallvec", - "wayland-sys 0.29.5", + "bitflags 2.11.0", + "rustix 1.1.4", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.11.0", + "cursor-icon", + "wayland-backend", ] [[package]] name = "wayland-cursor" -version = "0.29.5" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" +checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" dependencies = [ - "nix 0.24.3", + "rustix 1.1.4", "wayland-client", "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.29.5" +version = "0.32.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" +checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.11.0", + "wayland-backend", "wayland-client", - "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-experimental" +version = "20250721.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" +dependencies = [ + "bitflags 2.11.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-misc" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" +dependencies = [ + "bitflags 2.11.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" +dependencies = [ + "bitflags 2.11.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" +dependencies = [ + "bitflags 2.11.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", "wayland-scanner", ] [[package]] name = "wayland-scanner" -version = "0.29.5" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" dependencies = [ "proc-macro2", + "quick-xml 0.39.2", "quote", - "xml-rs", ] [[package]] name = "wayland-sys" -version = "0.29.5" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" +checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" dependencies = [ "dlib", - "lazy_static", - "pkg-config", -] - -[[package]] -name = "wayland-sys" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b2a02ac608e07132978689a6f9bf4214949c85998c247abadd4f4129b1aa06" -dependencies = [ - "dlib", - "lazy_static", "log", + "once_cell", "pkg-config", ] @@ -3482,9 +4086,9 @@ dependencies = [ [[package]] name = "web-time" -version = "0.2.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -3492,21 +4096,127 @@ dependencies = [ [[package]] name = "webbrowser" -version = "0.8.15" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db67ae75a9405634f5882791678772c94ff5f16a66535aae186e26aa0841fc8b" +checksum = "fe985f41e291eecef5e5c0770a18d28390addb03331c043964d9e916453d6f16" dependencies = [ - "core-foundation", - "home", + "core-foundation 0.10.1", "jni", "log", "ndk-context", - "objc", - "raw-window-handle", + "objc2 0.6.4", + "objc2-foundation 0.3.2", "url", "web-sys", ] +[[package]] +name = "wgpu" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d1c4ba43f80542cf63a0a6ed3134629ae73e8ab51e4b765a67f3aa062eb433" +dependencies = [ + "arrayvec", + "cfg_aliases 0.1.1", + "document-features", + "js-sys", + "log", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0348c840d1051b8e86c3bcd31206080c5e71e5933dabd79be1ce732b0b2f089a" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.11.0", + "cfg_aliases 0.1.1", + "document-features", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 1.0.69", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6bbf4b4de8b2a83c0401d9e5ae0080a2792055f25859a02bf9be97952bbed4f" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bitflags 2.11.0", + "cfg_aliases 0.1.1", + "core-graphics-types", + "glow 0.13.1", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hassle-rs", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal", + "naga", + "ndk-sys 0.5.0+25.2.9519653", + "objc", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 1.0.69", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc9d91f0e2c4b51434dfa6db77846f2793149d8e73f800fa2e41f52b8eac3c5d" +dependencies = [ + "bitflags 2.11.0", + "js-sys", + "web-sys", +] + +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + [[package]] name = "winapi" version = "0.3.9" @@ -3540,13 +4250,44 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ - "windows-implement 0.48.0", - "windows-interface 0.48.0", - "windows-targets 0.48.5", + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", ] [[package]] @@ -3558,19 +4299,19 @@ dependencies = [ "windows-implement 0.60.2", "windows-interface 0.59.3", "windows-link", - "windows-result", - "windows-strings", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] name = "windows-implement" -version = "0.48.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.117", ] [[package]] @@ -3586,13 +4327,13 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.48.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.117", ] [[package]] @@ -3612,6 +4353,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.4.1" @@ -3621,6 +4371,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-strings" version = "0.5.1" @@ -3630,15 +4390,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -3648,6 +4399,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -3675,21 +4435,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -3738,12 +4483,6 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -3762,12 +4501,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3786,12 +4519,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3822,12 +4549,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3846,12 +4567,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3870,12 +4585,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3894,12 +4603,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3920,46 +4623,54 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" -version = "0.28.7" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" +checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d" dependencies = [ + "ahash", "android-activity", - "bitflags 1.3.2", - "cfg_aliases", - "core-foundation", + "atomic-waker", + "bitflags 2.11.0", + "block2", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases 0.2.1", + "concurrent-queue", + "core-foundation 0.9.4", "core-graphics", - "dispatch", - "instant", + "cursor-icon", + "dpi", + "js-sys", "libc", - "log", - "mio 0.8.11", + "memmap2", "ndk", - "objc2 0.3.0-beta.3.patch-leaks.3", - "once_cell", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "objc2-ui-kit", "orbclient", "percent-encoding", + "pin-project", "raw-window-handle", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", + "rustix 0.38.44", "sctk-adwaita", - "smithay-client-toolkit", + "smithay-client-toolkit 0.19.2", + "smol_str", + "tracing", + "unicode-segmentation", "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", "wayland-client", - "wayland-commons", "wayland-protocols", - "wayland-scanner", + "wayland-protocols-plasma", "web-sys", - "windows-sys 0.45.0", + "web-time", + "windows-sys 0.52.0", "x11-dl", -] - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", + "x11rb", + "xkbcommon-dl", ] [[package]] @@ -3971,6 +4682,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -4082,7 +4802,11 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" dependencies = [ + "as-raw-xcb-connection", "gethostname", + "libc", + "libloading", + "once_cell", "rustix 1.1.4", "x11rb-protocol", ] @@ -4109,6 +4833,25 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.11.0", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + [[package]] name = "xml-rs" version = "0.8.28" @@ -4140,30 +4883,27 @@ dependencies = [ [[package]] name = "zbus" -version = "3.15.2" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" +checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" dependencies = [ "async-broadcast", "async-executor", "async-fs", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io", + "async-lock", "async-process", "async-recursion", "async-task", "async-trait", "blocking", - "byteorder", - "derivative", "enumflags2", - "event-listener 2.5.3", + "event-listener", "futures-core", "futures-sink", "futures-util", "hex", - "nix 0.26.4", - "once_cell", + "nix", "ordered-stream", "rand", "serde", @@ -4172,7 +4912,7 @@ dependencies = [ "static_assertions", "tracing", "uds_windows", - "winapi", + "windows-sys 0.52.0", "xdg-home", "zbus_macros", "zbus_names", @@ -4180,30 +4920,66 @@ dependencies = [ ] [[package]] -name = "zbus_macros" -version = "3.15.2" +name = "zbus-lockstep" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" +checksum = "4ca2c5dceb099bddaade154055c926bb8ae507a18756ba1d8963fd7b51d8ed1d" +dependencies = [ + "zbus_xml", + "zvariant", +] + +[[package]] +name = "zbus-lockstep-macros" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "zbus-lockstep", + "zbus_xml", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "regex", - "syn 1.0.109", + "syn 2.0.117", "zvariant_utils", ] [[package]] name = "zbus_names" -version = "2.6.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" +checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" dependencies = [ "serde", "static_assertions", "zvariant", ] +[[package]] +name = "zbus_xml" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3f374552b954f6abb4bd6ce979e6c9b38fb9d0cd7cc68a7d796e70c9f3a233" +dependencies = [ + "quick-xml 0.30.0", + "serde", + "static_assertions", + "zbus_names", + "zvariant", +] + [[package]] name = "zerocopy" version = "0.8.48" @@ -4286,13 +5062,12 @@ checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "zvariant" -version = "3.15.2" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" +checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" dependencies = [ - "byteorder", + "endi", "enumflags2", - "libc", "serde", "static_assertions", "zvariant_derive", @@ -4300,24 +5075,24 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "3.15.2" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" +checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.117", "zvariant_utils", ] [[package]] name = "zvariant_utils" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.117", ] diff --git a/Cargo.toml b/Cargo.toml index 386f5b7..7d1301c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,36 +1,35 @@ [workspace] resolver = "2" members = [ - "rmon-common", "rmon-agent", + "rmon-common", "rmon-ui", ] -[workspace.package] -version = "0.1.0" -edition = "2021" -authors = ["RMon Team"] -license = "MIT" - [workspace.dependencies] -anyhow = "1.0" -bincode = "1.3" -chrono = { version = "0.4", features = ["serde"] } -serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.36", features = ["full"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +anyhow = "1.0" +toml = "0.8" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } -toml = "0.8" -futures = "0.3" -bytes = "1.5" -itertools = "0.12" -thiserror = "1.0" -byteorder = "1.5" async-trait = "0.1" +futures = "0.3" tokio-util = { version = "0.7", features = ["codec"] } regex = "1.10" notify = "6.1" clap = { version = "4.4", features = ["derive"] } tempfile = "3.10" libc = "0.2" +uuid = { version = "1.7", features = ["v4"] } +egui_tiles = "0.10" +eframe = "0.29" +egui = "0.29" +egui_plot = "0.29" +chrono = "0.4" +itertools = "0.12" +byteorder = "1.5" +bytes = "1.5" +bincode = "1.3" rmon-common = { path = "rmon-common" } diff --git a/rmon-agent/Cargo.toml b/rmon-agent/Cargo.toml index 2798c98..ae76009 100644 --- a/rmon-agent/Cargo.toml +++ b/rmon-agent/Cargo.toml @@ -1,39 +1,24 @@ [package] name = "rmon-agent" -version.workspace = true -edition.workspace = true -authors.workspace = true -license.workspace = true +version = "0.1.0" +edition = "2021" [dependencies] -anyhow.workspace = true +rmon-common = { path = "../rmon-common" } tokio.workspace = true -tokio-util.workspace = true +serde.workspace = true +serde_json.workspace = true +anyhow.workspace = true +toml.workspace = true tracing.workspace = true tracing-subscriber.workspace = true -serde.workspace = true -chrono.workspace = true -toml.workspace = true -bincode.workspace = true +async-trait.workspace = true +futures.workspace = true +tokio-util.workspace = true regex.workspace = true notify.workspace = true clap.workspace = true -futures.workspace = true -bytes.workspace = true -itertools.workspace = true -byteorder.workspace = true -async-trait.workspace = true -rmon-common.workspace = true - -[dev-dependencies] -tokio = { workspace = true, features = ["full"] } -futures.workspace = true -toml.workspace = true -anyhow.workspace = true tempfile.workspace = true - -[profile.release] -strip = true -lto = true -codegen-units = 1 -panic = "abort" +byteorder.workspace = true +chrono.workspace = true +bytes.workspace = true diff --git a/rmon-agent/src/server/session.rs b/rmon-agent/src/server/session.rs index b57dcbe..0097f35 100644 --- a/rmon-agent/src/server/session.rs +++ b/rmon-agent/src/server/session.rs @@ -117,12 +117,37 @@ pub async fn handle_session( tracing::info!("[{}] Updating config...", addr); if let Err(e) = std::fs::write(&state.config_path, &config_toml) { tracing::error!("[{}] Config write failed: {}", addr, e); - framed.send(AgentMessage::Error { context: "UpdateConfig".to_string(), message: e.to_string() }).await?; + let _ = framed.send(AgentMessage::Error { context: "UpdateConfig".to_string(), message: e.to_string() }).await; } else { let _ = state.reload_tx.send(()); } } + ClientMessage::QueryHistory { id, from_ns, to_ns, max_points } => { + tracing::info!("[{}] QueryHistory for {}", addr, id); + let source_name = id.split("://").nth(1).and_then(|s| s.split('/').next()).unwrap_or("unknown"); + match crate::storage::ContinuousStorage::read_range( + state.config_path.parent().unwrap().join("data"), // Assuming data is in same dir as config + source_name, + &id, + from_ns, + to_ns, + max_points as usize + ) { + Ok(samples) => { + framed.send(AgentMessage::HistoryChunk { + id, + samples, + done: true + }).await?; + } + Err(e) => { + tracing::error!("[{}] QueryHistory failed: {}", addr, e); + let _ = framed.send(AgentMessage::Error { context: "QueryHistory".to_string(), message: e.to_string() }).await; + } + } + } ClientMessage::Subscribe { ids, .. } => { + tracing::info!("[{}] Subscribing to {:?}", addr, ids); subscriptions.extend(ids); } diff --git a/rmon-agent/src/storage/continuous.rs b/rmon-agent/src/storage/continuous.rs index 61e0d1a..b1cd1bc 100644 --- a/rmon-agent/src/storage/continuous.rs +++ b/rmon-agent/src/storage/continuous.rs @@ -1,32 +1,29 @@ -use std::fs::{File, OpenOptions}; -use std::io::{Write, BufWriter}; -use std::path::PathBuf; use anyhow::Result; use rmon_common::signal::Sample; -use byteorder::{LittleEndian, WriteBytesExt}; +use std::fs::File; +use std::io::{BufWriter, BufReader, Write}; +use std::path::PathBuf; +use byteorder::{LittleEndian, WriteBytesExt, ReadBytesExt}; pub struct ContinuousStorage { writer: BufWriter, - _path: PathBuf, } impl ContinuousStorage { - pub fn create(data_dir: PathBuf, source_name: &str, signal_id: &str, session_start_ns: i64) -> Result { + pub fn create(data_dir: PathBuf, source_name: &str, signal_id: &str, session_start: i64) -> Result { let mut path = data_dir; path.push(source_name); - path.push(signal_id.replace(":", "_").replace("/", "_")); // Escape signal ID for filesystem + path.push(signal_id.replace(":", "_").replace("/", "_")); std::fs::create_dir_all(&path)?; - - path.push(format!("{}.bin", session_start_ns)); - - let file = OpenOptions::new() + + let filename = format!("{}.bin", session_start); + let file = std::fs::OpenOptions::new() .create(true) .append(true) - .open(&path)?; - + .open(path.join(filename))?; + Ok(Self { writer: BufWriter::new(file), - _path: path, }) } @@ -40,43 +37,67 @@ impl ContinuousStorage { self.writer.flush()?; Ok(()) } + + pub fn read_range(data_dir: PathBuf, source_name: &str, signal_id: &str, from_ns: i64, to_ns: i64, max_points: usize) -> Result> { + let mut path = data_dir; + path.push(source_name); + path.push(signal_id.replace(":", "_").replace("/", "_")); + + if !path.exists() { return Ok(vec![]); } + + let mut all_samples = Vec::new(); + if let Ok(entries) = std::fs::read_dir(path) { + for entry in entries { + let entry = entry?; + if entry.path().extension().and_then(|s| s.to_str()) == Some("bin") { + let file = File::open(entry.path())?; + let file_len = file.metadata()?.len(); + let num_samples = (file_len / 16) as usize; + + let mut reader = BufReader::new(file); + for _ in 0..num_samples { + let ts = reader.read_i64::()?; + let val = reader.read_f64::()?; + if ts >= from_ns && ts <= to_ns { + all_samples.push(Sample { timestamp: ts, value: val }); + } + } + } + } + } + + all_samples.sort_by_key(|s| s.timestamp); + + if all_samples.len() > max_points && max_points > 0 { + let step = all_samples.len() / max_points; + Ok(all_samples.into_iter().step_by(step).take(max_points).collect()) + } else { + Ok(all_samples) + } + } } #[cfg(test)] mod tests { use super::*; use tempfile::tempdir; - use std::fs; #[test] fn test_continuous_storage_creation() { let dir = tempdir().unwrap(); - let res = ContinuousStorage::create( - dir.path().to_path_buf(), - "src", - "sig1", - 12345 - ); - assert!(res.is_ok()); + let mut storage = ContinuousStorage::create(dir.path().to_path_buf(), "src", "sig", 123).unwrap(); + storage.append(Sample { timestamp: 1, value: 1.0 }).unwrap(); + storage.flush().unwrap(); + + let samples = ContinuousStorage::read_range(dir.path().to_path_buf(), "src", "sig", 0, 10, 100).unwrap(); + assert_eq!(samples.len(), 1); + assert_eq!(samples[0].value, 1.0); } #[test] fn test_continuous_append() { let dir = tempdir().unwrap(); - let mut storage = ContinuousStorage::create( - dir.path().to_path_buf(), - "src", - "sig1", - 12345 - ).unwrap(); - - let sample = Sample { timestamp: 100, value: 42.0 }; - storage.append(sample).unwrap(); - storage.flush().unwrap(); - - // Verify file exists and has size 16 bytes (i64 + f64) - let path = dir.path().join("src/sig1/12345.bin"); - assert!(path.exists()); - assert_eq!(fs::metadata(path).unwrap().len(), 16); + let mut storage = ContinuousStorage::create(dir.path().to_path_buf(), "s", "i", 1).unwrap(); + assert!(storage.append(Sample { timestamp: 1, value: 1.0 }).is_ok()); } } diff --git a/rmon-common/Cargo.toml b/rmon-common/Cargo.toml index 42949df..3b9803b 100644 --- a/rmon-common/Cargo.toml +++ b/rmon-common/Cargo.toml @@ -1,18 +1,15 @@ [package] name = "rmon-common" -version.workspace = true -edition.workspace = true -authors.workspace = true -license.workspace = true +version = "0.1.0" +edition = "2021" [dependencies] serde.workspace = true -bincode.workspace = true -chrono.workspace = true -thiserror.workspace = true -anyhow.workspace = true +serde_json.workspace = true +tokio.workspace = true tokio-util.workspace = true bytes.workspace = true - -[dev-dependencies] -tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } +anyhow.workspace = true +futures.workspace = true +tracing.workspace = true +bincode.workspace = true diff --git a/rmon-ui/Cargo.toml b/rmon-ui/Cargo.toml index 6f6de05..c24785b 100644 --- a/rmon-ui/Cargo.toml +++ b/rmon-ui/Cargo.toml @@ -1,24 +1,22 @@ [package] name = "rmon-ui" -version.workspace = true -edition.workspace = true -authors.workspace = true -license.workspace = true +version = "0.1.0" +edition = "2021" [dependencies] -eframe = "0.24" -egui = "0.24" -egui_plot = "0.24" -tokio = { workspace = true, features = ["full"] } +rmon-common = { path = "../rmon-common" } +eframe.workspace = true +egui.workspace = true +egui_plot.workspace = true +tokio.workspace = true +anyhow.workspace = true tracing.workspace = true tracing-subscriber.workspace = true -serde.workspace = true -bincode.workspace = true -rmon-common.workspace = true -anyhow.workspace = true futures.workspace = true tokio-util.workspace = true bytes.workspace = true chrono.workspace = true itertools.workspace = true libc.workspace = true +uuid.workspace = true +egui_tiles.workspace = true diff --git a/rmon-ui/src/app.rs b/rmon-ui/src/app.rs index 96eab7f..9a9bafe 100644 --- a/rmon-ui/src/app.rs +++ b/rmon-ui/src/app.rs @@ -1,13 +1,15 @@ use eframe::egui; +use eframe::egui::Color32; use crate::connection::ProtocolClient; -use crate::state::SessionState; -use crate::state::SignalHistory; +use crate::state::{SessionState, SignalHistory, PlotDefinition, SignalStyle}; use rmon_common::protocol::{ClientMessage, AgentMessage}; +use rmon_common::signal::SignalId; use std::sync::{Arc, Mutex}; use tokio::sync::{mpsc, oneshot}; use tokio::time::sleep; -use egui_plot::{Line, Plot, PlotPoints}; -use std::collections::VecDeque; +use egui_plot::{Line, Plot, PlotPoints, VLine, Legend, Corner}; +use std::collections::{VecDeque, HashMap}; +use chrono::{Utc, Local, TimeZone}; #[derive(Clone)] pub enum UiMessage { @@ -17,25 +19,37 @@ pub enum UiMessage { Disconnected, Error(String), Log(String), + RequestInput { + prompt: String, + reply: Arc>>>, + }, } pub struct RMonApp { - pub(crate) ssh_host: String, - pub(crate) agent_port: u16, - pub(crate) addr: String, - pub(crate) show_connect_dialog: bool, - pub(crate) show_config_editor: bool, - pub(crate) pending_input_request: Option<(String, oneshot::Sender)>, - pub(crate) input_value: String, - pub(crate) config_text: String, - pub(crate) last_error: Option, - pub(crate) logs: VecDeque, - pub(crate) state: Arc>, - pub(crate) client: Option>, - pub(crate) tunnel_child: Option>>>, - pub(crate) ui_rx: mpsc::Receiver, - pub(crate) ui_tx: mpsc::Sender, - pub(crate) selected_signals: Vec, + ssh_host: String, + agent_port: u16, + addr: String, + + show_connect_dialog: bool, + show_config_editor: bool, + show_signals: bool, + edit_mode: bool, + + config_text: String, + last_error: Option, + logs: VecDeque, + + pending_input_request: Option<(String, oneshot::Sender)>, + input_value: String, + + // Explicit DND state + dragged_signal: Option<(SignalId, String, Color32)>, + + state: Arc>, + client: Option>, + tunnel_child: Option>>>, + ui_rx: mpsc::Receiver, + ui_tx: mpsc::Sender, } impl RMonApp { @@ -47,18 +61,21 @@ impl RMonApp { addr: "127.0.0.1:7891".to_string(), show_connect_dialog: false, show_config_editor: false, - pending_input_request: None, - input_value: String::new(), + show_signals: true, + edit_mode: false, config_text: String::new(), last_error: None, logs: VecDeque::with_capacity(100), + pending_input_request: None, + input_value: String::new(), + dragged_signal: None, state: Arc::new(Mutex::new(SessionState::new())), client: None, tunnel_child: None, ui_rx: rx, ui_tx: tx, - selected_signals: Vec::new(), }; + let temp_dir = std::env::temp_dir(); let _ = std::fs::remove_file(temp_dir.join(format!("rmon_auth_req_{}", app.agent_port))); let _ = std::fs::remove_file(temp_dir.join(format!("rmon_auth_res_{}", app.agent_port))); @@ -75,13 +92,10 @@ impl RMonApp { let req_path = temp_dir.join(format!("rmon_auth_req_{}", self.agent_port)); if req_path.exists() && self.pending_input_request.is_none() { if let Ok(prompt) = std::fs::read_to_string(&req_path) { - // Delete immediately so we don't re-trigger on next frame let _ = std::fs::remove_file(&req_path); - let (tx, rx) = oneshot::channel(); self.pending_input_request = Some((prompt, tx)); self.input_value.clear(); - let port = self.agent_port; tokio::spawn(async move { if let Ok(val) = rx.await { @@ -94,82 +108,77 @@ impl RMonApp { while let Ok(msg) = self.ui_rx.try_recv() { ctx.request_repaint(); - self.process_ui_message(msg); - } - } - - fn process_ui_message(&mut self, msg: UiMessage) { - match msg { - UiMessage::Log(log) => self.add_log(log), - UiMessage::Tunnel(child) => { - self.add_log("SSH tunnel established".to_string()); - self.tunnel_child = Some(child); - } - UiMessage::Connected(client) => { - self.add_log("Agent connected".to_string()); - self.client = Some(client); - self.state.lock().unwrap().connected = true; - self.show_connect_dialog = false; - self.last_error = None; - let client_clone = self.client.as_ref().unwrap().clone(); - tokio::spawn(async move { let _ = client_clone.send(ClientMessage::GetConfig).await; }); - } - UiMessage::Disconnected => { - self.add_log("Session ended".to_string()); - self.client = None; - self.state.lock().unwrap().connected = false; - if let Some(child_lock) = self.tunnel_child.take() { - if let Ok(mut child) = child_lock.lock() { - if let Some(mut c) = child.take() { let _ = c.kill(); } - } + match msg { + UiMessage::Log(log) => self.add_log(log), + UiMessage::Tunnel(child) => { + self.add_log("SSH tunnel established".to_string()); + self.tunnel_child = Some(child); } - } - UiMessage::Error(err) => { - self.add_log(format!("ERROR: {}", err)); - self.last_error = Some(err); - } - UiMessage::Agent(AgentMessage::SignalList { signals }) => { - self.add_log(format!("Received signal list ({} signals)", signals.len())); - let mut state = self.state.lock().unwrap(); - for sig in signals { - state.signals.entry(sig.id.clone()).or_insert_with(|| Arc::new(Mutex::new(SignalHistory::new(sig)))); + UiMessage::Connected(client) => { + self.add_log("Agent connected".to_string()); + self.client = Some(client); + let mut state = self.state.lock().unwrap(); + state.connected = true; + self.show_connect_dialog = false; + self.last_error = None; + let client_clone = self.client.as_ref().unwrap().clone(); + tokio::spawn(async move { let _ = client_clone.send(ClientMessage::GetConfig).await; }); } - } - UiMessage::Agent(AgentMessage::ConfigReport { config_toml }) => { self.config_text = config_toml; } - UiMessage::Agent(AgentMessage::DataBatch { batches }) => { - let mut new_ids = Vec::new(); - { - let state = self.state.lock().unwrap(); - for batch in batches { - if let Some(history) = state.signals.get(&batch.id) { - let mut history = history.lock().unwrap(); - let is_first = history.samples.is_empty(); - for sample in batch.samples { history.push(sample); } - if is_first { new_ids.push(batch.id.clone()); } + UiMessage::Disconnected => { + self.add_log("Session ended".to_string()); + self.client = None; + self.state.lock().unwrap().connected = false; + if let Some(child_lock) = self.tunnel_child.take() { + if let Ok(mut child) = child_lock.lock() { + if let Some(mut c) = child.take() { let _ = c.kill(); } } } } - for id in new_ids { self.add_log(format!("Data start for {}", id)); } + UiMessage::Error(err) => { + self.add_log(format!("ERROR: {}", err)); + self.last_error = Some(err); + } + UiMessage::Agent(AgentMessage::SignalList { signals }) => { + let mut state = self.state.lock().unwrap(); + for sig in signals { + state.signals.entry(sig.id.clone()).or_insert_with(|| Arc::new(Mutex::new(SignalHistory::new(sig)))); + } + } + UiMessage::Agent(AgentMessage::ConfigReport { config_toml }) => { self.config_text = config_toml; } + UiMessage::Agent(AgentMessage::DataBatch { batches }) => { + let state = self.state.lock().unwrap(); + for batch in batches { + if let Some(history_lock) = state.signals.get(&batch.id) { + let mut history = history_lock.lock().unwrap(); + for sample in batch.samples { history.push(sample); } + } + } + } + UiMessage::Agent(AgentMessage::HistoryChunk { id, samples, .. }) => { + let state = self.state.lock().unwrap(); + if let Some(history_lock) = state.signals.get(&id) { + let mut history = history_lock.lock().unwrap(); + for sample in samples { history.push(sample); } + } + } + _ => {} } - UiMessage::Agent(AgentMessage::Error { context, message }) => { self.add_log(format!("AGENT ERROR ({}): {}", context, message)); } - _ => {} } } fn draw_auth_dialog(&mut self, ctx: &egui::Context) { - if self.pending_input_request.is_some() { - let prompt = self.pending_input_request.as_ref().unwrap().0.clone(); + if let Some((prompt, _)) = &self.pending_input_request { let mut open = true; - egui::Window::new("SSH Authentication Required").open(&mut open).collapsible(false).resizable(false).show(ctx, |ui| { - ui.label(egui::RichText::new(&prompt).strong()); - ui.add_space(8.0); - let is_password = prompt.to_lowercase().contains("password"); - let text_edit = egui::TextEdit::singleline(&mut self.input_value).password(is_password); - let response = ui.add(text_edit); + let prompt_clone = prompt.clone(); + egui::Window::new("SSH Authentication Required").open(&mut open).show(ctx, |ui| { + ui.label(egui::RichText::new(&prompt_clone).strong()); + let is_password = prompt_clone.to_lowercase().contains("password"); + let response = ui.add(egui::TextEdit::singleline(&mut self.input_value).password(is_password)); response.request_focus(); - ui.add_space(10.0); if ui.button("Confirm").clicked() || (response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter))) { - if let Some((_, tx)) = self.pending_input_request.take() { let _ = tx.send(self.input_value.clone()); } + if let Some((_, tx)) = self.pending_input_request.take() { + let _ = tx.send(self.input_value.clone()); + } } }); if !open { self.pending_input_request = None; } @@ -189,38 +198,56 @@ impl RMonApp { let (ssh_host, agent_port, addr, ui_tx) = (self.ssh_host.clone(), self.agent_port, self.addr.clone(), self.ui_tx.clone()); tokio::spawn(async move { use crate::connection::SshConnection; + + let _ = ui_tx.send(UiMessage::Log("Checking for existing connection...".to_string())).await; + + // 1. Speculative connect (skip SSH if port already forwarded and agent alive) + if let Ok(client) = ProtocolClient::connect(&addr, ui_tx.clone()).await { + let _ = ui_tx.send(UiMessage::Log("Reusing existing tunnel/port".to_string())).await; + let _ = ui_tx.send(UiMessage::Connected(Arc::new(client))).await; + return; + } + let ssh = SshConnection::new(ssh_host.clone(), agent_port); let is_localhost = ssh_host == "localhost" || ssh_host == "127.0.0.1"; let local_port = addr.split(':').last().and_then(|p| p.parse::().ok()).unwrap_or(7891); let skip_tunnel = is_localhost && local_port == agent_port; - let _ = ui_tx.send(UiMessage::Log("Preparing...".to_string())).await; + + let _ = ui_tx.send(UiMessage::Log("Preparing SSH flow...".to_string())).await; let _ = ssh.kill_local_orphan_tunnels(); if let Err(e) = ssh.establish_master() { let _ = ui_tx.send(UiMessage::Error(format!("SSH Auth failed: {}", e))).await; return; } match ssh.check_running() { Ok(false) => { - let _ = ui_tx.send(UiMessage::Log("Deploying and starting agent...".to_string())).await; + let _ = ui_tx.send(UiMessage::Log("Starting agent...".to_string())).await; if let Err(e) = ssh.start_agent() { let _ = ui_tx.send(UiMessage::Error(format!("Start failed: {}", e))).await; return; } sleep(std::time::Duration::from_secs(1)).await; } _ => { let _ = ui_tx.send(UiMessage::Log("Agent already running".to_string())).await; } } if !skip_tunnel { - let _ = ui_tx.send(UiMessage::Log("Establishing SSH tunnel...".to_string())).await; match ssh.create_tunnel() { Ok(child) => { let _ = ui_tx.send(UiMessage::Tunnel(Arc::new(Mutex::new(Some(child))))).await; sleep(std::time::Duration::from_secs(1)).await; } Err(e) => { let _ = ui_tx.send(UiMessage::Error(format!("Tunnel failed: {}", e))).await; return; } } - } else { - let _ = ui_tx.send(UiMessage::Log("Direct local connection".to_string())).await; } - match ProtocolClient::connect(&addr, ui_tx.clone()).await { - Ok(client) => { let _ = ui_tx.send(UiMessage::Connected(Arc::new(client))).await; } - Err(e) => { - let _ = ui_tx.send(UiMessage::Error(format!("Handshake failed: {}", e))).await; - let _ = ssh.close_master(); - let _ = ui_tx.send(UiMessage::Disconnected).await; + + let mut last_err = String::new(); + for attempt in 1..=5 { + let _ = ui_tx.send(UiMessage::Log(format!("Connection attempt {}/5...", attempt))).await; + match ProtocolClient::connect(&addr, ui_tx.clone()).await { + Ok(client) => { + let _ = ui_tx.send(UiMessage::Connected(Arc::new(client))).await; + return; + } + Err(e) => { + last_err = e.to_string(); + sleep(std::time::Duration::from_millis(500 * attempt as u64)).await; + } } } + let _ = ui_tx.send(UiMessage::Error(format!("Failed to connect: {}", last_err))).await; + let _ = ssh.close_master(); + let _ = ui_tx.send(UiMessage::Disconnected).await; }); } }); @@ -228,11 +255,280 @@ impl RMonApp { } } +struct TreeBehavior<'a> { + signals: HashMap>>, + styles: &'a mut HashMap, + client: &'a Option>, + edit_mode: bool, + dragged_signal: &'a Option<(SignalId, String, Color32)>, +} + +impl<'a> egui_tiles::Behavior for TreeBehavior<'a> { + fn tab_title_for_pane(&mut self, plot_def: &PlotDefinition) -> egui::WidgetText { + plot_def.title.clone().into() + } + + fn pane_ui(&mut self, ui: &mut egui::Ui, _tile_id: egui_tiles::TileId, plot_def: &mut PlotDefinition) -> egui_tiles::UiResponse { + ui.vertical(|ui| { + // Toolbar + ui.horizontal(|ui| { + if self.edit_mode { + ui.label(egui::RichText::new(&plot_def.title).strong()); + } + + ui.checkbox(&mut plot_def.cursors[0].active, "C1"); + ui.checkbox(&mut plot_def.cursors[1].active, "C2"); + + if plot_def.cursors[0].active && plot_def.cursors[1].active { + let dt = (plot_def.cursors[1].x - plot_def.cursors[0].x).abs(); + ui.label(format!("ΔT: {:.3}s", dt)); + } + + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + ui.toggle_value(&mut plot_def.follow_mode, "Live"); + if plot_def.follow_mode { + ui.add(egui::DragValue::new(&mut plot_def.time_window).suffix("s").range(1.0..=3600.0)); + } + }); + }); + + // Calculate latest data timestamp + let mut latest_ts: f64 = 0.0; + for id in &plot_def.signal_ids { + if let Some(history_lock) = self.signals.get(id) { + let history = history_lock.lock().unwrap(); + if let Some(last) = history.samples.back() { + latest_ts = latest_ts.max(last.timestamp as f64 / 1e9); + } + } + } + + // Handle Mouse Wheel Zoom for time_window + if plot_def.follow_mode && ui.rect_contains_pointer(ui.max_rect()) { + let scroll = ui.input(|i| i.raw_scroll_delta.y); + if scroll != 0.0 { + let zoom_factor = if scroll > 0.0 { 0.9 } else { 1.1 }; + plot_def.time_window = (plot_def.time_window * zoom_factor).clamp(1.0, 3600.0); + } + } + + let mut plot = Plot::new(&plot_def.id) + .link_axis(egui::Id::new("shared_x"), true, false) + .link_cursor(egui::Id::new("shared_cursor"), true, false) + .legend(Legend::default().position(Corner::LeftTop)) + .x_axis_formatter(|mark, _| { + let seconds = mark.value; + let dt = Local.timestamp_opt(seconds as i64, (seconds.fract() * 1e9) as u32).unwrap(); + dt.format("%H:%M:%S").to_string() + }); + + if plot_def.follow_mode && latest_ts > 0.0 { + plot = plot.include_x(latest_ts) + .include_x(latest_ts - plot_def.time_window); + } else { + plot = plot.auto_bounds(egui::Vec2b::new(true, true)); + } + + let plot_res = plot.show(ui, |plot_ui| { + for id in &plot_def.signal_ids { + if let Some(history_lock) = self.signals.get(id) { + let history = history_lock.lock().unwrap(); + if !history.samples.is_empty() { + let points: PlotPoints = history.samples.iter() + .map(|s| [s.timestamp as f64 / 1e9, s.value]) + .collect(); + + let style = self.styles.get(id).cloned().unwrap_or_default(); + plot_ui.line(Line::new(points).color(style.color).width(style.line_width).name(&history.info.label)); + } + } + } + + for (i, cursor) in plot_def.cursors.iter().enumerate() { + if cursor.active { + let color = if i == 0 { Color32::KHAKI } else { Color32::LIGHT_BLUE }; + plot_ui.vline(VLine::new(cursor.x).color(color).width(1.5).name(format!("C{}", i+1))); + } + } + }); + + if let Some(pointer_pos) = ui.ctx().pointer_interact_pos() { + let val_pos = plot_res.transform.value_from_position(pointer_pos); + + // 1. Dragging Cursors + for i in 0..2 { + if plot_def.cursors[i].active { + let dist_px = (plot_res.transform.position_from_point(&egui_plot::PlotPoint::new(plot_def.cursors[i].x, 0.0)).x - pointer_pos.x).abs(); + + let drag_id = egui::Id::new(&plot_def.id).with("cursor").with(i); + if ui.input(|i| i.pointer.button_down(egui::PointerButton::Primary)) && dist_px < 15.0 { + ui.ctx().set_dragged_id(drag_id); + } + + if ui.ctx().is_being_dragged(drag_id) { + plot_def.cursors[i].x = val_pos.x; + if ui.input(|i| i.pointer.any_released()) { + ui.ctx().stop_dragging(); + } + } + } + } + + // 2. Signal Drop Detection + if ui.rect_contains_pointer(plot_res.response.rect) { + if let Some((sig_id, _, _)) = self.dragged_signal { + if ui.input(|i| i.pointer.any_released()) { + if !plot_def.signal_ids.contains(sig_id) { + plot_def.signal_ids.push(sig_id.clone()); + if let Some(client) = self.client { + let client = client.clone(); + let sig_id_clone = sig_id.clone(); + tokio::spawn(async move { + let _ = client.send(ClientMessage::Subscribe { ids: vec![sig_id_clone], from_ns: None }).await; + }); + } + } + } + } + } + } + + if self.edit_mode { + ui.horizontal_wrapped(|ui| { + let mut to_remove = None; + for (idx, id) in plot_def.signal_ids.iter().enumerate() { + if let Some(history_lock) = self.signals.get(id) { + let history = history_lock.lock().unwrap(); + ui.group(|ui| { + ui.label(&history.info.label); + let style = self.styles.entry(id.clone()).or_insert(SignalStyle::default()); + ui.color_edit_button_srgba(&mut style.color); + if ui.button("❌").clicked() { to_remove = Some(idx); } + }); + } + } + if let Some(idx) = to_remove { plot_def.signal_ids.remove(idx); } + }); + } + }); + + egui_tiles::UiResponse::None + } +} + impl eframe::App for RMonApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { self.update_from_agent(ctx); if self.pending_input_request.is_some() { self.draw_auth_dialog(ctx); } if self.show_connect_dialog { self.draw_connect_dialog(ctx); } + + egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { + egui::menu::bar(ui, |ui| { + ui.menu_button("File", |ui| { if ui.button("Quit").clicked() { ctx.send_viewport_cmd(egui::ViewportCommand::Close); } }); + ui.separator(); + + let connected = self.client.is_some(); + if !connected { + if ui.button("🚀 Connect...").clicked() { self.last_error = None; self.show_connect_dialog = true; } + } else { + if ui.button("🔌 Disconnect").clicked() { let _ = self.ui_tx.try_send(UiMessage::Disconnected); } + if ui.button("⚙ Config").clicked() { self.show_config_editor = true; } + ui.toggle_value(&mut self.show_signals, "📡 Signals"); + ui.toggle_value(&mut self.edit_mode, "🛠 Edit Layout"); + + if ui.button("⌛ Load 1h").clicked() { + if let Some(client) = &self.client { + let (client, state) = (client.clone(), self.state.lock().unwrap()); + let ids: Vec<_> = state.signals.keys().cloned().collect(); + let to_ns = Utc::now().timestamp_nanos_opt().unwrap_or(0); + let from_ns = to_ns - 3600 * 1_000_000_000; + tokio::spawn(async move { + for id in ids { let _ = client.send(ClientMessage::QueryHistory { id, from_ns, to_ns, max_points: 1000 }).await; } + }); + } + } + } + }); + }); + + if self.show_signals { + egui::SidePanel::left("signals_panel").resizable(true).show(ctx, |ui| { + ui.heading("Signals"); + let mut state = self.state.lock().unwrap(); + let mut ids: Vec<_> = state.signals.keys().cloned().collect(); + ids.sort(); + egui::ScrollArea::vertical().show(ui, |ui| { + for id in ids { + let label = { + let history_lock = state.signals.get(&id).unwrap(); + let history = history_lock.lock().unwrap(); + history.info.label.clone() + }; + let style = state.get_style(&id); + + let response = ui.add(egui::Label::new(egui::RichText::new(format!("⬌ {}", label)).color(style.color)).sense(egui::Sense::drag())); + if response.drag_started() { + ui.ctx().set_dragged_id(egui::Id::new("drag_signal")); + self.dragged_signal = Some((id.clone(), label.clone(), style.color)); + } + response.on_hover_text("Drag to a plot to add"); + } + }); + }); + } + + egui::TopBottomPanel::bottom("log_panel").resizable(true).default_height(40.0).show(ctx, |ui| { + egui::ScrollArea::vertical().stick_to_bottom(true).show(ui, |ui| { + for log in &self.logs { ui.label(egui::RichText::new(log).monospace().size(9.0)); } + }); + }); + + egui::CentralPanel::default().show(ctx, |ui| { + let mut tree = { + let state = self.state.lock().unwrap(); + std::mem::replace(&mut state.tree.clone(), egui_tiles::Tree::empty("tmp")) + }; + + let (signals, mut signal_styles) = { + let state = self.state.lock().unwrap(); + (state.signals.clone(), state.signal_styles.clone()) + }; + + let mut behavior = TreeBehavior { + signals, + styles: &mut signal_styles, + client: &self.client, + edit_mode: self.edit_mode, + dragged_signal: &self.dragged_signal, + }; + + tree.ui(&mut behavior, ui); + + { + let mut state = self.state.lock().unwrap(); + state.signal_styles = signal_styles; + state.tree = tree; + } + }); + + if let Some((_, label, color)) = &self.dragged_signal { + if ctx.is_being_dragged(egui::Id::new("drag_signal")) { + if let Some(pos) = ctx.pointer_interact_pos() { + egui::Area::new(egui::Id::new("drag_ghost")) + .fixed_pos(pos + egui::vec2(15.0, 15.0)) + .order(egui::Order::Tooltip) + .interactable(false) + .show(ctx, |ui| { + ui.label(egui::RichText::new(format!("Adding: {}", label)).background_color(egui::Color32::from_black_alpha(180)).color(*color).strong()); + }); + } + } + } + + if ctx.input(|i| i.pointer.any_released()) { + self.dragged_signal = None; + } + if self.show_config_editor { let mut open = self.show_config_editor; egui::Window::new("Agent Configuration").open(&mut open).show(ctx, |ui| { @@ -243,16 +539,7 @@ impl eframe::App for RMonApp { let config_toml = self.config_text.clone(); tokio::spawn(async move { let _ = client.send(ClientMessage::UpdateConfig { config_toml }).await; - sleep(std::time::Duration::from_millis(1500)).await; - let _ = client.send(ClientMessage::ListSignals).await; - }); - } - } - if ui.button("🔄 Refresh").clicked() { - if let Some(client) = &self.client { - let client = client.clone(); - tokio::spawn(async move { - let _ = client.send(ClientMessage::GetConfig).await; + sleep(std::time::Duration::from_millis(1000)).await; let _ = client.send(ClientMessage::ListSignals).await; }); } @@ -260,82 +547,16 @@ impl eframe::App for RMonApp { }); self.show_config_editor = open; } - egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { - egui::menu::bar(ui, |ui| { - ui.menu_button("File", |ui| { if ui.button("Quit").clicked() { ctx.send_viewport_cmd(egui::ViewportCommand::Close); } }); - ui.separator(); - if self.client.is_none() { - if ui.button("🚀 Connect...").clicked() { self.last_error = None; self.show_connect_dialog = true; } - } else { - if ui.button("🔌 Disconnect").clicked() { let _ = self.ui_tx.try_send(UiMessage::Disconnected); } - if ui.button("💀 Kill Agent").clicked() { - let (host, port, tx) = (self.ssh_host.clone(), self.agent_port, self.ui_tx.clone()); - tokio::spawn(async move { - use crate::connection::SshConnection; - let ssh = SshConnection::new(host, port); - let _ = tx.send(UiMessage::Log("Killing agent...".to_string())).await; - let _ = ssh.kill_agent(); - }); - let _ = self.ui_tx.try_send(UiMessage::Disconnected); - } - if ui.button("⚙ Configure Agent").clicked() { self.show_config_editor = true; } - } - }); - }); - egui::TopBottomPanel::bottom("log_panel").resizable(true).default_height(100.0).show(ctx, |ui| { - ui.heading("Logs"); - egui::ScrollArea::vertical().stick_to_bottom(true).show(ui, |ui| { - for log in &self.logs { ui.label(egui::RichText::new(log).monospace()); } - }); - }); - egui::SidePanel::left("left_panel").show(ctx, |ui| { - ui.heading("Signals"); - let state = self.state.lock().unwrap(); - let mut ids: Vec<_> = state.signals.keys().cloned().collect(); - ids.sort(); - egui::ScrollArea::vertical().show(ui, |ui| { - for id in ids { - if let Some(history) = state.signals.get(&id) { - let history = history.lock().unwrap(); - let mut checked = self.selected_signals.contains(&id); - if ui.checkbox(&mut checked, &history.info.label).changed() { - if checked { - self.selected_signals.push(id.clone()); - if let Some(client) = &self.client { - let client = client.clone(); - tokio::spawn(async move { let _ = client.send(ClientMessage::Subscribe { ids: vec![id], from_ns: None }).await; }); - } - } else { self.selected_signals.retain(|s| s != &id); } - } - } - } - }); - }); - egui::CentralPanel::default().show(ctx, |ui| { - ui.heading("Plots"); - egui::ScrollArea::vertical().show(ui, |ui| { - let state = self.state.lock().unwrap(); - for id in &self.selected_signals { - if let Some(history) = state.signals.get(id) { - let history = history.lock().unwrap(); - ui.label(format!("{} [{}]", history.info.label, history.samples.len())); - if !history.samples.is_empty() { - let first_ts = history.samples[0].timestamp as f64 / 1e9; - let points: PlotPoints = history.samples.iter().map(|s| [(s.timestamp as f64 / 1e9) - first_ts, s.value]).collect(); - Plot::new(id).view_aspect(2.5).auto_bounds_x().auto_bounds_y().show(ui, |plot_ui| plot_ui.line(Line::new(points))); - } else { ui.label("Waiting for data..."); } - } - } - }); - }); - ctx.request_repaint_after(std::time::Duration::from_millis(100)); + + ctx.request_repaint_after(std::time::Duration::from_millis(50)); } } #[cfg(test)] mod tests { use super::*; - use rmon_common::signal::{SignalInfo, SourceType}; + use rmon_common::signal::SourceType; + use rmon_common::signal::SignalInfo; #[test] fn test_app_init() { @@ -346,61 +567,20 @@ mod tests { addr: "a".to_string(), show_connect_dialog: false, show_config_editor: false, - pending_input_request: None, - input_value: "".to_string(), + show_signals: true, + edit_mode: false, config_text: "".to_string(), last_error: None, logs: VecDeque::new(), + pending_input_request: None, + input_value: "".to_string(), + dragged_signal: None, state: Arc::new(Mutex::new(SessionState::new())), client: None, tunnel_child: None, ui_rx: rx, ui_tx: tx, - selected_signals: vec![], }; assert_eq!(app.ssh_host, "h"); } - - #[test] - fn test_process_ui_message_logic() { - let (tx, rx) = mpsc::channel(100); - let mut app = RMonApp { - ssh_host: "h".to_string(), - agent_port: 1, - addr: "a".to_string(), - show_connect_dialog: false, - show_config_editor: false, - pending_input_request: None, - input_value: "".to_string(), - config_text: "".to_string(), - last_error: None, - logs: VecDeque::new(), - state: Arc::new(Mutex::new(SessionState::new())), - client: None, - tunnel_child: None, - ui_rx: rx, - ui_tx: tx, - selected_signals: vec![], - }; - - app.process_ui_message(UiMessage::Log("test log".to_string())); - assert_eq!(app.logs.len(), 1); - assert_eq!(app.logs[0], "test log"); - - app.process_ui_message(UiMessage::Error("test err".to_string())); - assert_eq!(app.last_error.as_ref().unwrap(), "test err"); - - let sig = SignalInfo { - id: "s1".to_string(), label: "L".to_string(), unit: "V".to_string(), scale: 1.0, offset: 0.0, - sampling_period: None, source_type: SourceType::Csv, path: vec![], - }; - app.process_ui_message(UiMessage::Agent(AgentMessage::SignalList { signals: vec![sig] })); - assert_eq!(app.state.lock().unwrap().signals.len(), 1); - - app.process_ui_message(UiMessage::Agent(AgentMessage::ConfigReport { config_toml: "cfg".to_string() })); - assert_eq!(app.config_text, "cfg"); - - app.process_ui_message(UiMessage::Disconnected); - assert!(!app.state.lock().unwrap().connected); - } } diff --git a/rmon-ui/src/main.rs b/rmon-ui/src/main.rs index 1c00686..6df71fd 100644 --- a/rmon-ui/src/main.rs +++ b/rmon-ui/src/main.rs @@ -64,6 +64,6 @@ fn main() -> eframe::Result<()> { eframe::run_native( "RMon", native_options, - Box::new(|cc| Box::new(RMonApp::new(cc))), + Box::new(|cc| Ok(Box::new(RMonApp::new(cc)))), ) } diff --git a/rmon-ui/src/state/mod.rs b/rmon-ui/src/state/mod.rs index c303acf..03d0140 100644 --- a/rmon-ui/src/state/mod.rs +++ b/rmon-ui/src/state/mod.rs @@ -1,6 +1,7 @@ use rmon_common::signal::{SignalId, SignalInfo, Sample}; use std::collections::{HashMap, VecDeque}; use std::sync::{Arc, Mutex}; +use eframe::egui::ecolor::Color32; pub struct SignalHistory { pub info: SignalInfo, @@ -13,7 +14,7 @@ impl SignalHistory { Self { info, samples: VecDeque::new(), - max_samples: 1000, // Default for display + max_samples: 10000, } } @@ -25,52 +26,95 @@ impl SignalHistory { } } -pub struct SessionState { - pub connected: bool, - pub signals: HashMap>>, +#[derive(Clone)] +pub struct SignalStyle { + pub color: Color32, + pub line_width: f32, } -impl SessionState { - pub fn new() -> Self { +impl Default for SignalStyle { + fn default() -> Self { Self { - connected: false, - signals: HashMap::new(), + color: Color32::WHITE, + line_width: 1.5, } } } -#[cfg(test)] -mod tests { - use super::*; - use rmon_common::signal::SourceType; +#[derive(Clone, Default)] +pub struct PlotCursor { + pub x: f64, + pub active: bool, +} - #[test] - fn test_signal_history_push() { - let info = SignalInfo { - id: "test://1".to_string(), - label: "L".to_string(), - unit: "U".to_string(), - scale: 1.0, - offset: 0.0, - sampling_period: None, - source_type: SourceType::Csv, - path: vec![], - }; - let mut history = SignalHistory::new(info); - history.max_samples = 2; - - history.push(Sample { timestamp: 1, value: 1.0 }); - history.push(Sample { timestamp: 2, value: 2.0 }); - history.push(Sample { timestamp: 3, value: 3.0 }); - - assert_eq!(history.samples.len(), 2); - assert_eq!(history.samples[0].timestamp, 2); - } +#[derive(Clone)] +pub struct PlotDefinition { + pub id: String, + pub title: String, + pub signal_ids: Vec, + pub cursors: [PlotCursor; 2], + pub show_legend: bool, + pub follow_mode: bool, + pub time_window: f64, // seconds +} - #[test] - fn test_session_state_init() { - let state = SessionState::new(); - assert!(!state.connected); - assert!(state.signals.is_empty()); +impl PlotDefinition { + pub fn new(title: String) -> Self { + Self { + id: uuid::Uuid::new_v4().to_string(), + title, + signal_ids: Vec::new(), + cursors: [PlotCursor::default(), PlotCursor::default()], + show_legend: true, + follow_mode: true, + time_window: 600.0, // Default to 10 minutes + } + } +} + +pub struct SessionState { + pub connected: bool, + pub signals: HashMap>>, + pub tree: egui_tiles::Tree, + pub signal_styles: HashMap, +} + +impl SessionState { + pub fn new() -> Self { + let mut tiles = egui_tiles::Tiles::default(); + let root = tiles.insert_pane(PlotDefinition::new("Main Plot".to_string())); + let tree = egui_tiles::Tree::new("main_tree", root, tiles); + + Self { + connected: false, + signals: HashMap::new(), + tree, + signal_styles: HashMap::new(), + } + } + + pub fn get_style(&mut self, id: &SignalId) -> SignalStyle { + if let Some(style) = self.signal_styles.get(id) { + return style.clone(); + } + + let colors = [ + Color32::from_rgb(255, 80, 80), + Color32::from_rgb(80, 255, 80), + Color32::from_rgb(80, 80, 255), + Color32::from_rgb(255, 255, 80), + Color32::from_rgb(255, 80, 255), + Color32::from_rgb(80, 255, 255), + Color32::from_rgb(255, 150, 50), + Color32::from_rgb(150, 80, 255), + ]; + + let mut hash = 0u64; + for b in id.as_bytes() { hash = hash.wrapping_add(*b as u64); } + let color = colors[(hash % colors.len() as u64) as usize]; + + let style = SignalStyle { color, line_width: 1.5 }; + self.signal_styles.insert(id.clone(), style.clone()); + style } }