mirror of
https://github.com/hubaldv/bioz-host-rs.git
synced 2025-12-06 05:11:17 +00:00
Compare commits
2 Commits
ef3fc12cb8
...
restructur
| Author | SHA1 | Date | |
|---|---|---|---|
| 2252771ac3 | |||
| 1ca1c2c7b4 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
.DS_Store
|
.DS_Store
|
||||||
log_*
|
log_*
|
||||||
|
*.icns
|
||||||
20
.vscode/tasks.json
vendored
20
.vscode/tasks.json
vendored
@@ -63,6 +63,26 @@
|
|||||||
// "isDefault": true
|
// "isDefault": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "cargo bundle - create app release",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "~/.cargo/bin/cargo", // note: full path to the cargo
|
||||||
|
"args": [
|
||||||
|
"bundle",
|
||||||
|
"--bin",
|
||||||
|
"main_gui",
|
||||||
|
"--release",
|
||||||
|
// "--target",
|
||||||
|
// "aarch64-apple-darwin",
|
||||||
|
// "x86_64-pc-windows-gnu"
|
||||||
|
// "--",
|
||||||
|
// "arg1"
|
||||||
|
],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
// "isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "Terminate All Tasks",
|
"label": "Terminate All Tasks",
|
||||||
"command": "echo ${input:terminate}",
|
"command": "echo ${input:terminate}",
|
||||||
|
|||||||
191
Cargo.lock
generated
191
Cargo.lock
generated
@@ -190,7 +190,7 @@ dependencies = [
|
|||||||
"clipboard-win",
|
"clipboard-win",
|
||||||
"image",
|
"image",
|
||||||
"log",
|
"log",
|
||||||
"objc2 0.6.1",
|
"objc2 0.6.3",
|
||||||
"objc2-app-kit 0.3.1",
|
"objc2-app-kit 0.3.1",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-core-graphics",
|
"objc2-core-graphics",
|
||||||
@@ -228,6 +228,29 @@ dependencies = [
|
|||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ashpd"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df"
|
||||||
|
dependencies = [
|
||||||
|
"async-fs",
|
||||||
|
"async-net",
|
||||||
|
"enumflags2",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"rand 0.9.2",
|
||||||
|
"raw-window-handle",
|
||||||
|
"serde",
|
||||||
|
"serde_repr",
|
||||||
|
"tokio",
|
||||||
|
"url",
|
||||||
|
"wayland-backend",
|
||||||
|
"wayland-client",
|
||||||
|
"wayland-protocols",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-broadcast"
|
name = "async-broadcast"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
@@ -266,6 +289,17 @@ dependencies = [
|
|||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-fs"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5"
|
||||||
|
dependencies = [
|
||||||
|
"async-lock",
|
||||||
|
"blocking",
|
||||||
|
"futures-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-io"
|
name = "async-io"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@@ -295,6 +329,17 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-net"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
|
||||||
|
dependencies = [
|
||||||
|
"async-io",
|
||||||
|
"blocking",
|
||||||
|
"futures-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-process"
|
name = "async-process"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
@@ -466,6 +511,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"postcard-rpc",
|
"postcard-rpc",
|
||||||
"postcard-schema",
|
"postcard-schema",
|
||||||
|
"rfd",
|
||||||
"simple_logger",
|
"simple_logger",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-serial",
|
"tokio-serial",
|
||||||
@@ -526,6 +572,15 @@ dependencies = [
|
|||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block2"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
|
||||||
|
dependencies = [
|
||||||
|
"objc2 0.6.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blocking"
|
name = "blocking"
|
||||||
version = "1.6.2"
|
version = "1.6.2"
|
||||||
@@ -873,7 +928,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
|
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"objc2 0.6.1",
|
"block2 0.6.2",
|
||||||
|
"libc",
|
||||||
|
"objc2 0.6.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1475,7 +1532,7 @@ dependencies = [
|
|||||||
"glutin_glx_sys",
|
"glutin_glx_sys",
|
||||||
"glutin_wgl_sys",
|
"glutin_wgl_sys",
|
||||||
"libloading",
|
"libloading",
|
||||||
"objc2 0.6.1",
|
"objc2 0.6.3",
|
||||||
"objc2-app-kit 0.3.1",
|
"objc2-app-kit 0.3.1",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-foundation 0.3.1",
|
"objc2-foundation 0.3.1",
|
||||||
@@ -2359,9 +2416,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2"
|
name = "objc2"
|
||||||
version = "0.6.1"
|
version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551"
|
checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"objc2-encode",
|
"objc2-encode",
|
||||||
]
|
]
|
||||||
@@ -2373,7 +2430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
|
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"libc",
|
"libc",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-core-data",
|
"objc2-core-data",
|
||||||
@@ -2389,7 +2446,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc"
|
checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"objc2 0.6.1",
|
"block2 0.6.2",
|
||||||
|
"objc2 0.6.3",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-core-graphics",
|
"objc2-core-graphics",
|
||||||
"objc2-foundation 0.3.1",
|
"objc2-foundation 0.3.1",
|
||||||
@@ -2402,7 +2460,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
|
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-core-location",
|
"objc2-core-location",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
@@ -2414,7 +2472,7 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
|
checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
]
|
]
|
||||||
@@ -2426,7 +2484,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
|
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
]
|
]
|
||||||
@@ -2439,7 +2497,7 @@ checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"dispatch2",
|
"dispatch2",
|
||||||
"objc2 0.6.1",
|
"objc2 0.6.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2450,7 +2508,7 @@ checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"dispatch2",
|
"dispatch2",
|
||||||
"objc2 0.6.1",
|
"objc2 0.6.3",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-io-surface",
|
"objc2-io-surface",
|
||||||
]
|
]
|
||||||
@@ -2461,7 +2519,7 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
|
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
"objc2-metal",
|
"objc2-metal",
|
||||||
@@ -2473,7 +2531,7 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
|
checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-contacts",
|
"objc2-contacts",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
@@ -2492,7 +2550,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"dispatch",
|
"dispatch",
|
||||||
"libc",
|
"libc",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
@@ -2505,7 +2563,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c"
|
checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"objc2 0.6.1",
|
"objc2 0.6.3",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2516,7 +2574,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c"
|
checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"objc2 0.6.1",
|
"objc2 0.6.3",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2526,7 +2584,7 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
|
checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-app-kit 0.2.2",
|
"objc2-app-kit 0.2.2",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
@@ -2539,7 +2597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
|
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
]
|
]
|
||||||
@@ -2551,7 +2609,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
|
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
"objc2-metal",
|
"objc2-metal",
|
||||||
@@ -2574,7 +2632,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
|
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-cloud-kit",
|
"objc2-cloud-kit",
|
||||||
"objc2-core-data",
|
"objc2-core-data",
|
||||||
@@ -2594,7 +2652,7 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
|
checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
]
|
]
|
||||||
@@ -2606,7 +2664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
|
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-core-location",
|
"objc2-core-location",
|
||||||
"objc2-foundation 0.2.2",
|
"objc2-foundation 0.2.2",
|
||||||
@@ -2728,7 +2786,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_shared",
|
"phf_shared",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2831,6 +2889,12 @@ dependencies = [
|
|||||||
"windows-sys 0.60.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pollster"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portable-atomic"
|
name = "portable-atomic"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
@@ -2910,6 +2974,15 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "presser"
|
name = "presser"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -3015,7 +3088,27 @@ version = "0.8.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||||
|
dependencies = [
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core 0.9.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.9.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3024,6 +3117,15 @@ version = "0.6.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "range-alloc"
|
name = "range-alloc"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@@ -3104,6 +3206,30 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
|
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rfd"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672"
|
||||||
|
dependencies = [
|
||||||
|
"ashpd",
|
||||||
|
"block2 0.6.2",
|
||||||
|
"dispatch2",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"objc2 0.6.3",
|
||||||
|
"objc2-app-kit 0.3.1",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"objc2-foundation 0.3.1",
|
||||||
|
"pollster",
|
||||||
|
"raw-window-handle",
|
||||||
|
"urlencoding",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
"windows-sys 0.60.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.26"
|
version = "0.1.26"
|
||||||
@@ -3638,9 +3764,11 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
"slab",
|
"slab",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
|
"tracing",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3826,8 +3954,15 @@ dependencies = [
|
|||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urlencoding"
|
||||||
|
version = "2.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8_iter"
|
name = "utf8_iter"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -4081,7 +4216,7 @@ dependencies = [
|
|||||||
"jni",
|
"jni",
|
||||||
"log",
|
"log",
|
||||||
"ndk-context",
|
"ndk-context",
|
||||||
"objc2 0.6.1",
|
"objc2 0.6.3",
|
||||||
"objc2-foundation 0.3.1",
|
"objc2-foundation 0.3.1",
|
||||||
"url",
|
"url",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
@@ -4759,7 +4894,7 @@ dependencies = [
|
|||||||
"android-activity",
|
"android-activity",
|
||||||
"atomic-waker",
|
"atomic-waker",
|
||||||
"bitflags 2.9.4",
|
"bitflags 2.9.4",
|
||||||
"block2",
|
"block2 0.5.1",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"calloop",
|
"calloop",
|
||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
@@ -4942,6 +5077,7 @@ dependencies = [
|
|||||||
"ordered-stream",
|
"ordered-stream",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_repr",
|
"serde_repr",
|
||||||
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"uds_windows",
|
"uds_windows",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
@@ -5098,6 +5234,7 @@ dependencies = [
|
|||||||
"endi",
|
"endi",
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
"serde",
|
"serde",
|
||||||
|
"url",
|
||||||
"winnow",
|
"winnow",
|
||||||
"zvariant_derive",
|
"zvariant_derive",
|
||||||
"zvariant_utils",
|
"zvariant_utils",
|
||||||
|
|||||||
10
Cargo.toml
10
Cargo.toml
@@ -13,6 +13,7 @@ log = "0.4.27"
|
|||||||
simple_logger = "5.0.0"
|
simple_logger = "5.0.0"
|
||||||
atomic_float = "1.1.0"
|
atomic_float = "1.1.0"
|
||||||
chrono = { version = "0.4.42" }
|
chrono = { version = "0.4.42" }
|
||||||
|
rfd = { version = "0.16.0", features = ["tokio"] }
|
||||||
|
|
||||||
[dependencies.bioz-icd-rs]
|
[dependencies.bioz-icd-rs]
|
||||||
path = "../bioz-icd-rs"
|
path = "../bioz-icd-rs"
|
||||||
@@ -41,3 +42,12 @@ features = [
|
|||||||
|
|
||||||
[dependencies.tokio-serial]
|
[dependencies.tokio-serial]
|
||||||
version = "5.4.4"
|
version = "5.4.4"
|
||||||
|
|
||||||
|
[package.metadata.bundle.bin.main_gui]
|
||||||
|
name = "Bio-Z App"
|
||||||
|
identifier = "bioz-host-rs"
|
||||||
|
icon = ["bundle/bio-z.icns"]
|
||||||
|
version = "0.1.0"
|
||||||
|
copyright = "Hubald Verzijl"
|
||||||
|
category = "Developer Tool"
|
||||||
|
long_description = "App belonging to the Bio-Z setup."
|
||||||
13
bundle/CreateCNS.src
Normal file
13
bundle/CreateCNS.src
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
mkdir MyIcon.iconset
|
||||||
|
sips -z 16 16 Icon1024.png --out MyIcon.iconset/icon_16x16.png
|
||||||
|
sips -z 32 32 Icon1024.png --out MyIcon.iconset/icon_16x16@2x.png
|
||||||
|
sips -z 32 32 Icon1024.png --out MyIcon.iconset/icon_32x32.png
|
||||||
|
sips -z 64 64 Icon1024.png --out MyIcon.iconset/icon_32x32@2x.png
|
||||||
|
sips -z 128 128 Icon1024.png --out MyIcon.iconset/icon_128x128.png
|
||||||
|
sips -z 256 256 Icon1024.png --out MyIcon.iconset/icon_128x128@2x.png
|
||||||
|
sips -z 256 256 Icon1024.png --out MyIcon.iconset/icon_256x256.png
|
||||||
|
sips -z 512 512 Icon1024.png --out MyIcon.iconset/icon_256x256@2x.png
|
||||||
|
sips -z 512 512 Icon1024.png --out MyIcon.iconset/icon_512x512.png
|
||||||
|
cp Icon1024.png MyIcon.iconset/icon_512x512@2x.png
|
||||||
|
iconutil -c icns MyIcon.iconset
|
||||||
|
rm -R MyIcon.iconset
|
||||||
11
bundle/readme.md
Normal file
11
bundle/readme.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
### Prepare
|
||||||
|
- Picture for icon from: https://pubs.acs.org/doi/10.1021/acsmeasuresciau.2c00033
|
||||||
|
- For packing as OSX-app or Windows, when on OSX, install mingw-w64 first for cross-linking:
|
||||||
|
`brew install mingw-w64`
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
- Create 1024x1024 picture
|
||||||
|
- Transform to icon
|
||||||
|
- Using *Image2Icon app*
|
||||||
|
- Using terminal: `source CreateCNS.src`
|
||||||
|
- Adjust path in `tasks.json` use a custom cargo-bundle command
|
||||||
18
readme.md
Normal file
18
readme.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Bio-Impedance Amplifier | GUI
|
||||||
|
This repository contains Rust-based software for communicating with a custom-built bio-impedance amplifier. It provides several key features:
|
||||||
|
|
||||||
|
- Single-frequency and frequency-sweep measurements
|
||||||
|
- Real-time visualization of magnitude and phase
|
||||||
|
- Support for both 2-lead and 4-lead measurements
|
||||||
|
- Data logging to `.csv` files
|
||||||
|
- Day and night display modes
|
||||||
|
- Control via on-screen buttons or keyboard shortcuts
|
||||||
|
|
||||||
|
## How to Use This Software
|
||||||
|
1. Install the Rust toolchain and run the software using:
|
||||||
|
```bash
|
||||||
|
cargo run --bin main_gui --release
|
||||||
|
```
|
||||||
|
2. Alternatively, a precompiled executable can be used instead of building from source.
|
||||||
|
3. The software uses the `postcard-rpc` crate to communicate directly with the USB hardware device’s endpoints. After connecting the hardware via USB, the device should automatically connect, and the indicator dot in the top-right corner will turn green.
|
||||||
|
4. Check the **Shortcuts** tab for useful information on available keyboard commands.
|
||||||
64
src/app.rs
64
src/app.rs
@@ -12,11 +12,12 @@ use chrono::Local;
|
|||||||
use atomic_float::AtomicF32;
|
use atomic_float::AtomicF32;
|
||||||
use tokio::{sync::mpsc::{Sender}};
|
use tokio::{sync::mpsc::{Sender}};
|
||||||
|
|
||||||
use eframe::egui::{self, Button, CollapsingHeader, Color32, ComboBox, DragValue, Id, Key, Label, Layout, Modifiers, TextEdit, Widget};
|
use eframe::egui::{self, Button, CollapsingHeader, Color32, ComboBox, DragValue, Id, Key, Label, Layout, Modifiers, RichText, TextEdit, Widget};
|
||||||
use egui_plot::{Corner, GridInput, GridMark, Legend, Line, Plot, PlotPoint, Points};
|
use egui_plot::{Corner, GridInput, GridMark, Legend, Line, Plot, PlotPoint, Points};
|
||||||
use egui_dock::{DockArea, DockState, Style};
|
use egui_dock::{DockArea, DockState, Style};
|
||||||
use egui_extras::{TableBuilder, Column};
|
use egui_extras::{TableBuilder, Column};
|
||||||
|
|
||||||
|
use crate::logging::LoggingStates;
|
||||||
use crate::plot::{TimeSeriesPlot, BodePlot};
|
use crate::plot::{TimeSeriesPlot, BodePlot};
|
||||||
|
|
||||||
use crate::signals::{LoggingSignal, StartStopSignal};
|
use crate::signals::{LoggingSignal, StartStopSignal};
|
||||||
@@ -67,7 +68,7 @@ pub struct App {
|
|||||||
pub measurement_points: Arc<Mutex<MeasurementPointSet>>,
|
pub measurement_points: Arc<Mutex<MeasurementPointSet>>,
|
||||||
pub periods_per_dft: Arc<Mutex<Option<f32>>>,
|
pub periods_per_dft: Arc<Mutex<Option<f32>>>,
|
||||||
pub periods_per_dft_sweep: Arc<Mutex<(Vec<u32>, Option<Vec<f32>>)>>,
|
pub periods_per_dft_sweep: Arc<Mutex<(Vec<u32>, Option<Vec<f32>>)>>,
|
||||||
pub gui_logging_enabled: Arc<AtomicBool>,
|
pub gui_logging_state: Arc<Mutex<LoggingStates>>,
|
||||||
log_filename: String,
|
log_filename: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,7 +541,7 @@ impl App {
|
|||||||
measurement_points,
|
measurement_points,
|
||||||
periods_per_dft,
|
periods_per_dft,
|
||||||
periods_per_dft_sweep,
|
periods_per_dft_sweep,
|
||||||
gui_logging_enabled: Arc::new(AtomicBool::new(false)),
|
gui_logging_state: Arc::new(Mutex::new(LoggingStates::Idle)),
|
||||||
log_filename: format!("log_{}.csv", Local::now().format("%Y%m%d"))
|
log_filename: format!("log_{}.csv", Local::now().format("%Y%m%d"))
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -619,23 +620,31 @@ impl eframe::App for App {
|
|||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
let mut gui_logging_enabled = self.gui_logging_enabled.load(Ordering::Relaxed);
|
let gui_logging_state = *self.gui_logging_state.lock().unwrap();
|
||||||
if ui.add(egui::Checkbox::new(&mut gui_logging_enabled, "Logging")).changed() {
|
|
||||||
self.gui_logging_enabled.store(gui_logging_enabled, Ordering::Relaxed);
|
let (color, signal) = match gui_logging_state {
|
||||||
if gui_logging_enabled {
|
LoggingStates::Idle => (Color32::DARK_RED, LoggingSignal::StartFileLogging(self.log_filename.clone())),
|
||||||
if let Err(e) = self.log_tx.try_send(LoggingSignal::StartFileLogging(self.log_filename.clone())) {
|
LoggingStates::Starting => (Color32::from_rgb(204, 153, 0), LoggingSignal::StopFileLogging),
|
||||||
error!("Failed to send logging signal: {:?}", e);
|
LoggingStates::Logging => (Color32::DARK_GREEN, LoggingSignal::StopFileLogging),
|
||||||
}
|
};
|
||||||
} else {
|
|
||||||
if let Err(e) = self.log_tx.try_send(LoggingSignal::StopFileLogging) {
|
let button = Button::new(
|
||||||
error!("Failed to send logging signal: {:?}", e);
|
RichText::new("Logging")
|
||||||
}
|
.strong()
|
||||||
}
|
.color(Color32::WHITE)
|
||||||
|
).fill(color)
|
||||||
|
.corner_radius(5.0)
|
||||||
|
.frame(true);
|
||||||
|
|
||||||
|
if ui.add(button).clicked() {
|
||||||
|
self.log_tx.try_send(signal).unwrap_or_else(|e| {
|
||||||
|
error!("Failed to send logging toggle signal: {:?}", e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
ui.add_enabled_ui(!gui_logging_enabled, |ui| {
|
ui.add_enabled_ui(gui_logging_state == LoggingStates::Idle, |ui| {
|
||||||
ui.label("Log filename:");
|
ui.label("Log filename:");
|
||||||
TextEdit::singleline(&mut self.log_filename).desired_width(125.0).id(Id::new("file_name_field")).ui(ui);
|
TextEdit::singleline(&mut self.log_filename).desired_width(125.0).id(Id::new("file_name_field")).ui(ui);
|
||||||
});
|
});
|
||||||
@@ -644,7 +653,7 @@ impl eframe::App for App {
|
|||||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||||
ui.scope(|ui| {
|
ui.scope(|ui| {
|
||||||
let is_connected = self.connected.load(Ordering::Relaxed);
|
let is_connected = self.connected.load(Ordering::Relaxed);
|
||||||
let color = if is_connected { Color32::GREEN } else { Color32::RED };
|
let color = if is_connected { Color32::DARK_GREEN } else { Color32::DARK_RED };
|
||||||
let tooltip = if is_connected { "Connected" } else { "Disconnected" };
|
let tooltip = if is_connected { "Connected" } else { "Disconnected" };
|
||||||
|
|
||||||
// Allocate a fixed-size rectangle for the LED
|
// Allocate a fixed-size rectangle for the LED
|
||||||
@@ -739,17 +748,22 @@ impl eframe::App for App {
|
|||||||
|
|
||||||
// Enable/disable GUI logging
|
// Enable/disable GUI logging
|
||||||
if ctx.input(|i| i.key_pressed(egui::Key::L)) {
|
if ctx.input(|i| i.key_pressed(egui::Key::L)) {
|
||||||
let mut gui_logging_enabled = self.gui_logging_enabled.load(Ordering::Relaxed);
|
let gui_logging_enabled = *self.gui_logging_state.lock().unwrap();
|
||||||
gui_logging_enabled = !gui_logging_enabled;
|
match gui_logging_enabled {
|
||||||
self.gui_logging_enabled.store(gui_logging_enabled, Ordering::Relaxed);
|
LoggingStates::Starting => {
|
||||||
if gui_logging_enabled {
|
// If currently starting, do nothing
|
||||||
if let Err(e) = self.log_tx.try_send(LoggingSignal::StartFileLogging(self.log_filename.clone())) {
|
return;
|
||||||
error!("Failed to send logging signal: {:?}", e);
|
},
|
||||||
}
|
LoggingStates::Logging => {
|
||||||
} else {
|
|
||||||
if let Err(e) = self.log_tx.try_send(LoggingSignal::StopFileLogging) {
|
if let Err(e) = self.log_tx.try_send(LoggingSignal::StopFileLogging) {
|
||||||
error!("Failed to send logging signal: {:?}", e);
|
error!("Failed to send logging signal: {:?}", e);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
LoggingStates::Idle => {
|
||||||
|
if let Err(e) = self.log_tx.try_send(LoggingSignal::StartFileLogging(self.log_filename.clone())) {
|
||||||
|
error!("Failed to send logging signal: {:?}", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,11 @@ async fn main() {
|
|||||||
let periods_per_dft = app.periods_per_dft.clone();
|
let periods_per_dft = app.periods_per_dft.clone();
|
||||||
let periods_per_dft_sweep = app.periods_per_dft_sweep.clone();
|
let periods_per_dft_sweep = app.periods_per_dft_sweep.clone();
|
||||||
|
|
||||||
let gui_logging_enabled = app.gui_logging_enabled.clone();
|
let gui_logging_state_1 = app.gui_logging_state.clone();
|
||||||
|
let gui_logging_state_2 = app.gui_logging_state.clone();
|
||||||
|
|
||||||
// Log thread
|
// Log thread
|
||||||
tokio::spawn(async move { log_data(log_rx).await });
|
tokio::spawn(async move { log_data(log_rx, gui_logging_state_1).await });
|
||||||
|
|
||||||
// Execute the runtime in its own thread.
|
// Execute the runtime in its own thread.
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
@@ -62,7 +63,7 @@ async fn main() {
|
|||||||
data_frequency_clone,
|
data_frequency_clone,
|
||||||
periods_per_dft,
|
periods_per_dft,
|
||||||
periods_per_dft_sweep,
|
periods_per_dft_sweep,
|
||||||
gui_logging_enabled,
|
gui_logging_state_2,
|
||||||
log_tx_clone,
|
log_tx_clone,
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use bioz_icd_rs::MeasurementPointSet;
|
|||||||
use crate::icd;
|
use crate::icd;
|
||||||
use crate::client::WorkbookClient;
|
use crate::client::WorkbookClient;
|
||||||
|
|
||||||
|
use crate::logging::LoggingStates;
|
||||||
use crate::plot::{TimeSeriesPlot, BodePlot};
|
use crate::plot::{TimeSeriesPlot, BodePlot};
|
||||||
|
|
||||||
use crate::signals::{LoggingSignal, StartStopSignal};
|
use crate::signals::{LoggingSignal, StartStopSignal};
|
||||||
@@ -31,7 +32,7 @@ pub async fn communicate_with_hardware(
|
|||||||
data_frequency: Arc<AtomicF32>,
|
data_frequency: Arc<AtomicF32>,
|
||||||
periods_per_dft: Arc<Mutex<Option<f32>>>,
|
periods_per_dft: Arc<Mutex<Option<f32>>>,
|
||||||
periods_per_dft_sweep: Arc<Mutex<(Vec<u32>, Option<Vec<f32>>)>>,
|
periods_per_dft_sweep: Arc<Mutex<(Vec<u32>, Option<Vec<f32>>)>>,
|
||||||
gui_logging_enabled: Arc<AtomicBool>,
|
gui_logging_state: Arc<Mutex<LoggingStates>>,
|
||||||
log_tx: Sender<LoggingSignal>,
|
log_tx: Sender<LoggingSignal>,
|
||||||
) {
|
) {
|
||||||
let data_counter = Arc::new(AtomicU32::new(0));
|
let data_counter = Arc::new(AtomicU32::new(0));
|
||||||
@@ -78,7 +79,7 @@ pub async fn communicate_with_hardware(
|
|||||||
let data_counter_clone_single = data_counter_clone.clone();
|
let data_counter_clone_single = data_counter_clone.clone();
|
||||||
|
|
||||||
// Clone log_tx for the task
|
// Clone log_tx for the task
|
||||||
let gui_logging_enabled_clone = gui_logging_enabled.clone();
|
let gui_logging_state_clone = gui_logging_state.clone();
|
||||||
let log_tx_clone = log_tx.clone();
|
let log_tx_clone = log_tx.clone();
|
||||||
|
|
||||||
let settings_clone = settings.clone();
|
let settings_clone = settings.clone();
|
||||||
@@ -100,11 +101,11 @@ pub async fn communicate_with_hardware(
|
|||||||
data_counter_clone_single.fetch_add(1, Ordering::Relaxed);
|
data_counter_clone_single.fetch_add(1, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
// Send logging signal
|
// Send logging signal
|
||||||
if gui_logging_enabled_clone.load(Ordering::Relaxed) {
|
if *gui_logging_state_clone.lock().unwrap() == LoggingStates::Logging {
|
||||||
let settings = *settings_clone.lock().unwrap();
|
let settings = *settings_clone.lock().unwrap();
|
||||||
match settings.frequency {
|
match settings.frequency {
|
||||||
Some(StartStopSignal::StartSingle(freq, _, _)) => {
|
Some(StartStopSignal::StartSingle(freq, _, _)) => {
|
||||||
if let Err(e) = log_tx_clone.send(LoggingSignal::SingleImpedance(SystemTime::now(), freq, val.magnitude, val.phase)).await {
|
if let Err(e) = log_tx_clone.try_send(LoggingSignal::SingleImpedance(SystemTime::now(), freq, val.magnitude, val.phase)) {
|
||||||
error!("Failed to send logging signal: {:?}", e);
|
error!("Failed to send logging signal: {:?}", e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -131,7 +132,7 @@ pub async fn communicate_with_hardware(
|
|||||||
let data_counter_clone_sweep = data_counter_clone.clone();
|
let data_counter_clone_sweep = data_counter_clone.clone();
|
||||||
|
|
||||||
// Clone log_tx for the task
|
// Clone log_tx for the task
|
||||||
let gui_logging_enabled_clone = gui_logging_enabled.clone();
|
let gui_logging_state_clone = gui_logging_state.clone();
|
||||||
let log_tx_clone = log_tx.clone();
|
let log_tx_clone = log_tx.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
@@ -147,7 +148,7 @@ pub async fn communicate_with_hardware(
|
|||||||
bode_plot.update_magnitudes(MeasurementPointSet::Eight, magnitudes.clone());
|
bode_plot.update_magnitudes(MeasurementPointSet::Eight, magnitudes.clone());
|
||||||
bode_plot.update_phases(MeasurementPointSet::Eight, phases.clone());
|
bode_plot.update_phases(MeasurementPointSet::Eight, phases.clone());
|
||||||
}
|
}
|
||||||
if gui_logging_enabled_clone.load(Ordering::Relaxed) {
|
if *gui_logging_state_clone.lock().unwrap() == LoggingStates::Logging {
|
||||||
if let Err(e) = log_tx_clone.send(LoggingSignal::SweepImpedance(SystemTime::now(), MeasurementPointSet::Eight.values().to_vec(), magnitudes.clone(), phases.clone())).await {
|
if let Err(e) = log_tx_clone.send(LoggingSignal::SweepImpedance(SystemTime::now(), MeasurementPointSet::Eight.values().to_vec(), magnitudes.clone(), phases.clone())).await {
|
||||||
error!("Failed to send logging signal: {:?}", e);
|
error!("Failed to send logging signal: {:?}", e);
|
||||||
}
|
}
|
||||||
@@ -161,7 +162,7 @@ pub async fn communicate_with_hardware(
|
|||||||
bode_plot.update_magnitudes(MeasurementPointSet::Eighteen, magnitudes.clone());
|
bode_plot.update_magnitudes(MeasurementPointSet::Eighteen, magnitudes.clone());
|
||||||
bode_plot.update_phases(MeasurementPointSet::Eighteen, phases.clone());
|
bode_plot.update_phases(MeasurementPointSet::Eighteen, phases.clone());
|
||||||
}
|
}
|
||||||
if gui_logging_enabled_clone.load(Ordering::Relaxed) {
|
if *gui_logging_state_clone.lock().unwrap() == LoggingStates::Logging {
|
||||||
if let Err(e) = log_tx_clone.send(LoggingSignal::SweepImpedance(SystemTime::now(), MeasurementPointSet::Eighteen.values().to_vec(), magnitudes.clone(), phases.clone())).await {
|
if let Err(e) = log_tx_clone.send(LoggingSignal::SweepImpedance(SystemTime::now(), MeasurementPointSet::Eighteen.values().to_vec(), magnitudes.clone(), phases.clone())).await {
|
||||||
error!("Failed to send logging signal: {:?}", e);
|
error!("Failed to send logging signal: {:?}", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,27 @@
|
|||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::time::UNIX_EPOCH;
|
||||||
|
|
||||||
use tokio::sync::mpsc::Receiver;
|
use tokio::sync::mpsc::Receiver;
|
||||||
use tokio::fs::File;
|
use tokio::fs::File;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
use std::path::Path;
|
|
||||||
use std::time::UNIX_EPOCH;
|
use rfd::AsyncFileDialog;
|
||||||
|
|
||||||
use crate::signals::LoggingSignal;
|
use crate::signals::LoggingSignal;
|
||||||
|
|
||||||
pub async fn log_data(mut data: Receiver<LoggingSignal>) {
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum LoggingStates {
|
||||||
|
Idle,
|
||||||
|
Starting,
|
||||||
|
Logging,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn log_data(
|
||||||
|
mut data: Receiver<LoggingSignal>,
|
||||||
|
gui_logging_state: Arc<Mutex<LoggingStates>>,
|
||||||
|
) {
|
||||||
let mut file: Option<File> = None;
|
let mut file: Option<File> = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@@ -38,36 +51,64 @@ pub async fn log_data(mut data: Receiver<LoggingSignal>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LoggingSignal::StartFileLogging(filename) => {
|
LoggingSignal::StartFileLogging(filename) => {
|
||||||
let path = Path::new(&filename);
|
// Update global logging state
|
||||||
let base = path.file_stem().and_then(|s| s.to_str()).unwrap_or("log");
|
*gui_logging_state.lock().unwrap() = LoggingStates::Starting;
|
||||||
let ext = path.extension().and_then(|s| s.to_str()).unwrap_or("");
|
|
||||||
|
|
||||||
|
// Open a folder picker for the user
|
||||||
|
let folder = match AsyncFileDialog::new()
|
||||||
|
.set_title("Select Folder for Logs")
|
||||||
|
.pick_folder()
|
||||||
|
.await {
|
||||||
|
Some(f) => f,
|
||||||
|
None => {
|
||||||
|
info!("File logging cancelled by user");
|
||||||
|
*gui_logging_state.lock().unwrap() = LoggingStates::Idle;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let log_dir = folder.path();
|
||||||
|
|
||||||
|
// Ensure the directory exists
|
||||||
|
std::fs::create_dir_all(&log_dir).ok();
|
||||||
|
|
||||||
|
// Build initial file path
|
||||||
|
let mut path = log_dir.join(&filename);
|
||||||
|
let base = path.file_stem().and_then(|s| s.to_str()).unwrap_or("log").to_string();
|
||||||
|
let ext = path.extension().and_then(|s| s.to_str()).unwrap_or("").to_string();
|
||||||
|
|
||||||
|
// Avoid overwriting existing files
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
let mut new_filename = filename.clone();
|
while path.exists() {
|
||||||
while Path::new(&new_filename).exists() {
|
|
||||||
counter += 1;
|
counter += 1;
|
||||||
new_filename = if ext.is_empty() {
|
path = if ext.is_empty() {
|
||||||
format!("{}_{}", base, counter)
|
log_dir.join(format!("{}_{}", base, counter))
|
||||||
} else {
|
} else {
|
||||||
format!("{}_{}.{}", base, counter, ext)
|
log_dir.join(format!("{}_{}.{}", base, counter, ext))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
match File::create(&new_filename).await {
|
// Create the file asynchronously
|
||||||
|
match File::create(&path).await {
|
||||||
Ok(f) => {
|
Ok(f) => {
|
||||||
info!("Started file logging to: {}", new_filename);
|
info!("Started file logging to: {}", path.display());
|
||||||
file = Some(f);
|
file = Some(f);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
info!("Failed to create log file '{}': {}", new_filename, e);
|
info!("Failed to create log file '{}': {}", path.display(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update global logging state
|
||||||
|
*gui_logging_state.lock().unwrap() = LoggingStates::Logging;
|
||||||
}
|
}
|
||||||
LoggingSignal::StopFileLogging => {
|
LoggingSignal::StopFileLogging => {
|
||||||
if file.is_some() {
|
if file.is_some() {
|
||||||
info!("Stopped file logging");
|
info!("Stopped file logging");
|
||||||
file = None;
|
file = None;
|
||||||
}
|
}
|
||||||
|
// Update global logging state
|
||||||
|
*gui_logging_state.lock().unwrap() = LoggingStates::Idle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user