update gtk and relm version to 0.9
This commit is contained in:
parent
a07acecea2
commit
57c24a1de8
535
Cargo.lock
generated
535
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
10
Cargo.toml
@ -9,7 +9,7 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
cairo-rs = { version = "0.17.0" }
|
cairo-rs = { version = "0.17.0" }
|
||||||
# glib = "0.17.9"
|
# glib = "0.17.9"
|
||||||
gtk = { version = "0.8.1", package = "gtk4", features = ["v4_12"] }
|
gtk = { version = "0.9", package = "gtk4", features = ["v4_14"] }
|
||||||
geo-types = "0.7.9"
|
geo-types = "0.7.9"
|
||||||
shapefile = { version = "0.4", features = ["geo-types"] }
|
shapefile = { version = "0.4", features = ["geo-types"] }
|
||||||
thiserror = "1.0.40"
|
thiserror = "1.0.40"
|
||||||
@ -28,8 +28,8 @@ glow = "0.13.1"
|
|||||||
proj = "0.27.2"
|
proj = "0.27.2"
|
||||||
image = "0.24.7"
|
image = "0.24.7"
|
||||||
anyhow = "1.0.72"
|
anyhow = "1.0.72"
|
||||||
relm4 = { version = "0.8.1", features = ["libadwaita"] }
|
relm4 = { version = "0.9", features = ["libadwaita"] }
|
||||||
relm4-components = "0.8.1"
|
relm4-components = "0.9"
|
||||||
rstar = "*"
|
rstar = "*"
|
||||||
geo = "0.26.0"
|
geo = "0.26.0"
|
||||||
topojson = "0.5.1"
|
topojson = "0.5.1"
|
||||||
@ -43,7 +43,7 @@ tokio = { version = "1.36.0", features = ["full"] }
|
|||||||
async-trait = "0.1.77"
|
async-trait = "0.1.77"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
once_cell = "1.19.0"
|
once_cell = "1.19.0"
|
||||||
relm4-icons = { version = "0.8.2" }
|
relm4-icons = { version = "0.9" }
|
||||||
surfman = "0.8.1"
|
surfman = "0.8.1"
|
||||||
euclid = "0.22.9"
|
euclid = "0.22.9"
|
||||||
gl = "0.14.0"
|
gl = "0.14.0"
|
||||||
@ -88,5 +88,5 @@ path = "radarg_plugin_interface"
|
|||||||
|
|
||||||
[dependencies.adw]
|
[dependencies.adw]
|
||||||
package = "libadwaita"
|
package = "libadwaita"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
features = ["v1_4"]
|
features = ["v1_4"]
|
||||||
|
|||||||
194
etws_loader/Cargo.lock
generated
194
etws_loader/Cargo.lock
generated
@ -56,6 +56,24 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.8.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allocator-api2"
|
||||||
|
version = "0.2.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android-tzdata"
|
name = "android-tzdata"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -77,6 +95,15 @@ version = "1.0.79"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "approx"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "as_derive_utils"
|
name = "as_derive_utils"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@ -194,6 +221,22 @@ version = "0.8.19"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "earcutr"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79127ed59a85d7687c409e9978547cffb7dc79675355ed22da6b66fd5f6ead01"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "etws_loader"
|
name = "etws_loader"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -203,6 +246,7 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
"chrono",
|
"chrono",
|
||||||
"flate2",
|
"flate2",
|
||||||
|
"geo",
|
||||||
"nom",
|
"nom",
|
||||||
"nom-derive",
|
"nom-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@ -222,6 +266,12 @@ dependencies = [
|
|||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "float_next_after"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generational-arena"
|
name = "generational-arena"
|
||||||
version = "0.2.9"
|
version = "0.2.9"
|
||||||
@ -231,6 +281,73 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "geo"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f811f663912a69249fa620dcd2a005db7254529da2d8a0b23942e81f47084501"
|
||||||
|
dependencies = [
|
||||||
|
"earcutr",
|
||||||
|
"float_next_after",
|
||||||
|
"geo-types",
|
||||||
|
"geographiclib-rs",
|
||||||
|
"log",
|
||||||
|
"num-traits",
|
||||||
|
"robust",
|
||||||
|
"rstar",
|
||||||
|
"spade",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "geo-types"
|
||||||
|
version = "0.7.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ff16065e5720f376fbced200a5ae0f47ace85fd70b7e54269790281353b6d61"
|
||||||
|
dependencies = [
|
||||||
|
"approx",
|
||||||
|
"num-traits",
|
||||||
|
"rstar",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "geographiclib-rs"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e5ed84f8089c70234b0a8e0aedb6dc733671612ddc0d37c6066052f9781960"
|
||||||
|
dependencies = [
|
||||||
|
"libm",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hash32"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"allocator-api2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heapless"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
|
||||||
|
dependencies = [
|
||||||
|
"hash32",
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.59"
|
version = "0.1.59"
|
||||||
@ -254,6 +371,15 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
@ -285,6 +411,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libm"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.11"
|
version = "0.4.11"
|
||||||
@ -361,6 +493,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
|
"libm",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -441,6 +574,23 @@ dependencies = [
|
|||||||
"tstr",
|
"tstr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "robust"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbf4a6aa5f6d6888f39e980649f3ad6b666acdce1d78e95b8a2cb076e687ae30"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rstar"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "133315eb94c7b1e8d0cb097e5a710d850263372fd028fff18969de708afc7008"
|
||||||
|
dependencies = [
|
||||||
|
"heapless",
|
||||||
|
"num-traits",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -511,6 +661,24 @@ version = "1.13.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spade"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61addf9117b11d1f5b4bf6fe94242ba25f59d2d4b2080544b771bd647024fd00"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
|
"num-traits",
|
||||||
|
"robust",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
@ -580,6 +748,12 @@ version = "1.0.12"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.90"
|
version = "0.2.90"
|
||||||
@ -778,3 +952,23 @@ name = "windows_x86_64_msvc"
|
|||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.7.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.7.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.48",
|
||||||
|
]
|
||||||
|
|||||||
@ -10,6 +10,7 @@ anyhow = "1.0.79"
|
|||||||
byteorder = "1.5.0"
|
byteorder = "1.5.0"
|
||||||
chrono = {version="0.4.33", features=["serde"]}
|
chrono = {version="0.4.33", features=["serde"]}
|
||||||
flate2 = "1.0.28"
|
flate2 = "1.0.28"
|
||||||
|
geo = "0.28.0"
|
||||||
nom = "7.1.3"
|
nom = "7.1.3"
|
||||||
nom-derive = "0.10.1"
|
nom-derive = "0.10.1"
|
||||||
num-traits = "0.2.17"
|
num-traits = "0.2.17"
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
mod error;
|
mod error;
|
||||||
|
use geo::{algorithm::haversine_destination::HaversineDestination, Point};
|
||||||
mod parser;
|
mod parser;
|
||||||
use abi_stable::{
|
use abi_stable::{
|
||||||
export_root_module,
|
export_root_module,
|
||||||
@ -14,7 +15,7 @@ use abi_stable::{
|
|||||||
};
|
};
|
||||||
use parser::{Record, ValueResult};
|
use parser::{Record, ValueResult};
|
||||||
use radarg_plugin_interface::{
|
use radarg_plugin_interface::{
|
||||||
CoordType, Error, MetaData, Plugin, PluginId, PluginMod, PluginMod_Ref, PluginResult,
|
CoordType, Error, Loc3, MetaData, Plugin, PluginId, PluginMod, PluginMod_Ref, PluginResult,
|
||||||
PluginResultType, PluginType, Plugin_TO,
|
PluginResultType, PluginType, Plugin_TO,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,6 +28,23 @@ struct ETWSLoader {
|
|||||||
id: PluginId,
|
id: PluginId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calculate_coverage(lat_deg: f64, lon_deg: f64, radius_km: f64) -> (f64, f64, f64, f64) {
|
||||||
|
let center = Point::new(lon_deg, lat_deg);
|
||||||
|
|
||||||
|
// 计算四个方向(北、南、东、西)的点
|
||||||
|
let north = center.haversine_destination(0.0, radius_km);
|
||||||
|
let south = center.haversine_destination(180.0, radius_km);
|
||||||
|
let east = center.haversine_destination(90.0, radius_km);
|
||||||
|
let west = center.haversine_destination(270.0, radius_km);
|
||||||
|
|
||||||
|
let min_lat = south.y();
|
||||||
|
let max_lat = north.y();
|
||||||
|
let min_lon = west.x();
|
||||||
|
let max_lon = east.x();
|
||||||
|
|
||||||
|
(min_lat, max_lat, min_lon, max_lon)
|
||||||
|
}
|
||||||
|
|
||||||
impl Plugin for ETWSLoader {
|
impl Plugin for ETWSLoader {
|
||||||
fn plugin_id(&self) -> &PluginId {
|
fn plugin_id(&self) -> &PluginId {
|
||||||
&self.id
|
&self.id
|
||||||
@ -80,33 +98,55 @@ impl Plugin for ETWSLoader {
|
|||||||
};
|
};
|
||||||
let dimension_des = b.info.dimension_des;
|
let dimension_des = b.info.dimension_des;
|
||||||
let c = if dimension_des.contains(&format!("lat")) {
|
let c = if dimension_des.contains(&format!("lat")) {
|
||||||
|
let len = b.info.dimension_values.len();
|
||||||
|
|
||||||
|
let lon = b.info.dimension_values.get(len - 1).unwrap();
|
||||||
|
let lat = b.info.dimension_values.get(len - 2).unwrap();
|
||||||
|
|
||||||
|
lon_range = [lon[0], lon[lon.len() - 1]];
|
||||||
|
lat_range = [lat[0], lat[lat.len() - 1]];
|
||||||
|
|
||||||
CoordType::Cartesian
|
CoordType::Cartesian
|
||||||
} else if dimension_des.contains(&format!("ele"))
|
} else if dimension_des.contains(&format!("ele"))
|
||||||
|
|| dimension_des.contains(&format!("el"))
|
||||||
|| dimension_des.contains(&format!("elevation"))
|
|| dimension_des.contains(&format!("elevation"))
|
||||||
{
|
{
|
||||||
CoordType::Polar
|
let (min_lat, max_lat, min_lon, max_lon) = calculate_coverage(
|
||||||
|
b.info.radar_lat.unwrap(),
|
||||||
|
b.info.radar_lon.unwrap(),
|
||||||
|
b.info.dimension_end[2],
|
||||||
|
);
|
||||||
|
|
||||||
|
lon_range = [min_lon, max_lon];
|
||||||
|
lat_range = [min_lat, max_lat];
|
||||||
|
CoordType::Polar(
|
||||||
|
Loc3 {
|
||||||
|
x: b.info.radar_lon.unwrap(),
|
||||||
|
y: b.info.radar_lat.unwrap(),
|
||||||
|
z: b.info.radar_alt.unwrap(),
|
||||||
|
},
|
||||||
|
b.info.dimension_end[2],
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
CoordType::Other
|
CoordType::Other
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let shape = match b.info.dimension_size.len() {
|
let shape = match b.info.dimension_size.len() {
|
||||||
1 => radarg_plugin_interface::DataShape::Vector,
|
1 => radarg_plugin_interface::DataShape::Vector,
|
||||||
2 => {
|
2 => {
|
||||||
let lat = b.info.dimension_values.get(0).unwrap();
|
// let lat = b.info.dimension_values.get(0).unwrap();
|
||||||
let lon = b.info.dimension_values.get(1).unwrap();
|
// let lon = b.info.dimension_values.get(1).unwrap();
|
||||||
lat_range = [lat[0], lat[lat.len() - 1]];
|
// lat_range = [lat[0], lat[lat.len() - 1]];
|
||||||
lon_range = [lon[0], lon[lon.len() - 1]];
|
// lon_range = [lon[0], lon[lon.len() - 1]];
|
||||||
radarg_plugin_interface::DataShape::Matrix
|
radarg_plugin_interface::DataShape::Matrix
|
||||||
},
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let lat = b.info.dimension_values.get(1).unwrap();
|
// let lat = b.info.dimension_values.get(1).unwrap();
|
||||||
let lon = b.info.dimension_values.get(2).unwrap();
|
// let lon = b.info.dimension_values.get(2).unwrap();
|
||||||
lat_range = [lat[0], lat[lat.len() - 1]];
|
// lat_range = [lat[0], lat[lat.len() - 1]];
|
||||||
lon_range = [lon[0], lon[lon.len() - 1]];
|
// lon_range = [lon[0], lon[lon.len() - 1]];
|
||||||
radarg_plugin_interface::DataShape::Cube
|
radarg_plugin_interface::DataShape::Cube
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let data_type = match b.info.value_name.as_str() {
|
let data_type = match b.info.value_name.as_str() {
|
||||||
@ -197,7 +237,7 @@ mod tests {
|
|||||||
|
|
||||||
fn test() {
|
fn test() {
|
||||||
let result =
|
let result =
|
||||||
Record::parse_from_path("/Volumes/data2/RadarArray/HangZhou/radarData/OutputProducts/RadarProducts/FuseDataX/20220727/ZJHZAA_20220727200000_FR.dat.gz")
|
Record::parse_from_path("/Volumes/data2/RadarArray/ShaoXing/radarData/OutputProducts/RadarProducts/BasicProductsX/20230627/20230627163400/ZJSXAA_20230627163400_VIL.dat.gz")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -364,237 +364,13 @@ pub struct BlockJsonInfo {
|
|||||||
pub fill_value: f64,
|
pub fill_value: f64,
|
||||||
pub value_scale: f32,
|
pub value_scale: f32,
|
||||||
pub value_offset: f32,
|
pub value_offset: f32,
|
||||||
|
pub radar_alt: Option<f64>,
|
||||||
|
pub radar_lat: Option<f64>,
|
||||||
|
pub radar_lon: Option<f64>,
|
||||||
|
pub radar_name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ParsedBlock {
|
pub struct ParsedBlock {
|
||||||
pub info: BlockJsonInfo,
|
pub info: BlockJsonInfo,
|
||||||
pub data: ValueResult,
|
pub data: ValueResult,
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn _parse_matrix(
|
|
||||||
// input: &[u8],
|
|
||||||
// type_: ValueTypes,
|
|
||||||
// order: Order,
|
|
||||||
// len: usize,
|
|
||||||
// offset: f32,
|
|
||||||
// scale: f32,
|
|
||||||
// fill_value: f64,
|
|
||||||
// ) -> IResult<&[u8], ValueResult> {
|
|
||||||
// use std::mem;
|
|
||||||
// let need_trans = offset != 0.0 || scale != 1.0;
|
|
||||||
// let trans_to_bigger = offset.trunc() != offset || scale != 1.0;
|
|
||||||
// match type_ {
|
|
||||||
// ValueTypes::I64 => {
|
|
||||||
// let ratio = mem::size_of::<i64>() / mem::size_of::<u8>();
|
|
||||||
// let (input, result) = take(len * ratio)(input)?;
|
|
||||||
// let result = unsafe {
|
|
||||||
// let ptr = result.as_ptr() as *const i64;
|
|
||||||
// let slice = std::slice::from_raw_parts(ptr, len);
|
|
||||||
// let slice = slice.to_vec();
|
|
||||||
|
|
||||||
// if trans_to_bigger {
|
|
||||||
// let offset = offset as f32;
|
|
||||||
// ValueResult::F32(
|
|
||||||
// slice
|
|
||||||
// .into_iter()
|
|
||||||
// .map(|p| (p as f32 - offset) / scale)
|
|
||||||
// .collect::<Vec<f32>>(),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// ValueResult::I64(if need_trans {
|
|
||||||
// let offset = offset as i64;
|
|
||||||
// slice.into_iter().map(|p| p - offset).collect::<Vec<i64>>()
|
|
||||||
// } else {
|
|
||||||
// slice
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok((input, result))
|
|
||||||
// }
|
|
||||||
// ValueTypes::F64 => {
|
|
||||||
// let ratio = mem::size_of::<f64>() / mem::size_of::<u8>();
|
|
||||||
// let (input, result) = take(len * ratio)(input)?;
|
|
||||||
// let result = unsafe {
|
|
||||||
// let ptr = result.as_ptr() as *const f64;
|
|
||||||
// let slice = std::slice::from_raw_parts(ptr, len);
|
|
||||||
// let slice = slice.to_vec();
|
|
||||||
|
|
||||||
// ValueResult::F64(if need_trans {
|
|
||||||
// let offset = offset as f64;
|
|
||||||
// slice
|
|
||||||
// .into_iter()
|
|
||||||
// .map(|p| (p - offset) / scale as f64)
|
|
||||||
// .collect::<Vec<f64>>()
|
|
||||||
// } else {
|
|
||||||
// slice
|
|
||||||
// })
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok((input, result))
|
|
||||||
// }
|
|
||||||
// ValueTypes::I32 => {
|
|
||||||
// let ratio = mem::size_of::<i32>() / mem::size_of::<u8>();
|
|
||||||
// let (input, result) = take(len * ratio)(input)?;
|
|
||||||
// let result = unsafe {
|
|
||||||
// let ptr = result.as_ptr() as *const i32;
|
|
||||||
// let slice = std::slice::from_raw_parts(ptr, len);
|
|
||||||
// let slice = slice.to_vec();
|
|
||||||
|
|
||||||
// if trans_to_bigger {
|
|
||||||
// let offset = offset as f32;
|
|
||||||
// ValueResult::F32(
|
|
||||||
// slice
|
|
||||||
// .into_iter()
|
|
||||||
// .map(|p| (p as f32 - offset) / scale)
|
|
||||||
// .collect::<Vec<f32>>(),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// ValueResult::I32(if need_trans {
|
|
||||||
// let offset = offset as i32;
|
|
||||||
// slice.into_iter().map(|p| p - offset).collect::<Vec<i32>>()
|
|
||||||
// } else {
|
|
||||||
// slice
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok((input, result))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ValueTypes::U32 => {
|
|
||||||
// let ratio = mem::size_of::<u32>() / mem::size_of::<u8>();
|
|
||||||
// let (input, result) = take(len * ratio)(input)?;
|
|
||||||
// let result = unsafe {
|
|
||||||
// let ptr = result.as_ptr() as *const u32;
|
|
||||||
// let slice = std::slice::from_raw_parts(ptr, len);
|
|
||||||
// let slice = slice.to_vec();
|
|
||||||
|
|
||||||
// if trans_to_bigger {
|
|
||||||
// let offset = offset as f32;
|
|
||||||
// ValueResult::F32(
|
|
||||||
// slice
|
|
||||||
// .into_iter()
|
|
||||||
// .map(|p| (p as f32 - offset) / scale)
|
|
||||||
// .collect::<Vec<f32>>(),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// ValueResult::U32(if need_trans {
|
|
||||||
// let offset = offset as u32;
|
|
||||||
// slice.into_iter().map(|p| p - offset).collect::<Vec<u32>>()
|
|
||||||
// } else {
|
|
||||||
// slice
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok((input, result))
|
|
||||||
// }
|
|
||||||
// ValueTypes::F32 => {
|
|
||||||
// let ratio = mem::size_of::<f32>() / mem::size_of::<u8>();
|
|
||||||
// let (input, result) = take(len * ratio)(input)?;
|
|
||||||
// let result = unsafe {
|
|
||||||
// let ptr = result.as_ptr() as *const f32;
|
|
||||||
// let slice = std::slice::from_raw_parts(ptr, len);
|
|
||||||
// let slice = slice.to_vec();
|
|
||||||
|
|
||||||
// ValueResult::F32(if need_trans {
|
|
||||||
// let offset = offset as f32;
|
|
||||||
// slice
|
|
||||||
// .into_iter()
|
|
||||||
// .map(|p| (p - offset) / scale)
|
|
||||||
// .collect::<Vec<f32>>()
|
|
||||||
// } else {
|
|
||||||
// slice
|
|
||||||
// })
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok((input, result))
|
|
||||||
// }
|
|
||||||
// ValueTypes::U64 => {
|
|
||||||
// let ratio = mem::size_of::<u64>() / mem::size_of::<u8>();
|
|
||||||
// let (input, result) = take(len * ratio)(input)?;
|
|
||||||
// let result = unsafe {
|
|
||||||
// let ptr = result.as_ptr() as *const u64;
|
|
||||||
// let slice = std::slice::from_raw_parts(ptr, len);
|
|
||||||
// let slice = slice.to_vec();
|
|
||||||
|
|
||||||
// if trans_to_bigger {
|
|
||||||
// let offset = offset as f64;
|
|
||||||
// let scale = scale as f64;
|
|
||||||
// ValueResult::F64(
|
|
||||||
// slice
|
|
||||||
// .into_iter()
|
|
||||||
// .map(|p| (p as f64 - offset) / scale)
|
|
||||||
// .collect::<Vec<f64>>(),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// ValueResult::U64(if need_trans {
|
|
||||||
// let offset = offset as u64;
|
|
||||||
// slice.into_iter().map(|p| p - offset).collect::<Vec<u64>>()
|
|
||||||
// } else {
|
|
||||||
// slice
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok((input, result))
|
|
||||||
// }
|
|
||||||
// ValueTypes::I8 => {
|
|
||||||
// let (input, result) = take(len)(input)?;
|
|
||||||
// let result = unsafe {
|
|
||||||
// let ptr = result.as_ptr() as *const i8;
|
|
||||||
// let slice = std::slice::from_raw_parts(ptr, len);
|
|
||||||
|
|
||||||
// let slice = slice.to_vec();
|
|
||||||
|
|
||||||
// if trans_to_bigger {
|
|
||||||
// let offset = offset as f32;
|
|
||||||
// ValueResult::F32(
|
|
||||||
// slice
|
|
||||||
// .into_iter()
|
|
||||||
// .map(|p| (p as f32 - offset) / scale)
|
|
||||||
// .collect::<Vec<f32>>(),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// ValueResult::I8(if need_trans {
|
|
||||||
// let offset = offset as i8;
|
|
||||||
// slice.into_iter().map(|p| p - offset).collect::<Vec<i8>>()
|
|
||||||
// } else {
|
|
||||||
// slice
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// Ok((input, result))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ValueTypes::U8 => {
|
|
||||||
// let (input, slice) = take(len)(input)?;
|
|
||||||
// let slice = slice.to_vec();
|
|
||||||
// let result = if trans_to_bigger {
|
|
||||||
// let offset = offset as f32;
|
|
||||||
// ValueResult::F32(
|
|
||||||
// slice
|
|
||||||
// .into_iter()
|
|
||||||
// .map(|p| {
|
|
||||||
// if p as f64 != fill_value {
|
|
||||||
// (p as f32 - offset) / scale
|
|
||||||
// } else {
|
|
||||||
// p as f32
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .collect::<Vec<f32>>(),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// ValueResult::U8(if need_trans {
|
|
||||||
// let offset = offset as u8;
|
|
||||||
// slice.into_iter().map(|p| p - offset).collect::<Vec<u8>>()
|
|
||||||
// } else {
|
|
||||||
// slice
|
|
||||||
// })
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok((input, result))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
{"rustc_fingerprint":6534886339914138005,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.77.0-nightly (d78329b92 2024-01-13)\nbinary: rustc\ncommit-hash: d78329b92e8d141d19505e7c1527181c4ab87ed4\ncommit-date: 2024-01-13\nhost: aarch64-apple-darwin\nrelease: 1.77.0-nightly\nLLVM version: 17.0.6\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/tsuki/.rustup/toolchains/nightly-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"v8.1a\"\ntarget_feature=\"v8.2a\"\ntarget_feature=\"v8.3a\"\ntarget_feature=\"v8.4a\"\ntarget_feature=\"vh\"\ntarget_has_atomic\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"128\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"128\"\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"apple\"\nunix\n","stderr":""}},"successes":{}}
|
{"rustc_fingerprint":7112235087551312656,"outputs":{"16495917692426387086":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/tsuki/.rustup/toolchains/nightly-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"v8.1a\"\ntarget_feature=\"v8.2a\"\ntarget_feature=\"v8.3a\"\ntarget_feature=\"v8.4a\"\ntarget_feature=\"vh\"\ntarget_has_atomic\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"128\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"128\"\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"apple\"\nub_checks\nunix\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.80.0-nightly (867900499 2024-05-23)\nbinary: rustc\ncommit-hash: 8679004993f08807289911d9f400f4ac4391d2bc\ncommit-date: 2024-05-23\nhost: aarch64-apple-darwin\nrelease: 1.80.0-nightly\nLLVM version: 18.1.6\n","stderr":""}},"successes":{}}
|
||||||
@ -1 +1 @@
|
|||||||
16f3840281ed1c0f
|
498af0718dbbcb83
|
||||||
@ -1 +1 @@
|
|||||||
{"rustc":17942353898403517573,"features":"[]","declared_features":"","target":8454914719411586997,"profile":14094339167972473758,"path":17523903030608720598,"deps":[[3470807962260834726,"serde",false,3464438898850424389],[6147374319788932929,"serde_json",false,4018346002534341099],[6644485573429891122,"thiserror",false,15376366722783231122],[6954241390595330609,"nom",false,17004332135801955629],[8926101378076943148,"byteorder",false,6029042559770906212],[8944703748776155531,"chrono",false,14085117952510397354],[10043922549268360936,"radarg_plugin_interface",false,2929903515477199145],[11138931377059941435,"num_traits",false,16208028648554347177],[12701726091060201577,"abi_stable",false,46919867052192855],[12732307821348191974,"anyhow",false,13132421988549874417],[12935855096716563853,"flate2",false,9880693184163145737],[16098302879908240583,"nom_derive",false,9783335926581460414]],"local":[{"CheckDepInfo":{"dep_info":"release/.fingerprint/etws_loader-826e392dbec97b5d/dep-lib-etws_loader"}}],"rustflags":[],"metadata":41698518999418921,"config":2202906307356721367,"compile_kind":0}
|
{"rustc":17942353898403517573,"features":"[]","declared_features":"","target":8454914719411586997,"profile":14094339167972473758,"path":17523903030608720598,"deps":[[3470807962260834726,"serde",false,3464438898850424389],[6147374319788932929,"serde_json",false,4018346002534341099],[6644485573429891122,"thiserror",false,15376366722783231122],[6954241390595330609,"nom",false,17004332135801955629],[8926101378076943148,"byteorder",false,6029042559770906212],[8944703748776155531,"chrono",false,1826932702640569830],[10043922549268360936,"radarg_plugin_interface",false,2929903515477199145],[11138931377059941435,"num_traits",false,4243888007213205890],[11576086755270729966,"geo",false,13469853973119584516],[12701726091060201577,"abi_stable",false,46919867052192855],[12732307821348191974,"anyhow",false,13132421988549874417],[12935855096716563853,"flate2",false,9880693184163145737],[16098302879908240583,"nom_derive",false,9783335926581460414]],"local":[{"CheckDepInfo":{"dep_info":"release/.fingerprint/etws_loader-826e392dbec97b5d/dep-lib-etws_loader"}}],"rustflags":[],"metadata":41698518999418921,"config":2202906307356721367,"compile_kind":0}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{"$message_type":"diagnostic","message":"unused imports: `Write`, `self`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":323,"byte_end":327,"line_start":13,"line_end":13,"column_start":15,"column_end":19,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":15,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/parser.rs","byte_start":335,"byte_end":340,"line_start":13,"line_end":13,"column_start":27,"column_end":32,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":27,"highlight_end":32}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_imports)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"remove the unused imports","code":null,"level":"help","spans":[{"file_name":"src/parser.rs","byte_start":323,"byte_end":329,"line_start":13,"line_end":13,"column_start":15,"column_end":21,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":15,"highlight_end":21}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"src/parser.rs","byte_start":333,"byte_end":340,"line_start":13,"line_end":13,"column_start":25,"column_end":32,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":25,"highlight_end":32}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused imports: `Write`, `self`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:13:15\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m13\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0muse std::io::{self, Read, Write};\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(unused_imports)]` on by default\u001b[0m\n\n"}
|
{"$message_type":"diagnostic","message":"unused imports: `Write`, `self`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":323,"byte_end":327,"line_start":13,"line_end":13,"column_start":15,"column_end":19,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":15,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/parser.rs","byte_start":335,"byte_end":340,"line_start":13,"line_end":13,"column_start":27,"column_end":32,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":27,"highlight_end":32}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_imports)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"remove the unused imports","code":null,"level":"help","spans":[{"file_name":"src/parser.rs","byte_start":323,"byte_end":329,"line_start":13,"line_end":13,"column_start":15,"column_end":21,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":15,"highlight_end":21}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"src/parser.rs","byte_start":333,"byte_end":340,"line_start":13,"line_end":13,"column_start":25,"column_end":32,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":25,"highlight_end":32}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused imports: `Write`, `self`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:13:15\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m13\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0muse std::io::{self, Read, Write};\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(unused_imports)]` on by default\u001b[0m\n\n"}
|
||||||
{"$message_type":"diagnostic","message":"unused variable: `hlen2`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":6651,"byte_end":6656,"line_start":198,"line_end":198,"column_start":21,"column_end":26,"is_primary":true,"text":[{"text":" let (input, hlen2) = Self::_parse_u32(input, order)?;","highlight_start":21,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_variables)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/parser.rs","byte_start":6651,"byte_end":6656,"line_start":198,"line_end":198,"column_start":21,"column_end":26,"is_primary":true,"text":[{"text":" let (input, hlen2) = Self::_parse_u32(input, order)?;","highlight_start":21,"highlight_end":26}],"label":null,"suggested_replacement":"_hlen2","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `hlen2`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:198:21\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m198\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let (input, hlen2) = Self::_parse_u32(input, order)?;\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_hlen2`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(unused_variables)]` on by default\u001b[0m\n\n"}
|
{"$message_type":"diagnostic","message":"unused variable: `hlen2`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":6651,"byte_end":6656,"line_start":198,"line_end":198,"column_start":21,"column_end":26,"is_primary":true,"text":[{"text":" let (input, hlen2) = Self::_parse_u32(input, order)?;","highlight_start":21,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_variables)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/parser.rs","byte_start":6651,"byte_end":6656,"line_start":198,"line_end":198,"column_start":21,"column_end":26,"is_primary":true,"text":[{"text":" let (input, hlen2) = Self::_parse_u32(input, order)?;","highlight_start":21,"highlight_end":26}],"label":null,"suggested_replacement":"_hlen2","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `hlen2`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:198:21\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m198\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let (input, hlen2) = Self::_parse_u32(input, order)?;\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_hlen2`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(unused_variables)]` on by default\u001b[0m\n\n"}
|
||||||
{"$message_type":"diagnostic","message":"unused variable: `order`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":9035,"byte_end":9040,"line_start":279,"line_end":279,"column_start":9,"column_end":14,"is_primary":true,"text":[{"text":" order: Order,","highlight_start":9,"highlight_end":14}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/parser.rs","byte_start":9035,"byte_end":9040,"line_start":279,"line_end":279,"column_start":9,"column_end":14,"is_primary":true,"text":[{"text":" order: Order,","highlight_start":9,"highlight_end":14}],"label":null,"suggested_replacement":"_order","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `order`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:279:9\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m279\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m order: Order,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_order`\u001b[0m\n\n"}
|
{"$message_type":"diagnostic","message":"unused variable: `order`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":9035,"byte_end":9040,"line_start":279,"line_end":279,"column_start":9,"column_end":14,"is_primary":true,"text":[{"text":" order: Order,","highlight_start":9,"highlight_end":14}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/parser.rs","byte_start":9035,"byte_end":9040,"line_start":279,"line_end":279,"column_start":9,"column_end":14,"is_primary":true,"text":[{"text":" order: Order,","highlight_start":9,"highlight_end":14}],"label":null,"suggested_replacement":"_order","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `order`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:279:9\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m279\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m order: Order,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_order`\u001b[0m\n\n"}
|
||||||
{"$message_type":"diagnostic","message":"unused variable: `dimension_len`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/lib.rs","byte_start":1109,"byte_end":1122,"line_start":43,"line_end":43,"column_start":26,"column_end":39,"is_primary":true,"text":[{"text":" let (dimension_len, data) = match b.data {","highlight_start":26,"highlight_end":39}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/lib.rs","byte_start":1109,"byte_end":1122,"line_start":43,"line_end":43,"column_start":26,"column_end":39,"is_primary":true,"text":[{"text":" let (dimension_len, data) = match b.data {","highlight_start":26,"highlight_end":39}],"label":null,"suggested_replacement":"_dimension_len","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `dimension_len`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/lib.rs:43:26\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m43\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let (dimension_len, data) = match b.data {\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_dimension_len`\u001b[0m\n\n"}
|
{"$message_type":"diagnostic","message":"unused variable: `dimension_len`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/lib.rs","byte_start":1799,"byte_end":1812,"line_start":61,"line_end":61,"column_start":26,"column_end":39,"is_primary":true,"text":[{"text":" let (dimension_len, data) = match b.data {","highlight_start":26,"highlight_end":39}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/lib.rs","byte_start":1799,"byte_end":1812,"line_start":61,"line_end":61,"column_start":26,"column_end":39,"is_primary":true,"text":[{"text":" let (dimension_len, data) = match b.data {","highlight_start":26,"highlight_end":39}],"label":null,"suggested_replacement":"_dimension_len","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `dimension_len`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/lib.rs:61:26\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m61\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let (dimension_len, data) = match b.data {\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_dimension_len`\u001b[0m\n\n"}
|
||||||
{"$message_type":"diagnostic","message":"variants `I64` and `U64` are never constructed","code":{"code":"dead_code","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":563,"byte_end":573,"line_start":28,"line_end":28,"column_start":6,"column_end":16,"is_primary":false,"text":[{"text":"enum ValueTypes {","highlight_start":6,"highlight_end":16}],"label":"variants in this enum","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/parser.rs","byte_start":580,"byte_end":583,"line_start":29,"line_end":29,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":" I64,","highlight_start":5,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/parser.rs","byte_start":616,"byte_end":619,"line_start":33,"line_end":33,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":" U64,","highlight_start":5,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(dead_code)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: variants `I64` and `U64` are never constructed\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:29:5\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m28\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0menum ValueTypes {\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m----------\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12mvariants in this enum\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m29\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m I64,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m...\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m33\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m U64,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(dead_code)]` on by default\u001b[0m\n\n"}
|
{"$message_type":"diagnostic","message":"variants `I64` and `U64` are never constructed","code":{"code":"dead_code","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":563,"byte_end":573,"line_start":28,"line_end":28,"column_start":6,"column_end":16,"is_primary":false,"text":[{"text":"enum ValueTypes {","highlight_start":6,"highlight_end":16}],"label":"variants in this enum","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/parser.rs","byte_start":580,"byte_end":583,"line_start":29,"line_end":29,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":" I64,","highlight_start":5,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/parser.rs","byte_start":616,"byte_end":619,"line_start":33,"line_end":33,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":" U64,","highlight_start":5,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(dead_code)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: variants `I64` and `U64` are never constructed\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:29:5\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m28\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0menum ValueTypes {\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m----------\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12mvariants in this enum\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m29\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m I64,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m...\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m33\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m U64,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(dead_code)]` on by default\u001b[0m\n\n"}
|
||||||
{"$message_type":"diagnostic","message":"5 warnings emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: 5 warnings emitted\u001b[0m\n\n"}
|
{"$message_type":"diagnostic","message":"5 warnings emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: 5 warnings emitted\u001b[0m\n\n"}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -19,11 +19,22 @@ pub struct PluginId {
|
|||||||
pub instance: u64,
|
pub instance: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, StableAbi, Copy)]
|
||||||
|
#[sabi(impl_InterfaceType(Sync, Send, Debug, Debug))]
|
||||||
|
pub struct Loc3 {
|
||||||
|
pub x: f64,
|
||||||
|
pub y: f64,
|
||||||
|
pub z: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Range = f64;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(StableAbi, Clone, Debug, Copy)]
|
#[derive(StableAbi, Clone, Debug, Copy)]
|
||||||
#[sabi(impl_InterfaceType(Sync, Send, Debug, Debug))]
|
#[sabi(impl_InterfaceType(Sync, Send, Debug, Debug))]
|
||||||
pub enum CoordType {
|
pub enum CoordType {
|
||||||
Polar,
|
Polar(Loc3, Range),
|
||||||
Cartesian,
|
Cartesian,
|
||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
{"rustc_fingerprint":8475780184195034948,"outputs":{"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/ruomu/.rustup/toolchains/nightly-x86_64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_feature=\"ssse3\"\ntarget_has_atomic\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"128\"\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"apple\"\nunix\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.74.0-nightly (8142a319e 2023-09-13)\nbinary: rustc\ncommit-hash: 8142a319ed5c1d1f96e5a1881a6546e463b77c8f\ncommit-date: 2023-09-13\nhost: x86_64-apple-darwin\nrelease: 1.74.0-nightly\nLLVM version: 17.0.0\n","stderr":""}},"successes":{}}
|
{"rustc_fingerprint":756262368934451307,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.77.0-nightly (d78329b92 2024-01-13)\nbinary: rustc\ncommit-hash: d78329b92e8d141d19505e7c1527181c4ab87ed4\ncommit-date: 2024-01-13\nhost: aarch64-apple-darwin\nrelease: 1.77.0-nightly\nLLVM version: 17.0.6\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/tsuki/.rustup/toolchains/nightly-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"v8.1a\"\ntarget_feature=\"v8.2a\"\ntarget_feature=\"v8.3a\"\ntarget_feature=\"v8.4a\"\ntarget_feature=\"vh\"\ntarget_has_atomic\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"128\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"128\"\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"apple\"\nunix\n","stderr":""}},"successes":{}}
|
||||||
@ -8,9 +8,9 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::components::sidebar::{SideBarInputMsg, SideBarModel};
|
use crate::components::sidebar::{SideBarInputMsg, SideBarModel};
|
||||||
use crate::data_utils::tools;
|
use crate::data_utils::tools;
|
||||||
|
use crate::pipeline::element::Buffer;
|
||||||
|
use crate::pipeline::element::Element;
|
||||||
use crate::pipeline::element_imp::{Context, ElementInput, GridImpConfig};
|
use crate::pipeline::element_imp::{Context, ElementInput, GridImpConfig};
|
||||||
use crate::pipeline::new_element::Buffer;
|
|
||||||
use crate::pipeline::new_element::Element;
|
|
||||||
use crate::pipeline::runner::Runner;
|
use crate::pipeline::runner::Runner;
|
||||||
use crate::pipeline::{DataTarget, Key};
|
use crate::pipeline::{DataTarget, Key};
|
||||||
use crate::pipeline::{KVBuffer, OffscreenRenderer};
|
use crate::pipeline::{KVBuffer, OffscreenRenderer};
|
||||||
@ -290,7 +290,7 @@ impl Component for AppModel {
|
|||||||
"CR",
|
"CR",
|
||||||
dialog_cms.clone(),
|
dialog_cms.clone(),
|
||||||
dialog_dispatcher.clone(),
|
dialog_dispatcher.clone(),
|
||||||
false,
|
true,
|
||||||
cfg,
|
cfg,
|
||||||
path.clone(),
|
path.clone(),
|
||||||
dialog_buffer.clone(),
|
dialog_buffer.clone(),
|
||||||
|
|||||||
@ -34,7 +34,7 @@ pub enum DataType {
|
|||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum CoordType {
|
pub enum CoordType {
|
||||||
Polar,
|
Polar((f64,f64,f64), f64),
|
||||||
LatLon,
|
LatLon,
|
||||||
}
|
}
|
||||||
pub trait MultiDimensionData<T>
|
pub trait MultiDimensionData<T>
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
|
use crate::pipeline::element_imp::ElementImpl::MultiLayerGrid;
|
||||||
use crate::pipeline::element_imp::*;
|
use crate::pipeline::element_imp::*;
|
||||||
use crate::utils::*;
|
use crate::utils::*;
|
||||||
use crate::CONFIG;
|
use crate::CONFIG;
|
||||||
|
use abi_stable::traits::IntoOwned;
|
||||||
|
use num_traits::FromPrimitive;
|
||||||
use radarg_plugin_interface::{CoordType, DataShape, PluginResult, PluginResultType};
|
use radarg_plugin_interface::{CoordType, DataShape, PluginResult, PluginResultType};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -16,7 +19,7 @@ macro_rules! dispatch {
|
|||||||
$branch => {
|
$branch => {
|
||||||
let mut $v = $wrap::default();
|
let mut $v = $wrap::default();
|
||||||
$v.color_map = $conf.drawers.$v.color_mapper.clone();
|
$v.color_map = $conf.drawers.$v.color_mapper.clone();
|
||||||
$v.fill_value = <$t>::from_f64($fill_value);
|
$v.fill_value = <$t>::from_f64($fill_value).unwrap();
|
||||||
Arc::new($v) as Arc<dyn Any + Send + Sync>
|
Arc::new($v) as Arc<dyn Any + Send + Sync>
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
@ -26,20 +29,79 @@ macro_rules! dispatch {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! dispatch_polar {
|
||||||
|
($block:ident,$conf:ident, $wrap:tt , $fill_value: ident, $center:ident, $(
|
||||||
|
{
|
||||||
|
$t:ty | $branch: pat => $v:ident
|
||||||
|
}
|
||||||
|
),+ $(,)?) => {
|
||||||
|
match $block.data_type {
|
||||||
|
$(
|
||||||
|
$branch => {
|
||||||
|
let mut $v = $wrap::default();
|
||||||
|
$v.color_map = $conf.drawers.$v.color_mapper.clone();
|
||||||
|
$v.fill_value = <$t>::from_f64($fill_value).unwrap();
|
||||||
|
$v.center = $center;
|
||||||
|
Arc::new($v) as Arc<dyn Any + Send + Sync>
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
|
||||||
|
_ => { panic!("") }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! dispatch_3d {
|
||||||
|
($block:ident,$conf:ident, $wrap:tt , $fill_value: ident, $(
|
||||||
|
{
|
||||||
|
$t:ty | $branch: pat => $v:ident
|
||||||
|
}
|
||||||
|
),+ $(,)?) => {
|
||||||
|
match $block.data_type {
|
||||||
|
$(
|
||||||
|
$branch => {
|
||||||
|
let mut $v = $wrap::default();
|
||||||
|
$v.color_map = $conf.drawers.$v.color_mapper.clone();
|
||||||
|
$v.fill_value = <$t>::from_f64($fill_value).unwrap();
|
||||||
|
|
||||||
|
let mut cfg = MultiLayerGridImpConfig{
|
||||||
|
two_d_config: $v,
|
||||||
|
layer: 0,
|
||||||
|
};
|
||||||
|
Arc::new(cfg) as Arc<dyn Any + Send + Sync>
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
|
||||||
|
_ => { panic!("") }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! dis {
|
macro_rules! dis {
|
||||||
($block:ident, $config:ident, $wrap:tt, $fill_value: ident) => {
|
($mac:ident ,$block:ident, $config:ident, $wrap:tt, $fill_value: ident, $($other:ident,)?) => {
|
||||||
dispatch!(
|
$mac!(
|
||||||
$block, $config, $wrap, $fill_value,
|
$block, $config, $wrap, $fill_value, $($other,)?
|
||||||
{ i8|PluginResultType::R => reflectivity },
|
{ i8|PluginResultType::R => reflectivity },
|
||||||
{ i8|PluginResultType::DBZ => reflectivity },
|
{ i8|PluginResultType::DBZ => reflectivity },
|
||||||
{ f32|PluginResultType::ZDR => differential_reflectivity },
|
{ f32|PluginResultType::ZDR => differential_reflectivity },
|
||||||
{ f32|PluginResultType::KDP => specific_differential_phase },
|
{ f32|PluginResultType::KDP => specific_differential_phase },
|
||||||
{ i8|PluginResultType::PHIDP => differential_phase }
|
{ f32|PluginResultType::PHIDP => differential_phase },
|
||||||
|
{ i8 |PluginResultType::V => velocity },
|
||||||
|
{ i8 |PluginResultType::SW => spectrum_width },
|
||||||
|
{ f32|PluginResultType::CC => correlation_coefficient },
|
||||||
|
{ i8 |PluginResultType::HCA => hydrometeor_classification },
|
||||||
|
{ f32|PluginResultType::VIL => vertically_integrated_liquid },
|
||||||
|
{ f32|PluginResultType::OHP => one_hour_precipitation },
|
||||||
|
{ f32|PluginResultType::THP => three_hour_precipitation },
|
||||||
|
{ f32|PluginResultType::ET => echo_tops },
|
||||||
|
{ f32|PluginResultType::EB => echo_bases }
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tools(data: &PluginResult) -> (ElementImpl, Arc<dyn Any + Send + Sync>) {
|
type Cfg = Arc<dyn Any + Send + Sync>;
|
||||||
|
|
||||||
|
pub fn tools(data: &PluginResult) -> (ElementImpl, Cfg) {
|
||||||
let blocks_num = data.blocks.len();
|
let blocks_num = data.blocks.len();
|
||||||
|
|
||||||
if blocks_num == 0 {
|
if blocks_num == 0 {
|
||||||
@ -55,21 +117,22 @@ pub fn tools(data: &PluginResult) -> (ElementImpl, Arc<dyn Any + Send + Sync>) {
|
|||||||
let config = CONFIG.read().unwrap();
|
let config = CONFIG.read().unwrap();
|
||||||
|
|
||||||
let imp = match block.coord_type {
|
let imp = match block.coord_type {
|
||||||
CoordType::Polar => {
|
CoordType::Polar(loc, range) => {
|
||||||
let cfg = dis!(block, config, PolarElementConfig, fill_value);
|
let center = (loc.x, loc.y);
|
||||||
|
let cfg = dis!(dispatch_polar, block, config, PolarElementConfig, fill_value, center,);
|
||||||
(PolarElementImp().into(), cfg)
|
(PolarElementImp().into(), cfg)
|
||||||
}
|
}
|
||||||
CoordType::Cartesian => {
|
CoordType::Cartesian => match block.shape {
|
||||||
let cfg = dis!(block, config, GridImpConfig, fill_value);
|
DataShape::Cube => {
|
||||||
(
|
let cfg = dis!(dispatch_3d, block, config, GridImpConfig, fill_value,);
|
||||||
match block.shape {
|
(MultiLayerGridImp::new().into(), cfg)
|
||||||
DataShape::Cube => MultiLayerGridImp().into(),
|
}
|
||||||
DataShape::Matrix => GridImp().into(),
|
DataShape::Matrix => (
|
||||||
_ => panic!("Invalid shape"),
|
GridImp::new().into(),
|
||||||
},
|
dis!(dispatch, block, config, GridImpConfig, fill_value,),
|
||||||
cfg,
|
),
|
||||||
)
|
_ => panic!("Invalid shape"),
|
||||||
}
|
},
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Invalid type")
|
panic!("Invalid type")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,323 +1,60 @@
|
|||||||
use super::{offscreen_renderer::CanvasWrapper, Dispatcher};
|
use super::dispatcher;
|
||||||
use crate::components::Widget;
|
use super::element_imp::Context;
|
||||||
|
use super::element_imp::ElementImpl;
|
||||||
|
use super::element_imp::ElementOutput;
|
||||||
|
use super::offscreen_renderer;
|
||||||
|
use super::offscreen_renderer::CanvasWrapper;
|
||||||
|
use super::runner;
|
||||||
|
use super::runner::Runner;
|
||||||
|
use super::Dispatcher;
|
||||||
use crate::coords::cms::CMS;
|
use crate::coords::cms::CMS;
|
||||||
use crate::coords::Range;
|
use crate::coords::Range;
|
||||||
use crate::data::MetaInfo;
|
use crate::data::MetaInfo;
|
||||||
use crate::errors::{PipelineError, RenderError};
|
use crate::pipeline::OffscreenRenderer;
|
||||||
use crate::predefined::color_mapper::ColorMapper;
|
|
||||||
use crate::widgets::Render;
|
use crate::widgets::Render;
|
||||||
|
use crate::PLUGIN_MANAGER;
|
||||||
use crate::RUNTIME;
|
use crate::RUNTIME;
|
||||||
use chrono::{DateTime, TimeZone, Utc};
|
use chrono::prelude::*;
|
||||||
use femtovg::{ImageFlags, ImageId};
|
use femtovg::ImageFlags;
|
||||||
use futures::StreamExt;
|
use femtovg::ImageId;
|
||||||
use num_traits::{AsPrimitive, FromPrimitive, NumOps};
|
use futures::future::BoxFuture;
|
||||||
|
use glow::HasContext;
|
||||||
|
use num_traits::AsPrimitive;
|
||||||
|
use num_traits::FromPrimitive;
|
||||||
|
use num_traits::Num;
|
||||||
|
use num_traits::NumOps;
|
||||||
|
use quick_cache::sync::Cache;
|
||||||
use radarg_plugin_interface::PluginResult;
|
use radarg_plugin_interface::PluginResult;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::BorrowMut;
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::cell::RefCell;
|
||||||
use std::fmt::Formatter;
|
use std::collections::HashMap;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::fmt::Debug;
|
||||||
|
use std::hash::Hash;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicI32;
|
||||||
use std::{
|
use std::sync::Arc;
|
||||||
fmt::Debug,
|
use std::sync::RwLock;
|
||||||
sync::{Arc, Mutex},
|
use std::time::Duration;
|
||||||
};
|
use tokio::sync::oneshot;
|
||||||
use tokio::sync::{
|
use tokio::sync::{mpsc, Mutex};
|
||||||
oneshot::{channel, Receiver},
|
use tracing::subscriber;
|
||||||
Notify,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type ElementID = usize;
|
static ELEMENT_ID: AtomicI32 = AtomicI32::new(0);
|
||||||
static ELEMENT_ID: AtomicUsize = AtomicUsize::new(0);
|
pub type ElementID = i32;
|
||||||
|
pub type KVBuffer<T, V> = Cache<T, V>;
|
||||||
|
pub type Buffer<T> = KVBuffer<T, Arc<RwLock<RenderResult>>>;
|
||||||
|
|
||||||
pub type Data = Box<dyn Any + Send + Sync>;
|
pub type Data = Arc<PluginResult>;
|
||||||
pub type Buffer = Arc<Mutex<BTreeMap<DateTime<Utc>, Option<RenderResult>>>>;
|
|
||||||
type DrawFunc = Rc<Box<dyn Fn(&Render)>>;
|
|
||||||
type IResult<T> = Result<T, PipelineError>;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
|
||||||
pub enum Element {
|
pub struct Key {
|
||||||
TimeSeries(TimeSeriesElement),
|
|
||||||
Instant(InstantElement),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Element {
|
|
||||||
pub fn create_time_series(
|
|
||||||
imp: Arc<dyn ElementImpl>,
|
|
||||||
dispatcher: Rc<Dispatcher>,
|
|
||||||
key: String,
|
|
||||||
cms: CMS,
|
|
||||||
) -> Self {
|
|
||||||
Element::TimeSeries(TimeSeriesElement::new(imp, dispatcher, cms, key))
|
|
||||||
}
|
|
||||||
pub fn create_instant(
|
|
||||||
_type: InstantElementDrawerType,
|
|
||||||
dispatcher: Rc<Dispatcher>,
|
|
||||||
key: String,
|
|
||||||
) -> Self {
|
|
||||||
Element::Instant(InstantElement::new(_type, dispatcher, key))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn id(&self) -> ElementID {
|
|
||||||
match self {
|
|
||||||
Element::TimeSeries(e) => e.id,
|
|
||||||
Element::Instant(e) => e.id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn key(&self) -> String {
|
|
||||||
match self {
|
|
||||||
Element::TimeSeries(e) => e.key.clone(),
|
|
||||||
Element::Instant(e) => e.key.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_instance(mut self) -> InstantElement {
|
|
||||||
match self {
|
|
||||||
Element::TimeSeries(e) => panic!("TimeSeries element does not have instance"),
|
|
||||||
Element::Instant(v) => v,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_time_series_instance(mut self) -> TimeSeriesElement {
|
|
||||||
match self {
|
|
||||||
Element::TimeSeries(v) => v,
|
|
||||||
Element::Instant(e) => panic!("Instant element does not have instance"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TimeSeriesElement {
|
|
||||||
pub id: ElementID,
|
pub id: ElementID,
|
||||||
pub key: String,
|
pub name: String,
|
||||||
cms: CMS,
|
pub root: std::path::PathBuf,
|
||||||
imp: Arc<dyn ElementImpl>,
|
pub datetime: Option<DateTime<Utc>>,
|
||||||
registers: Arc<Mutex<HashMap<DateTime<Utc>, Vec<Arc<Notify>>>>>,
|
pub unique_key: Option<String>,
|
||||||
pipeline: Pipeline,
|
|
||||||
pub buffer: Buffer,
|
|
||||||
dispatcher: Rc<Dispatcher>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum InstantElementDrawerType {
|
|
||||||
Draw(DrawFunc),
|
|
||||||
Prepared(DataTarget),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for InstantElementDrawerType {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("InstantElementDrawerType").finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct InstantElement {
|
|
||||||
pub id: ElementID,
|
|
||||||
pub key: String,
|
|
||||||
draw_type: InstantElementDrawerType,
|
|
||||||
dispatcher: Rc<Dispatcher>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ElementImplMap {
|
|
||||||
ColorMap,
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ElementImpl: Debug + Send + Sync + 'static {
|
|
||||||
fn render(&self, data: &PluginResult, canvas: &mut CanvasWrapper, cms: &mut CMS) -> Target;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InstantElement {
|
|
||||||
fn new(_type: InstantElementDrawerType, dispatcher: Rc<Dispatcher>, key: String) -> Self {
|
|
||||||
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
key,
|
|
||||||
draw_type: _type,
|
|
||||||
dispatcher,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn render(&mut self, render: &Render) {
|
|
||||||
match self.draw_type {
|
|
||||||
InstantElementDrawerType::Draw(ref func) => {
|
|
||||||
func(render);
|
|
||||||
}
|
|
||||||
InstantElementDrawerType::Prepared(ref mut target) => {
|
|
||||||
render.draw_img(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn imp(&self) -> &InstantElementDrawerType {
|
|
||||||
&self.draw_type
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_time_series(
|
|
||||||
self,
|
|
||||||
dispatcher: Rc<Dispatcher>,
|
|
||||||
cms: CMS,
|
|
||||||
) -> (TimeSeriesElement, DateTime<Utc>) {
|
|
||||||
// let imp = Arc::new(InstantElementImpl::new(self));
|
|
||||||
// if let InstantElementDrawerType::Prepared(mut target) = self.draw_type {
|
|
||||||
// let mut time_series = TimeSeriesElement::new(imp, dispatcher, cms, self.key);
|
|
||||||
// let data = target.take_data().unwrap();
|
|
||||||
// let time_stamp = data.blocks.first().unwrap().datetime;
|
|
||||||
// let meta_info: MetaInfo = data.meta.clone().into();
|
|
||||||
// use chrono::prelude::*;
|
|
||||||
// let time = Utc.timestamp_opt(time_stamp, 0).unwrap();
|
|
||||||
// (*time_series.buffer)
|
|
||||||
// .lock()
|
|
||||||
// .unwrap()
|
|
||||||
// .insert(time, Some(RenderResult::new(target, meta_info)));
|
|
||||||
// (time_series, time)
|
|
||||||
// } else {
|
|
||||||
panic!("InstantElementDrawerType is not prepared");
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TimeSeriesElement {
|
|
||||||
fn new(imp: Arc<dyn ElementImpl>, dispatcher: Rc<Dispatcher>, cms: CMS, key: String) -> Self {
|
|
||||||
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
|
||||||
let mut pipeline = Pipeline::new(20, key.clone());
|
|
||||||
pipeline.set_dispatcher(dispatcher.clone());
|
|
||||||
let buffer = Arc::new(Mutex::new(BTreeMap::new()));
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
key,
|
|
||||||
imp,
|
|
||||||
cms,
|
|
||||||
registers: Arc::new(Mutex::new(HashMap::new())),
|
|
||||||
buffer,
|
|
||||||
dispatcher,
|
|
||||||
pipeline,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register(
|
|
||||||
&mut self,
|
|
||||||
datetime: DateTime<Utc>,
|
|
||||||
) -> IResult<Receiver<Result<RenderResult, RenderError>>> {
|
|
||||||
use tokio::sync::Notify;
|
|
||||||
use tokio::task;
|
|
||||||
|
|
||||||
let (sender, recv) = channel::<Result<RenderResult, RenderError>>();
|
|
||||||
self.change_time(datetime)?;
|
|
||||||
|
|
||||||
let buffer = self.buffer.lock().unwrap();
|
|
||||||
if buffer.contains_key(&datetime) {
|
|
||||||
let target = buffer.get(&datetime).unwrap();
|
|
||||||
|
|
||||||
// Already in buffer
|
|
||||||
if let Some(target) = target {
|
|
||||||
sender.send(Ok(target.clone())).unwrap();
|
|
||||||
} else {
|
|
||||||
let new_notifer = {
|
|
||||||
let n = Arc::new(Notify::new());
|
|
||||||
let n_clone = n.clone();
|
|
||||||
self.register_noti(datetime, n);
|
|
||||||
n_clone
|
|
||||||
};
|
|
||||||
|
|
||||||
let buffer = self.buffer.clone();
|
|
||||||
task::spawn_local(async move {
|
|
||||||
new_notifer.notified().await;
|
|
||||||
let result = buffer.lock().unwrap().get(&datetime).unwrap().clone();
|
|
||||||
sender.send(Ok(result.unwrap())).unwrap();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Ok(recv);
|
|
||||||
} else {
|
|
||||||
return Err(PipelineError::DataError("No data found".to_string()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_cms(&mut self, cms: CMS) {
|
|
||||||
self.cms = cms;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn imp(&self) -> &Arc<dyn ElementImpl> {
|
|
||||||
&self.imp
|
|
||||||
}
|
|
||||||
|
|
||||||
fn register_noti(&self, datetime: DateTime<Utc>, noti: Arc<Notify>) {
|
|
||||||
self.registers
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.entry(datetime)
|
|
||||||
.or_insert_with(Vec::new)
|
|
||||||
.push(noti);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn change_time(&mut self, date_time: DateTime<Utc>) -> IResult<()> {
|
|
||||||
let imp = self.imp.clone();
|
|
||||||
println!("Change time to {:?}", date_time);
|
|
||||||
let tasks = self.pipeline.set_current(
|
|
||||||
date_time,
|
|
||||||
true,
|
|
||||||
3,
|
|
||||||
Arc::new(move |data, canvas, cms| imp.render(data, canvas, cms)),
|
|
||||||
self.cms.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let tasks = tasks.map(|tms| tms.into_iter().map(|time| (time, None)));
|
|
||||||
if let Some(tasks) = tasks {
|
|
||||||
if tasks.len() == 0 {
|
|
||||||
return Err(PipelineError::DataError("No data found".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut buffer = self.buffer.lock().unwrap();
|
|
||||||
buffer.extend(tasks);
|
|
||||||
let buffer = self.buffer.clone();
|
|
||||||
let registers = self.registers.clone();
|
|
||||||
|
|
||||||
let listening_func = self.pipeline.listening(move |recv, idx| {
|
|
||||||
let buffer = buffer.clone();
|
|
||||||
let registers = registers.clone();
|
|
||||||
Box::pin(async move {
|
|
||||||
let registers = registers;
|
|
||||||
let (dt, result) = recv.await.unwrap();
|
|
||||||
if let Ok(result) = result {
|
|
||||||
let mut buffer = buffer.lock().unwrap();
|
|
||||||
*buffer.get_mut(&dt).unwrap() = Some(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
registers.lock().unwrap().get_mut(&dt).map(|x| {
|
|
||||||
x.into_iter().for_each(|n| {
|
|
||||||
n.notify_waiters();
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
let runner = Pipeline::run(&mut self.pipeline);
|
|
||||||
|
|
||||||
RUNTIME.spawn(listening_func);
|
|
||||||
RUNTIME.spawn(runner);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
Err(PipelineError::DataError("No data found".to_string()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct RenderResult {
|
|
||||||
target: DataTarget,
|
|
||||||
meta_info: MetaInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RenderResult {
|
|
||||||
pub fn new(target: DataTarget, meta_info: MetaInfo) -> Self {
|
|
||||||
Self { target, meta_info }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_meta_info(&self) -> MetaInfo {
|
|
||||||
self.meta_info.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_mut_target(&mut self) -> &mut Target {
|
|
||||||
&mut self.target
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -327,7 +64,6 @@ pub struct Target {
|
|||||||
pub width: f32,
|
pub width: f32,
|
||||||
pub height: f32,
|
pub height: f32,
|
||||||
pub bounds: (Range, Range),
|
pub bounds: (Range, Range),
|
||||||
// pub data: Option<Arc<dyn Any + Send + Sync + 'static>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
|
||||||
@ -344,7 +80,6 @@ impl Target {
|
|||||||
height: f32,
|
height: f32,
|
||||||
bounds: (Range, Range),
|
bounds: (Range, Range),
|
||||||
thumbnail: Option<gtk::gdk::Texture>,
|
thumbnail: Option<gtk::gdk::Texture>,
|
||||||
// data: Option<Arc<dyn Any + Send + Sync + 'static>>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
target,
|
target,
|
||||||
@ -352,7 +87,6 @@ impl Target {
|
|||||||
height,
|
height,
|
||||||
bounds,
|
bounds,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
// data,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,38 +260,216 @@ impl Target {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DataTarget {
|
pub struct DataTarget {
|
||||||
data: Option<PluginResult>,
|
pub data: Option<Data>,
|
||||||
target: Target,
|
target: Target,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataTarget {
|
impl DataTarget {
|
||||||
pub fn new(data: Option<PluginResult>, target: Target) -> Self {
|
pub fn new(data: Option<Data>, target: Target) -> Self {
|
||||||
Self { data, target }
|
Self { data, target }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn take_data(&mut self) -> Option<PluginResult> {
|
#[derive(Debug, Clone)]
|
||||||
self.data.take()
|
pub struct RenderResult {
|
||||||
|
unique_key: Option<String>,
|
||||||
|
target: DataTarget,
|
||||||
|
meta_info: MetaInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderResult {
|
||||||
|
pub fn new(target: DataTarget, meta_info: MetaInfo, unique_key: Option<String>) -> Self {
|
||||||
|
Self { target, meta_info,unique_key }
|
||||||
|
}
|
||||||
|
pub fn get_meta_info(&self) -> MetaInfo {
|
||||||
|
self.meta_info.clone()
|
||||||
|
}
|
||||||
|
pub fn get_mut_target(&mut self) -> &mut Target {
|
||||||
|
&mut self.target.target
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data(&self) -> Option<&PluginResult> {
|
pub fn get_key(&self) -> Option<&String>{
|
||||||
self.data.as_ref()
|
self.unique_key.as_ref()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mut_data(&mut self) -> Option<&mut PluginResult> {
|
|
||||||
self.data.as_mut()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for DataTarget {
|
#[derive(Debug)]
|
||||||
type Target = Target;
|
pub struct Element {
|
||||||
|
pub id: i32,
|
||||||
fn deref(&self) -> &Self::Target {
|
pub name: String,
|
||||||
&self.target
|
pub cache: bool,
|
||||||
}
|
root: std::path::PathBuf,
|
||||||
|
config: Arc<dyn Any + Send + Sync>,
|
||||||
|
imp: ElementImpl,
|
||||||
|
subscribers: Arc<Mutex<HashMap<Key, Vec<oneshot::Sender<Arc<Mutex<PluginResult>>>>>>>,
|
||||||
|
cancellers: Arc<Mutex<HashMap<Key, oneshot::Sender<()>>>>,
|
||||||
|
current_key: Option<Key>,
|
||||||
|
dispatcher: Arc<Dispatcher>,
|
||||||
|
buffer: Arc<Buffer<Key>>,
|
||||||
|
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
||||||
|
current_target: Option<Arc<RwLock<RenderResult>>>,
|
||||||
|
cms: CMS,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerefMut for DataTarget {
|
pub enum ElementEvent<'a> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
Init,
|
||||||
&mut self.target
|
Draw,
|
||||||
|
DateTime(DateTime<Utc>),
|
||||||
|
Key(&'a Key),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Element {
|
||||||
|
pub fn new(
|
||||||
|
name: impl Into<String>,
|
||||||
|
cms: CMS,
|
||||||
|
dispatcher: Arc<Dispatcher>,
|
||||||
|
cache: bool,
|
||||||
|
config: Arc<dyn Any + Send + Sync>,
|
||||||
|
root: std::path::PathBuf,
|
||||||
|
buffer: Arc<Buffer<Key>>,
|
||||||
|
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
||||||
|
imp: ElementImpl,
|
||||||
|
) -> Self {
|
||||||
|
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
Element {
|
||||||
|
id,
|
||||||
|
name: name.into(),
|
||||||
|
cache,
|
||||||
|
imp,
|
||||||
|
config,
|
||||||
|
root,
|
||||||
|
subscribers: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
cancellers: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
cms: cms,
|
||||||
|
current_key: None,
|
||||||
|
buffer,
|
||||||
|
file_pool,
|
||||||
|
current_target: None,
|
||||||
|
dispatcher,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn r<'b>(&mut self, event: ElementEvent<'b>, render: &Render) {
|
||||||
|
let need_cache = self.cache;
|
||||||
|
let output_type = self.imp.output_type();
|
||||||
|
|
||||||
|
fn _init(
|
||||||
|
this: &mut Element,
|
||||||
|
need_cache: bool,
|
||||||
|
output_type: ElementOutput,
|
||||||
|
render: &Render,
|
||||||
|
) {
|
||||||
|
let data = this.file_pool.get(&this.root);
|
||||||
|
if let Some(data) = data {
|
||||||
|
let target = this._rrrr(data, need_cache, output_type, render);
|
||||||
|
if let Some(target) = target {
|
||||||
|
let time = target.meta_info.datetime.unwrap();
|
||||||
|
if !need_cache {
|
||||||
|
this.current_target = Some(Arc::new(RwLock::new(target)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let unique_key = target.unique_key.clone();
|
||||||
|
let key = this.generate_key(time, unique_key);
|
||||||
|
let target = Arc::new(RwLock::new(target));
|
||||||
|
this.buffer.insert(key, target.clone());
|
||||||
|
this.current_target = Some(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match event {
|
||||||
|
ElementEvent::Init => {
|
||||||
|
_init(self, need_cache, output_type, render);
|
||||||
|
}
|
||||||
|
ElementEvent::Draw => {
|
||||||
|
if let Some(current) = self.current_target.as_ref() {
|
||||||
|
let mut img = current.write().unwrap();
|
||||||
|
let mut img = img.get_mut_target();
|
||||||
|
render.draw_img(img);
|
||||||
|
} else {
|
||||||
|
_init(self, need_cache, output_type, render);
|
||||||
|
if let ElementOutput::Target = output_type {
|
||||||
|
let mut _img = self.current_target.as_ref().unwrap();
|
||||||
|
let mut img = _img.write().unwrap();
|
||||||
|
let mut img = img.get_mut_target();
|
||||||
|
render.draw_img(img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ElementEvent::DateTime(time) => {
|
||||||
|
let path = self.dispatcher.get_single_path(&self.name, time, true);
|
||||||
|
path.map(|path| {
|
||||||
|
// let data = self.file_pool.get(&path);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ElementEvent::Key(key) => {
|
||||||
|
self.buffer.get(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_target_to_buffer(&self, key: Key, render_result: RenderResult) {
|
||||||
|
let result = Arc::new(RwLock::new(render_result));
|
||||||
|
self.buffer.insert(key, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _rrrr(
|
||||||
|
&self,
|
||||||
|
data: Data,
|
||||||
|
need_cache: bool,
|
||||||
|
output_type: ElementOutput,
|
||||||
|
render: &Render,
|
||||||
|
) -> Option<RenderResult> {
|
||||||
|
match output_type {
|
||||||
|
ElementOutput::Target => {
|
||||||
|
use tokio::task;
|
||||||
|
let cms = self.cms.clone();
|
||||||
|
let imp = self.imp.clone();
|
||||||
|
let config = self.config.clone();
|
||||||
|
|
||||||
|
let handle = task::spawn_blocking(move || {
|
||||||
|
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
||||||
|
let mut canvas = offscreen_renderer.create_canvas();
|
||||||
|
let mut context = Context::new(cms, &mut canvas);
|
||||||
|
let mut runner = Runner::new(imp, config, context);
|
||||||
|
let (target, unique_key) = runner.run(&data);
|
||||||
|
let meta = data.meta.clone().into();
|
||||||
|
Some(RenderResult::new(DataTarget::new(Some(data), target), meta, unique_key))
|
||||||
|
});
|
||||||
|
RUNTIME.block_on(handle).ok().flatten()
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
let mut canvas = render.get_canvas();
|
||||||
|
let mut canvas = canvas.as_mut().unwrap();
|
||||||
|
let mut context = Context::new(self.cms.clone(), &mut canvas);
|
||||||
|
let mut runner = Runner::new(self.imp, self.config.clone(), context);
|
||||||
|
runner.run_without_target(&data);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_file(&self, path: impl AsRef<std::path::Path>) -> PluginResult {
|
||||||
|
let loader = PLUGIN_MANAGER.get_plugin_by_name("etws_loader").unwrap();
|
||||||
|
let path = path.as_ref().as_os_str().to_str().unwrap();
|
||||||
|
let mut loaded_data = loader.load(path.into()).unwrap();
|
||||||
|
|
||||||
|
loaded_data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_key(&self) -> Key {
|
||||||
|
self.current_key.clone().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_key(&self, datetime: DateTime<Utc>, unique_key: Option<String>) -> Key {
|
||||||
|
Key {
|
||||||
|
id: self.id,
|
||||||
|
name: self.name.clone(),
|
||||||
|
root: self.root.clone(),
|
||||||
|
datetime: Some(datetime),
|
||||||
|
unique_key,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,14 +16,14 @@ use std::fmt::Debug;
|
|||||||
const EARTH_RADIUS: f64 = 6371.0;
|
const EARTH_RADIUS: f64 = 6371.0;
|
||||||
|
|
||||||
macro_rules! impl_element_imp_dispatch {
|
macro_rules! impl_element_imp_dispatch {
|
||||||
($({$Abc: ident, $t:ty},)+) => {
|
($({$Abc: ident, $t:ty, $input:ident },)+) => {
|
||||||
impl ElementImpl {
|
impl ElementImpl {
|
||||||
pub fn process<'a,'b:'a, T>(&self,
|
pub fn process<'a,'b:'a, T>(&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
input: ElementInput<'a, T>,
|
input: ElementInput<'a, T>,
|
||||||
config: &dyn Any,
|
config: &dyn Any,
|
||||||
context: &mut Context<'b>
|
context: &mut Context<'b>
|
||||||
)
|
) -> Option<String>
|
||||||
where
|
where
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive + 'static,
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive + 'static,
|
||||||
{
|
{
|
||||||
@ -31,8 +31,9 @@ macro_rules! impl_element_imp_dispatch {
|
|||||||
$(
|
$(
|
||||||
Self::$Abc(imp) => {
|
Self::$Abc(imp) => {
|
||||||
let config = config.downcast_ref::<<$t as ElementImp>::Config<'a, T>>().unwrap();
|
let config = config.downcast_ref::<<$t as ElementImp>::Config<'a, T>>().unwrap();
|
||||||
if let ElementInput::$Abc(data) = input {
|
if let ElementInput::$input(data) = input {
|
||||||
imp.process(dims, data, config, context);
|
imp.process(dims, data, config, context);
|
||||||
|
imp.unique_key(config)
|
||||||
} else {
|
} else {
|
||||||
panic!("Invalid input type");
|
panic!("Invalid input type");
|
||||||
}
|
}
|
||||||
@ -57,7 +58,7 @@ macro_rules! impl_element_imp_dispatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_element_try_from_dispatch {
|
macro_rules! impl_element_try_from_dispatch {
|
||||||
($({ $Abc: ident, $t:ty},)+) => {
|
($({ $Abc: ident, $t:ty $(, $other:ident)? },)+) => {
|
||||||
$(
|
$(
|
||||||
impl TryFrom<ElementImpl> for $t {
|
impl TryFrom<ElementImpl> for $t {
|
||||||
type Error = &'static str;
|
type Error = &'static str;
|
||||||
@ -73,7 +74,7 @@ macro_rules! impl_element_try_from_dispatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_element_into_dispatch {
|
macro_rules! impl_element_into_dispatch {
|
||||||
($({ $Abc: ident, $t:ty},)+) => {
|
($({ $Abc: ident, $t:ty $(,$other:ident)? },)+) => {
|
||||||
$(
|
$(
|
||||||
impl From<$t> for ElementImpl {
|
impl From<$t> for ElementImpl {
|
||||||
fn from(value: $t) -> Self {
|
fn from(value: $t) -> Self {
|
||||||
@ -85,7 +86,7 @@ macro_rules! impl_element_into_dispatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_element_input_into_dispatch {
|
macro_rules! impl_element_input_into_dispatch {
|
||||||
($({$Abc: ident, $t: ty},)+) => {
|
($({$Abc: ident, $t: ty $(,$other:ident)?},)+) => {
|
||||||
$(
|
$(
|
||||||
impl<'a, T> From<$t> for ElementInput<'a, T> {
|
impl<'a, T> From<$t> for ElementInput<'a, T> {
|
||||||
fn from(value: $t) -> Self {
|
fn from(value: $t) -> Self {
|
||||||
@ -99,9 +100,9 @@ macro_rules! impl_element_input_into_dispatch {
|
|||||||
macro_rules! for_all_variants {
|
macro_rules! for_all_variants {
|
||||||
($macro: tt) => {
|
($macro: tt) => {
|
||||||
$macro! {
|
$macro! {
|
||||||
{Grid, GridImp},
|
{Grid, GridImp, Grid},
|
||||||
{MultiLayerGrid, MultiLayerGridImp},
|
{MultiLayerGrid, MultiLayerGridImp, Grid},
|
||||||
{Polar, PolarElementImp},
|
{Polar, PolarElementImp, Grid},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -154,6 +155,8 @@ pub trait ElementImp: Debug + TryFrom<ElementImpl> + Into<ElementImpl> {
|
|||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
|
|
||||||
|
fn new() -> Self;
|
||||||
|
|
||||||
fn process<'a, 'b: 'a, T>(
|
fn process<'a, 'b: 'a, T>(
|
||||||
&self,
|
&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
@ -164,6 +167,13 @@ pub trait ElementImp: Debug + TryFrom<ElementImpl> + Into<ElementImpl> {
|
|||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive;
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive;
|
||||||
|
|
||||||
fn output_type(&self) -> ElementOutput;
|
fn output_type(&self) -> ElementOutput;
|
||||||
|
|
||||||
|
fn unique_key<'a, T>(&self, config: &Self::Config<'a, T>) -> Option<String>
|
||||||
|
where
|
||||||
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive + 'static,
|
||||||
|
{
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ElementConfig {
|
pub trait ElementConfig {
|
||||||
@ -181,7 +191,7 @@ where
|
|||||||
T: PartialOrd + PartialEq + Send + Sync + Debug + Clone,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Clone,
|
||||||
{
|
{
|
||||||
pub color_map: ColorMapperComb<T>,
|
pub color_map: ColorMapperComb<T>,
|
||||||
pub fill_value: T
|
pub fill_value: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GridImp {
|
impl GridImp {
|
||||||
@ -238,6 +248,10 @@ impl ElementImp for GridImp {
|
|||||||
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + Clone + FromPrimitive> = GridImpConfig<T> where
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + Clone + FromPrimitive> = GridImpConfig<T> where
|
||||||
T: 'a;
|
T: 'a;
|
||||||
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
||||||
|
|
||||||
|
fn new() -> Self {
|
||||||
|
Self()
|
||||||
|
}
|
||||||
fn process<'a, 'b: 'a, T>(
|
fn process<'a, 'b: 'a, T>(
|
||||||
&self,
|
&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
@ -262,7 +276,7 @@ impl ElementImp for GridImp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct MultiLayerGridImp();
|
pub struct MultiLayerGridImp(GridImp);
|
||||||
|
|
||||||
impl MultiLayerGridImp {
|
impl MultiLayerGridImp {
|
||||||
fn draw<'a, 'b: 'a, T>(
|
fn draw<'a, 'b: 'a, T>(
|
||||||
@ -274,7 +288,8 @@ impl MultiLayerGridImp {
|
|||||||
) where
|
) where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy + FromPrimitive,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy + FromPrimitive,
|
||||||
{
|
{
|
||||||
let two = config.twod.clone();
|
// let two = config.twod.clone();
|
||||||
|
let two = self.0;
|
||||||
let _layer = data.into_dimensionality::<Ix3>().unwrap();
|
let _layer = data.into_dimensionality::<Ix3>().unwrap();
|
||||||
let data = _layer.index_axis(Axis(0), config.layer).into_dyn();
|
let data = _layer.index_axis(Axis(0), config.layer).into_dyn();
|
||||||
|
|
||||||
@ -286,9 +301,9 @@ pub struct MultiLayerGridImpConfig<T>
|
|||||||
where
|
where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug + Clone,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Clone,
|
||||||
{
|
{
|
||||||
twod: GridImp,
|
// twod: GridImp,
|
||||||
two_d_config: GridImpConfig<T>,
|
pub two_d_config: GridImpConfig<T>,
|
||||||
layer: usize,
|
pub layer: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElementImp for MultiLayerGridImp {
|
impl ElementImp for MultiLayerGridImp {
|
||||||
@ -296,6 +311,10 @@ impl ElementImp for MultiLayerGridImp {
|
|||||||
MultiLayerGridImpConfig<T>;
|
MultiLayerGridImpConfig<T>;
|
||||||
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
||||||
|
|
||||||
|
fn new() -> Self {
|
||||||
|
Self(GridImp())
|
||||||
|
}
|
||||||
|
|
||||||
fn process<'a, 'b: 'a, T>(
|
fn process<'a, 'b: 'a, T>(
|
||||||
&self,
|
&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
@ -311,6 +330,13 @@ impl ElementImp for MultiLayerGridImp {
|
|||||||
fn output_type(&self) -> ElementOutput {
|
fn output_type(&self) -> ElementOutput {
|
||||||
ElementOutput::Target
|
ElementOutput::Target
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unique_key<'a, T>(&self, config: &Self::Config<'a, T>) -> Option<String>
|
||||||
|
where
|
||||||
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive + 'static,
|
||||||
|
{
|
||||||
|
Some(format!("l_{}", config.layer))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@ -363,7 +389,7 @@ impl PolarElementImp {
|
|||||||
|
|
||||||
let distance = EARTH_RADIUS * c * 1000.0;
|
let distance = EARTH_RADIUS * c * 1000.0;
|
||||||
|
|
||||||
if distance > max_r + dpi.1 {
|
if distance > max_r + dpi.0 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,20 +399,20 @@ impl PolarElementImp {
|
|||||||
let ori_degree = y.atan2(x).to_degrees();
|
let ori_degree = y.atan2(x).to_degrees();
|
||||||
let degree = (ori_degree + 360.0) % 360.0;
|
let degree = (ori_degree + 360.0) % 360.0;
|
||||||
|
|
||||||
let distance_dpi = dpi.1;
|
let distance_dpi = dpi.0;
|
||||||
let degree_dpi = dpi.0;
|
let degree_dpi = dpi.1;
|
||||||
let final_degree = self.closest_value(degree, degree_dpi);
|
let final_degree = self.closest_value(degree, degree_dpi);
|
||||||
let final_distance = self.closest_value(distance, distance_dpi);
|
let final_distance = self.closest_value(distance, distance_dpi);
|
||||||
Some((final_degree, final_distance))
|
Some((final_degree, final_distance))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw<'a, T>(
|
fn draw<'a,'b:'a, T>(
|
||||||
&self,
|
&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
center: (f64, f64),
|
center: (f64, f64),
|
||||||
data: ArrayView2<T>,
|
data: ArrayView2<T>,
|
||||||
config: &'a PolarElementConfig<T>,
|
config: &'a PolarElementConfig<T>,
|
||||||
context: &mut Context<'a>,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy + FromPrimitive,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy + FromPrimitive,
|
||||||
{
|
{
|
||||||
@ -396,10 +422,10 @@ impl PolarElementImp {
|
|||||||
|
|
||||||
let dpi = (
|
let dpi = (
|
||||||
dims.0[[0, 1]] - dims.0[[0, 0]],
|
dims.0[[0, 1]] - dims.0[[0, 0]],
|
||||||
dims.1[[1, 1]] - dims.1[[1, 0]],
|
dims.1[[1, 0]] - dims.1[[0, 0]],
|
||||||
);
|
);
|
||||||
|
|
||||||
let (azs, rs) = dims;
|
let (rs, azs) = dims;
|
||||||
|
|
||||||
let (w, h) = (canvas.width(), canvas.height());
|
let (w, h) = (canvas.width(), canvas.height());
|
||||||
|
|
||||||
@ -410,6 +436,7 @@ impl PolarElementImp {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some((_x, _y)) = self.map_to_polar(center, dpi, 0.0, map_point.unwrap()) {
|
if let Some((_x, _y)) = self.map_to_polar(center, dpi, 0.0, map_point.unwrap()) {
|
||||||
|
println!("{}, {}", _x, _y);
|
||||||
let (_x, _y) = (_x as usize, _y as usize);
|
let (_x, _y) = (_x as usize, _y as usize);
|
||||||
let value = data[[_x, _y]];
|
let value = data[[_x, _y]];
|
||||||
let color = config.color_map.color(value);
|
let color = config.color_map.color(value);
|
||||||
@ -431,6 +458,10 @@ impl ElementImp for PolarElementImp {
|
|||||||
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + Clone + FromPrimitive> = PolarElementConfig<T> where
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + Clone + FromPrimitive> = PolarElementConfig<T> where
|
||||||
T: 'a;
|
T: 'a;
|
||||||
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
||||||
|
|
||||||
|
fn new() -> Self {
|
||||||
|
Self()
|
||||||
|
}
|
||||||
fn process<'a, 'b: 'a, T>(
|
fn process<'a, 'b: 'a, T>(
|
||||||
&self,
|
&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
@ -443,9 +474,10 @@ impl ElementImp for PolarElementImp {
|
|||||||
let shape = input.shape();
|
let shape = input.shape();
|
||||||
if shape.len() == 2 {
|
if shape.len() == 2 {
|
||||||
let data = input.into_dimensionality::<Ix2>().unwrap();
|
let data = input.into_dimensionality::<Ix2>().unwrap();
|
||||||
// self.draw(dims, config.center, data, config, context);
|
self.draw(dims, config.center, data, config, context);
|
||||||
} else if shape.len() == 3 {
|
} else if shape.len() == 3 {
|
||||||
let data = input.into_dimensionality::<Ix3>().unwrap();
|
let data = input.into_dimensionality::<Ix3>().unwrap();
|
||||||
|
self.draw(dims, config.center, data.index_axis(Axis(0), 5), config, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,10 +509,12 @@ pub enum ElementImpl {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ElementInput<'a, T> {
|
pub enum ElementInput<'a, T> {
|
||||||
Grid(ArrayViewD<'a, T>),
|
Grid(ArrayViewD<'a, T>),
|
||||||
MultiLayerGrid(ArrayViewD<'a, T>),
|
|
||||||
Polar(ArrayViewD<'a, T>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for_all_variants!(impl_element_into_dispatch);
|
for_all_variants!(impl_element_into_dispatch);
|
||||||
for_all_variants!(impl_element_try_from_dispatch);
|
for_all_variants!(impl_element_try_from_dispatch);
|
||||||
for_all_variants!(impl_element_imp_dispatch);
|
for_all_variants!(impl_element_imp_dispatch);
|
||||||
|
|
||||||
|
impl_element_input_into_dispatch!(
|
||||||
|
{Grid, ArrayViewD<'a, T>},
|
||||||
|
);
|
||||||
|
|||||||
@ -1,74 +0,0 @@
|
|||||||
use super::predefined::GridFieldRenderer;
|
|
||||||
use super::renders::DataRenderer;
|
|
||||||
use crate::components::Widget;
|
|
||||||
use crate::data::{Radar2d, Radar3d};
|
|
||||||
use crate::pipeline::element::{ElementImpl, ElementImplMap, Target};
|
|
||||||
use crate::pipeline::offscreen_renderer::CanvasWrapper;
|
|
||||||
use crate::predefined::color_mapper::ColorMapper;
|
|
||||||
use crate::widgets::LayerImpl;
|
|
||||||
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
|
|
||||||
use radarg_plugin_interface::{DataShape, PluginResult};
|
|
||||||
use std::any::Any;
|
|
||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct GridElementImpl<CMAP, T>
|
|
||||||
where
|
|
||||||
T: Num + NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
|
||||||
CMAP: ColorMapper<T>,
|
|
||||||
{
|
|
||||||
renderer: GridFieldRenderer<CMAP, T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<CMAP, T> GridElementImpl<CMAP, T>
|
|
||||||
where
|
|
||||||
T: Num + NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
|
||||||
CMAP: ColorMapper<T>,
|
|
||||||
{
|
|
||||||
pub fn new(color: CMAP) -> Self {
|
|
||||||
Self {
|
|
||||||
renderer: GridFieldRenderer::new(color),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<CMAP, T> ElementImpl for GridElementImpl<CMAP, T>
|
|
||||||
where
|
|
||||||
T: Num
|
|
||||||
+ NumOps
|
|
||||||
+ PartialOrd
|
|
||||||
+ Copy
|
|
||||||
+ Clone
|
|
||||||
+ Debug
|
|
||||||
+ Send
|
|
||||||
+ Sync
|
|
||||||
+ FromPrimitive
|
|
||||||
+ AsPrimitive<f64>,
|
|
||||||
CMAP: ColorMapper<T> + Debug + 'static,
|
|
||||||
{
|
|
||||||
fn render(
|
|
||||||
&self,
|
|
||||||
data: &PluginResult,
|
|
||||||
canvas: &mut CanvasWrapper,
|
|
||||||
cms: &mut crate::coords::cms::CMS,
|
|
||||||
) -> crate::pipeline::element::Target {
|
|
||||||
let first_block = data.blocks.first().unwrap();
|
|
||||||
match first_block.shape {
|
|
||||||
DataShape::Vector => {
|
|
||||||
panic!("Vector data is not supported")
|
|
||||||
}
|
|
||||||
DataShape::Matrix => {
|
|
||||||
let data: Radar2d<T> = first_block.clone().into();
|
|
||||||
let data = data.as_ref();
|
|
||||||
let result = self.renderer.render(canvas, cms, &data, (3000.0, 3000.0));
|
|
||||||
result
|
|
||||||
}
|
|
||||||
DataShape::Cube => {
|
|
||||||
let data: Radar3d<T> = first_block.clone().into();
|
|
||||||
let data = data.index_axis(ndarray::Axis(0), 0);
|
|
||||||
let result = self.renderer.render(canvas, cms, &data, (3000.0, 3000.0));
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +1,12 @@
|
|||||||
pub mod dispatcher;
|
pub mod dispatcher;
|
||||||
// pub mod element;
|
// pub mod element;
|
||||||
// mod element_impl;
|
// mod element_impl;
|
||||||
pub mod new_element;
|
pub mod element;
|
||||||
// mod new_element_impl;
|
// mod new_element_impl;
|
||||||
// mod new_pipeline;
|
// mod new_pipeline;
|
||||||
pub mod offscreen_renderer;
|
pub mod offscreen_renderer;
|
||||||
// mod predefined;
|
// mod predefined;
|
||||||
pub mod element_imp;
|
pub mod element_imp;
|
||||||
mod renders;
|
|
||||||
pub mod runner;
|
pub mod runner;
|
||||||
// pub mod utils;
|
// pub mod utils;
|
||||||
|
|
||||||
@ -15,5 +14,5 @@ pub use dispatcher::Dispatcher;
|
|||||||
// pub use element::*;
|
// pub use element::*;
|
||||||
// pub use element_impl::*;
|
// pub use element_impl::*;
|
||||||
// pub use new_pipeline::Pipeline;
|
// pub use new_pipeline::Pipeline;
|
||||||
pub use new_element::*;
|
pub use element::*;
|
||||||
pub use offscreen_renderer::OffscreenRenderer;
|
pub use offscreen_renderer::OffscreenRenderer;
|
||||||
|
|||||||
@ -1,468 +0,0 @@
|
|||||||
use super::dispatcher;
|
|
||||||
use super::element_imp::Context;
|
|
||||||
use super::element_imp::ElementImpl;
|
|
||||||
use super::element_imp::ElementOutput;
|
|
||||||
use super::offscreen_renderer;
|
|
||||||
use super::offscreen_renderer::CanvasWrapper;
|
|
||||||
use super::runner;
|
|
||||||
use super::runner::Runner;
|
|
||||||
use super::Dispatcher;
|
|
||||||
use crate::coords::cms::CMS;
|
|
||||||
use crate::coords::Range;
|
|
||||||
use crate::data::MetaInfo;
|
|
||||||
use crate::pipeline::OffscreenRenderer;
|
|
||||||
use crate::widgets::Render;
|
|
||||||
use crate::PLUGIN_MANAGER;
|
|
||||||
use crate::RUNTIME;
|
|
||||||
use chrono::prelude::*;
|
|
||||||
use femtovg::ImageFlags;
|
|
||||||
use femtovg::ImageId;
|
|
||||||
use futures::future::BoxFuture;
|
|
||||||
use glow::HasContext;
|
|
||||||
use num_traits::AsPrimitive;
|
|
||||||
use num_traits::FromPrimitive;
|
|
||||||
use num_traits::Num;
|
|
||||||
use num_traits::NumOps;
|
|
||||||
use quick_cache::sync::Cache;
|
|
||||||
use radarg_plugin_interface::PluginResult;
|
|
||||||
use std::any::Any;
|
|
||||||
use std::borrow::BorrowMut;
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fmt::Debug;
|
|
||||||
use std::hash::Hash;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::atomic::AtomicI32;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::RwLock;
|
|
||||||
use std::time::Duration;
|
|
||||||
use tokio::sync::oneshot;
|
|
||||||
use tokio::sync::{mpsc, Mutex};
|
|
||||||
use tracing::subscriber;
|
|
||||||
|
|
||||||
static ELEMENT_ID: AtomicI32 = AtomicI32::new(0);
|
|
||||||
pub type ElementID = i32;
|
|
||||||
pub type KVBuffer<T, V> = Cache<T, V>;
|
|
||||||
pub type Buffer<T> = KVBuffer<T, Arc<RwLock<RenderResult>>>;
|
|
||||||
|
|
||||||
pub type Data = Arc<PluginResult>;
|
|
||||||
|
|
||||||
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
|
|
||||||
pub struct Key {
|
|
||||||
pub id: ElementID,
|
|
||||||
pub name: String,
|
|
||||||
pub root: std::path::PathBuf,
|
|
||||||
pub datetime: Option<DateTime<Utc>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct Target {
|
|
||||||
pub target: TargetType,
|
|
||||||
pub thumbnail: Option<gtk::gdk::Texture>,
|
|
||||||
pub width: f32,
|
|
||||||
pub height: f32,
|
|
||||||
pub bounds: (Range, Range),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
|
|
||||||
pub enum TargetType {
|
|
||||||
ImageId(ImageId),
|
|
||||||
Mem(Vec<u8>),
|
|
||||||
NativeBuffer(Vec<u8>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Target {
|
|
||||||
pub fn new(
|
|
||||||
target: TargetType,
|
|
||||||
width: f32,
|
|
||||||
height: f32,
|
|
||||||
bounds: (Range, Range),
|
|
||||||
thumbnail: Option<gtk::gdk::Texture>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
target,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
bounds,
|
|
||||||
thumbnail,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn size(&self, cms: &Render) -> (f32, f32) {
|
|
||||||
let (x, y) = self.bounds;
|
|
||||||
|
|
||||||
let p1 = (x.0, y.0);
|
|
||||||
let p2 = (x.1, y.1);
|
|
||||||
|
|
||||||
let (x1, y1) = cms.map(p1).unwrap();
|
|
||||||
let (x2, y2) = cms.map(p2).unwrap();
|
|
||||||
|
|
||||||
((x2 - x1).abs(), (y2 - y1).abs())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn native_buffer_to_native_texture(
|
|
||||||
&self,
|
|
||||||
gl: &glow::Context,
|
|
||||||
flags: ImageFlags,
|
|
||||||
) -> glow::NativeTexture {
|
|
||||||
if let TargetType::NativeBuffer(ref mem) = self.target {
|
|
||||||
use glow::*;
|
|
||||||
let texture = unsafe {
|
|
||||||
let id = gl.create_texture().unwrap();
|
|
||||||
gl.bind_texture(glow::TEXTURE_2D, Some(id));
|
|
||||||
gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
|
|
||||||
gl.pixel_store_i32(glow::UNPACK_ROW_LENGTH, 3000 as i32);
|
|
||||||
gl.pixel_store_i32(glow::UNPACK_SKIP_PIXELS, 0);
|
|
||||||
gl.pixel_store_i32(glow::UNPACK_SKIP_ROWS, 0);
|
|
||||||
id
|
|
||||||
};
|
|
||||||
let width = 3000; // 纹理宽度
|
|
||||||
let height = 3000; // 纹理高度
|
|
||||||
unsafe {
|
|
||||||
gl.tex_image_2d(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
0, // level
|
|
||||||
glow::RGBA as i32, // internal_format
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
0, // border
|
|
||||||
glow::RGBA, // format
|
|
||||||
glow::UNSIGNED_BYTE, // type
|
|
||||||
Some(&mem), // pixels
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.contains(ImageFlags::GENERATE_MIPMAPS) {
|
|
||||||
if flags.contains(ImageFlags::NEAREST) {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_MIN_FILTER,
|
|
||||||
glow::NEAREST_MIPMAP_NEAREST as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_MIN_FILTER,
|
|
||||||
glow::LINEAR_MIPMAP_LINEAR as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if flags.contains(ImageFlags::NEAREST) {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_MIN_FILTER,
|
|
||||||
glow::NEAREST as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_MIN_FILTER,
|
|
||||||
glow::LINEAR as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.contains(ImageFlags::NEAREST) {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_MAG_FILTER,
|
|
||||||
glow::NEAREST as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_MAG_FILTER,
|
|
||||||
glow::LINEAR as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.contains(ImageFlags::REPEAT_X) {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_WRAP_S,
|
|
||||||
glow::REPEAT as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_WRAP_S,
|
|
||||||
glow::CLAMP_TO_EDGE as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.contains(ImageFlags::REPEAT_Y) {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_WRAP_T,
|
|
||||||
glow::REPEAT as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
gl.tex_parameter_i32(
|
|
||||||
glow::TEXTURE_2D,
|
|
||||||
glow::TEXTURE_WRAP_T,
|
|
||||||
glow::CLAMP_TO_EDGE as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 4);
|
|
||||||
gl.pixel_store_i32(glow::UNPACK_ROW_LENGTH, 0);
|
|
||||||
gl.pixel_store_i32(glow::UNPACK_SKIP_PIXELS, 0);
|
|
||||||
gl.pixel_store_i32(glow::UNPACK_SKIP_ROWS, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.contains(ImageFlags::GENERATE_MIPMAPS) {
|
|
||||||
unsafe {
|
|
||||||
gl.generate_mipmap(glow::TEXTURE_2D);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
gl.bind_texture(glow::TEXTURE_2D, None);
|
|
||||||
}
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
} else {
|
|
||||||
panic!("Target is not mem");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn origin(&self, cms: &Render) -> (f32, f32) {
|
|
||||||
let (x, y) = self.bounds;
|
|
||||||
let p1 = (x.0, y.1);
|
|
||||||
cms.map(p1).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_target(&mut self, target: TargetType) {
|
|
||||||
self.target = target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct DataTarget {
|
|
||||||
pub data: Option<Data>,
|
|
||||||
target: Target,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataTarget {
|
|
||||||
pub fn new(data: Option<Data>, target: Target) -> Self {
|
|
||||||
Self { data, target }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct RenderResult {
|
|
||||||
target: DataTarget,
|
|
||||||
meta_info: MetaInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RenderResult {
|
|
||||||
pub fn new(target: DataTarget, meta_info: MetaInfo) -> Self {
|
|
||||||
Self { target, meta_info }
|
|
||||||
}
|
|
||||||
pub fn get_meta_info(&self) -> MetaInfo {
|
|
||||||
self.meta_info.clone()
|
|
||||||
}
|
|
||||||
pub fn get_mut_target(&mut self) -> &mut Target {
|
|
||||||
&mut self.target.target
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Element {
|
|
||||||
pub id: i32,
|
|
||||||
pub name: String,
|
|
||||||
pub cache: bool,
|
|
||||||
root: std::path::PathBuf,
|
|
||||||
config: Arc<dyn Any + Send + Sync>,
|
|
||||||
imp: ElementImpl,
|
|
||||||
subscribers: Arc<Mutex<HashMap<Key, Vec<oneshot::Sender<Arc<Mutex<PluginResult>>>>>>>,
|
|
||||||
cancellers: Arc<Mutex<HashMap<Key, oneshot::Sender<()>>>>,
|
|
||||||
current_key: Option<Key>,
|
|
||||||
dispatcher: Arc<Dispatcher>,
|
|
||||||
buffer: Arc<Buffer<Key>>,
|
|
||||||
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
|
||||||
current_target: Option<Arc<RwLock<RenderResult>>>,
|
|
||||||
cms: CMS,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ElementEvent<'a> {
|
|
||||||
Init,
|
|
||||||
Draw,
|
|
||||||
DateTime(DateTime<Utc>),
|
|
||||||
Key(&'a Key),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Element {
|
|
||||||
pub fn new(
|
|
||||||
name: impl Into<String>,
|
|
||||||
cms: CMS,
|
|
||||||
dispatcher: Arc<Dispatcher>,
|
|
||||||
cache: bool,
|
|
||||||
config: Arc<dyn Any + Send + Sync>,
|
|
||||||
root: std::path::PathBuf,
|
|
||||||
buffer: Arc<Buffer<Key>>,
|
|
||||||
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
|
||||||
imp: ElementImpl,
|
|
||||||
) -> Self {
|
|
||||||
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
|
||||||
Element {
|
|
||||||
id,
|
|
||||||
name: name.into(),
|
|
||||||
cache,
|
|
||||||
imp,
|
|
||||||
config,
|
|
||||||
root,
|
|
||||||
subscribers: Arc::new(Mutex::new(HashMap::new())),
|
|
||||||
cancellers: Arc::new(Mutex::new(HashMap::new())),
|
|
||||||
cms: cms,
|
|
||||||
current_key: None,
|
|
||||||
buffer,
|
|
||||||
file_pool,
|
|
||||||
current_target: None,
|
|
||||||
dispatcher,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn r<'b>(&mut self, event: ElementEvent<'b>, render: &Render) {
|
|
||||||
let need_cache = self.cache;
|
|
||||||
let output_type = self.imp.output_type();
|
|
||||||
|
|
||||||
fn _init(
|
|
||||||
this: &mut Element,
|
|
||||||
need_cache: bool,
|
|
||||||
output_type: ElementOutput,
|
|
||||||
render: &Render,
|
|
||||||
) {
|
|
||||||
let data = this.file_pool.get(&this.root);
|
|
||||||
if let Some(data) = data {
|
|
||||||
let target = this._rrrr(data, need_cache, output_type, render);
|
|
||||||
if let Some(target) = target {
|
|
||||||
let time = target.meta_info.datetime.unwrap();
|
|
||||||
let key = this.generate_key(time);
|
|
||||||
let target = Arc::new(RwLock::new(target));
|
|
||||||
this.buffer.insert(key, target.clone());
|
|
||||||
this.current_target = Some(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match event {
|
|
||||||
ElementEvent::Init => {
|
|
||||||
_init(self, need_cache, output_type, render);
|
|
||||||
}
|
|
||||||
ElementEvent::Draw => {
|
|
||||||
if let Some(current) = self.current_target.as_ref() {
|
|
||||||
let mut img = current.write().unwrap();
|
|
||||||
let mut img = img.get_mut_target();
|
|
||||||
render.draw_img(img);
|
|
||||||
} else {
|
|
||||||
_init(self, need_cache, output_type, render);
|
|
||||||
if let ElementOutput::Target = output_type {
|
|
||||||
let mut _img = self.current_target.as_ref().unwrap();
|
|
||||||
let mut img = _img.write().unwrap();
|
|
||||||
let mut img = img.get_mut_target();
|
|
||||||
render.draw_img(img);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ElementEvent::DateTime(time) => {
|
|
||||||
let path = self.dispatcher.get_single_path(&self.name, time, true);
|
|
||||||
path.map(|path| {
|
|
||||||
// let data = self.file_pool.get(&path);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ElementEvent::Key(key) => {
|
|
||||||
self.buffer.get(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert_target_to_buffer(&self, key: Key, render_result: RenderResult) {
|
|
||||||
let result = Arc::new(RwLock::new(render_result));
|
|
||||||
self.buffer.insert(key, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn _rrrr(
|
|
||||||
&self,
|
|
||||||
data: Data,
|
|
||||||
need_cache: bool,
|
|
||||||
output_type: ElementOutput,
|
|
||||||
render: &Render,
|
|
||||||
) -> Option<RenderResult> {
|
|
||||||
match output_type {
|
|
||||||
ElementOutput::Target => {
|
|
||||||
use tokio::task;
|
|
||||||
let cms = self.cms.clone();
|
|
||||||
let imp = self.imp.clone();
|
|
||||||
let config = self.config.clone();
|
|
||||||
|
|
||||||
let handle = task::spawn_blocking(move || {
|
|
||||||
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
|
||||||
let mut canvas = offscreen_renderer.create_canvas();
|
|
||||||
let mut context = Context::new(cms, &mut canvas);
|
|
||||||
let mut runner = Runner::new(imp, config, context);
|
|
||||||
let target = runner.run(&data);
|
|
||||||
let meta = data.meta.clone().into();
|
|
||||||
Some(RenderResult::new(DataTarget::new(Some(data), target), meta))
|
|
||||||
});
|
|
||||||
let result = RUNTIME.block_on(handle).ok().flatten();
|
|
||||||
result
|
|
||||||
// let result = RUNTIME.spawn(async {handle.await});
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
let mut canvas = render.get_canvas();
|
|
||||||
let mut canvas = canvas.as_mut().unwrap();
|
|
||||||
let mut context = Context::new(self.cms.clone(), &mut canvas);
|
|
||||||
let mut runner = Runner::new(self.imp, self.config.clone(), context);
|
|
||||||
runner.run_without_target(&data);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_file(&self, path: impl AsRef<std::path::Path>) -> PluginResult {
|
|
||||||
let loader = PLUGIN_MANAGER.get_plugin_by_name("etws_loader").unwrap();
|
|
||||||
let path = path.as_ref().as_os_str().to_str().unwrap();
|
|
||||||
let mut loaded_data = loader.load(path.into()).unwrap();
|
|
||||||
|
|
||||||
loaded_data
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_key(&self) -> Key {
|
|
||||||
self.current_key.clone().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_key(&self, datetime: DateTime<Utc>) -> Key {
|
|
||||||
Key {
|
|
||||||
id: self.id,
|
|
||||||
name: self.name.clone(),
|
|
||||||
root: self.root.clone(),
|
|
||||||
datetime: Some(datetime),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn key(&self) -> String {
|
|
||||||
format!("{}-{}", self.id, self.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,104 +0,0 @@
|
|||||||
use super::{
|
|
||||||
new_element::ElementImpl, offscreen_renderer::CanvasWrapper, predefined::GridFieldRenderer,
|
|
||||||
renders::DataRenderer, Target,
|
|
||||||
};
|
|
||||||
use crate::{
|
|
||||||
data::{Radar2d, Radar3d},
|
|
||||||
predefined::color_mapper::{BoundaryNorm, ColorMapper},
|
|
||||||
};
|
|
||||||
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
|
|
||||||
use radarg_plugin_interface::{DataShape, PluginResult};
|
|
||||||
use std::{any::Any, fmt::Debug, marker::PhantomData};
|
|
||||||
|
|
||||||
macro_rules! create_element_imp {
|
|
||||||
($imp: expr) => {{
|
|
||||||
let c: ElementImp = $imp.into();
|
|
||||||
c
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! element {
|
|
||||||
($generic:ident,$(($branch:tt,$imp:ty)),+) => {
|
|
||||||
pub(super) type ElementConfig = dyn Any + Send + Sync + 'static;
|
|
||||||
|
|
||||||
pub enum ElementImp<$generic>
|
|
||||||
where
|
|
||||||
$generic: NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
|
||||||
{
|
|
||||||
$(
|
|
||||||
$branch($imp),
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<$generic> ElementImp<$generic>
|
|
||||||
where
|
|
||||||
$generic: Num + NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
|
||||||
{
|
|
||||||
pub fn render(
|
|
||||||
&self,
|
|
||||||
data: &PluginResult,
|
|
||||||
canvas: &mut CanvasWrapper,
|
|
||||||
cms: &mut crate::coords::cms::CMS,
|
|
||||||
config: &ElementConfig) -> Target
|
|
||||||
{
|
|
||||||
match self {
|
|
||||||
$(
|
|
||||||
ElementImp::$branch(imp) => imp.render(data,canvas,cms,config.downcast_ref::<<$imp as ElementImpl>::Config>().unwrap()),
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(
|
|
||||||
impl<$generic> From<$imp> for ElementImp<$generic>
|
|
||||||
where
|
|
||||||
$generic: NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
|
||||||
{
|
|
||||||
fn from(imp: $imp) -> Self {
|
|
||||||
ElementImp::$branch(imp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// element!(T, (Grid, GridElementImpl<T>));
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct GridElementImpl {}
|
|
||||||
|
|
||||||
impl GridElementImpl {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ElementImpl for GridElementImpl {
|
|
||||||
type Config = GridFieldRenderer<BoundaryNorm<T>, T>;
|
|
||||||
fn render(
|
|
||||||
&self,
|
|
||||||
data: &PluginResult,
|
|
||||||
canvas: &mut CanvasWrapper,
|
|
||||||
cms: &mut crate::coords::cms::CMS,
|
|
||||||
config: &Self::Config<T>,
|
|
||||||
) -> super::Target {
|
|
||||||
let first_block = data.blocks.first().unwrap();
|
|
||||||
match first_block.shape {
|
|
||||||
DataShape::Vector => {
|
|
||||||
panic!("Vector data is not supported")
|
|
||||||
}
|
|
||||||
DataShape::Matrix => {
|
|
||||||
let data: Radar2d<T> = first_block.clone().into();
|
|
||||||
let data = data.as_ref();
|
|
||||||
let result = config.render(canvas, cms, &data, (3000.0, 3000.0));
|
|
||||||
result
|
|
||||||
}
|
|
||||||
DataShape::Cube => {
|
|
||||||
let data: Radar3d<T> = first_block.clone().into();
|
|
||||||
let data = data.index_axis(ndarray::Axis(0), 0);
|
|
||||||
let result = config.render(canvas, cms, &data, (3000.0, 3000.0));
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,196 +0,0 @@
|
|||||||
use super::{
|
|
||||||
dispatcher::Dispatcher,
|
|
||||||
element::{DataTarget, RenderResult},
|
|
||||||
offscreen_renderer::{CanvasWrapper, OffscreenRenderer},
|
|
||||||
// utils::data_to_element,
|
|
||||||
};
|
|
||||||
use crate::coords::cms::CMS;
|
|
||||||
use crate::pipeline::element::Target;
|
|
||||||
use crate::{
|
|
||||||
coords::{proj::Mercator, Mapper},
|
|
||||||
data::MetaInfo,
|
|
||||||
errors::RenderError,
|
|
||||||
widgets::Layer,
|
|
||||||
PLUGIN_MANAGER,
|
|
||||||
};
|
|
||||||
use chrono::prelude::*;
|
|
||||||
use femtovg::{renderer::OpenGl, Canvas, ImageId};
|
|
||||||
use futures::{future::BoxFuture, Future};
|
|
||||||
use radarg_plugin_interface::PluginResult;
|
|
||||||
use smallvec::SmallVec;
|
|
||||||
use std::fmt::{Debug, Formatter};
|
|
||||||
use std::{
|
|
||||||
cell::RefCell,
|
|
||||||
rc::Rc,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
};
|
|
||||||
use tokio::{
|
|
||||||
sync::{mpsc, oneshot},
|
|
||||||
task,
|
|
||||||
};
|
|
||||||
|
|
||||||
type RenderR = Result<RenderResult, RenderError>;
|
|
||||||
pub struct Pipeline {
|
|
||||||
pool: Vec<BoxFuture<'static, ()>>,
|
|
||||||
results: SmallVec<[RenderResult; 20]>,
|
|
||||||
dispatcher: Option<Rc<Dispatcher>>,
|
|
||||||
handlers: Option<Vec<oneshot::Receiver<(DateTime<Utc>, RenderR)>>>,
|
|
||||||
handler: Option<mpsc::Receiver<RenderR>>,
|
|
||||||
sender: Option<mpsc::Sender<RenderR>>,
|
|
||||||
key: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Pipeline {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("Pipeline").finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Pipeline {
|
|
||||||
pub fn new(len: usize, key: String) -> Self {
|
|
||||||
Self {
|
|
||||||
pool: Vec::new(),
|
|
||||||
results: SmallVec::new(),
|
|
||||||
dispatcher: None,
|
|
||||||
handlers: None,
|
|
||||||
handler: None,
|
|
||||||
sender: None,
|
|
||||||
key,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_dispatcher(&mut self, dispatcher: Rc<Dispatcher>) {
|
|
||||||
self.dispatcher = Some(dispatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(&mut self) -> &mut Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_current(
|
|
||||||
&mut self,
|
|
||||||
current_time: DateTime<Utc>,
|
|
||||||
check_existed: bool,
|
|
||||||
max_retry_time: usize,
|
|
||||||
task: Arc<dyn Fn(&PluginResult, &mut CanvasWrapper, &mut CMS) -> Target + Send + Sync>,
|
|
||||||
cms: CMS,
|
|
||||||
) -> Option<Vec<DateTime<Utc>>> {
|
|
||||||
let paths = {
|
|
||||||
self.dispatcher.as_ref().unwrap().get_path(
|
|
||||||
&self.key,
|
|
||||||
current_time,
|
|
||||||
check_existed,
|
|
||||||
max_retry_time,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(paths) = paths {
|
|
||||||
let mut recvs = Vec::new();
|
|
||||||
let mut result = Vec::new();
|
|
||||||
for (path, datetime) in paths.into_iter() {
|
|
||||||
let (sender, mut receiver) = oneshot::channel();
|
|
||||||
self.add_task(
|
|
||||||
datetime,
|
|
||||||
self.worker(datetime, task.clone(), cms.clone(), path),
|
|
||||||
sender,
|
|
||||||
);
|
|
||||||
recvs.push(receiver);
|
|
||||||
result.push(datetime);
|
|
||||||
}
|
|
||||||
self.handlers.replace(recvs);
|
|
||||||
Some(result)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn work_num(&self) -> usize {
|
|
||||||
self.pool.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn worker(
|
|
||||||
&self,
|
|
||||||
datetime: DateTime<Utc>,
|
|
||||||
task: Arc<dyn Fn(&PluginResult, &mut CanvasWrapper, &mut CMS) -> Target + Send + Sync>,
|
|
||||||
mut cms: CMS,
|
|
||||||
path: impl AsRef<str> + Send + 'static,
|
|
||||||
) -> BoxFuture<'static, RenderR> {
|
|
||||||
Box::pin(async move {
|
|
||||||
let loader = PLUGIN_MANAGER.get_plugin_by_name("etws_loader").unwrap();
|
|
||||||
let mut loaded_data = loader.load(path.as_ref().into()).unwrap();
|
|
||||||
let meta = loaded_data.meta.clone().into();
|
|
||||||
|
|
||||||
let handle = task::spawn_blocking(move || {
|
|
||||||
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
|
||||||
let mut canvas_wrapper = offscreen_renderer.create_canvas();
|
|
||||||
let target = task(&loaded_data, &mut canvas_wrapper, &mut cms);
|
|
||||||
DataTarget::new(Some(loaded_data), target)
|
|
||||||
});
|
|
||||||
|
|
||||||
let target = handle.await.unwrap();
|
|
||||||
Ok(RenderResult::new(target, meta))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_task<TASK>(
|
|
||||||
&mut self,
|
|
||||||
time: DateTime<Utc>,
|
|
||||||
task: TASK,
|
|
||||||
tx: oneshot::Sender<(DateTime<Utc>, RenderR)>,
|
|
||||||
) where
|
|
||||||
TASK: Future<Output = RenderR> + 'static + Send,
|
|
||||||
{
|
|
||||||
let future = async move {
|
|
||||||
let data = task.await;
|
|
||||||
tx.send((time, data)).unwrap();
|
|
||||||
};
|
|
||||||
|
|
||||||
self.pool.push(Box::pin(future));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(value: &mut Self) -> BoxFuture<'static, ()> {
|
|
||||||
let pool = value.get_pool();
|
|
||||||
Box::pin(async move {
|
|
||||||
for f in pool.into_iter() {
|
|
||||||
task::spawn(f);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn listening<F>(&mut self, f: F) -> BoxFuture<'static, ()>
|
|
||||||
where
|
|
||||||
F: Fn(oneshot::Receiver<(DateTime<Utc>, RenderR)>, usize) -> BoxFuture<'static, ()>
|
|
||||||
+ Send
|
|
||||||
+ 'static
|
|
||||||
+ Sync,
|
|
||||||
{
|
|
||||||
let mut handler = self.handlers.take().unwrap();
|
|
||||||
Box::pin(async move {
|
|
||||||
let l = handler.into_iter().enumerate().map(|(h, i)| f(i, h));
|
|
||||||
for f in l {
|
|
||||||
task::spawn(f);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn listening_one_by_one<F>(&mut self, f: Vec<F>) -> BoxFuture<'static, ()>
|
|
||||||
where
|
|
||||||
F: FnOnce(oneshot::Receiver<(DateTime<Utc>, RenderR)>) -> BoxFuture<'static, ()>
|
|
||||||
+ Send
|
|
||||||
+ 'static
|
|
||||||
+ Sync,
|
|
||||||
{
|
|
||||||
let mut handler = self.handlers.take().unwrap();
|
|
||||||
Box::pin(async move {
|
|
||||||
for (h, f) in handler.into_iter().zip(f) {
|
|
||||||
task::spawn(f(h));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_pool(&mut self) -> Vec<BoxFuture<'static, ()>> {
|
|
||||||
use std::mem::replace;
|
|
||||||
let pool = replace(&mut self.pool, Vec::new());
|
|
||||||
pool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,168 +0,0 @@
|
|||||||
use crate::errors::PoolError;
|
|
||||||
use smallvec::SmallVec;
|
|
||||||
use sorted_vec::SortedSet;
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
|
|
||||||
type PResult<T> = Result<T, PoolError>;
|
|
||||||
|
|
||||||
pub struct Pool<T>
|
|
||||||
where
|
|
||||||
T: Send + Sync + Ord,
|
|
||||||
{
|
|
||||||
items: SortedSet<T>,
|
|
||||||
current: Option<(i64, usize)>,
|
|
||||||
len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Pool<T>
|
|
||||||
where
|
|
||||||
T: Send + Sync + Ord,
|
|
||||||
{
|
|
||||||
pub fn new(len: usize) -> Self {
|
|
||||||
Pool {
|
|
||||||
items: VecDeque::new(),
|
|
||||||
current: None,
|
|
||||||
len,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(&mut self, timestamp: i64, item: T) -> PResult<()> {
|
|
||||||
let len = self.items.len();
|
|
||||||
|
|
||||||
if len == 0 {
|
|
||||||
self.items.push_back((timestamp, item));
|
|
||||||
self.current.replace((timestamp, 0));
|
|
||||||
return Ok(());
|
|
||||||
} else {
|
|
||||||
return Err(PoolError::PoolInitialized("Pool is already initialized"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add(&mut self, item: T, timestamp: i64) -> PResult<()> {
|
|
||||||
let len = self.items.len();
|
|
||||||
if len == self.len {
|
|
||||||
return Err(PoolError::PoolFull);
|
|
||||||
}
|
|
||||||
if len == 0 {
|
|
||||||
return Err(PoolError::PoolInitialized("Pool is not initialized"));
|
|
||||||
}
|
|
||||||
if len == 1 {
|
|
||||||
if self.items[0].0 < timestamp {
|
|
||||||
self.items.push_back((timestamp, item));
|
|
||||||
} else {
|
|
||||||
self.items.push_front((timestamp, item));
|
|
||||||
self.current.replace((timestamp, 1));
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let back = self
|
|
||||||
.items
|
|
||||||
.back()
|
|
||||||
.map(|(last_timestamp, _)| *last_timestamp < timestamp)
|
|
||||||
.unwrap();
|
|
||||||
let front = self
|
|
||||||
.items
|
|
||||||
.front()
|
|
||||||
.map(|(first_timestamp, _)| *first_timestamp > timestamp)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if !(back || front) {
|
|
||||||
return Err(PoolError::TimestampError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if back {
|
|
||||||
self.items.push_back((timestamp, item));
|
|
||||||
} else {
|
|
||||||
self.items.push_front((timestamp, item));
|
|
||||||
self.current.as_mut().map(|(_, index)| *index += 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev(&self) -> Option<&T> {
|
|
||||||
self.current
|
|
||||||
.map(|(_, index)| &self.items[index])
|
|
||||||
.map(|(_, item)| item)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next(&mut self) -> Option<&T> {
|
|
||||||
let len = self.items.len();
|
|
||||||
let current = self.current.as_mut().map(|(_, index)| index);
|
|
||||||
|
|
||||||
if let Some(index) = current {
|
|
||||||
if *index + 1 < len {
|
|
||||||
*index += 1;
|
|
||||||
self.current
|
|
||||||
.as_ref()
|
|
||||||
.map(|(_, index)| &self.items[*index])
|
|
||||||
.map(|(_, item)| item)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self, index: isize) -> Option<&T> {
|
|
||||||
self.current
|
|
||||||
.as_ref()
|
|
||||||
.map(|(_, current_index)| *current_index as isize + index)
|
|
||||||
.and_then(|index| {
|
|
||||||
if index >= 0 && index < self.items.len() as isize {
|
|
||||||
Some(&self.items[index as usize])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map(|(_, item)| item)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_mut(&mut self, index: isize) -> Option<&mut T> {
|
|
||||||
self.current
|
|
||||||
.as_ref()
|
|
||||||
.map(|(_, current_index)| *current_index as isize + index)
|
|
||||||
.and_then(|index| {
|
|
||||||
if index >= 0 && index < self.items.len() as isize {
|
|
||||||
Some(&mut self.items[index as usize])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map(|(_, item)| item)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item = &T> {
|
|
||||||
self.items.iter().map(|(_, item)| item)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
|
|
||||||
self.items.iter_mut().map(|(_, item)| item)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_current(&mut self, timestamp: i64, item: T) -> PResult<()> {
|
|
||||||
if self.items.len() == 0 {
|
|
||||||
return Err(PoolError::PoolInitialized("Pool is not initialized"));
|
|
||||||
}
|
|
||||||
|
|
||||||
let position = self.items.iter().position(|(time, _)| *time == timestamp);
|
|
||||||
|
|
||||||
if let Some(p) = position {
|
|
||||||
let start = (p - self.len / 2).max(0);
|
|
||||||
let end = (p + self.len / 2).min(self.items.len() - 1);
|
|
||||||
self.items = self.items.drain(start..end).collect();
|
|
||||||
self.current.replace((timestamp, self.len / 2));
|
|
||||||
return Ok(());
|
|
||||||
} else {
|
|
||||||
self.items.clear();
|
|
||||||
self.init(timestamp, item);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.items.len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,210 +0,0 @@
|
|||||||
use super::{
|
|
||||||
dispatcher::Dispatcher,
|
|
||||||
offscreen_renderer::{CanvasWrapper, OffscreenRenderer},
|
|
||||||
};
|
|
||||||
use crate::{
|
|
||||||
coords::{cms::CMS, proj::Mercator, Mapper},
|
|
||||||
data::MetaInfo,
|
|
||||||
errors::RenderError,
|
|
||||||
widgets::Layer,
|
|
||||||
PLUGIN_MANAGER,
|
|
||||||
};
|
|
||||||
use chrono::prelude::*;
|
|
||||||
use femtovg::{renderer::OpenGl, Canvas, ImageId};
|
|
||||||
use futures::{future::BoxFuture, Future};
|
|
||||||
use smallvec::SmallVec;
|
|
||||||
use std::{
|
|
||||||
cell::RefCell,
|
|
||||||
rc::Rc,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
};
|
|
||||||
use tokio::{
|
|
||||||
sync::{mpsc, oneshot},
|
|
||||||
task,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct RenderResult {
|
|
||||||
pub meta: MetaInfo,
|
|
||||||
pub layer: Layer,
|
|
||||||
time: DateTime<Utc>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RenderResult {
|
|
||||||
pub fn new(layer: Layer, time: DateTime<Utc>, meta: MetaInfo) -> Self {
|
|
||||||
Self { layer, time, meta }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn timestamp(&self) -> i64 {
|
|
||||||
self.time.timestamp()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn time(&self) -> DateTime<Utc> {
|
|
||||||
self.time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type RenderR = Result<RenderResult, RenderError>;
|
|
||||||
pub struct Pipeline {
|
|
||||||
pool: Vec<BoxFuture<'static, ()>>,
|
|
||||||
results: SmallVec<[RenderResult; 20]>,
|
|
||||||
dispatcher: Option<Rc<RefCell<Dispatcher>>>,
|
|
||||||
handlers: Option<Vec<oneshot::Receiver<RenderR>>>,
|
|
||||||
handler: Option<mpsc::Receiver<RenderR>>,
|
|
||||||
sender: Option<mpsc::Sender<RenderR>>,
|
|
||||||
key: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Pipeline {
|
|
||||||
pub fn new(len: usize, key: String) -> Self {
|
|
||||||
Self {
|
|
||||||
pool: Vec::new(),
|
|
||||||
results: SmallVec::new(),
|
|
||||||
dispatcher: None,
|
|
||||||
handlers: None,
|
|
||||||
handler: None,
|
|
||||||
sender: None,
|
|
||||||
key,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_dispatcher(&mut self, dispatcher: Rc<RefCell<Dispatcher>>) {
|
|
||||||
self.dispatcher = Some(dispatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(&mut self) -> &mut Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_current(
|
|
||||||
&mut self,
|
|
||||||
current_time: DateTime<Utc>,
|
|
||||||
check_existed: bool,
|
|
||||||
max_retry_time: usize,
|
|
||||||
) -> Option<Vec<DateTime<Utc>>> {
|
|
||||||
let paths = {
|
|
||||||
let dispatcher = self.dispatcher.as_ref().unwrap();
|
|
||||||
let dispatcher = dispatcher.borrow();
|
|
||||||
dispatcher.get_path(&self.key, current_time, check_existed, max_retry_time)
|
|
||||||
};
|
|
||||||
if let Some(paths) = paths {
|
|
||||||
let mut recvs = Vec::new();
|
|
||||||
let mut result = Vec::new();
|
|
||||||
for (path, datetime) in paths.into_iter() {
|
|
||||||
let (sender, mut receiver) = oneshot::channel::<RenderR>();
|
|
||||||
self.add_task(datetime.timestamp(), self.worker(datetime, path), sender);
|
|
||||||
recvs.push(receiver);
|
|
||||||
result.push(datetime);
|
|
||||||
}
|
|
||||||
self.handlers.replace(recvs);
|
|
||||||
Some(result)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn work_num(&self) -> usize {
|
|
||||||
self.pool.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn worker(
|
|
||||||
&self,
|
|
||||||
datetime: DateTime<Utc>,
|
|
||||||
path: impl AsRef<str> + Send + 'static,
|
|
||||||
) -> BoxFuture<'static, RenderR> {
|
|
||||||
Box::pin(async move {
|
|
||||||
let loader = PLUGIN_MANAGER.get_plugin_by_name("etws_loader").unwrap();
|
|
||||||
let mut loaded_data = loader.load(path.as_ref().into()).unwrap();
|
|
||||||
let first_block = loaded_data.blocks.pop().unwrap();
|
|
||||||
if let Some((_, layer)) = data_to_layer(first_block) {
|
|
||||||
let handle = task::spawn_blocking(move || {
|
|
||||||
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
|
||||||
let canvas_wrapper = offscreen_renderer.create_canvas();
|
|
||||||
let canvas_mutex = std::sync::Arc::new(std::sync::Mutex::new(canvas_wrapper));
|
|
||||||
|
|
||||||
let f = {
|
|
||||||
let p = layer.get_prepare();
|
|
||||||
let mut _p = p.lock().unwrap();
|
|
||||||
_p.take()
|
|
||||||
};
|
|
||||||
|
|
||||||
let target = if let Some(f) = f {
|
|
||||||
let imp = layer.get_imp().unwrap();
|
|
||||||
let map: Mapper = Mercator::default().into();
|
|
||||||
let cms = CMS::new(map, (3000.0, 3000.0));
|
|
||||||
let canvas = canvas_mutex.clone();
|
|
||||||
let c = f(imp, canvas.clone(), cms);
|
|
||||||
let canvas = canvas.lock().unwrap();
|
|
||||||
Some(c)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
layer.set_render_target(target.unwrap());
|
|
||||||
layer
|
|
||||||
});
|
|
||||||
let target = handle.await.unwrap();
|
|
||||||
Ok(RenderResult::new(target, datetime, loaded_data.meta.into()))
|
|
||||||
} else {
|
|
||||||
println!("no layer");
|
|
||||||
Err(RenderError::None)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_task<TASK>(&mut self, timestamp: i64, task: TASK, tx: oneshot::Sender<RenderR>)
|
|
||||||
where
|
|
||||||
TASK: Future<Output = RenderR> + 'static + Send,
|
|
||||||
{
|
|
||||||
let future = async move {
|
|
||||||
let data = task.await;
|
|
||||||
tx.send(data).unwrap();
|
|
||||||
};
|
|
||||||
|
|
||||||
self.pool.push(Box::pin(future));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(value: &mut Self) -> BoxFuture<'static, ()> {
|
|
||||||
let pool = value.get_pool();
|
|
||||||
Box::pin(async move {
|
|
||||||
for f in pool.into_iter() {
|
|
||||||
task::spawn(f);
|
|
||||||
// f.await;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn listening<F>(&mut self, f: F) -> BoxFuture<'static, ()>
|
|
||||||
where
|
|
||||||
F: Fn(oneshot::Receiver<RenderR>, usize) -> BoxFuture<'static, ()> + Send + 'static + Sync,
|
|
||||||
{
|
|
||||||
let mut handler = self.handlers.take().unwrap();
|
|
||||||
Box::pin(async move {
|
|
||||||
let l = handler.into_iter().enumerate().map(|(h, i)| f(i, h));
|
|
||||||
for f in l.into_iter() {
|
|
||||||
f.await;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn listening_one_by_one<F>(&mut self, f: Vec<F>) -> BoxFuture<'static, ()>
|
|
||||||
where
|
|
||||||
F: FnOnce(oneshot::Receiver<RenderR>) -> BoxFuture<'static, ()> + Send + 'static + Sync,
|
|
||||||
{
|
|
||||||
let mut handler = self.handlers.take().unwrap();
|
|
||||||
Box::pin(async move {
|
|
||||||
for (h, f) in handler.into_iter().zip(f) {
|
|
||||||
task::spawn(f(h));
|
|
||||||
// f(h).await;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_pool(&mut self) -> Vec<BoxFuture<'static, ()>> {
|
|
||||||
use std::mem::replace;
|
|
||||||
let pool = replace(&mut self.pool, Vec::new());
|
|
||||||
pool
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cancel_task(&mut self, timestamp: i64) {}
|
|
||||||
}
|
|
||||||
@ -26,11 +26,12 @@ macro_rules! impl_for_runner {
|
|||||||
$(
|
$(
|
||||||
$t(ref v) => {
|
$t(ref v) => {
|
||||||
let input = ArrayViewD::from_shape($size, v.as_ref()).unwrap();
|
let input = ArrayViewD::from_shape($size, v.as_ref()).unwrap();
|
||||||
let data = ElementInput::Grid(input);
|
let data = input.into();
|
||||||
$imp.process($dims, data, $config, $context );
|
$imp.process($dims, data, $config, $context )
|
||||||
}
|
}
|
||||||
|
|
||||||
)+
|
)+
|
||||||
|
_ => { panic!("") }
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -50,7 +51,7 @@ impl<'a> Runner<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self, data: &PluginResult) -> Target {
|
pub fn run(&mut self, data: &PluginResult) -> (Target, Option<String>) {
|
||||||
use femtovg::{ImageFlags, PixelFormat::Rgba8};
|
use femtovg::{ImageFlags, PixelFormat::Rgba8};
|
||||||
let canvas = &mut self.context.canvas;
|
let canvas = &mut self.context.canvas;
|
||||||
let (w, h) = (canvas.width(), canvas.height());
|
let (w, h) = (canvas.width(), canvas.height());
|
||||||
@ -62,7 +63,7 @@ impl<'a> Runner<'a> {
|
|||||||
canvas.set_render_target(RenderTarget::Image(new_img));
|
canvas.set_render_target(RenderTarget::Image(new_img));
|
||||||
|
|
||||||
// Drawing
|
// Drawing
|
||||||
let dims = self.run_without_target(data);
|
let (dims, key) = self.run_without_target(data);
|
||||||
|
|
||||||
// Reading Pixels
|
// Reading Pixels
|
||||||
let mut pixels: Vec<u8> = vec![0; w as usize * h as usize * 4];
|
let mut pixels: Vec<u8> = vec![0; w as usize * h as usize * 4];
|
||||||
@ -79,21 +80,28 @@ impl<'a> Runner<'a> {
|
|||||||
debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
|
debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
|
||||||
}
|
}
|
||||||
self.context.canvas.set_render_target(RenderTarget::Screen);
|
self.context.canvas.set_render_target(RenderTarget::Screen);
|
||||||
let d1_start = (dims.0.view()).first().unwrap().clone();
|
// let d1_start = (dims.0.view()).first().unwrap().clone();
|
||||||
let d1_end = (dims.0.view()).last().unwrap().clone();
|
// let d1_end = (dims.0.view()).last().unwrap().clone();
|
||||||
let d2_start = dims.1.view().first().unwrap().clone();
|
// let d2_start = dims.1.view().first().unwrap().clone();
|
||||||
let d2_end = dims.1.view().last().unwrap().clone();
|
// let d2_end = dims.1.view().last().unwrap().clone();
|
||||||
|
|
||||||
Target::new(
|
let lon_range = data.meta.lon_range.unwrap().to_vec();
|
||||||
|
let lat_range = data.meta.lat_range.unwrap().to_vec();
|
||||||
|
|
||||||
|
(Target::new(
|
||||||
TargetType::NativeBuffer(pixels),
|
TargetType::NativeBuffer(pixels),
|
||||||
w as f32,
|
w as f32,
|
||||||
h as f32,
|
h as f32,
|
||||||
((d1_start, d1_end).into(), (d2_start, d2_end).into()),
|
((lon_range[0], lon_range[1]).into(), (lat_range[0], lat_range[1]).into()),
|
||||||
None,
|
None,
|
||||||
)
|
), key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_without_target(&mut self, data: &PluginResult) -> (Array2<f64>, Array2<f64>) {
|
pub fn run_without_target(&mut self, data: &PluginResult) -> ((Array2<f64>, Array2<f64>), Option<String>) {
|
||||||
|
|
||||||
|
let lon_range = data.meta.lon_range.unwrap().to_vec();
|
||||||
|
let lat_range = data.meta.lat_range.unwrap().to_vec();
|
||||||
|
|
||||||
let block = data.blocks.first().unwrap();
|
let block = data.blocks.first().unwrap();
|
||||||
let data = &block.data;
|
let data = &block.data;
|
||||||
let dims = &block.dimension_values;
|
let dims = &block.dimension_values;
|
||||||
@ -119,19 +127,12 @@ impl<'a> Runner<'a> {
|
|||||||
let cms = &mut context.cms;
|
let cms = &mut context.cms;
|
||||||
let canvas = &mut context.canvas;
|
let canvas = &mut context.canvas;
|
||||||
let (w, h) = (canvas.width(), canvas.height());
|
let (w, h) = (canvas.width(), canvas.height());
|
||||||
|
cms.set_lat_range(lat_range[0]..lat_range[1]);
|
||||||
let lat_start = dims.1.view().first().unwrap().clone();
|
cms.set_lon_range(lon_range[0]..lon_range[1]);
|
||||||
let lat_end = dims.1.view().last().unwrap().clone();
|
|
||||||
|
|
||||||
let lon_start = dims.0.view().first().unwrap().clone();
|
|
||||||
let lon_end = dims.0.view().last().unwrap().clone();
|
|
||||||
|
|
||||||
cms.set_lat_range(lat_start..lat_end);
|
|
||||||
cms.set_lon_range(lon_start..lon_end);
|
|
||||||
|
|
||||||
use VecResult::*;
|
use VecResult::*;
|
||||||
|
|
||||||
impl_for_runner!(
|
let unique_key = impl_for_runner!(
|
||||||
imp,
|
imp,
|
||||||
data,
|
data,
|
||||||
(dims.0.view(), dims.1.view()),
|
(dims.0.view(), dims.1.view()),
|
||||||
@ -149,6 +150,6 @@ impl<'a> Runner<'a> {
|
|||||||
{ U32 },
|
{ U32 },
|
||||||
);
|
);
|
||||||
context.canvas.flush();
|
context.canvas.flush();
|
||||||
dims
|
(dims, unique_key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ macro_rules! match_in_macro_3d {
|
|||||||
let data_shape: Vec<usize> = $block.size.into();
|
let data_shape: Vec<usize> = $block.size.into();
|
||||||
let coord_type = match $block.coord_type{
|
let coord_type = match $block.coord_type{
|
||||||
radarg_plugin_interface::CoordType::Cartesian => CoordType::LatLon,
|
radarg_plugin_interface::CoordType::Cartesian => CoordType::LatLon,
|
||||||
radarg_plugin_interface::CoordType::Polar => CoordType::Polar,
|
radarg_plugin_interface::CoordType::Polar(loc, range) => CoordType::Polar((loc.x, loc.y, loc.z), range),
|
||||||
_ => panic!("Unsupported coord type")
|
_ => panic!("Unsupported coord type")
|
||||||
};
|
};
|
||||||
match data {
|
match data {
|
||||||
@ -48,7 +48,7 @@ macro_rules! match_in_macro {
|
|||||||
let data_shape: Vec<usize> = $block.size.into();
|
let data_shape: Vec<usize> = $block.size.into();
|
||||||
let coord_type = match $block.coord_type{
|
let coord_type = match $block.coord_type{
|
||||||
radarg_plugin_interface::CoordType::Cartesian => CoordType::LatLon,
|
radarg_plugin_interface::CoordType::Cartesian => CoordType::LatLon,
|
||||||
radarg_plugin_interface::CoordType::Polar => CoordType::Polar,
|
radarg_plugin_interface::CoordType::Polar(loc, range) => CoordType::Polar((loc.x, loc.y, loc.z), range),
|
||||||
_ => panic!("Unsupported coord type")
|
_ => panic!("Unsupported coord type")
|
||||||
};
|
};
|
||||||
match data {
|
match data {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use super::{Layer, WindowCoord};
|
|||||||
use crate::coords::proj::Mercator;
|
use crate::coords::proj::Mercator;
|
||||||
use crate::coords::Mapper;
|
use crate::coords::Mapper;
|
||||||
use crate::map_tile::MapTile;
|
use crate::map_tile::MapTile;
|
||||||
use crate::pipeline::new_element::{Target, TargetType};
|
use crate::pipeline::element::{Target, TargetType};
|
||||||
use femtovg::{Canvas, Color, FontId, Paint, Renderer};
|
use femtovg::{Canvas, Color, FontId, Paint, Renderer};
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use gtk::glib::{self, prelude::*, Properties};
|
use gtk::glib::{self, prelude::*, Properties};
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use super::super::Render;
|
use super::super::Render;
|
||||||
use crate::errors::PipelineError;
|
use crate::errors::PipelineError;
|
||||||
use crate::pipeline::new_element::{self, Target};
|
use crate::pipeline::element::{self, Target};
|
||||||
use crate::pipeline::new_element::{Element, ElementEvent};
|
use crate::pipeline::element::{Element, ElementEvent};
|
||||||
use crate::RUNTIME;
|
use crate::RUNTIME;
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user