sync
This commit is contained in:
parent
c102f99606
commit
3d57f61196
@ -67,7 +67,7 @@ pub struct MetaData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(StableAbi, Clone, Debug)]
|
#[derive(StableAbi, Clone, Copy, Debug)]
|
||||||
#[sabi(impl_InterfaceType(Sync, Send, Debug))]
|
#[sabi(impl_InterfaceType(Sync, Send, Debug))]
|
||||||
pub enum PluginResultType {
|
pub enum PluginResultType {
|
||||||
// Single
|
// Single
|
||||||
|
|||||||
@ -5,7 +5,8 @@ use super::{
|
|||||||
setting::SettingModel,
|
setting::SettingModel,
|
||||||
ControlPanelOutputMsg, TimelineMsg,
|
ControlPanelOutputMsg, TimelineMsg,
|
||||||
};
|
};
|
||||||
use crate::pipeline::element::Element;
|
use crate::pipeline::element::{Element, InstantElement, InstantElementDrawerType};
|
||||||
|
use crate::data_utils::plugin_result_impl;
|
||||||
use crate::{
|
use crate::{
|
||||||
coords::{
|
coords::{
|
||||||
cms::CMS,
|
cms::CMS,
|
||||||
@ -45,6 +46,8 @@ use std::{
|
|||||||
use radarg_plugin_interface::PluginResult;
|
use radarg_plugin_interface::PluginResult;
|
||||||
use tokio::{sync::oneshot, task};
|
use tokio::{sync::oneshot, task};
|
||||||
use tracing::{debug, error, info, warn};
|
use tracing::{debug, error, info, warn};
|
||||||
|
use crate::pipeline::{GridElementImpl, OffscreenRenderer};
|
||||||
|
use crate::widgets::AssoElement;
|
||||||
|
|
||||||
relm4::new_action_group!(FileActionGroup, "file");
|
relm4::new_action_group!(FileActionGroup, "file");
|
||||||
relm4::new_stateless_action!(OpenAction, FileActionGroup, "open");
|
relm4::new_stateless_action!(OpenAction, FileActionGroup, "open");
|
||||||
@ -216,7 +219,18 @@ impl Component for AppModel {
|
|||||||
.forward(sender.input_sender(), move |response| match response {
|
.forward(sender.input_sender(), move |response| match response {
|
||||||
OpenDialogResponse::Accept(path) => {
|
OpenDialogResponse::Accept(path) => {
|
||||||
let data = Self::open_file_only(path);
|
let data = Self::open_file_only(path);
|
||||||
let mut layer = Layer::new(true, "New Layer".to_string(), None);
|
let element_impl = plugin_result_impl(&data);
|
||||||
|
let mut renderer = OffscreenRenderer::new(3000,3000).unwrap();
|
||||||
|
let mut canvas = renderer.create_canvas();
|
||||||
|
let mut cms_ref = dialog_cms.lock().unwrap();
|
||||||
|
|
||||||
|
let data = element_impl.render(&data,&mut canvas,&mut (*cms_ref));
|
||||||
|
let element = Element::create_instant(
|
||||||
|
InstantElementDrawerType::Prepared(data),
|
||||||
|
dialog_dispatcher.clone(),
|
||||||
|
"New Element".to_string(),
|
||||||
|
).get_instance();
|
||||||
|
let layer = Layer::new(true, "New Layer".to_string(), AssoElement::Instant(element));
|
||||||
AppMsg::NewLayer(layer)
|
AppMsg::NewLayer(layer)
|
||||||
}
|
}
|
||||||
_ => AppMsg::Close,
|
_ => AppMsg::Close,
|
||||||
|
|||||||
44
src/data_utils.rs
Normal file
44
src/data_utils.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
use radarg_plugin_interface::{CoordType, PluginResult, PluginResultType};
|
||||||
|
use crate::pipeline::element::ElementImpl;
|
||||||
|
use crate::pipeline::GridElementImpl;
|
||||||
|
use crate::utils::*;
|
||||||
|
macro_rules! data_to_grid {
|
||||||
|
($_type:ident,$(($branch:path ,$boundary_norm: expr)),+) => {
|
||||||
|
match $_type {
|
||||||
|
$(
|
||||||
|
$branch => {
|
||||||
|
let element_impl = GridElementImpl::new($boundary_norm);
|
||||||
|
Box::new(element_impl)
|
||||||
|
}
|
||||||
|
),+
|
||||||
|
_ => panic!("Invalid type")
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pub fn plugin_result_impl(a: &PluginResult) -> Box<dyn ElementImpl> {
|
||||||
|
let block= a.blocks.first().unwrap();
|
||||||
|
match block.coord_type {
|
||||||
|
CoordType::Cartesian => {
|
||||||
|
let _type = block.data_type;
|
||||||
|
data_to_grid!(
|
||||||
|
_type,
|
||||||
|
(PluginResultType::R, create_dbz_boundarynorm()),
|
||||||
|
(PluginResultType::V, create_vel_boundarynorm()),
|
||||||
|
(PluginResultType::CC, create_cc_boundarynorm()),
|
||||||
|
(PluginResultType::ZDR, create_zdr_boundarynorm()),
|
||||||
|
(PluginResultType::PHIDP, create_phidp_boundarynorm()),
|
||||||
|
(PluginResultType::KDP, create_kdp_boundarynorm()),
|
||||||
|
(PluginResultType::DBZ, create_dbz_boundarynorm()),
|
||||||
|
(PluginResultType::VIL, create_vil_boundarynorm()),
|
||||||
|
(PluginResultType::OHP, create_vil_boundarynorm()),
|
||||||
|
(PluginResultType::THP, create_vil_boundarynorm()),
|
||||||
|
(PluginResultType::ET, create_et_boundarynorm())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
CoordType::Other | CoordType::Polar => {
|
||||||
|
panic!("Invalid type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -25,6 +25,7 @@ use once_cell::{sync::Lazy as SafeLazy, unsync::Lazy as UnsafeLazy};
|
|||||||
use tracing::info;
|
use tracing::info;
|
||||||
use tracing_subscriber;
|
use tracing_subscriber;
|
||||||
mod widgets;
|
mod widgets;
|
||||||
|
mod data_utils;
|
||||||
|
|
||||||
const APP_ID: &str = "org.tsuki.radar_g";
|
const APP_ID: &str = "org.tsuki.radar_g";
|
||||||
static RUNTIME: SafeLazy<Runtime> =
|
static RUNTIME: SafeLazy<Runtime> =
|
||||||
|
|||||||
@ -23,6 +23,7 @@ use std::{
|
|||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
use radarg_plugin_interface::PluginResult;
|
||||||
use tokio::sync::{
|
use tokio::sync::{
|
||||||
oneshot::{channel, Receiver, Sender},
|
oneshot::{channel, Receiver, Sender},
|
||||||
Notify,
|
Notify,
|
||||||
@ -35,7 +36,7 @@ static ELEMENT_ID: AtomicUsize = AtomicUsize::new(0);
|
|||||||
pub type Data = Box<dyn Any + Send + Sync>;
|
pub type Data = Box<dyn Any + Send + Sync>;
|
||||||
pub type Buffer =
|
pub type Buffer =
|
||||||
Arc<Mutex<BTreeMap<DateTime<Utc>, (Option<Data>, Option<RenderResult>)>>>;
|
Arc<Mutex<BTreeMap<DateTime<Utc>, (Option<Data>, Option<RenderResult>)>>>;
|
||||||
type DrawFunc = Box<dyn Fn(&mut CanvasWrapper, &CMS)>;
|
type DrawFunc = Arc<Box<dyn Fn(&mut CanvasWrapper, &CMS)>>;
|
||||||
type IResult<T> = Result<T, PipelineError>;
|
type IResult<T> = Result<T, PipelineError>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -55,7 +56,7 @@ impl Element {
|
|||||||
}
|
}
|
||||||
pub fn create_instant(
|
pub fn create_instant(
|
||||||
_type: InstantElementDrawerType,
|
_type: InstantElementDrawerType,
|
||||||
dispatcher: Arc<Dispatcher>,
|
dispatcher: Rc<Dispatcher>,
|
||||||
key: String,
|
key: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Element::Instant(InstantElement::new(_type, dispatcher, key))
|
Element::Instant(InstantElement::new(_type, dispatcher, key))
|
||||||
@ -73,6 +74,20 @@ impl Element {
|
|||||||
Element::Instant(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)]
|
#[derive(Debug)]
|
||||||
pub struct TimeSeriesElement {
|
pub struct TimeSeriesElement {
|
||||||
@ -86,6 +101,7 @@ pub struct TimeSeriesElement {
|
|||||||
dispatcher: Rc<Dispatcher>,
|
dispatcher: Rc<Dispatcher>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum InstantElementDrawerType {
|
pub enum InstantElementDrawerType {
|
||||||
Draw(DrawFunc),
|
Draw(DrawFunc),
|
||||||
Prepared(Target),
|
Prepared(Target),
|
||||||
@ -96,20 +112,20 @@ impl Debug for InstantElementDrawerType {
|
|||||||
f.debug_struct("InstantElementDrawerType").finish()
|
f.debug_struct("InstantElementDrawerType").finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct InstantElement {
|
pub struct InstantElement {
|
||||||
pub id: ElementID,
|
pub id: ElementID,
|
||||||
pub key: String,
|
pub key: String,
|
||||||
draw_type: InstantElementDrawerType,
|
draw_type: InstantElementDrawerType,
|
||||||
dispatcher: Arc<Dispatcher>,
|
dispatcher: Rc<Dispatcher>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ElementImpl: Debug + Send + Sync + 'static {
|
pub trait ElementImpl: Debug + Send + Sync + 'static {
|
||||||
fn render(&self, data: Box<dyn Any>, canvas: &mut CanvasWrapper, cms: &mut CMS) -> Target;
|
fn render(&self, data: &PluginResult, canvas: &mut CanvasWrapper, cms: &mut CMS) -> Target;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InstantElement {
|
impl InstantElement {
|
||||||
fn new(_type: InstantElementDrawerType, dispatcher: Arc<Dispatcher>, key: String) -> Self {
|
fn new(_type: InstantElementDrawerType, dispatcher: Rc<Dispatcher>, key: String) -> Self {
|
||||||
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
@ -201,7 +217,7 @@ impl TimeSeriesElement {
|
|||||||
date_time,
|
date_time,
|
||||||
true,
|
true,
|
||||||
3,
|
3,
|
||||||
Arc::new(move |canvas, cms| imp.render(Box::new(()), canvas, cms)),
|
Arc::new(move |data ,canvas, cms| imp.render(data, canvas, cms)),
|
||||||
self.cms.clone(),
|
self.cms.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ use crate::widgets::{LayerImpl, CMS};
|
|||||||
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
|
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use radarg_plugin_interface::PluginResult;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GridElementImpl<CMAP, T>
|
pub struct GridElementImpl<CMAP, T>
|
||||||
@ -46,11 +47,12 @@ where
|
|||||||
{
|
{
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
data: Box<dyn Any>,
|
data: &PluginResult,
|
||||||
canvas: &mut CanvasWrapper,
|
canvas: &mut CanvasWrapper,
|
||||||
cms: &mut crate::coords::cms::CMS,
|
cms: &mut crate::coords::cms::CMS,
|
||||||
) -> crate::pipeline::element::Target {
|
) -> crate::pipeline::element::Target {
|
||||||
let data = data.downcast::<Radar2d<T>>().unwrap();
|
let first_block = data.blocks.first().unwrap();
|
||||||
|
let data = first_block.clone().into();
|
||||||
let result = self.renderer.render(canvas, cms, &data, (3000.0, 3000.0));
|
let result = self.renderer.render(canvas, cms, &data, (3000.0, 3000.0));
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,3 +11,4 @@ pub use dispatcher::Dispatcher;
|
|||||||
pub use element::RenderResult;
|
pub use element::RenderResult;
|
||||||
pub use new_pipeline::Pipeline;
|
pub use new_pipeline::Pipeline;
|
||||||
pub use offscreen_renderer::OffscreenRenderer;
|
pub use offscreen_renderer::OffscreenRenderer;
|
||||||
|
pub use element_impl::*;
|
||||||
|
|||||||
@ -23,6 +23,7 @@ use std::{
|
|||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
use radarg_plugin_interface::PluginResult;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
sync::{mpsc, oneshot},
|
sync::{mpsc, oneshot},
|
||||||
task,
|
task,
|
||||||
@ -83,7 +84,7 @@ impl Pipeline {
|
|||||||
current_time: DateTime<Utc>,
|
current_time: DateTime<Utc>,
|
||||||
check_existed: bool,
|
check_existed: bool,
|
||||||
max_retry_time: usize,
|
max_retry_time: usize,
|
||||||
task: Arc<dyn Fn(&mut CanvasWrapper, &mut CMS) -> Target + Send + Sync>,
|
task: Arc<dyn Fn(&PluginResult ,&mut CanvasWrapper, &mut CMS) -> Target + Send + Sync>,
|
||||||
cms: Arc<Mutex<CMS>>,
|
cms: Arc<Mutex<CMS>>,
|
||||||
) -> Option<Vec<DateTime<Utc>>> {
|
) -> Option<Vec<DateTime<Utc>>> {
|
||||||
let paths = {
|
let paths = {
|
||||||
@ -122,25 +123,25 @@ impl Pipeline {
|
|||||||
fn worker(
|
fn worker(
|
||||||
&self,
|
&self,
|
||||||
datetime: DateTime<Utc>,
|
datetime: DateTime<Utc>,
|
||||||
task: Arc<dyn Fn(&mut CanvasWrapper, &mut CMS) -> Target + Send + Sync>,
|
task: Arc<dyn Fn(&PluginResult ,&mut CanvasWrapper, &mut CMS) -> Target + Send + Sync>,
|
||||||
cms: Arc<Mutex<CMS>>,
|
cms: Arc<Mutex<CMS>>,
|
||||||
path: impl AsRef<str> + Send + 'static,
|
path: impl AsRef<str> + Send + 'static,
|
||||||
) -> BoxFuture<'static, RenderR> {
|
) -> BoxFuture<'static, RenderR> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let loader = PLUGIN_MANAGER.get_plugin_by_name("etws_loader").unwrap();
|
let loader = PLUGIN_MANAGER.get_plugin_by_name("etws_loader").unwrap();
|
||||||
let mut loaded_data = loader.load(path.as_ref().into()).unwrap();
|
let mut loaded_data = loader.load(path.as_ref().into()).unwrap();
|
||||||
let first_block = loaded_data.blocks.pop().unwrap();
|
let meta = loaded_data.meta.clone().into();
|
||||||
|
|
||||||
let handle = task::spawn_blocking(move || {
|
let handle = task::spawn_blocking(move || {
|
||||||
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
||||||
let mut canvas_wrapper = offscreen_renderer.create_canvas();
|
let mut canvas_wrapper = offscreen_renderer.create_canvas();
|
||||||
let mut cms = cms.lock().unwrap();
|
let mut cms = cms.lock().unwrap();
|
||||||
let target = task(&mut canvas_wrapper, &mut cms);
|
let target = task(&loaded_data,&mut canvas_wrapper, &mut cms);
|
||||||
target
|
target
|
||||||
});
|
});
|
||||||
|
|
||||||
let target = handle.await.unwrap();
|
let target = handle.await.unwrap();
|
||||||
Ok(RenderResult::new(target, loaded_data.meta.into()))
|
Ok(RenderResult::new(target, meta))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ type PrepareFunc = Arc<
|
|||||||
type DrawFunc = Arc<dyn Fn(&Layer, Render, (f32, f32)) + Send + Sync>;
|
type DrawFunc = Arc<dyn Fn(&Layer, Render, (f32, f32)) + Send + Sync>;
|
||||||
pub type LayerImplSync = Arc<Mutex<Box<dyn LayerImpl + Send + Sync>>>;
|
pub type LayerImplSync = Arc<Mutex<Box<dyn LayerImpl + Send + Sync>>>;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum AssoElement {
|
pub enum AssoElement {
|
||||||
TimeSeries(Arc<Mutex<element::TimeSeriesElement>>),
|
TimeSeries(Arc<Mutex<element::TimeSeriesElement>>),
|
||||||
Instant(element::InstantElement),
|
Instant(element::InstantElement),
|
||||||
@ -60,18 +61,18 @@ impl Layer {
|
|||||||
|
|
||||||
pub fn draw(&self, render: &Render, window_size: (f32, f32)) {
|
pub fn draw(&self, render: &Render, window_size: (f32, f32)) {
|
||||||
if self.visiable {
|
if self.visiable {
|
||||||
if let Some(element) = &self.associated_element {
|
// if let Some(element) = &self.associated_element {
|
||||||
let element = element.lock().unwrap();
|
// let element = element.lock().unwrap();
|
||||||
match *element {
|
// match *element {
|
||||||
Element::TimeSeries(ref e) => {
|
// Element::TimeSeries(ref e) => {
|
||||||
if self.time.is_none() {
|
// if self.time.is_none() {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
let time = self.time.unwrap();
|
// let time = self.time.unwrap();
|
||||||
}
|
// }
|
||||||
Element::Instant(ref e) => {}
|
// Element::Instant(ref e) => {}
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ mod imp;
|
|||||||
mod layers;
|
mod layers;
|
||||||
use super::super::Render;
|
use super::super::Render;
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
pub use layers::{Layer, LayerImpl, LayerImplSync};
|
pub use layers::{Layer, LayerImpl, LayerImplSync, AssoElement};
|
||||||
use std::cell::Ref;
|
use std::cell::Ref;
|
||||||
|
|
||||||
use super::imp::{RenderConfig, RenderStatus};
|
use super::imp::{RenderConfig, RenderStatus};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user