rebuild factor
This commit is contained in:
parent
6ceebdd7f4
commit
3a9f0dcaa3
10
.dir-locals.el
Normal file
10
.dir-locals.el
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
((nil . ((eval . (progn
|
||||||
|
;; radar_g 调试配置
|
||||||
|
(dap-register-debug-template
|
||||||
|
"radar_g::LLDB"
|
||||||
|
(list :type "lldb"
|
||||||
|
:request "launch"
|
||||||
|
:name "radar_g::LLDB"
|
||||||
|
:gdbpath "~/.cargo/bin/rust-lldb"
|
||||||
|
:program "${workspaceFolder}/target/debug/cinrad_g"
|
||||||
|
:cwd "${workspaceFolder}"))
|
||||||
18
Cargo.lock
generated
18
Cargo.lock
generated
@ -779,7 +779,7 @@ dependencies = [
|
|||||||
"proj",
|
"proj",
|
||||||
"proj-sys",
|
"proj-sys",
|
||||||
"quadtree_rs",
|
"quadtree_rs",
|
||||||
"quick_cache",
|
"quick_cache 0.4.3",
|
||||||
"radarg_core",
|
"radarg_core",
|
||||||
"radarg_plugin_interface",
|
"radarg_plugin_interface",
|
||||||
"rayon",
|
"rayon",
|
||||||
@ -1838,6 +1838,7 @@ dependencies = [
|
|||||||
"nom",
|
"nom",
|
||||||
"nom-derive",
|
"nom-derive",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"paste 1.0.15",
|
||||||
"pathfinder_geometry",
|
"pathfinder_geometry",
|
||||||
"radarg_core",
|
"radarg_core",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
@ -4159,6 +4160,18 @@ dependencies = [
|
|||||||
"parking_lot",
|
"parking_lot",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick_cache"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "27a893a83255c587d31137bc7e350387b49267b0deac44120fd8fa8bd0d61645"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
"parking_lot",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.6.13"
|
version = "0.6.13"
|
||||||
@ -4181,12 +4194,15 @@ dependencies = [
|
|||||||
name = "radarg_core"
|
name = "radarg_core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"abi_stable",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"core_extensions",
|
||||||
"dirs",
|
"dirs",
|
||||||
"ndarray 0.16.1",
|
"ndarray 0.16.1",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"proj",
|
"proj",
|
||||||
"proj-sys",
|
"proj-sys",
|
||||||
|
"quick_cache 0.6.5",
|
||||||
"radarg_plugin_interface",
|
"radarg_plugin_interface",
|
||||||
"relm4",
|
"relm4",
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
|
|||||||
@ -43,6 +43,7 @@ femtovg = "0.9.2"
|
|||||||
rust-embed = "8.5.0"
|
rust-embed = "8.5.0"
|
||||||
tempfile = "3.12.0"
|
tempfile = "3.12.0"
|
||||||
relm4 = { version = "0.9.0", features = ["libadwaita"] }
|
relm4 = { version = "0.9.0", features = ["libadwaita"] }
|
||||||
|
paste = "1.0.15"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["sdf_font"]
|
default = ["sdf_font"]
|
||||||
|
|||||||
@ -13,8 +13,8 @@ pub enum Error {
|
|||||||
#[error("Invalid Program {0}")]
|
#[error("Invalid Program {0}")]
|
||||||
InvalidProgram(String),
|
InvalidProgram(String),
|
||||||
|
|
||||||
#[error("Invalid CoordType")]
|
#[error("Error: {0}")]
|
||||||
InvalidDataType,
|
InvalidDataType(String),
|
||||||
|
|
||||||
#[error("Init Error, cause of {0}")]
|
#[error("Init Error, cause of {0}")]
|
||||||
InitError(anyhow::Error),
|
InitError(anyhow::Error),
|
||||||
|
|||||||
@ -106,14 +106,14 @@ impl Graphics for AggFastPath {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mount(&mut self, gl: &glow::Context) -> Result<()> {
|
fn mount(&self, gl: &glow::Context) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.use_program(self.program.native_program);
|
gl.use_program(self.program.native_program);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unmount(&mut self, gl: &glow::Context) -> Result<()> {
|
fn unmount(&self, gl: &glow::Context) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.use_program(None);
|
gl.use_program(None);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ pub trait Graphics {
|
|||||||
|
|
||||||
fn program_mut(&mut self) -> &mut Program;
|
fn program_mut(&mut self) -> &mut Program;
|
||||||
|
|
||||||
fn mount(&mut self, gl: &glow::Context) -> Result<()> {
|
fn mount(&self, gl: &glow::Context) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.use_program(self.program_ref().native_program.clone());
|
gl.use_program(self.program_ref().native_program.clone());
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ pub trait Graphics {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unmount(&mut self, gl: &glow::Context) -> Result<()> {
|
fn unmount(&self, gl: &glow::Context) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.use_program(None);
|
gl.use_program(None);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,7 @@ impl PPI {
|
|||||||
|
|
||||||
pub fn data_info(&self, data: &RadarGridData) -> Result<(f32, f32, ProbeDataType, usize, f32)> {
|
pub fn data_info(&self, data: &RadarGridData) -> Result<(f32, f32, ProbeDataType, usize, f32)> {
|
||||||
if data.coord_type().is_none() {
|
if data.coord_type().is_none() {
|
||||||
return Err(Error::InvalidDataType);
|
return Err(Error::InvalidDataType(format!("Invalid CoordType")));
|
||||||
}
|
}
|
||||||
match data.coord_type().unwrap() {
|
match data.coord_type().unwrap() {
|
||||||
CoordType::Polar {
|
CoordType::Polar {
|
||||||
@ -79,7 +79,7 @@ impl PPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::InvalidDataType);
|
return Err(Error::InvalidDataType(format!("Invalid CoordType")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,14 +163,14 @@ impl Graphics for PPI {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mount(&mut self, gl: &glow::Context) -> Result<()> {
|
fn mount(&self, gl: &glow::Context) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.use_program(self.program.native_program);
|
gl.use_program(self.program.native_program);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unmount(&mut self, gl: &glow::Context) -> Result<()> {
|
fn unmount(&self, gl: &glow::Context) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.use_program(None);
|
gl.use_program(None);
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ impl AttaWithBuffer for PPI {
|
|||||||
return Ok((vertices, None, len));
|
return Ok((vertices, None, len));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::InvalidDataType);
|
return Err(Error::InvalidDataType(format!("Invalid CoordType")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use log::*;
|
use log::*;
|
||||||
use radarg_core::radarg_data::Data;
|
use radarg_core::{datapool::Value, radarg_data::Data};
|
||||||
use std::{cell::RefCell, path::PathBuf, rc::Rc};
|
use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::*,
|
errors::*,
|
||||||
@ -19,7 +19,10 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
|
|
||||||
use super::layout_type::{self, ViewPort};
|
use super::{
|
||||||
|
layout_type::{self, ViewPort},
|
||||||
|
ModuleRefs,
|
||||||
|
};
|
||||||
use super::{ModulePackage, Programs};
|
use super::{ModulePackage, Programs};
|
||||||
use crate::{font_manager::FontManager, graphics::font::Text};
|
use crate::{font_manager::FontManager, graphics::font::Text};
|
||||||
|
|
||||||
@ -61,17 +64,12 @@ impl App {
|
|||||||
&mut self.context.programs
|
&mut self.context.programs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn supported_modules(&mut self) -> Vec<super::Modules> {
|
pub fn supported_modules<'a>(
|
||||||
self.program().supported_modules()
|
&mut self,
|
||||||
|
data: &'a Value<Data>,
|
||||||
|
) -> HashMap<&'a Arc<Data>, Vec<ModuleRefs>> {
|
||||||
|
self.program().supported_modules(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn load_data(
|
|
||||||
// &mut self,
|
|
||||||
// data: &Vec<Data>,
|
|
||||||
// setting: &radarg_core::config::Setting,
|
|
||||||
// ) -> Result<ModulePackage> {
|
|
||||||
// self.program().load_data(data, setting)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
|
|||||||
@ -3,8 +3,11 @@ use femtovg::renderer::OpenGl;
|
|||||||
use femtovg::Canvas;
|
use femtovg::Canvas;
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use layout_type::ViewPort;
|
use layout_type::ViewPort;
|
||||||
use modules::PPIModuleConfigComponent;
|
use modules::{PPIModuleConfigComponent, PPIModuleRef};
|
||||||
use radarg_core::radarg_data::Data;
|
use radarg_core::{datapool::Value, radarg_data::Data};
|
||||||
|
|
||||||
|
use paste::paste;
|
||||||
|
|
||||||
use relm4::{
|
use relm4::{
|
||||||
gtk,
|
gtk,
|
||||||
gtk::prelude::{Cast, IsA},
|
gtk::prelude::{Cast, IsA},
|
||||||
@ -14,22 +17,22 @@ use relm4::{
|
|||||||
pub mod layout_type;
|
pub mod layout_type;
|
||||||
mod modules;
|
mod modules;
|
||||||
|
|
||||||
use crate::font_manager::FontManager;
|
use crate::{
|
||||||
use crate::graphics::collections::agg_fast_path::AggFastPath;
|
errors::*,
|
||||||
use crate::graphics::font::Text;
|
font_manager::FontManager,
|
||||||
use crate::graphics::ppi::PPI;
|
graphics::{
|
||||||
use crate::graphics::threed::Trackball;
|
collections::agg_fast_path::AggFastPath, font::Text, ppi::PPI,
|
||||||
use crate::graphics::transforms::plane::PlaneTrans;
|
transforms::plane::PlaneTrans, AttaWithProgram, AttachWithIO, Graphics,
|
||||||
use crate::graphics::{AttaWithProgram, AttachWithIO};
|
},
|
||||||
use crate::ui::operation::Operation;
|
ui::{operation::Operation, typ::LayoutAttach},
|
||||||
use crate::ui::typ::LayoutAttach;
|
utils::resources::GL,
|
||||||
use crate::utils::resources::GL;
|
};
|
||||||
use crate::{errors::*, graphics::Graphics};
|
|
||||||
pub use app::{App, Context};
|
pub use app::{App, Context};
|
||||||
pub use modules::{Module, ModuleCursor, PPIModule, PPIPackage};
|
pub use modules::{Module, ModuleCursor, PPIModule, PPIPackage};
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
|
use std::{cell::RefCell, collections::HashMap};
|
||||||
|
use std::{rc::Rc, sync::Arc};
|
||||||
|
|
||||||
static MODULE_PACKAGE_ID: AtomicUsize = AtomicUsize::new(0);
|
static MODULE_PACKAGE_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
@ -77,19 +80,22 @@ impl Programs {
|
|||||||
PPIModule::new(&self.gl, &mut self._ppi, &mut self._text, &mut self._line)
|
PPIModule::new(&self.gl, &mut self._ppi, &mut self._text, &mut self._line)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn supported_modules(&mut self) -> Vec<Modules> {
|
pub fn ppi_ref(&self) -> PPIModuleRef {
|
||||||
vec![Modules::PPI(self.ppi())]
|
PPIModuleRef::new(&self.gl, &self._ppi, &self._text, &self._line)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn load_data(
|
pub fn supported_modules<'a>(
|
||||||
// &mut self,
|
&mut self,
|
||||||
// data: &Vec<Data>,
|
data: &'a Value<Data>,
|
||||||
// setting: &radarg_core::config::Setting,
|
) -> HashMap<&'a Arc<Data>, Vec<ModuleRefs>> {
|
||||||
// ) -> Result<Vec<ModulePackage>> {
|
let mut result = HashMap::new();
|
||||||
// data.iter()
|
|
||||||
// .map(|d| self.ppi().load_data(, setting).map(|v| v.into()))
|
for (k, d) in data.iter() {
|
||||||
// .collect()
|
result.insert(d, vec![ModuleRefs::PPI(self.ppi_ref())]);
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw_modules(
|
pub fn draw_modules(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -108,7 +114,7 @@ impl Programs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_module_package {
|
macro_rules! impl_module_package {
|
||||||
($({$t:ty => $b: tt | $module:tt | $c: ty}),+) => {
|
($({$t:ty => $b: tt | $module:tt | $module_ref:tt | $c: ty}),+) => {
|
||||||
|
|
||||||
pub enum Modules<'b, 'gl: 'b>{
|
pub enum Modules<'b, 'gl: 'b>{
|
||||||
$(
|
$(
|
||||||
@ -116,6 +122,35 @@ macro_rules! impl_module_package {
|
|||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ModuleRefs<'b, 'gl:'b>{
|
||||||
|
$(
|
||||||
|
$b($module_ref<'b,'gl>)
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Modules<'_, '_> {
|
||||||
|
pub fn load_data(&self, data:&Data, setting: &radarg_core::config::Setting) -> Result<ModulePackage> {
|
||||||
|
match self {
|
||||||
|
$(
|
||||||
|
Modules::$b(m) => {
|
||||||
|
let cursor = m.load_data(data.into(), setting)?;
|
||||||
|
Ok(cursor.into())
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModuleRefs<'_, '_> {
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
$(
|
||||||
|
ModuleRefs::$b(m) => m.name(),
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum _ModulePackage {
|
pub enum _ModulePackage {
|
||||||
$(
|
$(
|
||||||
@ -209,7 +244,7 @@ macro_rules! impl_module_package {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl_module_package!(
|
impl_module_package!(
|
||||||
{PPIPackage => PPI | PPIModule | PPIModuleConfigComponent}
|
{PPIPackage => PPI | PPIModule | PPIModuleRef | PPIModuleConfigComponent}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl ModulePackage {
|
impl ModulePackage {
|
||||||
|
|||||||
@ -11,10 +11,13 @@ use crate::{
|
|||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||||
use radarg_core::config::Setting;
|
use radarg_core::config::Setting;
|
||||||
use std::{cell::RefCell, path::Component, rc::Rc};
|
use std::{cell::RefCell, path::Component, rc::Rc, sync::Arc};
|
||||||
mod ppi;
|
mod ppi;
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
pub use ppi::{PPIModule, PPIModuleConfigComponent, PPIModuleConfigComponentWidgets, PPIPackage};
|
pub use ppi::{
|
||||||
|
PPIModule, PPIModuleConfigComponent, PPIModuleConfigComponentWidgets, PPIModuleRef, PPIPackage,
|
||||||
|
};
|
||||||
|
|
||||||
use relm4::Component as RComponent;
|
use relm4::Component as RComponent;
|
||||||
|
|
||||||
use super::{layout_type::ViewPort, SideBarInputMsg};
|
use super::{layout_type::ViewPort, SideBarInputMsg};
|
||||||
@ -95,6 +98,8 @@ pub trait Module: Sized {
|
|||||||
type Data;
|
type Data;
|
||||||
type Operation: AttachWithIO;
|
type Operation: AttachWithIO;
|
||||||
|
|
||||||
|
const NAME: &'static str;
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
cursor: &mut Self::Cursor,
|
cursor: &mut Self::Cursor,
|
||||||
@ -102,7 +107,7 @@ pub trait Module: Sized {
|
|||||||
viewport: &ViewPort,
|
viewport: &ViewPort,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
|
|
||||||
fn load_data<'dt>(&self, data: &Rc<Self::Data>, setting: &Setting) -> Result<Self::Cursor>;
|
fn load_data<'dt>(&self, data: &Arc<Self::Data>, setting: &Setting) -> Result<Self::Cursor>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ModuleCursor {
|
pub trait ModuleCursor {
|
||||||
|
|||||||
@ -21,6 +21,7 @@ use glow::HasContext;
|
|||||||
use std::{
|
use std::{
|
||||||
cell::{RefCell, RefMut},
|
cell::{RefCell, RefMut},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use tracker::track;
|
use tracker::track;
|
||||||
|
|
||||||
@ -40,6 +41,125 @@ pub struct PPIModule<'b, 'gl: 'b> {
|
|||||||
text_program: &'b mut Text,
|
text_program: &'b mut Text,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct PPIModuleRef<'b, 'gl: 'b> {
|
||||||
|
gl: &'gl GL,
|
||||||
|
ppi_program: &'b PPI,
|
||||||
|
line_program: &'b AggFastPath,
|
||||||
|
text_program: &'b Text,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b, 'a: 'b> PPIModuleRef<'b, 'a> {
|
||||||
|
pub fn new(gl: &'a GL, ppi: &'b PPI, text: &'b Text, line: &'b AggFastPath) -> Self {
|
||||||
|
let config = PPIConfig::default();
|
||||||
|
Self {
|
||||||
|
gl,
|
||||||
|
ppi_program: ppi,
|
||||||
|
text_program: text,
|
||||||
|
line_program: line,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_ppi_pg(
|
||||||
|
&self,
|
||||||
|
attach: &mut Attach,
|
||||||
|
data: &RadarGridData,
|
||||||
|
config: &PPIModuleConfig,
|
||||||
|
) -> Result<()> {
|
||||||
|
let (vbo, ebo, len) = self
|
||||||
|
.ppi_program
|
||||||
|
.bake(&self.gl, data, &config.to_ppi_config())?;
|
||||||
|
attach.bind_data(&vbo, ebo.as_ref(), len, glow::DYNAMIC_DRAW);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_line_pg(
|
||||||
|
&self,
|
||||||
|
attach: &mut Attach,
|
||||||
|
data: &RadarGridData,
|
||||||
|
config: &PPIModuleConfig,
|
||||||
|
) -> Result<()> {
|
||||||
|
let raw_config = config.to_line_config();
|
||||||
|
|
||||||
|
// Will be changed in the future
|
||||||
|
let outskirt = 10.0;
|
||||||
|
|
||||||
|
let mut paths = vec![];
|
||||||
|
|
||||||
|
let range_line_num = config.range_line_num;
|
||||||
|
let r = outskirt / range_line_num as f32;
|
||||||
|
let seg_num = 200;
|
||||||
|
let angle = 2f32 * f32::consts::PI / seg_num as f32;
|
||||||
|
|
||||||
|
for range in 1..=range_line_num {
|
||||||
|
// Create the path
|
||||||
|
let mut path = Path::new(true);
|
||||||
|
let r = r * range as f32;
|
||||||
|
// Draw the circle
|
||||||
|
for seg in 0..seg_num {
|
||||||
|
let angle = angle * seg as f32;
|
||||||
|
let x = (angle.cos() * r) as f32;
|
||||||
|
let y = (angle.sin() * r) as f32;
|
||||||
|
path.push([x, y, 0.01]);
|
||||||
|
}
|
||||||
|
path.finish();
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ath_lin_num = config.ath_line_num;
|
||||||
|
|
||||||
|
let a = 2.0 * f32::consts::PI / ath_lin_num as f32;
|
||||||
|
for _a in 0..=ath_lin_num {
|
||||||
|
let mut path = Path::new(false);
|
||||||
|
let x = (a * _a as f32).cos() * outskirt;
|
||||||
|
let y = (a * _a as f32).sin() * outskirt;
|
||||||
|
path.push([0.0, 0.0, 0.01]);
|
||||||
|
path.push([x, y, 0.01]);
|
||||||
|
path.finish();
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.vertical_axis {
|
||||||
|
let mut path = Path::new(false);
|
||||||
|
path.push([0.0, 0.0, 0.0]);
|
||||||
|
path.push([0.0, 0.0, outskirt]);
|
||||||
|
path.finish();
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (vbo, ebo, len) = self.line_program.bake(&self.gl, &paths, &raw_config)?;
|
||||||
|
attach.bind_data(&vbo, ebo.as_ref(), len, glow::STATIC_DRAW);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_tick(
|
||||||
|
&self,
|
||||||
|
attach: &mut Attach,
|
||||||
|
data: &RadarGridData,
|
||||||
|
config: &PPIModuleConfig,
|
||||||
|
) -> Result<()> {
|
||||||
|
let font_style = config.to_font_config();
|
||||||
|
|
||||||
|
match font_style {
|
||||||
|
FontConfig::Textline(line_style, font_style) => {
|
||||||
|
let new_text = TextLine::new("Hello,World", Some(font_style), None);
|
||||||
|
let position_text =
|
||||||
|
PositionText::new(new_text, [0.0, 0.0, 0.0], Anchor::BottomCenter);
|
||||||
|
let text_pg_config = config.to_font_config();
|
||||||
|
let (vbo, ebo, len) =
|
||||||
|
self.text_program
|
||||||
|
.bake(&self.gl, &position_text, &text_pg_config)?;
|
||||||
|
attach.bind_data(&vbo, ebo.as_ref(), len, glow::STATIC_DRAW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
"PPI"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
gl: &'a GL,
|
gl: &'a GL,
|
||||||
@ -158,6 +278,8 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
type Data = RadarGridData;
|
type Data = RadarGridData;
|
||||||
type Operation = PlaneTrans;
|
type Operation = PlaneTrans;
|
||||||
|
|
||||||
|
const NAME: &'static str = "PPI";
|
||||||
|
|
||||||
fn render<'dt>(
|
fn render<'dt>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cursor: &mut Self::Cursor,
|
cursor: &mut Self::Cursor,
|
||||||
@ -238,7 +360,7 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_data<'dt>(&self, data: &Rc<Self::Data>, setting: &Setting) -> Result<Self::Cursor> {
|
fn load_data<'dt>(&self, data: &Arc<Self::Data>, setting: &Setting) -> Result<Self::Cursor> {
|
||||||
// Init the memory
|
// Init the memory
|
||||||
let (vao, vbo, ebo) = self.ppi_program.init(&self.gl);
|
let (vao, vbo, ebo) = self.ppi_program.init(&self.gl);
|
||||||
let mut ppi_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, None);
|
let mut ppi_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, None);
|
||||||
@ -246,12 +368,17 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
// Get the data info
|
// Get the data info
|
||||||
let (r, a, t, max_layer, unvalid) = self.ppi_program.data_info(&data)?;
|
let (r, a, t, max_layer, unvalid) = self.ppi_program.data_info(&data)?;
|
||||||
|
|
||||||
|
println!("name: {}", data.info.value_name);
|
||||||
|
|
||||||
// Find the color map
|
// Find the color map
|
||||||
let cmap = setting.find(&t);
|
let cmap = setting.find(&t);
|
||||||
|
|
||||||
// Check if the color map is valid
|
// Check if the color map is valid
|
||||||
if cmap.is_none() {
|
if cmap.is_none() {
|
||||||
return Err(Error::InvalidDataType);
|
return Err(Error::InvalidDataType(format!(
|
||||||
|
"{}'s colormap is not found",
|
||||||
|
data.info.value_name
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
let cmap = cmap.unwrap();
|
let cmap = cmap.unwrap();
|
||||||
|
|
||||||
@ -294,7 +421,7 @@ pub struct PPIPackage {
|
|||||||
ppi_attach: Attach,
|
ppi_attach: Attach,
|
||||||
line_attach: Attach,
|
line_attach: Attach,
|
||||||
tick_attach: Attach,
|
tick_attach: Attach,
|
||||||
data: Rc<RadarGridData>,
|
data: Arc<RadarGridData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PPIPackage {
|
impl PPIPackage {
|
||||||
@ -303,7 +430,7 @@ impl PPIPackage {
|
|||||||
ppi_attach: Attach,
|
ppi_attach: Attach,
|
||||||
line_attach: Attach,
|
line_attach: Attach,
|
||||||
tick_attach: Attach,
|
tick_attach: Attach,
|
||||||
data: Rc<RadarGridData>,
|
data: Arc<RadarGridData>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
draw_helper: true,
|
draw_helper: true,
|
||||||
@ -415,35 +542,71 @@ impl SimpleComponent for PPIModuleConfigComponent {
|
|||||||
type Output = OutputMsg;
|
type Output = OutputMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
adw::PreferencesGroup {
|
adw::PreferencesPage {
|
||||||
set_title:"PPI Config",
|
adw::PreferencesGroup {
|
||||||
set_hexpand:true,
|
set_title:"PPI Config",
|
||||||
set_vexpand:true,
|
set_hexpand:true,
|
||||||
adw::SwitchRow {
|
adw::SwitchRow {
|
||||||
set_title:"Ticks",
|
set_title:"Ticks",
|
||||||
set_active: init_config.ticks,
|
set_active: init_config.ticks,
|
||||||
connect_active_notify[sender, config_ref] => move |this| {
|
connect_active_notify[sender, config_ref] => move |this| {
|
||||||
let active = this.is_active();
|
let active = this.is_active();
|
||||||
config_ref.borrow_mut().set_ticks(active);
|
config_ref.borrow_mut().set_ticks(active);
|
||||||
}
|
sender.output(OutputMsg::Refresh);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
adw::SwitchRow{
|
||||||
|
set_title:"Three D",
|
||||||
|
set_active: init_config.is_three_d,
|
||||||
|
connect_active_notify[sender, config_ref] => move |this| {
|
||||||
|
let active = this.is_active();
|
||||||
|
config_ref.borrow_mut().set_is_three_d(active);
|
||||||
|
sender.output(OutputMsg::Refresh);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
adw::SpinRow {
|
||||||
|
set_title: "Layer",
|
||||||
|
set_digits: 0,
|
||||||
|
set_numeric: true,
|
||||||
|
set_snap_to_ticks: true,
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_adjustment=>k::Adjustment::new(
|
||||||
|
init_config.layer as f64 + 1.0,
|
||||||
|
1.0,
|
||||||
|
init_config.max_layer as f64,
|
||||||
|
1.0,
|
||||||
|
1.0,
|
||||||
|
1.0
|
||||||
|
),
|
||||||
|
connect_value_notify[sender, config_ref] => move |this| {
|
||||||
|
let layer = this.value() as usize - 1;
|
||||||
|
config_ref.borrow_mut().set_layer(layer);
|
||||||
|
sender.output(OutputMsg::Refresh);
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
adw::SpinRow {
|
adw::PreferencesGroup {
|
||||||
set_title: "Layer",
|
set_title:"Show Config",
|
||||||
set_value: init_config.layer as f64,
|
set_hexpand:true,
|
||||||
set_range: (0.0, init_config.max_layer as f64),
|
adw::PreferencesRow {
|
||||||
set_digits: 0,
|
set_title:"Color Line",
|
||||||
set_numeric: true,
|
#[wrap(Some)]
|
||||||
set_climb_rate: 1.0,
|
set_child=>k::Box{
|
||||||
connect_value_notify[sender, config_ref] => move |this| {
|
gtk::ColorDialogButton {
|
||||||
let layer = this.value() as usize;
|
set_dialog=>k::ColorDialog {},
|
||||||
config_ref.borrow_mut().set_layer(layer);
|
set_rgba: >k::gdk::RGBA::new(init_config.line_color[0], init_config.line_color[1],init_config.line_color[2],init_config.line_color[3]),
|
||||||
}
|
connect_rgba_notify[sender, config_ref] => move |this| {
|
||||||
},
|
let rgba = this.rgba();
|
||||||
gtk::Button {
|
let color = [rgba.red(), rgba.green(), rgba.blue(), rgba.alpha()];
|
||||||
set_label: "Refresh",
|
config_ref.borrow_mut().set_line_color(color);
|
||||||
connect_clicked[sender] => move |_| {
|
sender.output(OutputMsg::Refresh);
|
||||||
sender.output(OutputMsg::Refresh);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,3 +25,9 @@ pub struct IO {
|
|||||||
pub mouse: MouseIO,
|
pub mouse: MouseIO,
|
||||||
pub keyboard: KeyboardIO,
|
pub keyboard: KeyboardIO,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IO {
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.mouse.wheel_delta = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use nom::error::Error;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ETWSError {
|
pub enum ETWSError {
|
||||||
@ -6,9 +7,17 @@ pub enum ETWSError {
|
|||||||
#[from]
|
#[from]
|
||||||
source: std::io::Error,
|
source: std::io::Error,
|
||||||
},
|
},
|
||||||
#[error("Format Error")]
|
#[error("Unsupported Format")]
|
||||||
FormatError {
|
FormatError {
|
||||||
#[from]
|
#[from]
|
||||||
source: anyhow::Error,
|
source: anyhow::Error,
|
||||||
},
|
},
|
||||||
|
#[error("Binary Error")]
|
||||||
|
NomError,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<nom::Err<nom::error::Error<&'a [u8]>>> for ETWSError {
|
||||||
|
fn from(value: nom::Err<nom::error::Error<&'a [u8]>>) -> Self {
|
||||||
|
ETWSError::NomError
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -168,7 +168,7 @@ impl DataLoaderPlugin for ETWSLoader {
|
|||||||
{ "DBZ" | "CR" | "FR" | "R" => DBZ},
|
{ "DBZ" | "CR" | "FR" | "R" => DBZ},
|
||||||
{ "VIL" => VIL},
|
{ "VIL" => VIL},
|
||||||
{ "EB" => EB},
|
{ "EB" => EB},
|
||||||
{ "V" => V},
|
{ "V" | "VEL" => V},
|
||||||
{ "ZDR" => ZDR},
|
{ "ZDR" => ZDR},
|
||||||
{ "PHIDP" => PHIDP},
|
{ "PHIDP" => PHIDP},
|
||||||
{ "KDP" => KDP},
|
{ "KDP" => KDP},
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use crate::error::ETWSError;
|
||||||
use abi_stable::std_types::vec;
|
use abi_stable::std_types::vec;
|
||||||
use bytemuck::cast_slice;
|
use bytemuck::cast_slice;
|
||||||
use nom::{
|
use nom::{
|
||||||
@ -244,34 +245,84 @@ fn parse_sub_pulse_config(input: &[u8]) -> IResult<&[u8], SubPulseConfig> {
|
|||||||
Ok((input, sub_pulse_config))
|
Ok((input, sub_pulse_config))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_raw_data<P: AsRef<Path>>(path: P) -> io::Result<RadarData> {
|
pub fn parse_raw_data<P: AsRef<Path>>(path: P) -> Result<RadarData, ETWSError> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
|
|
||||||
|
if path.extension().is_none() {
|
||||||
|
if path.is_file() {
|
||||||
|
let mut file = File::open(path)?;
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
file.read_to_end(&mut buf).unwrap();
|
||||||
|
if &buf[0..4] == b"SSTM" || &buf[16..20] == b"STDM" || &buf[0..4] == b"RSTM" {
|
||||||
|
return get_radar_data(buf);
|
||||||
|
} else {
|
||||||
|
return Err(ETWSError::FormatError {
|
||||||
|
source: anyhow::anyhow!("Invalid file format"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(ETWSError::IOError {
|
||||||
|
source: io::Error::new(io::ErrorKind::NotFound, "File not found"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if path.extension().unwrap() == "zip" {
|
if path.extension().unwrap() == "zip" {
|
||||||
let file = File::open(path).unwrap();
|
let file = File::open(path).unwrap();
|
||||||
let mut archive = ZipArchive::new(file).unwrap();
|
let mut archive = ZipArchive::new(file).unwrap();
|
||||||
let mut file = archive.by_index(0).unwrap();
|
let mut file = archive.by_index(0).unwrap();
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
file.read_to_end(&mut buf).unwrap();
|
file.read_to_end(&mut buf)?;
|
||||||
|
if buf.len() < 4 {
|
||||||
|
return Err(ETWSError::FormatError {
|
||||||
|
source: anyhow::anyhow!("Invalid file format"),
|
||||||
|
});
|
||||||
|
}
|
||||||
if &buf[0..4] == b"SSTM" || &buf[16..20] == b"STDM" || &buf[0..4] == b"RSTM" {
|
if &buf[0..4] == b"SSTM" || &buf[16..20] == b"STDM" || &buf[0..4] == b"RSTM" {
|
||||||
return get_radar_data(buf);
|
return get_radar_data(buf);
|
||||||
} else {
|
} else {
|
||||||
panic!("Invalid file format");
|
return Err(ETWSError::FormatError {
|
||||||
|
source: anyhow::anyhow!("Invalid file format"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if path.extension().unwrap() == ".gz" {
|
||||||
|
let file = File::open(path)?;
|
||||||
|
let mut archive = flate2::read::GzDecoder::new(file);
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
archive.read_to_end(&mut buf)?;
|
||||||
|
if buf.len() < 4 {
|
||||||
|
return Err(ETWSError::FormatError {
|
||||||
|
source: anyhow::anyhow!("Invalid file format"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if &buf[0..4] == b"SSTM" || &buf[16..20] == b"STDM" || &buf[0..4] == b"RSTM" {
|
||||||
|
return get_radar_data(buf);
|
||||||
|
} else {
|
||||||
|
return Err(ETWSError::FormatError {
|
||||||
|
source: anyhow::anyhow!("Invalid file format"),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut file = File::open(path).unwrap();
|
let mut file = File::open(path)?;
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
file.read_to_end(&mut buf).unwrap();
|
file.read_to_end(&mut buf)?;
|
||||||
|
if buf.len() < 4 {
|
||||||
|
return Err(ETWSError::FormatError {
|
||||||
|
source: anyhow::anyhow!("Invalid file format"),
|
||||||
|
});
|
||||||
|
}
|
||||||
if &buf[0..4] == b"SSTM" || &buf[16..20] == b"STDM" || &buf[0..4] == b"RSTM" {
|
if &buf[0..4] == b"SSTM" || &buf[16..20] == b"STDM" || &buf[0..4] == b"RSTM" {
|
||||||
return get_radar_data(buf);
|
return get_radar_data(buf);
|
||||||
} else {
|
} else {
|
||||||
panic!("Invalid file format");
|
return Err(ETWSError::FormatError {
|
||||||
|
source: anyhow::anyhow!("Invalid file format"),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_radar_data(data: Vec<u8>) -> io::Result<RadarData> {
|
fn get_radar_data(data: Vec<u8>) -> Result<RadarData, ETWSError> {
|
||||||
let total_length = data.len() as u64;
|
let total_length = data.len() as u64;
|
||||||
// 使用 Cursor 来处理 Vec<u8>
|
// 使用 Cursor 来处理 Vec<u8>
|
||||||
let mut cursor = Cursor::new(data);
|
let mut cursor = Cursor::new(data);
|
||||||
@ -279,24 +330,24 @@ fn get_radar_data(data: Vec<u8>) -> io::Result<RadarData> {
|
|||||||
// 读取 GENERIC_HEADER
|
// 读取 GENERIC_HEADER
|
||||||
let mut buffer = vec![0u8; 32];
|
let mut buffer = vec![0u8; 32];
|
||||||
cursor.read_exact(&mut buffer)?;
|
cursor.read_exact(&mut buffer)?;
|
||||||
let (_, generic_header) = parse_generic_header(&buffer).unwrap();
|
let (_, generic_header) = parse_generic_header(&buffer)?;
|
||||||
|
|
||||||
// 读取 SITE_CONFIG
|
// 读取 SITE_CONFIG
|
||||||
let mut buffer = vec![0u8; 128];
|
let mut buffer = vec![0u8; 128];
|
||||||
cursor.read_exact(&mut buffer)?;
|
cursor.read_exact(&mut buffer)?;
|
||||||
let (_, site_config) = parse_site_config(&buffer).unwrap();
|
let (_, site_config) = parse_site_config(&buffer)?;
|
||||||
|
|
||||||
// 读取 TASK_CONFIG
|
// 读取 TASK_CONFIG
|
||||||
let mut buffer = vec![0u8; 256];
|
let mut buffer = vec![0u8; 256];
|
||||||
cursor.read_exact(&mut buffer)?;
|
cursor.read_exact(&mut buffer)?;
|
||||||
let (_, task_config) = parse_task_config(&buffer).unwrap();
|
let (_, task_config) = parse_task_config(&buffer)?;
|
||||||
|
|
||||||
// 读取 SCAN_CONFIG
|
// 读取 SCAN_CONFIG
|
||||||
let mut scan_configs = Vec::new();
|
let mut scan_configs = Vec::new();
|
||||||
for _ in 0..task_config.scan_beam_number {
|
for _ in 0..task_config.scan_beam_number {
|
||||||
let mut buffer = vec![0u8; 640];
|
let mut buffer = vec![0u8; 640];
|
||||||
cursor.read_exact(&mut buffer)?;
|
cursor.read_exact(&mut buffer)?;
|
||||||
let (_, scan_config) = parse_scan_config(&buffer).unwrap();
|
let (_, scan_config) = parse_scan_config(&buffer)?;
|
||||||
scan_configs.push(scan_config);
|
scan_configs.push(scan_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,7 +356,7 @@ fn get_radar_data(data: Vec<u8>) -> io::Result<RadarData> {
|
|||||||
for _ in 0..task_config.cut_number {
|
for _ in 0..task_config.cut_number {
|
||||||
let mut buffer = vec![0u8; 256];
|
let mut buffer = vec![0u8; 256];
|
||||||
cursor.read_exact(&mut buffer)?;
|
cursor.read_exact(&mut buffer)?;
|
||||||
let (_, beam_config) = parse_beam_config(&buffer).unwrap();
|
let (_, beam_config) = parse_beam_config(&buffer)?;
|
||||||
beam_configs.push(beam_config);
|
beam_configs.push(beam_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,19 +505,22 @@ fn parse_final_data(
|
|||||||
all_length: u64,
|
all_length: u64,
|
||||||
cut_number: usize,
|
cut_number: usize,
|
||||||
mut cursor: Cursor<Vec<u8>>,
|
mut cursor: Cursor<Vec<u8>>,
|
||||||
) -> io::Result<(
|
) -> Result<
|
||||||
HashMap<&'static str, Vec<f64>>,
|
(
|
||||||
Vec<f64>,
|
HashMap<&'static str, Vec<f64>>,
|
||||||
Vec<f64>,
|
Vec<f64>,
|
||||||
Vec<f64>,
|
Vec<f64>,
|
||||||
)> {
|
Vec<f64>,
|
||||||
|
),
|
||||||
|
ETWSError,
|
||||||
|
> {
|
||||||
let position = cursor.position();
|
let position = cursor.position();
|
||||||
let mut radial_buffer = vec![0u8; 128];
|
let mut radial_buffer = vec![0u8; 128];
|
||||||
let mut header_buffer = vec![0u8; 32];
|
let mut header_buffer = vec![0u8; 32];
|
||||||
cursor.read_exact(&mut radial_buffer)?;
|
cursor.read_exact(&mut radial_buffer)?;
|
||||||
|
|
||||||
// First Block
|
// First Block
|
||||||
let (_, radial_data) = parse_radial_data(&radial_buffer).unwrap();
|
let (_, radial_data) = parse_radial_data(&radial_buffer)?;
|
||||||
// Radial_number: I don't know why not use it.
|
// Radial_number: I don't know why not use it.
|
||||||
// let radial_number = radial_data.radial_number as usize;
|
// let radial_number = radial_data.radial_number as usize;
|
||||||
|
|
||||||
@ -480,7 +534,7 @@ fn parse_final_data(
|
|||||||
|
|
||||||
for idx in 0..type_number {
|
for idx in 0..type_number {
|
||||||
cursor.read_exact(&mut header_buffer)?;
|
cursor.read_exact(&mut header_buffer)?;
|
||||||
let (_, header) = parse_type_header(&header_buffer).unwrap();
|
let (_, header) = parse_type_header(&header_buffer)?;
|
||||||
let first_beam_block = beam_block_exact(&mut cursor, &header)?;
|
let first_beam_block = beam_block_exact(&mut cursor, &header)?;
|
||||||
let first_beam = single_beam_block(&first_beam_block, header.bin_length as usize)?;
|
let first_beam = single_beam_block(&first_beam_block, header.bin_length as usize)?;
|
||||||
gate_len[idx] = first_beam.len();
|
gate_len[idx] = first_beam.len();
|
||||||
@ -516,31 +570,32 @@ fn parse_final_data(
|
|||||||
for e in 0..cut_number {
|
for e in 0..cut_number {
|
||||||
for a in 0..azm_number {
|
for a in 0..azm_number {
|
||||||
cursor.read_exact(&mut radial_buffer)?;
|
cursor.read_exact(&mut radial_buffer)?;
|
||||||
let (_, radial_data) = parse_radial_data(&radial_buffer).unwrap();
|
let (_, radial_data) = parse_radial_data(&radial_buffer)?;
|
||||||
els[e] = radial_data.elevation as f64;
|
els[e] = radial_data.elevation as f64;
|
||||||
azs[a] = radial_data.azimuth as f64;
|
azs[a] = radial_data.azimuth as f64;
|
||||||
let type_number = radial_data.moment_number as usize;
|
let type_number = radial_data.moment_number as usize;
|
||||||
for typ in 0..type_number {
|
for typ in 0..type_number {
|
||||||
cursor.read_exact(&mut header_buffer)?;
|
cursor.read_exact(&mut header_buffer)?;
|
||||||
let (_, header) = parse_type_header(&header_buffer).unwrap();
|
let (_, header) = parse_type_header(&header_buffer)?;
|
||||||
let beam_block = beam_block_exact(&mut cursor, &header)?;
|
let beam_block = beam_block_exact(&mut cursor, &header)?;
|
||||||
let mut beam = single_beam_block(&beam_block, header.bin_length as usize)?;
|
let mut beam = single_beam_block(&beam_block, header.bin_length as usize)?;
|
||||||
|
|
||||||
beam.iter_mut()
|
beam.iter_mut()
|
||||||
.for_each(|v| *v = (*v - header.offset as f64) / header.scale as f64);
|
.for_each(|v| *v = (*v - header.offset as f64) / header.scale as f64);
|
||||||
|
|
||||||
let typ_name = types.get(typ).unwrap();
|
if let Some(typ_name) = types.get(typ) {
|
||||||
|
if typ_name == &"Unknown" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let e = radial_data.elevation_number as usize - 1;
|
||||||
|
|
||||||
if typ_name == &"Unknown" {
|
datas.get_mut(typ_name).unwrap()[e * (azm_number * gate_len[typ])
|
||||||
|
+ a * gate_len[typ]
|
||||||
|
..e * (azm_number * gate_len[typ]) + (a + 1) * gate_len[typ]]
|
||||||
|
.copy_from_slice(&beam);
|
||||||
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let e = radial_data.elevation_number as usize - 1;
|
|
||||||
|
|
||||||
datas.get_mut(typ_name).unwrap()[e * (azm_number * gate_len[typ])
|
|
||||||
+ a * gate_len[typ]
|
|
||||||
..e * (azm_number * gate_len[typ]) + (a + 1) * gate_len[typ]]
|
|
||||||
.copy_from_slice(&beam);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,12 +7,13 @@ use super::{
|
|||||||
sidebar::{SideBarInputMsg, SideBarModel},
|
sidebar::{SideBarInputMsg, SideBarModel},
|
||||||
ControlPanelOutputMsg, TimelineMsg,
|
ControlPanelOutputMsg, TimelineMsg,
|
||||||
};
|
};
|
||||||
use crate::datapool::{DataPool, Value};
|
|
||||||
use crate::predefined::color_mapper::{BoundaryNorm, ColorMapper, ColorMapperComb, Discrete};
|
use crate::predefined::color_mapper::{BoundaryNorm, ColorMapper, ColorMapperComb, Discrete};
|
||||||
use crate::widgets::{DynamicCol, ElementType};
|
use crate::widgets::{DynamicCol, ElementType};
|
||||||
use crate::{plugin_system::init_plugin, widgets::render::Layer, PLUGIN_MANAGER};
|
use crate::{widgets::render::Layer, PLUGIN_MANAGER};
|
||||||
use chrono::{prelude::*, Duration};
|
use chrono::{prelude::*, Duration};
|
||||||
|
use gtk::Widget;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use radarg_core::datapool::{DataPool, Value};
|
||||||
use radarg_core::Data;
|
use radarg_core::Data;
|
||||||
use relm4::{
|
use relm4::{
|
||||||
actions::{AccelsPlus, RelmAction, RelmActionGroup},
|
actions::{AccelsPlus, RelmAction, RelmActionGroup},
|
||||||
@ -61,15 +62,16 @@ pub enum FileIOType {
|
|||||||
pub enum AppMsg {
|
pub enum AppMsg {
|
||||||
Refresh,
|
Refresh,
|
||||||
FileIO { typ: FileIOType },
|
FileIO { typ: FileIOType },
|
||||||
OpenDialog,
|
OpenDialog { widget: Widget },
|
||||||
|
CloseDialog,
|
||||||
|
OpenAlert { body: String, title: String },
|
||||||
|
CloseAlert,
|
||||||
CloseRequest,
|
CloseRequest,
|
||||||
Close,
|
Close,
|
||||||
OpenFileDialog,
|
OpenFileDialog,
|
||||||
}
|
}
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
pub struct AppModel {
|
pub struct AppModel {
|
||||||
waiting_for: Option<DateTime<Utc>>,
|
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
open_dialog: Controller<OpenDialog>,
|
open_dialog: Controller<OpenDialog>,
|
||||||
@ -81,12 +83,6 @@ pub struct AppModel {
|
|||||||
sidebar: Controller<SideBarModel>,
|
sidebar: Controller<SideBarModel>,
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
setting: Controller<SettingModel>,
|
setting: Controller<SettingModel>,
|
||||||
|
|
||||||
// Data
|
|
||||||
selected_layer: Vec<usize>,
|
|
||||||
#[do_not_track]
|
|
||||||
layers: Share<Vec<Layer>>,
|
|
||||||
|
|
||||||
// File Pool
|
// File Pool
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
file_pool: Share<DataPool>,
|
file_pool: Share<DataPool>,
|
||||||
@ -184,16 +180,10 @@ impl Component for AppModel {
|
|||||||
set_title: "Dialog",
|
set_title: "Dialog",
|
||||||
set_presentation_mode: adw::DialogPresentationMode::Floating,
|
set_presentation_mode: adw::DialogPresentationMode::Floating,
|
||||||
set_follows_content_size: true,
|
set_follows_content_size: true,
|
||||||
set_can_close: true,
|
set_can_close: true
|
||||||
|
},
|
||||||
|
alert_dialog = adw::AlertDialog{
|
||||||
|
|
||||||
#[wrap(Some)]
|
|
||||||
set_child=>k::Box{
|
|
||||||
set_height_request: 200,
|
|
||||||
set_width_request: 200,
|
|
||||||
gtk::Label{
|
|
||||||
set_text:"Dialog",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,21 +210,14 @@ impl Component for AppModel {
|
|||||||
root: Self::Root,
|
root: Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
let layers = Rc::new(RefCell::new(vec![]));
|
let data_pool = DataPool::new(&PLUGIN_MANAGER, 10);
|
||||||
// let control = ControlPanelModel::builder().launch(layers.clone()).forward(
|
|
||||||
// sender.input_sender(),
|
|
||||||
// |msg| match msg {
|
|
||||||
// ControlPanelOutputMsg::OpenFile((key, time)) => AppMsg::Close,
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
|
|
||||||
let data_pool = DataPool::new(10);
|
|
||||||
let data_pool = Rc::new(RefCell::new(data_pool));
|
let data_pool = Rc::new(RefCell::new(data_pool));
|
||||||
|
|
||||||
// SideBar Component
|
// SideBar Component
|
||||||
let sidebar = SideBarModel::builder()
|
let sidebar = SideBarModel::builder()
|
||||||
.launch(None)
|
.launch(None)
|
||||||
.forward(sender.input_sender(), |msg| match msg {
|
.forward(sender.input_sender(), |msg| match msg {
|
||||||
|
SideBarOutputMsg::Dialog(widget) => AppMsg::OpenDialog { widget },
|
||||||
SideBarOutputMsg::QueueDraw => AppMsg::Refresh,
|
SideBarOutputMsg::QueueDraw => AppMsg::Refresh,
|
||||||
_ => AppMsg::Close,
|
_ => AppMsg::Close,
|
||||||
});
|
});
|
||||||
@ -242,7 +225,7 @@ impl Component for AppModel {
|
|||||||
let sidebar_sender = sidebar.sender();
|
let sidebar_sender = sidebar.sender();
|
||||||
|
|
||||||
// Monitor Component
|
// Monitor Component
|
||||||
let render = MonitorModel::builder().launch(layers.clone()).forward(
|
let render = MonitorModel::builder().launch(()).forward(
|
||||||
sender.input_sender(),
|
sender.input_sender(),
|
||||||
clone!(
|
clone!(
|
||||||
#[strong]
|
#[strong]
|
||||||
@ -250,11 +233,22 @@ impl Component for AppModel {
|
|||||||
move |model_message| match model_message {
|
move |model_message| match model_message {
|
||||||
MonitorOutputMsg::Attached(new_module) => {
|
MonitorOutputMsg::Attached(new_module) => {
|
||||||
sidebar_sender.emit(SideBarInputMsg::Package(new_module));
|
sidebar_sender.emit(SideBarInputMsg::Package(new_module));
|
||||||
AppMsg::OpenDialog
|
AppMsg::CloseDialog
|
||||||
// AppMsg::Close
|
}
|
||||||
|
MonitorOutputMsg::Dialog(widget) => {
|
||||||
|
AppMsg::OpenDialog { widget }
|
||||||
|
}
|
||||||
|
MonitorOutputMsg::DialogClose => {
|
||||||
|
AppMsg::CloseDialog
|
||||||
|
}
|
||||||
|
MonitorOutputMsg::Alert(content, title) => {
|
||||||
|
AppMsg::OpenAlert {
|
||||||
|
body: content,
|
||||||
|
title,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MonitorOutputMsg::Fc => {
|
MonitorOutputMsg::Fc => {
|
||||||
AppMsg::OpenDialog
|
AppMsg::Close
|
||||||
}
|
}
|
||||||
_ => AppMsg::Close,
|
_ => AppMsg::Close,
|
||||||
}
|
}
|
||||||
@ -287,7 +281,10 @@ impl Component for AppModel {
|
|||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to load data, cause: {:?}", e);
|
error!("Failed to load data, cause: {:?}", e);
|
||||||
AppMsg::Close
|
AppMsg::OpenAlert {
|
||||||
|
body: format!("Failed to load data, cause: {:?}", e),
|
||||||
|
title: "Error".to_string(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,15 +295,12 @@ impl Component for AppModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let model = AppModel {
|
let model = AppModel {
|
||||||
waiting_for: None,
|
|
||||||
render,
|
render,
|
||||||
setting,
|
setting,
|
||||||
open_dialog: dialog,
|
open_dialog: dialog,
|
||||||
selected_layer: vec![],
|
|
||||||
sidebar,
|
sidebar,
|
||||||
file_pool: data_pool,
|
file_pool: data_pool,
|
||||||
// control,
|
// control,
|
||||||
layers,
|
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -315,7 +309,6 @@ impl Component for AppModel {
|
|||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
let mut group = RelmActionGroup::<FileActionGroup>::new();
|
let mut group = RelmActionGroup::<FileActionGroup>::new();
|
||||||
relm4::main_application().set_accelerators_for_action::<OpenAction>(&["<primary>O"]);
|
relm4::main_application().set_accelerators_for_action::<OpenAction>(&["<primary>O"]);
|
||||||
// register_layer_actions(&widgets.main_window, sender.clone());
|
|
||||||
let action: RelmAction<OpenAction> = {
|
let action: RelmAction<OpenAction> = {
|
||||||
RelmAction::new_stateless(move |_| {
|
RelmAction::new_stateless(move |_| {
|
||||||
sender.input(AppMsg::OpenFileDialog);
|
sender.input(AppMsg::OpenFileDialog);
|
||||||
@ -343,9 +336,24 @@ impl Component for AppModel {
|
|||||||
AppMsg::OpenFileDialog => {
|
AppMsg::OpenFileDialog => {
|
||||||
self.open_dialog.emit(OpenDialogMsg::Open);
|
self.open_dialog.emit(OpenDialogMsg::Open);
|
||||||
}
|
}
|
||||||
AppMsg::OpenDialog => {
|
AppMsg::OpenDialog { widget } => {
|
||||||
|
widgets.dialog.set_child(Some(&widget));
|
||||||
widgets.dialog.present(Some(root));
|
widgets.dialog.present(Some(root));
|
||||||
}
|
}
|
||||||
|
AppMsg::CloseDialog => {
|
||||||
|
widgets.dialog.close();
|
||||||
|
}
|
||||||
|
AppMsg::OpenAlert { body, title } => {
|
||||||
|
widgets.alert_dialog.set_body(&body);
|
||||||
|
widgets.alert_dialog.set_title(&title);
|
||||||
|
widgets.alert_dialog.add_responses(&[("Close", "Close")]);
|
||||||
|
|
||||||
|
widgets
|
||||||
|
.alert_dialog
|
||||||
|
.set_response_appearance("Close", adw::ResponseAppearance::Destructive);
|
||||||
|
|
||||||
|
widgets.alert_dialog.present(Some(root));
|
||||||
|
}
|
||||||
AppMsg::FileIO {
|
AppMsg::FileIO {
|
||||||
typ: FileIOType::Open(data),
|
typ: FileIOType::Open(data),
|
||||||
} => self.render.emit(MonitorInputMsg::PushData(data)),
|
} => self.render.emit(MonitorInputMsg::PushData(data)),
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
use super::messages::*;
|
use super::messages::*;
|
||||||
use super::thumbnail::{ImgItem, TypedListView};
|
use super::thumbnail::{ImgItem, TypedListView};
|
||||||
use crate::plugin_system::init_plugin;
|
|
||||||
use crate::predefined::color_mapper::BoundaryNorm;
|
use crate::predefined::color_mapper::BoundaryNorm;
|
||||||
use crate::widgets::render::Layer;
|
use crate::widgets::render::Layer;
|
||||||
use crate::widgets::timeline::{Selection, TimeLine};
|
use crate::widgets::timeline::{Selection, TimeLine};
|
||||||
|
|||||||
136
radar-g/src/components/monitor/dialog_widget.rs
Normal file
136
radar-g/src/components/monitor/dialog_widget.rs
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
use epoxy::S;
|
||||||
|
use gi::pg::ModuleRefs;
|
||||||
|
use gtk::Widget;
|
||||||
|
use radarg_core::Data;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use relm4::{
|
||||||
|
adw::{self, prelude::*},
|
||||||
|
factory::FactoryVecDeque,
|
||||||
|
gtk::{self, prelude::*},
|
||||||
|
prelude::*,
|
||||||
|
view, ComponentParts, ComponentSender, SimpleComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::widgets;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ItemInfo {
|
||||||
|
pub module_name: &'static str,
|
||||||
|
pub module_icon: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DialogOutput {
|
||||||
|
Cancel,
|
||||||
|
Open(usize),
|
||||||
|
}
|
||||||
|
pub struct Dialog {}
|
||||||
|
|
||||||
|
#[relm4::component(pub)]
|
||||||
|
impl SimpleComponent for Dialog {
|
||||||
|
type Widgets = DialogWidgets;
|
||||||
|
type Init = HashMap<(usize, String), Vec<ItemInfo>>;
|
||||||
|
type Input = ();
|
||||||
|
type Output = DialogOutput;
|
||||||
|
|
||||||
|
view! {
|
||||||
|
root=adw::BreakpointBin {
|
||||||
|
set_height_request:600,
|
||||||
|
set_width_request:800,
|
||||||
|
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_child=&adw::ToolbarView{
|
||||||
|
set_hexpand:true,
|
||||||
|
set_vexpand:true,
|
||||||
|
add_top_bar=&adw::HeaderBar{
|
||||||
|
set_hexpand:true,
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_title_widget=>k::Label{
|
||||||
|
set_label: "Header",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_content=&adw::Clamp{
|
||||||
|
set_hexpand:true,
|
||||||
|
#[wrap(Some)]
|
||||||
|
#[name(content)]
|
||||||
|
set_child=>k::Box{
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_hexpand:true,
|
||||||
|
set_spacing: 10,
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: Self::Root,
|
||||||
|
sender: relm4::ComponentSender<Self>,
|
||||||
|
) -> relm4::ComponentParts<Self> {
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
if init.len() > 1 {
|
||||||
|
view! {
|
||||||
|
label=gtk::Label {
|
||||||
|
set_label: "The file you opened contains multiple data blocks; please select one to proceed to the next step.",
|
||||||
|
add_css_class: "h3",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
widgets.content.append(&label);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((k, name), v) in init.iter() {
|
||||||
|
view! {
|
||||||
|
tile=gtk::Expander{
|
||||||
|
set_label: Some(&format!("Data {}: {}", k, name)),
|
||||||
|
set_expanded: true,
|
||||||
|
set_hexpand: true,
|
||||||
|
#[name(content)]
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_child=>k::FlowBox{
|
||||||
|
set_homogeneous: true,
|
||||||
|
set_column_spacing: 10,
|
||||||
|
set_row_spacing: 10,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
let data_id = *k;
|
||||||
|
|
||||||
|
for values in v.iter() {
|
||||||
|
view! {
|
||||||
|
item=gtk::Button {
|
||||||
|
set_icon_name: &values.module_icon,
|
||||||
|
connect_clicked[sender] => move |_| {
|
||||||
|
sender.output(DialogOutput::Open(data_id));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
content.append(&item);
|
||||||
|
}
|
||||||
|
|
||||||
|
widgets.content.append(&tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
let model = Self {};
|
||||||
|
|
||||||
|
// let widgets = model.sequence.widget().clone();
|
||||||
|
// let contour = model.counter.widget().clone();
|
||||||
|
|
||||||
|
ComponentParts {
|
||||||
|
model: model,
|
||||||
|
widgets,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {}
|
||||||
|
}
|
||||||
@ -1,10 +1,12 @@
|
|||||||
use crate::datapool::Value;
|
use gi::pg::{ModulePackage, Modules};
|
||||||
use gi::pg::ModulePackage;
|
use gtk::Widget;
|
||||||
|
use radarg_core::datapool::Value;
|
||||||
use radarg_core::Data;
|
use radarg_core::Data;
|
||||||
use std::{cell::RefCell, fmt::Debug, rc::Rc};
|
use std::{cell::RefCell, fmt::Debug, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
pub enum MonitorInputMsg {
|
pub enum MonitorInputMsg {
|
||||||
PushData(Value<Data>),
|
PushData(Value<Data>),
|
||||||
|
Draw(Arc<Data>),
|
||||||
QueueDraw,
|
QueueDraw,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
@ -13,6 +15,9 @@ impl Debug for MonitorInputMsg {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
MonitorInputMsg::QueueDraw => write!(f, "MonitorInputMsg::QueueDraw"),
|
MonitorInputMsg::QueueDraw => write!(f, "MonitorInputMsg::QueueDraw"),
|
||||||
|
MonitorInputMsg::Draw(data) => {
|
||||||
|
write!(f, "MonitorInputMsg::Draw({:?})", data)
|
||||||
|
}
|
||||||
MonitorInputMsg::PushData(data) => write!(f, "MonitorInputMsg::PushData({:?})", data),
|
MonitorInputMsg::PushData(data) => write!(f, "MonitorInputMsg::PushData({:?})", data),
|
||||||
MonitorInputMsg::None => write!(f, "MonitorInputMsg::None"),
|
MonitorInputMsg::None => write!(f, "MonitorInputMsg::None"),
|
||||||
}
|
}
|
||||||
@ -22,6 +27,9 @@ impl Debug for MonitorInputMsg {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MonitorOutputMsg {
|
pub enum MonitorOutputMsg {
|
||||||
Attached(Rc<RefCell<ModulePackage>>),
|
Attached(Rc<RefCell<ModulePackage>>),
|
||||||
|
Dialog(Widget),
|
||||||
|
DialogClose,
|
||||||
|
Alert(String, String),
|
||||||
Fc,
|
Fc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
mod dialog_widget;
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
pub mod monitor;
|
pub mod monitor;
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use super::dialog_widget::{Dialog, DialogOutput, ItemInfo};
|
||||||
use super::messages::{MonitorInputMsg, MonitorOutputMsg};
|
use super::messages::{MonitorInputMsg, MonitorOutputMsg};
|
||||||
use crate::predefined::color_mapper::BoundaryNorm;
|
use crate::predefined::color_mapper::BoundaryNorm;
|
||||||
use crate::widgets::render::RenderConfig;
|
use crate::widgets::render::RenderConfig;
|
||||||
@ -8,9 +9,10 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use geo::k_nearest_concave_hull;
|
use geo::k_nearest_concave_hull;
|
||||||
use gi::graphics::transforms::plane::PlaneTrans;
|
use gi::graphics::transforms::plane::PlaneTrans;
|
||||||
use gi::pg::ModulePackage;
|
use gi::pg::{Module, ModulePackage};
|
||||||
use gi::ui::operation::Operation;
|
use gi::ui::operation::Operation;
|
||||||
use gtk::glib::clone;
|
use gtk::glib::clone;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -21,6 +23,7 @@ use adw::prelude::*;
|
|||||||
use femtovg::ImageId;
|
use femtovg::ImageId;
|
||||||
use fns::debounce;
|
use fns::debounce;
|
||||||
use gi::ui::typ::MainLoadAttach;
|
use gi::ui::typ::MainLoadAttach;
|
||||||
|
use radarg_core::Data;
|
||||||
use relm4::{component::Component, *};
|
use relm4::{component::Component, *};
|
||||||
use slippy_map_tiles::Tile;
|
use slippy_map_tiles::Tile;
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
@ -49,7 +52,7 @@ pub struct MonitorWidgets {
|
|||||||
impl Component for MonitorModel {
|
impl Component for MonitorModel {
|
||||||
type CommandOutput = MonitorCommand;
|
type CommandOutput = MonitorCommand;
|
||||||
type Input = MonitorInputMsg;
|
type Input = MonitorInputMsg;
|
||||||
type Init = Rc<RefCell<Vec<Layer>>>;
|
type Init = ();
|
||||||
type Output = MonitorOutputMsg;
|
type Output = MonitorOutputMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
@ -95,24 +98,60 @@ impl Component for MonitorModel {
|
|||||||
self.reset();
|
self.reset();
|
||||||
match message {
|
match message {
|
||||||
MonitorInputMsg::PushData(data) => {
|
MonitorInputMsg::PushData(data) => {
|
||||||
sender.output(MonitorOutputMsg::Fc);
|
widgets.renderer.get_gi(|gi| {
|
||||||
// widgets
|
let supported_modules = gi.supported_modules(&data);
|
||||||
// .renderer
|
|
||||||
// .get_gi(|gi| match gi.load_data(&data, &SETTING) {
|
let mut result = HashMap::new();
|
||||||
// Ok(package) => {
|
for (data, modules) in supported_modules {
|
||||||
// info!("data load success!");
|
let mut module_packages = vec![];
|
||||||
// let rc_package = Rc::new(RefCell::new(package));
|
for module in modules {
|
||||||
// self.set_module_packages(vec![rc_package.clone()]);
|
module_packages.push(ItemInfo {
|
||||||
// sender.output(MonitorOutputMsg::Attached(rc_package));
|
module_name: module.name(),
|
||||||
// }
|
module_icon: "plus",
|
||||||
// Err(err) => {
|
});
|
||||||
// error!("Load Error, cause of {}", err);
|
}
|
||||||
// }
|
result.insert((data.id, data.description.clone()), module_packages);
|
||||||
// })
|
}
|
||||||
|
|
||||||
|
let dialog = Dialog::builder().launch(result).forward(
|
||||||
|
sender.input_sender(),
|
||||||
|
move |msg| match msg {
|
||||||
|
DialogOutput::Open(index) => {
|
||||||
|
let data = data.iter().find(|d| *d.0 == index).unwrap();
|
||||||
|
MonitorInputMsg::Draw(data.1.clone())
|
||||||
|
}
|
||||||
|
_ => MonitorInputMsg::None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let widget = dialog.widget().to_owned().upcast();
|
||||||
|
|
||||||
|
sender.output(MonitorOutputMsg::Dialog(widget));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
MonitorInputMsg::QueueDraw => {
|
MonitorInputMsg::QueueDraw => {
|
||||||
widgets.renderer.queue_draw();
|
widgets.renderer.queue_draw();
|
||||||
}
|
}
|
||||||
|
MonitorInputMsg::Draw(ref data) => {
|
||||||
|
widgets.renderer.get_gi(|gi| {
|
||||||
|
let data: &Data = &*data;
|
||||||
|
|
||||||
|
match gi.program().ppi().load_data(data.into(), &SETTING) {
|
||||||
|
Ok(package) => {
|
||||||
|
let package = Rc::new(RefCell::new(package.into()));
|
||||||
|
self.set_module_packages(vec![package.clone()]);
|
||||||
|
sender.output(MonitorOutputMsg::Attached(package));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Error loading data: {:?}", e);
|
||||||
|
sender.output(MonitorOutputMsg::Alert(e.to_string(), format!("Close")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.input(MonitorInputMsg::QueueDraw);
|
||||||
|
});
|
||||||
|
sender.output(MonitorOutputMsg::DialogClose);
|
||||||
|
}
|
||||||
MonitorInputMsg::None => {}
|
MonitorInputMsg::None => {}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,12 +4,13 @@ use chrono::{DateTime, Utc};
|
|||||||
use gi::pg::SideBarInputMsg;
|
use gi::pg::SideBarInputMsg;
|
||||||
use gi::pg::{Components, ModulePackage};
|
use gi::pg::{Components, ModulePackage};
|
||||||
use glib_macros::clone;
|
use glib_macros::clone;
|
||||||
use gtk::glib;
|
|
||||||
use gtk::prelude::WidgetExt;
|
use gtk::prelude::WidgetExt;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
use gtk::{glib, Widget};
|
||||||
use relm4::actions::{AccelsPlus, RelmAction};
|
use relm4::actions::{AccelsPlus, RelmAction};
|
||||||
use relm4::RelmRemoveAllExt;
|
use relm4::RelmRemoveAllExt;
|
||||||
use relm4::{
|
use relm4::{
|
||||||
|
adw::{self, prelude::*},
|
||||||
binding::{Binding, U8Binding},
|
binding::{Binding, U8Binding},
|
||||||
factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque},
|
factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque},
|
||||||
gtk::gio,
|
gtk::gio,
|
||||||
@ -18,7 +19,7 @@ use relm4::{
|
|||||||
column::TypedColumnView,
|
column::TypedColumnView,
|
||||||
list::{RelmListItem, TypedListView},
|
list::{RelmListItem, TypedListView},
|
||||||
},
|
},
|
||||||
RelmObjectExt,
|
view, RelmObjectExt,
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ pub struct SideBarModel {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SideBarOutputMsg {
|
pub enum SideBarOutputMsg {
|
||||||
|
Dialog(Widget),
|
||||||
QueueDraw,
|
QueueDraw,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +56,46 @@ impl Component for SideBarModel {
|
|||||||
set_margin_all: 5,
|
set_margin_all: 5,
|
||||||
|
|
||||||
#[name="container"]
|
#[name="container"]
|
||||||
gtk::Box {}
|
gtk::Box {
|
||||||
|
gtk::Button {
|
||||||
|
set_hexpand:true,
|
||||||
|
set_label: "Refresh",
|
||||||
|
connect_clicked[sender] => move |_| {
|
||||||
|
|
||||||
|
view! {
|
||||||
|
widget=adw::BreakpointBin{
|
||||||
|
set_width_request: 800,
|
||||||
|
set_height_request:600,
|
||||||
|
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_child=&adw::ToolbarView{
|
||||||
|
set_hexpand:true,
|
||||||
|
set_vexpand:true,
|
||||||
|
|
||||||
|
add_top_bar=&adw::HeaderBar{
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_title_widget=>k::Label{
|
||||||
|
set_label: "Header",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_content=>k::Box{
|
||||||
|
gtk::Button{
|
||||||
|
set_label:"Expanders",
|
||||||
|
},
|
||||||
|
gtk::Button{
|
||||||
|
set_label:"Expanders",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sender.output(SideBarOutputMsg::Dialog(widget.upcast()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
use crate::PLUGIN_MANAGER;
|
|
||||||
use quick_cache::sync::Cache;
|
|
||||||
use radarg_core::errors::DataError;
|
|
||||||
use radarg_core::Data;
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::ops::Deref;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct Value<T: Display>(Arc<Vec<T>>);
|
|
||||||
|
|
||||||
impl<T: Display> Value<T> {
|
|
||||||
pub fn new(data: Vec<T>) -> Self {
|
|
||||||
Self(Arc::new(data))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Display> Deref for Value<T> {
|
|
||||||
type Target = Vec<T>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Value<Data> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
for data in self.0.iter() {
|
|
||||||
writeln!(f, "{}", data)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DataPool {
|
|
||||||
pool: Cache<PathBuf, Value<Data>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataPool {
|
|
||||||
pub fn new(cap: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
pool: Cache::new(cap),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_or_load(&self, path: impl Into<PathBuf>) -> Result<Value<Data>, DataError> {
|
|
||||||
let path = path.into();
|
|
||||||
self.pool.get_or_insert_with(&path, || {
|
|
||||||
PLUGIN_MANAGER.try_load_data(&path).map(Value::new)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,15 +3,13 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
use gtk::{gio, prelude::SettingsExt};
|
use gtk::{gio, prelude::SettingsExt};
|
||||||
use plugin_system::{init_plugin, PluginManager};
|
use radarg_core::plugin_system::{init_plugin, PluginManager};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
use std::{ptr, sync::Mutex};
|
use std::{ptr, sync::Mutex};
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
mod actions;
|
mod actions;
|
||||||
mod components;
|
mod components;
|
||||||
mod datapool;
|
|
||||||
mod plugin_system;
|
|
||||||
use crate::components::app::AppMsg;
|
use crate::components::app::AppMsg;
|
||||||
use components::app::AppModel;
|
use components::app::AppModel;
|
||||||
use gi::{App as GI, Helper, GL};
|
use gi::{App as GI, Helper, GL};
|
||||||
|
|||||||
@ -183,6 +183,8 @@ impl GLAreaImpl for Render {
|
|||||||
|
|
||||||
viewport.unbind();
|
viewport.unbind();
|
||||||
|
|
||||||
|
self.io.borrow_mut().reset();
|
||||||
|
|
||||||
glib::Propagation::Proceed
|
glib::Propagation::Proceed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,9 +63,12 @@ impl Render {
|
|||||||
this,
|
this,
|
||||||
move |_, x, y| {
|
move |_, x, y| {
|
||||||
this.imp().set_io(|io| {
|
this.imp().set_io(|io| {
|
||||||
io.mouse.wheel_delta = y as f32;
|
io.mouse.wheel_delta = -y as f32;
|
||||||
});
|
});
|
||||||
this.queue_draw();
|
|
||||||
|
if y != 0.0 {
|
||||||
|
this.queue_draw();
|
||||||
|
}
|
||||||
glib::Propagation::Proceed
|
glib::Propagation::Proceed
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
@ -136,7 +139,7 @@ impl Render {
|
|||||||
f(&mut cfg);
|
f(&mut cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_gi<F: FnMut(&mut GI)>(&self, mut f: F) {
|
pub fn get_gi<F: FnOnce(&mut GI)>(&self, mut f: F) {
|
||||||
let mut gi = self.imp().gi.borrow_mut();
|
let mut gi = self.imp().gi.borrow_mut();
|
||||||
f(&mut gi.as_mut().unwrap());
|
f(&mut gi.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,9 @@ dirs = "5.0.1"
|
|||||||
num-traits = "0.2.19"
|
num-traits = "0.2.19"
|
||||||
serde = { version = "1.0.209", features = ["derive"] }
|
serde = { version = "1.0.209", features = ["derive"] }
|
||||||
relm4 = { version = "0.9.0", features = ["libadwaita"] }
|
relm4 = { version = "0.9.0", features = ["libadwaita"] }
|
||||||
|
abi_stable = "0.11.3"
|
||||||
|
core_extensions = "1.5.3"
|
||||||
|
quick_cache = "0.6.5"
|
||||||
|
|
||||||
[dependencies.radarg_plugin_interface]
|
[dependencies.radarg_plugin_interface]
|
||||||
version = "0.1"
|
version = "0.1"
|
||||||
|
|||||||
76
radarg_core/src/datapool/mod.rs
Normal file
76
radarg_core/src/datapool/mod.rs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
use crate::errors::DataError;
|
||||||
|
use crate::plugin_system::PluginManager;
|
||||||
|
use crate::Data;
|
||||||
|
use quick_cache::sync::Cache;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Value<T: Display>(Arc<HashMap<usize, Arc<T>>>);
|
||||||
|
|
||||||
|
impl Value<Data> {
|
||||||
|
pub fn new(data: Vec<Data>) -> Self {
|
||||||
|
let mut hashmap = HashMap::new();
|
||||||
|
for data in data {
|
||||||
|
hashmap.insert(data.id, Arc::new(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
Self(Arc::new(hashmap))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, key: usize) -> Option<&Arc<Data>> {
|
||||||
|
self.0.get(&key)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> std::collections::hash_map::Iter<'_, usize, Arc<Data>> {
|
||||||
|
self.0.iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Display> Value<T> {
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.0.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Display> Deref for Value<T> {
|
||||||
|
type Target = HashMap<usize, Arc<T>>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Value<Data> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
for data in self.0.iter() {
|
||||||
|
writeln!(f, "{:?}", data)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DataPool {
|
||||||
|
plugin_manager: &'static PluginManager,
|
||||||
|
pool: Cache<PathBuf, Value<Data>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DataPool {
|
||||||
|
pub fn new(plugin_manager: &'static PluginManager, cap: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
plugin_manager,
|
||||||
|
pool: Cache::new(cap),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_load(&self, path: impl Into<PathBuf>) -> Result<Value<Data>, DataError> {
|
||||||
|
let path = path.into();
|
||||||
|
self.pool.get_or_insert_with(&path, || {
|
||||||
|
self.plugin_manager.try_load_data(&path).map(Value::new)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,8 @@ pub mod config;
|
|||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod radarg_data;
|
pub mod radarg_data;
|
||||||
use rust_embed::RustEmbed;
|
use rust_embed::RustEmbed;
|
||||||
|
pub mod datapool;
|
||||||
|
pub mod plugin_system;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod widget_interface;
|
pub mod widget_interface;
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use crate::errors::DataError;
|
||||||
|
use crate::Data;
|
||||||
use abi_stable::{
|
use abi_stable::{
|
||||||
external_types::crossbeam_channel::{self, RReceiver, RSender},
|
external_types::crossbeam_channel::{self, RReceiver, RSender},
|
||||||
library::{lib_header_from_path, LibraryError, LibrarySuffix, RawLibrary},
|
library::{lib_header_from_path, LibraryError, LibrarySuffix, RawLibrary},
|
||||||
@ -5,8 +7,6 @@ use abi_stable::{
|
|||||||
std_types::{RBox, RErr, ROk, RResult, RSome, RStr, RString, RVec},
|
std_types::{RBox, RErr, ROk, RResult, RSome, RStr, RString, RVec},
|
||||||
};
|
};
|
||||||
use core_extensions::*;
|
use core_extensions::*;
|
||||||
use radarg_core::errors::DataError;
|
|
||||||
use radarg_core::Data;
|
|
||||||
use radarg_plugin_interface::{DataLoaderPlugin, DataLoaderPlugin_TO, PluginId, PluginMod_Ref};
|
use radarg_plugin_interface::{DataLoaderPlugin, DataLoaderPlugin_TO, PluginId, PluginMod_Ref};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, VecDeque},
|
collections::{HashMap, VecDeque},
|
||||||
@ -1,25 +1,61 @@
|
|||||||
use std::{fmt::Display, rc::Rc};
|
use std::{
|
||||||
|
fmt::Display,
|
||||||
|
hash::Hash,
|
||||||
|
rc::Rc,
|
||||||
|
sync::{atomic::AtomicUsize, Arc},
|
||||||
|
};
|
||||||
|
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use ndarray::ArrayD;
|
use ndarray::ArrayD;
|
||||||
use radarg_plugin_interface::{
|
use radarg_plugin_interface::{
|
||||||
LoadedData, ProbeDataType as RPT, RadarGridData as RawRadarGridData, VecResult::*,
|
DataLoaderPlugin, LoadedData, ProbeDataType as RPT, RadarGridData as RawRadarGridData,
|
||||||
|
VecResult::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static DATA_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Data {
|
pub struct Data {
|
||||||
RadarGridData(Rc<RadarGridData>),
|
pub id: usize,
|
||||||
|
pub description: String,
|
||||||
|
_data: _Data,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Data {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.id == other.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash for Data {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.id.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for Data {}
|
||||||
|
|
||||||
|
impl Display for Data {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self._data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum _Data {
|
||||||
|
RadarGridData(Arc<RadarGridData>),
|
||||||
JsonData,
|
JsonData,
|
||||||
PlainText(String),
|
PlainText(String),
|
||||||
Binary(Vec<u8>),
|
Binary(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Data {
|
impl Display for _Data {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Data::RadarGridData(info) => write!(f, "RadarGridData: {}", info),
|
_Data::RadarGridData(info) => write!(f, "RadarGridData: {}", info),
|
||||||
Data::JsonData => write!(f, "JsonData"),
|
_Data::JsonData => write!(f, "JsonData"),
|
||||||
Data::PlainText(_) => write!(f, "PlainText"),
|
_Data::PlainText(_) => write!(f, "PlainText"),
|
||||||
Data::Binary(_) => write!(f, "Binary"),
|
_Data::Binary(_) => write!(f, "Binary"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,7 +149,7 @@ impl Display for RadarGridData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct GridDataInfo {
|
pub struct GridDataInfo {
|
||||||
pub shape: Vec<usize>,
|
pub shape: Vec<usize>,
|
||||||
pub dimensions: Vec<Vec<f64>>,
|
pub dimensions: Vec<Vec<f64>>,
|
||||||
@ -228,13 +264,62 @@ raw2new!(
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
impl From<LoadedData> for Data {
|
impl From<LoadedData> for _Data {
|
||||||
fn from(value: LoadedData) -> Self {
|
fn from(value: LoadedData) -> Self {
|
||||||
match value {
|
match value {
|
||||||
LoadedData::Binary(v) => Data::Binary(v.into_vec()),
|
LoadedData::Binary(v) => _Data::Binary(v.into_vec()),
|
||||||
LoadedData::JsonData => Data::JsonData,
|
LoadedData::JsonData => _Data::JsonData,
|
||||||
LoadedData::PlainText(v) => Data::PlainText(v.into_string()),
|
LoadedData::PlainText(v) => _Data::PlainText(v.into_string()),
|
||||||
LoadedData::RadarGridData(v) => Data::RadarGridData(Rc::new(v.into())),
|
LoadedData::RadarGridData(v) => _Data::RadarGridData(Arc::new(v.into())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<LoadedData> for Data {
|
||||||
|
fn from(value: LoadedData) -> Self {
|
||||||
|
let description = match &value {
|
||||||
|
LoadedData::Binary(_) => "Binary".into(),
|
||||||
|
LoadedData::JsonData => "JsonData".into(),
|
||||||
|
LoadedData::PlainText(_) => "PlainText".into(),
|
||||||
|
LoadedData::RadarGridData(v) => format!("{}", v.info.value_name),
|
||||||
|
};
|
||||||
|
Data {
|
||||||
|
id: DATA_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst),
|
||||||
|
description: description,
|
||||||
|
_data: value.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl<'a> From<&'a Data> for &'a Rc<RadarGridData> {
|
||||||
|
// fn from(data: &'a Data) -> Self {
|
||||||
|
// match &data._data {
|
||||||
|
// _Data::RadarGridData(v) => v,
|
||||||
|
// _ => panic!("Unsupported data type"),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
impl<'a> From<&'a Data> for &'a Arc<RadarGridData> {
|
||||||
|
fn from(data: &'a Data) -> Self {
|
||||||
|
match &data._data {
|
||||||
|
_Data::RadarGridData(v) => v,
|
||||||
|
_ => panic!("Unsupported data type"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod test {
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use super::RadarGridData;
|
||||||
|
|
||||||
|
use super::Data;
|
||||||
|
|
||||||
|
fn test() {
|
||||||
|
let radar_data = RadarGridData {
|
||||||
|
data: ndarray::ArrayD::from_shape_vec(ndarray::IxDyn(&[1, 1]), vec![1.0]).unwrap(),
|
||||||
|
info: super::GridDataInfo::default(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user