mirror of
https://github.com/Zenithsiz/zsw.git
synced 2026-02-03 17:52:15 +00:00
Replaced custom "runtime" with tokio, with optional tokio-console support.
`Wgpu` now arcs the window (maybe reversible eventually once tokio supports scoped tasks).
This commit is contained in:
parent
2dff20531c
commit
6e69d72bee
2
.cargo/config.toml
Normal file
2
.cargo/config.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[build]
|
||||
rustflags = ["--cfg", "tokio_unstable"]
|
||||
657
Cargo.lock
generated
657
Cargo.lock
generated
@ -50,6 +50,15 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.53"
|
||||
@ -94,6 +103,38 @@ dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e"
|
||||
dependencies = [
|
||||
"async-stream-impl",
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stream-impl"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic_refcell"
|
||||
version = "0.1.8"
|
||||
@ -132,6 +173,12 @@ dependencies = [
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.2"
|
||||
@ -201,6 +248,12 @@ version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
||||
|
||||
[[package]]
|
||||
name = "cache-padded"
|
||||
version = "1.2.0"
|
||||
@ -288,7 +341,7 @@ version = "3.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a1132dc3944b31c20dd8b906b3a9f0a5d0243e092d59171414969657ac6aa85"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.4.0",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -362,6 +415,43 @@ dependencies = [
|
||||
"cache-padded",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console-api"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc347c19eb5b940f396ac155822caee6662f850d97306890ac3773ed76c90c5a"
|
||||
dependencies = [
|
||||
"prost",
|
||||
"prost-types",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console-subscriber"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "565a7dfea2d10dd0e5c57cc394d5d441b1910960d8c9211ed14135e0e6ec3a20"
|
||||
dependencies = [
|
||||
"console-api",
|
||||
"crossbeam-channel",
|
||||
"crossbeam-utils",
|
||||
"futures",
|
||||
"hdrhistogram",
|
||||
"humantime",
|
||||
"prost-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thread_local",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tonic",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "copyless"
|
||||
version = "0.1.5"
|
||||
@ -703,6 +793,15 @@ version = "2.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fern"
|
||||
version = "0.6.0"
|
||||
@ -719,6 +818,24 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide 0.4.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@ -916,6 +1033,25 @@ dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util 0.7.1",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
@ -925,6 +1061,28 @@ dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hdrhistogram"
|
||||
version = "7.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31672b7011be2c4f7456c4ddbcb40e7e9a4a9fad8efe49a6ebaf5f307d0109c0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"byteorder",
|
||||
"flate2",
|
||||
"nom",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
@ -946,6 +1104,82 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-timeout"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
|
||||
dependencies = [
|
||||
"hyper",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tokio-io-timeout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
@ -1000,6 +1234,15 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
@ -1174,6 +1417,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multimap"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
|
||||
|
||||
[[package]]
|
||||
name = "naga"
|
||||
version = "0.8.5"
|
||||
@ -1509,7 +1758,7 @@ dependencies = [
|
||||
"backtrace",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"petgraph",
|
||||
"petgraph 0.5.1",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"thread-id",
|
||||
@ -1528,10 +1777,40 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"fixedbitset 0.2.0",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f"
|
||||
dependencies = [
|
||||
"fixedbitset 0.4.1",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.8"
|
||||
@ -1623,6 +1902,59 @@ version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9145ac0af1d93c638c98c40cf7d25665f427b2a44ad0a99b1dccf3e2f25bb987"
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-build"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck 0.3.3",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"multimap",
|
||||
"petgraph 0.6.0",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"regex",
|
||||
"tempfile",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.15"
|
||||
@ -1721,6 +2053,32 @@ dependencies = [
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "renderdoc-sys"
|
||||
version = "0.7.1"
|
||||
@ -1794,6 +2152,24 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.5"
|
||||
@ -1834,6 +2210,16 @@ dependencies = [
|
||||
"wayland-protocols",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spirv"
|
||||
version = "0.2.0+1.5.4"
|
||||
@ -1861,6 +2247,20 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
@ -1907,6 +2307,15 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.6.1"
|
||||
@ -1929,6 +2338,87 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.0",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-io-timeout"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
@ -1938,12 +2428,154 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff08f4649d10a70ffa3522ca559031285d8e421d727ac85c60825761818f5d0a"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"base64",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-timeout",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost",
|
||||
"prost-derive",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util 0.6.9",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tonic-build"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9403f1bafde247186684b230dc6f38b5cd514584e8bec1dd32514be4745fa757"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"prost-build",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"indexmap",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"rand",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util 0.7.1",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-futures"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
|
||||
dependencies = [
|
||||
"pin-project",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9df98b037d039d03400d9dd06b0f8ce05486b5f25e9a2d7d36196e142ebbc52"
|
||||
dependencies = [
|
||||
"sharded-slab",
|
||||
"thread_local",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ccbe8381883510b6a2d8f1e32905bddd178c11caef8083086d0c0c9ab0ac281"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.9"
|
||||
@ -1956,12 +2588,28 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
@ -2382,6 +3030,7 @@ dependencies = [
|
||||
"cgmath",
|
||||
"chrono",
|
||||
"clap",
|
||||
"console-subscriber",
|
||||
"crossbeam",
|
||||
"egui",
|
||||
"egui_wgpu_backend",
|
||||
@ -2399,6 +3048,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"wgpu",
|
||||
"winit",
|
||||
"zsw-egui",
|
||||
@ -2509,6 +3159,7 @@ dependencies = [
|
||||
"futures",
|
||||
"log",
|
||||
"pollster",
|
||||
"tokio",
|
||||
"winit",
|
||||
"zsw-egui",
|
||||
"zsw-img",
|
||||
|
||||
@ -24,6 +24,7 @@ egui_wgpu_backend = "0.16.0"
|
||||
# Async
|
||||
futures = "0.3.21"
|
||||
pollster = "0.2.4"
|
||||
tokio = "1.17.0"
|
||||
|
||||
# Error handling
|
||||
anyhow = "1.0.52"
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
use {
|
||||
anyhow::Context,
|
||||
futures::lock::Mutex,
|
||||
std::{mem, thread, time::Duration},
|
||||
std::{mem, time::Duration},
|
||||
winit::window::Window,
|
||||
zsw_egui::Egui,
|
||||
zsw_img::ImageLoader,
|
||||
@ -91,7 +91,7 @@ impl Renderer {
|
||||
&self,
|
||||
window: &Window,
|
||||
input: &Input,
|
||||
wgpu: &'wgpu Wgpu<'window>,
|
||||
wgpu: &'wgpu Wgpu,
|
||||
panels: &Panels,
|
||||
egui: &'egui Egui,
|
||||
image_loader: &ImageLoader,
|
||||
@ -125,9 +125,8 @@ impl Renderer {
|
||||
});
|
||||
|
||||
// Then sleep until next frame
|
||||
// TODO: Await while sleeping
|
||||
if let Some(duration) = sleep_duration.checked_sub(total_duration) {
|
||||
thread::sleep(duration);
|
||||
tokio::time::sleep(duration).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,7 +142,7 @@ impl Renderer {
|
||||
/// # Blocking
|
||||
/// Locks [`zsw_panels::PanelsLock`] on `panels`
|
||||
async fn update<'window, 'panels>(
|
||||
wgpu: &Wgpu<'window>,
|
||||
wgpu: &Wgpu,
|
||||
panels: &'panels Panels,
|
||||
image_loader: &ImageLoader,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
@ -166,7 +165,7 @@ impl Renderer {
|
||||
async fn render<'window, 'wgpu, 'egui, 'panels>(
|
||||
window: &Window,
|
||||
input: &Input,
|
||||
wgpu: &'wgpu Wgpu<'window>,
|
||||
wgpu: &'wgpu Wgpu,
|
||||
panels: &'panels Panels,
|
||||
egui: &'egui Egui,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
|
||||
@ -119,7 +119,7 @@ impl SettingsWindow {
|
||||
/// Blocks until [`Self::paint_jobs`] on `egui` is called.
|
||||
pub async fn run<'wgpu, 'egui, 'playlist, 'panels, 'profiles>(
|
||||
&self,
|
||||
wgpu: &'wgpu Wgpu<'_>,
|
||||
wgpu: &'wgpu Wgpu,
|
||||
egui: &'egui Egui,
|
||||
window: &Window,
|
||||
panels: &'panels Panels,
|
||||
|
||||
@ -7,7 +7,6 @@ use {
|
||||
Future,
|
||||
},
|
||||
std::{
|
||||
collections::VecDeque,
|
||||
mem,
|
||||
ops::{Deref, DerefMut},
|
||||
pin::Pin,
|
||||
@ -24,8 +23,8 @@ struct Inner<T> {
|
||||
/// If this value has been seen
|
||||
seen: bool,
|
||||
|
||||
/// All wakers
|
||||
wakers: VecDeque<Waker>,
|
||||
/// Waker
|
||||
waker: Option<Waker>,
|
||||
}
|
||||
|
||||
/// Fetch-update lock
|
||||
@ -43,7 +42,7 @@ impl<T> FetchUpdateLock<T> {
|
||||
let inner = Inner {
|
||||
value,
|
||||
seen: false,
|
||||
wakers: VecDeque::new(),
|
||||
waker: None,
|
||||
};
|
||||
Self {
|
||||
inner: Mutex::new(inner),
|
||||
@ -63,7 +62,7 @@ impl<T> FetchUpdateLock<T> {
|
||||
|
||||
// Set that the value was seen and wake up someone to update it
|
||||
inner.seen = true;
|
||||
if let Some(waker) = inner.wakers.pop_front() {
|
||||
if let Some(waker) = inner.waker.take() {
|
||||
waker.wake();
|
||||
}
|
||||
|
||||
@ -94,7 +93,7 @@ impl<T> FetchUpdateLock<T> {
|
||||
// DEADLOCK: Caller ensures we can wait.
|
||||
// We guarantee we unlock while waiting
|
||||
CondVarFuture::new(move |waker| {
|
||||
inner.wakers.push_back(waker.clone());
|
||||
inner.waker = Some(waker.clone());
|
||||
mem::drop(inner);
|
||||
})
|
||||
.await;
|
||||
|
||||
@ -1,181 +0,0 @@
|
||||
//! Future helpers
|
||||
|
||||
// Imports
|
||||
use {
|
||||
parking_lot::{Condvar, Mutex},
|
||||
std::{
|
||||
future::Future,
|
||||
sync::{
|
||||
atomic::{self, AtomicBool},
|
||||
Arc,
|
||||
},
|
||||
task,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/// Future runner
|
||||
///
|
||||
/// Adapts a future to run on it's own thread, and be cancellable
|
||||
/// when polling.
|
||||
#[derive(Debug)]
|
||||
pub struct FutureRunner {
|
||||
/// Signal
|
||||
signal: Arc<FutureSignal>,
|
||||
|
||||
/// If we're running
|
||||
running: AtomicBool,
|
||||
}
|
||||
|
||||
impl FutureRunner {
|
||||
/// Creates a new future runner
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
// Create the waker
|
||||
Self {
|
||||
signal: Arc::new(FutureSignal::new()),
|
||||
running: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
/// Executes the future
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if called more than once
|
||||
#[allow(clippy::result_unit_err)] // TODO: Use custom enum to say if we were cancelled
|
||||
pub fn run<F>(&self, f: F) -> Result<F::Output, ()>
|
||||
where
|
||||
F: Future,
|
||||
{
|
||||
// 'lock' the running bool
|
||||
assert!(
|
||||
!self.running.swap(true, atomic::Ordering::AcqRel),
|
||||
"Cannot run a future runner more than once"
|
||||
);
|
||||
|
||||
// Pin the future
|
||||
futures::pin_mut!(f);
|
||||
|
||||
// Create the waker
|
||||
let waker = task::Waker::from(Arc::clone(&self.signal));
|
||||
let mut ctx = task::Context::from_waker(&waker);
|
||||
|
||||
// Then poll it until we should exit
|
||||
// Note: On the first loop, `wait` instantly returns for us to loop
|
||||
while let FutureSignalStatus::Poll = self.signal.wait() {
|
||||
match f.as_mut().poll(&mut ctx) {
|
||||
task::Poll::Ready(output) => return Ok(output),
|
||||
task::Poll::Pending => (),
|
||||
}
|
||||
}
|
||||
|
||||
// Exit the signal if we're still waiting
|
||||
self.signal.exit();
|
||||
|
||||
Err(())
|
||||
}
|
||||
|
||||
/// Stops the future
|
||||
pub fn stop(&self) {
|
||||
self.signal.exit();
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FutureRunner {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FutureRunner {
|
||||
fn drop(&mut self) {
|
||||
// Stop the future on-drop
|
||||
self.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// Signal inner
|
||||
#[derive(Debug)]
|
||||
struct FutureSignalInner {
|
||||
/// If we should exit
|
||||
should_exit: bool,
|
||||
|
||||
/// If the future should be polled
|
||||
should_poll: bool,
|
||||
}
|
||||
|
||||
/// Status on signal waiting
|
||||
enum FutureSignalStatus {
|
||||
/// Should poll
|
||||
Poll,
|
||||
|
||||
/// Should exit
|
||||
Exit,
|
||||
}
|
||||
|
||||
/// Waker signal for [`FuturesRunner`]
|
||||
#[derive(Debug)]
|
||||
struct FutureSignal {
|
||||
/// Inner
|
||||
inner: Mutex<FutureSignalInner>,
|
||||
|
||||
/// Condvar for waiting
|
||||
cond_var: Condvar,
|
||||
}
|
||||
|
||||
impl FutureSignal {
|
||||
/// Creates a new signal
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
inner: Mutex::new(FutureSignalInner {
|
||||
should_exit: false,
|
||||
should_poll: true,
|
||||
}),
|
||||
cond_var: Condvar::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Waits until the future should be polled, or we should quit
|
||||
fn wait(&self) -> FutureSignalStatus {
|
||||
// Keep waiting until either `should_poll` or `should_exit` are true
|
||||
// DEADLOCK: We'll be woken up in the waker eventually
|
||||
let mut inner = self.inner.lock();
|
||||
loop {
|
||||
match (inner.should_exit, inner.should_poll) {
|
||||
// If we should exit, regardless if we should poll, return
|
||||
// Note: Doesn't matter if we set `should_poll` to false here
|
||||
(true, _) => break FutureSignalStatus::Exit,
|
||||
|
||||
// Else if we should poll, set it to false and return
|
||||
(_, true) => {
|
||||
inner.should_poll = false;
|
||||
break FutureSignalStatus::Poll;
|
||||
},
|
||||
|
||||
// Else wait
|
||||
_ => self.cond_var.wait(&mut inner),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets to exit
|
||||
pub fn exit(&self) {
|
||||
// Lock, set `should_exit` to `true` and notify
|
||||
// DEADLOCK: `Self::wait` only locks it temporarily without blocking
|
||||
let mut inner = self.inner.lock();
|
||||
inner.should_exit = true;
|
||||
let _ = self.cond_var.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
impl task::Wake for FutureSignal {
|
||||
fn wake(self: std::sync::Arc<Self>) {
|
||||
// Set that we should be polling
|
||||
// DEADLOCK: `Self::wait` only locks it temporarily without blocking
|
||||
let mut inner = self.inner.lock();
|
||||
inner.should_poll = true;
|
||||
|
||||
// Then notify the waiter
|
||||
let _ = self.cond_var.notify_one();
|
||||
}
|
||||
}
|
||||
@ -61,7 +61,6 @@
|
||||
// Modules
|
||||
mod display_wrapper;
|
||||
mod fetch_update_lock;
|
||||
mod future;
|
||||
mod lock;
|
||||
mod rect;
|
||||
mod scan_dir;
|
||||
@ -71,7 +70,6 @@ mod thread;
|
||||
pub use {
|
||||
display_wrapper::DisplayWrapper,
|
||||
fetch_update_lock::{FetchUpdateLock, FetchUpdateLockGuard},
|
||||
future::FutureRunner,
|
||||
lock::Lock,
|
||||
rect::Rect,
|
||||
scan_dir::dir_files_iter,
|
||||
|
||||
@ -61,7 +61,7 @@ use {
|
||||
anyhow::Context,
|
||||
crossbeam::atomic::AtomicCell,
|
||||
futures::lock::{Mutex, MutexGuard},
|
||||
std::marker::PhantomData,
|
||||
std::sync::Arc,
|
||||
wgpu::TextureFormat,
|
||||
winit::{dpi::PhysicalSize, window::Window},
|
||||
};
|
||||
@ -92,7 +92,7 @@ pub struct Surface {
|
||||
// seems to not result in any panics, but it might be worth checking, especially if we
|
||||
// ever need to "restart" `wgpu` in any scenario without restarting the application.
|
||||
#[derive(Debug)]
|
||||
pub struct Wgpu<'window> {
|
||||
pub struct Wgpu {
|
||||
/// Device
|
||||
// TODO: There exists a `Device::poll` method, but I'm not sure if we should
|
||||
// have to call that? Seems to be used for async, but we don't use any
|
||||
@ -130,27 +130,27 @@ pub struct Wgpu<'window> {
|
||||
// without showing the user at least 1 frame of the resized surface.
|
||||
queued_resize: AtomicCell<Option<PhysicalSize<u32>>>,
|
||||
|
||||
/// Window lifetime
|
||||
// Note: Our surface must outlive the window, so we make sure of it using the `'window` lifetime
|
||||
window_phantom: PhantomData<&'window Window>,
|
||||
/// Window
|
||||
// Note: Our surface must outlive the window, so we make sure of it by arcing it
|
||||
_window: Arc<Window>,
|
||||
|
||||
/// Lock source
|
||||
lock_source: LockSource,
|
||||
}
|
||||
|
||||
impl<'window> Wgpu<'window> {
|
||||
impl Wgpu {
|
||||
/// Creates the `wgpu` wrapper given the window to create it in.
|
||||
pub async fn new(window: &'window Window) -> Result<Wgpu<'window>, anyhow::Error> {
|
||||
pub async fn new(window: Arc<Window>) -> Result<Self, anyhow::Error> {
|
||||
// Create the surface and adapter
|
||||
// SAFETY: Due to our lifetime, we ensure the window outlives us and thus the surface
|
||||
let (surface, adapter) = unsafe { self::create_surface_and_adapter(window).await? };
|
||||
// SAFETY: Due to the window being arced, and we storing it, we ensure the window outlives us and thus the surface
|
||||
let (surface, adapter) = unsafe { self::create_surface_and_adapter(&window).await? };
|
||||
|
||||
// Then create the device and it's queue
|
||||
let (device, queue) = self::create_device(&adapter).await?;
|
||||
|
||||
// Configure the surface and get the preferred texture format and surface size
|
||||
let (surface_texture_format, surface_size) =
|
||||
self::configure_window_surface(window, &surface, &adapter, &device)?;
|
||||
self::configure_window_surface(&window, &surface, &adapter, &device)?;
|
||||
|
||||
log::info!("Successfully initialized");
|
||||
Ok(Self {
|
||||
@ -162,7 +162,7 @@ impl<'window> Wgpu<'window> {
|
||||
queue,
|
||||
surface_texture_format,
|
||||
queued_resize: AtomicCell::new(None),
|
||||
window_phantom: PhantomData,
|
||||
_window: window,
|
||||
lock_source: LockSource,
|
||||
})
|
||||
}
|
||||
|
||||
@ -32,8 +32,10 @@ epi = "0.16.0"
|
||||
|
||||
# Async
|
||||
async-channel = "1.6.1"
|
||||
console-subscriber = {version = "0.1.3", optional = true}
|
||||
futures = "0.3.21"
|
||||
pollster = "0.2.4"
|
||||
tokio = {version = "1.17.0", features = ["full"]}
|
||||
|
||||
# Serialization
|
||||
serde = {version = "1.0.132", features = ["derive"]}
|
||||
@ -73,3 +75,7 @@ native-dialog = "0.6.3"
|
||||
crossbeam = "0.8.1"
|
||||
parking_lot = {version = "0.12.0", features = ["deadlock_detection"]}
|
||||
rayon = "1.5.1"
|
||||
|
||||
[features]
|
||||
|
||||
tokio-console = ["console-subscriber", "tokio/tracing"]
|
||||
|
||||
182
zsw/src/app.rs
182
zsw/src/app.rs
@ -13,8 +13,10 @@ use {
|
||||
crate::Args,
|
||||
anyhow::Context,
|
||||
cgmath::{Point2, Vector2},
|
||||
futures::future::OptionFuture,
|
||||
pollster::FutureExt,
|
||||
std::{iter, num::NonZeroUsize, thread},
|
||||
std::{num::NonZeroUsize, sync::Arc, thread},
|
||||
tokio::task,
|
||||
winit::{
|
||||
dpi::{PhysicalPosition, PhysicalSize},
|
||||
event_loop::EventLoop,
|
||||
@ -32,135 +34,145 @@ use {
|
||||
zsw_profiles::Profiles,
|
||||
zsw_renderer::Renderer,
|
||||
zsw_settings_window::SettingsWindow,
|
||||
zsw_util::{FutureRunner, Rect},
|
||||
zsw_util::Rect,
|
||||
zsw_wgpu::Wgpu,
|
||||
};
|
||||
|
||||
/// Runs the application
|
||||
// TODO: Not arc everything
|
||||
#[allow(clippy::too_many_lines)] // TODO: Refactor
|
||||
pub fn run(args: &Args) -> Result<(), anyhow::Error> {
|
||||
#[allow(clippy::future_not_send)] // We only want this to run in the main thread anyway, we spawn everything else
|
||||
pub async fn run(args: Arc<Args>) -> Result<(), anyhow::Error> {
|
||||
// Build the window
|
||||
let (mut event_loop, window) = self::create_window()?;
|
||||
let window = Arc::new(window);
|
||||
|
||||
// Create the wgpu interface
|
||||
// TODO: Execute future inn background and continue initializing
|
||||
let wgpu = Wgpu::new(&window).block_on().context("Unable to create renderer")?;
|
||||
let wgpu = Wgpu::new(Arc::clone(&window))
|
||||
.await
|
||||
.context("Unable to create renderer")?;
|
||||
let wgpu = Arc::new(wgpu);
|
||||
|
||||
// Create the playlist
|
||||
let playlist = Playlist::new();
|
||||
let playlist = Arc::new(playlist);
|
||||
|
||||
// Create the image loader
|
||||
let image_loader = ImageLoader::new();
|
||||
let image_loader = Arc::new(image_loader);
|
||||
|
||||
// Create the panels
|
||||
let panels = Panels::new(wgpu.device(), wgpu.surface_texture_format()).context("Unable to create panels")?;
|
||||
let panels = Arc::new(panels);
|
||||
|
||||
// Create egui
|
||||
let egui = Egui::new(&window, &wgpu).context("Unable to create egui state")?;
|
||||
let egui = Arc::new(egui);
|
||||
|
||||
// Create the profiles
|
||||
let profiles = Profiles::new().context("Unable to load profiles")?;
|
||||
let profiles = Arc::new(profiles);
|
||||
|
||||
// Create the event handler
|
||||
let mut event_handler = EventHandler::new();
|
||||
|
||||
// Create the renderer
|
||||
let renderer = Renderer::new();
|
||||
let renderer = Arc::new(renderer);
|
||||
|
||||
// Create the settings window
|
||||
let settings_window = SettingsWindow::new();
|
||||
let settings_window = Arc::new(settings_window);
|
||||
|
||||
// Create the input
|
||||
let input = Input::new();
|
||||
let input = Arc::new(input);
|
||||
|
||||
// All runners
|
||||
// Note: They must exists outside of the thread scope because
|
||||
// their `run` can last until the very end of the function
|
||||
let profile_loader_runner = FutureRunner::new();
|
||||
let playlist_runner = FutureRunner::new();
|
||||
let image_loader_threads = thread::available_parallelism().map_or(1, NonZeroUsize::get);
|
||||
let image_loader_runners = iter::repeat_with(FutureRunner::new)
|
||||
.take(image_loader_threads)
|
||||
// TODO: Bundle all of these onto a single struct to pass onto the runners,
|
||||
// via some generic
|
||||
|
||||
// Then add all futures
|
||||
let profiles_loader_task: OptionFuture<_> = args
|
||||
.profile
|
||||
.clone()
|
||||
.map({
|
||||
let profiles = Arc::clone(&profiles);
|
||||
let playlist = Arc::clone(&playlist);
|
||||
let panels = Arc::clone(&panels);
|
||||
move |path| {
|
||||
task::Builder::new()
|
||||
.name("Profiles loader")
|
||||
.spawn(async move { profiles.run_loader_applier(&path, &playlist, &panels).await })
|
||||
}
|
||||
})
|
||||
.into();
|
||||
let playlist_task = task::Builder::new().name("Playlist runner").spawn({
|
||||
let playlist = Arc::clone(&playlist);
|
||||
async move { playlist.run().await }
|
||||
});
|
||||
let image_loader_tasks = thread::available_parallelism().map_or(1, NonZeroUsize::get);
|
||||
let image_loader_tasks = (0..image_loader_tasks)
|
||||
.map(|idx| {
|
||||
let image_loader = Arc::clone(&image_loader);
|
||||
let playlist = Arc::clone(&playlist);
|
||||
task::Builder::new()
|
||||
.name(&format!("Image loader #{idx}"))
|
||||
.spawn(async move { image_loader.run(&playlist).await })
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let settings_window_runner = FutureRunner::new();
|
||||
let renderer_runner = FutureRunner::new();
|
||||
|
||||
|
||||
// Start all threads and then wait in the main thread for events
|
||||
// DEADLOCK: We ensure all threads lock each lock in the same order,
|
||||
// and that we don't lock them.
|
||||
thread::scope(|s| {
|
||||
// Create the thread spawner
|
||||
let mut thread_spawner = zsw_util::ThreadSpawner::new(s);
|
||||
|
||||
// Spawn the profile loader if we have any
|
||||
// DEADLOCK: See above
|
||||
if let Some(path) = &args.profile {
|
||||
thread_spawner.spawn("Profile loader", || {
|
||||
// Note: We don't care whether we got cancelled or returned successfully
|
||||
profile_loader_runner
|
||||
.run(profiles.run_loader_applier(path, &playlist, &panels))
|
||||
.into_ok_or_err();
|
||||
})?;
|
||||
let settings_window_task = task::Builder::new().name("Settings window runner").spawn({
|
||||
let settings_window = Arc::clone(&settings_window);
|
||||
let wgpu = Arc::clone(&wgpu);
|
||||
let egui = Arc::clone(&egui);
|
||||
let window = Arc::clone(&window);
|
||||
let profiles = Arc::clone(&profiles);
|
||||
let playlist = Arc::clone(&playlist);
|
||||
let panels = Arc::clone(&panels);
|
||||
let renderer = Arc::clone(&renderer);
|
||||
async move {
|
||||
settings_window
|
||||
.run(&wgpu, &egui, &window, &panels, &playlist, &profiles, &renderer)
|
||||
.await;
|
||||
}
|
||||
|
||||
// Spawn the playlist thread
|
||||
// DEADLOCK: See above
|
||||
thread_spawner.spawn("Playlist", || {
|
||||
playlist_runner.run(playlist.run()).into_err();
|
||||
})?;
|
||||
|
||||
// Spawn all image loaders
|
||||
// DEADLOCK: See above
|
||||
for (thread_idx, runner) in image_loader_runners.iter().enumerate() {
|
||||
thread_spawner.spawn(format!("Image Loader${thread_idx}"), || {
|
||||
runner.run(image_loader.run(&playlist)).into_err();
|
||||
})?;
|
||||
});
|
||||
let renderer_task = task::Builder::new().name("Renderer runner").spawn({
|
||||
let wgpu = Arc::clone(&wgpu);
|
||||
let egui = Arc::clone(&egui);
|
||||
let window = Arc::clone(&window);
|
||||
let panels = Arc::clone(&panels);
|
||||
let renderer = Arc::clone(&renderer);
|
||||
let input = Arc::clone(&input);
|
||||
async move {
|
||||
renderer
|
||||
.run(&window, &input, &wgpu, &panels, &egui, &image_loader)
|
||||
.await;
|
||||
}
|
||||
});
|
||||
|
||||
// Spawn the settings window thread
|
||||
// DEADLOCK: See above
|
||||
thread_spawner.spawn("Settings window", || {
|
||||
settings_window_runner
|
||||
.run(settings_window.run(&wgpu, &egui, &window, &panels, &playlist, &profiles, &renderer))
|
||||
.into_err();
|
||||
})?;
|
||||
// Run the event loop until exit
|
||||
event_loop.run_return(|event, _, control_flow| {
|
||||
event_handler
|
||||
.handle_event(&wgpu, &egui, &settings_window, &input, event, control_flow)
|
||||
.block_on();
|
||||
});
|
||||
|
||||
// Spawn the renderer thread
|
||||
// DEADLOCK: See above
|
||||
thread_spawner.spawn("Renderer", || {
|
||||
renderer_runner
|
||||
.run(renderer.run(&window, &input, &wgpu, &panels, &egui, &image_loader))
|
||||
.into_err();
|
||||
})?;
|
||||
// Then join all tasks
|
||||
let _ = profiles_loader_task
|
||||
.await
|
||||
.transpose()
|
||||
.context("Unable to await for profiles loader runner")?;
|
||||
playlist_task.await.context("Unable to await for playlist runner")?;
|
||||
for task in image_loader_tasks {
|
||||
task.await.context("Unable to wait for image loader runner")?;
|
||||
}
|
||||
settings_window_task
|
||||
.await
|
||||
.context("Unable to await for settings window runner")?;
|
||||
renderer_task.await.context("Unable to await for renderer runner")?;
|
||||
|
||||
// Run event loop in this thread until we quit
|
||||
// DEADLOCK: `run_return` exits once the user requests it.
|
||||
// See above
|
||||
// Note: Doesn't make sense to use a runner here, since nothing will call `stop`.
|
||||
event_loop.run_return(|event, _, control_flow| {
|
||||
event_handler
|
||||
.handle_event(&wgpu, &egui, &settings_window, &input, event, control_flow)
|
||||
.block_on();
|
||||
});
|
||||
|
||||
// Note: In release builds, once we get here, we can just exit,
|
||||
// no need to make the user wait for shutdown code.
|
||||
#[cfg(not(debug_assertions))]
|
||||
std::process::exit(0);
|
||||
|
||||
// Stop all runners at the end
|
||||
// Note: Order doesn't matter, as they don't block
|
||||
playlist_runner.stop();
|
||||
image_loader_runners.iter().for_each(FutureRunner::stop);
|
||||
settings_window_runner.stop();
|
||||
renderer_runner.stop();
|
||||
|
||||
// Then join all threads
|
||||
thread_spawner.join_all().context("Unable to join all threads")?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates the window, as well as the associated event loop
|
||||
|
||||
@ -28,7 +28,7 @@ impl EventHandler {
|
||||
// TODO: Inverse dependencies of `settings_window` and `panels` and let them depend on us
|
||||
pub async fn handle_event<'window, 'egui>(
|
||||
&mut self,
|
||||
wgpu: &Wgpu<'_>,
|
||||
wgpu: &Wgpu,
|
||||
egui: &'egui Egui,
|
||||
settings_window: &SettingsWindow,
|
||||
input: &Input,
|
||||
|
||||
@ -76,7 +76,18 @@ mod logger;
|
||||
pub use self::args::Args;
|
||||
|
||||
// Imports
|
||||
use {anyhow::Context, clap::StructOpt};
|
||||
use {
|
||||
anyhow::Context,
|
||||
clap::StructOpt,
|
||||
std::{
|
||||
num::NonZeroUsize,
|
||||
sync::{
|
||||
atomic::{self, AtomicUsize},
|
||||
Arc,
|
||||
},
|
||||
thread,
|
||||
},
|
||||
};
|
||||
|
||||
fn main() -> Result<(), anyhow::Error> {
|
||||
// Initialize logger
|
||||
@ -85,9 +96,9 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
Err(err) => eprintln!("Unable to initialize logger: {err:?}"),
|
||||
}
|
||||
|
||||
// Initialize the deadlock detection
|
||||
#[cfg(debug_assertions)]
|
||||
self::deadlock_init();
|
||||
// Initialize the tokio console subscriber if given the feature
|
||||
#[cfg(feature = "tokio-console")]
|
||||
console_subscriber::init();
|
||||
|
||||
// Customize the rayon pool thread
|
||||
// Note: This is used indirectly in `image` by `jpeg-decoder`
|
||||
@ -98,7 +109,7 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
|
||||
// Get arguments
|
||||
let args = match Args::try_parse() {
|
||||
Ok(args) => args,
|
||||
Ok(args) => Arc::new(args),
|
||||
Err(err) => {
|
||||
log::warn!("Unable to retrieve arguments: {err:?}");
|
||||
err.exit();
|
||||
@ -106,10 +117,23 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
};
|
||||
log::debug!("Arguments: {args:#?}");
|
||||
|
||||
// Create the runtime and enter it
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
.worker_threads(2 * thread::available_parallelism().map_or(1, NonZeroUsize::get)) // TODO: Adjust?
|
||||
.enable_time()
|
||||
.thread_name_fn(|| {
|
||||
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
let id = NEXT_ID.fetch_add(1, atomic::Ordering::AcqRel);
|
||||
format!("tokio-runtime-{}", id)
|
||||
})
|
||||
.build()
|
||||
.context("Unable to create runtime")?;
|
||||
let _runtime_enter = runtime.enter();
|
||||
|
||||
// Run the app and restart if we get an error (up to 5 errors)
|
||||
let mut errors = 0;
|
||||
while errors < 5 {
|
||||
match app::run(&args) {
|
||||
match runtime.block_on(app::run(Arc::clone(&args))) {
|
||||
Ok(()) => {
|
||||
log::info!("Application finished");
|
||||
break;
|
||||
@ -124,34 +148,3 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initializes deadlock detection
|
||||
#[cfg(debug_assertions)]
|
||||
fn deadlock_init() {
|
||||
// Create a background thread which checks for deadlocks every 10s
|
||||
#[allow(clippy::let_underscore_drop)] // We want to detach the thread
|
||||
let _ = std::thread::Builder::new()
|
||||
.name("Deadlock detection".to_owned())
|
||||
.spawn(move || loop {
|
||||
// Sleep so we aren't continuously checking
|
||||
std::thread::sleep(std::time::Duration::from_secs(10));
|
||||
|
||||
// Then check if we have any and continue if we don't
|
||||
log::debug!("Checking for deadlocks");
|
||||
let deadlocks = parking_lot::deadlock::check_deadlock();
|
||||
if deadlocks.is_empty() {
|
||||
log::debug!("Found no deadlocks");
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we do, log them
|
||||
log::warn!("Detected {} deadlocks", deadlocks.len());
|
||||
for (idx, threads) in deadlocks.iter().enumerate() {
|
||||
log::warn!("Deadlock #{idx}");
|
||||
for thread in threads {
|
||||
log::warn!("\tThread Id {:#?}", thread.thread_id());
|
||||
log::warn!("\tBacktrace: {:#?}", thread.backtrace());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user