sync
This commit is contained in:
parent
26939857c9
commit
cf3b1fabfc
@ -7,7 +7,7 @@ use relm4::actions::{AccelsPlus, ActionablePlus, RelmAction, RelmActionGroup};
|
|||||||
use relm4::{ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent};
|
use relm4::{ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent};
|
||||||
|
|
||||||
use crate::components::app::{AppModel, AppMsg, LayerMsg};
|
use crate::components::app::{AppModel, AppMsg, LayerMsg};
|
||||||
use crate::widgets::{AssoElement, Layer};
|
use crate::widgets::Layer;
|
||||||
|
|
||||||
relm4::new_action_group!(pub LayerActionGroup, "layer");
|
relm4::new_action_group!(pub LayerActionGroup, "layer");
|
||||||
relm4::new_stateless_action!(pub AddLayerAction, LayerActionGroup, "add");
|
relm4::new_stateless_action!(pub AddLayerAction, LayerActionGroup, "add");
|
||||||
@ -15,24 +15,12 @@ relm4::new_stateless_action!(pub RemoveLayerAction, LayerActionGroup, "remove");
|
|||||||
relm4::new_stateless_action!(pub MoveLayerAction, LayerActionGroup, "move");
|
relm4::new_stateless_action!(pub MoveLayerAction, LayerActionGroup, "move");
|
||||||
|
|
||||||
pub fn register_layer_actions<W: AsRef<gtk::Widget>>(widget: W, sender: ComponentSender<AppModel>) {
|
pub fn register_layer_actions<W: AsRef<gtk::Widget>>(widget: W, sender: ComponentSender<AppModel>) {
|
||||||
let add_action: RelmAction<AddLayerAction> = {
|
|
||||||
let sender = sender.clone();
|
|
||||||
RelmAction::new_stateless(move |_| {
|
|
||||||
sender.input(AppMsg::LayerManager(LayerMsg::Add(Layer::new(
|
|
||||||
true,
|
|
||||||
"Test".to_string(),
|
|
||||||
AssoElement::Test,
|
|
||||||
))))
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let remove_action: RelmAction<RemoveLayerAction> = {
|
let remove_action: RelmAction<RemoveLayerAction> = {
|
||||||
let sender = sender.clone();
|
let sender = sender.clone();
|
||||||
RelmAction::new_stateless(move |_| sender.input(AppMsg::LayerManager(LayerMsg::Remove(0))))
|
RelmAction::new_stateless(move |_| sender.input(AppMsg::LayerManager(LayerMsg::Remove(0))))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut group: RelmActionGroup<LayerActionGroup> = RelmActionGroup::new();
|
let mut group: RelmActionGroup<LayerActionGroup> = RelmActionGroup::new();
|
||||||
group.add_action(add_action);
|
|
||||||
group.add_action(remove_action);
|
group.add_action(remove_action);
|
||||||
group.register_for_widget(widget)
|
group.register_for_widget(widget)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,18 +8,16 @@ 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::DataTarget;
|
|
||||||
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::OffscreenRenderer;
|
use crate::pipeline::{DataTarget, Key};
|
||||||
|
use crate::pipeline::{KVBuffer, OffscreenRenderer};
|
||||||
use crate::predefined::color_mapper::{BoundaryNorm, ColorMapper, ColorMapperComb, Discrete};
|
use crate::predefined::color_mapper::{BoundaryNorm, ColorMapper, ColorMapperComb, Discrete};
|
||||||
use crate::predefined::widgets::ColorBar;
|
use crate::predefined::widgets::ColorBar;
|
||||||
use crate::utils::meshgrid;
|
use crate::utils::meshgrid;
|
||||||
use crate::widgets::{AssoElement, DynamicCol};
|
use crate::widgets::{DynamicCol, ElementType};
|
||||||
use crate::{
|
|
||||||
actions::register_layer_actions,
|
|
||||||
pipeline::element::{Element, InstantElement, InstantElementDrawerType, TimeSeriesElement},
|
|
||||||
};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
coords::{
|
coords::{
|
||||||
cms::CMS,
|
cms::CMS,
|
||||||
@ -28,7 +26,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
data::MetaInfo,
|
data::MetaInfo,
|
||||||
errors::RenderError,
|
errors::RenderError,
|
||||||
pipeline::{Dispatcher, Pipeline, RenderResult},
|
pipeline::{Dispatcher, RenderResult},
|
||||||
plugin_system::init_plugin,
|
plugin_system::init_plugin,
|
||||||
widgets::render::Layer,
|
widgets::render::Layer,
|
||||||
CONFIG, PLUGIN_MANAGER,
|
CONFIG, PLUGIN_MANAGER,
|
||||||
@ -85,10 +83,9 @@ pub enum AppMsg {
|
|||||||
OpenDialog,
|
OpenDialog,
|
||||||
LayerManager(LayerMsg),
|
LayerManager(LayerMsg),
|
||||||
Layer,
|
Layer,
|
||||||
NewElement(Element),
|
NewElement(Rc<Element>),
|
||||||
DeleteElement(ElementKey),
|
DeleteElement(ElementKey),
|
||||||
}
|
}
|
||||||
pub type Buffer = Rc<RefCell<HashMap<String, BTreeMap<DateTime<Utc>, Option<RenderResult>>>>>;
|
|
||||||
type RcDispatcher = Rc<Dispatcher>;
|
type RcDispatcher = Rc<Dispatcher>;
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
pub struct AppModel {
|
pub struct AppModel {
|
||||||
@ -109,7 +106,11 @@ pub struct AppModel {
|
|||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
layers: Rc<RefCell<Vec<Layer>>>,
|
layers: Rc<RefCell<Vec<Layer>>>,
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
elements: Vec<Arc<Mutex<TimeSeriesElement>>>,
|
buffer: Arc<Buffer<Key>>,
|
||||||
|
#[do_not_track]
|
||||||
|
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
||||||
|
#[do_not_track]
|
||||||
|
elements: Vec<Rc<Element>>,
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
setting: Controller<SettingModel>,
|
setting: Controller<SettingModel>,
|
||||||
}
|
}
|
||||||
@ -228,10 +229,7 @@ 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 layers = Rc::new(RefCell::new(vec![]));
|
||||||
Layer::new(true, "Layer 1".to_string(), AssoElement::Test),
|
|
||||||
Layer::new(true, "Layer 2".to_string(), AssoElement::Test),
|
|
||||||
]));
|
|
||||||
let control = ControlPanelModel::builder().launch(layers.clone()).forward(
|
let control = ControlPanelModel::builder().launch(layers.clone()).forward(
|
||||||
sender.input_sender(),
|
sender.input_sender(),
|
||||||
|msg| match msg {
|
|msg| match msg {
|
||||||
@ -239,6 +237,9 @@ impl Component for AppModel {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let buffer = Arc::new(Buffer::new(100));
|
||||||
|
let file_pool = Arc::new(KVBuffer::new(20));
|
||||||
|
|
||||||
let sidebar =
|
let sidebar =
|
||||||
SideBarModel::builder()
|
SideBarModel::builder()
|
||||||
.launch(layers.clone())
|
.launch(layers.clone())
|
||||||
@ -263,33 +264,27 @@ impl Component for AppModel {
|
|||||||
|
|
||||||
let mut dispatcher = Rc::new(Dispatcher::new(5, 5, chrono::Duration::minutes(1)));
|
let mut dispatcher = Rc::new(Dispatcher::new(5, 5, chrono::Duration::minutes(1)));
|
||||||
let cms = CMS::new(Mercator::default().into(), (3000.0, 3000.0));
|
let cms = CMS::new(Mercator::default().into(), (3000.0, 3000.0));
|
||||||
|
let dialog_buffer = buffer.clone();
|
||||||
|
let dialog_cms = cms.clone();
|
||||||
|
|
||||||
let dialog = {
|
let dialog = {
|
||||||
let dialog_dispatcher = dispatcher.clone();
|
let dialog_dispatcher = dispatcher.clone();
|
||||||
let dialog_sidebar_sender = sidebar.sender().clone();
|
let dialog_sidebar_sender = sidebar.sender().clone();
|
||||||
let dialog_render_sender = render.sender().clone();
|
let dialog_render_sender = render.sender().clone();
|
||||||
|
let dialog_file_pool = file_pool.clone();
|
||||||
OpenDialog::builder()
|
OpenDialog::builder()
|
||||||
.transient_for_native(&root)
|
.transient_for_native(&root)
|
||||||
.launch(OpenDialogSettings::default())
|
.launch(OpenDialogSettings::default())
|
||||||
.forward(sender.input_sender(), move |response| match response {
|
.forward(sender.input_sender(), move |response| match response {
|
||||||
OpenDialogResponse::Accept(path) => {
|
OpenDialogResponse::Accept(path) => {
|
||||||
*FILE_PATH_ROOT.lock().unwrap() = path.clone();
|
*FILE_PATH_ROOT.lock().unwrap() = path.clone();
|
||||||
let data = Self::open_file_only(path);
|
let data = Self::open_file_only(path.clone());
|
||||||
let meta: MetaInfo = (&data.meta).clone().into();
|
let meta: MetaInfo = (&data.meta).clone().into();
|
||||||
let (lat_start, lat_end) = meta.lat_range.unwrap();
|
let (lat_start, lat_end) = meta.lat_range.unwrap();
|
||||||
let (lon_start, lon_end) = meta.lon_range.unwrap();
|
let (lon_start, lon_end) = meta.lon_range.unwrap();
|
||||||
let imp = tools(&data);
|
let imp = tools(&data);
|
||||||
// let element_impl = plugin_result_impl(&data);
|
|
||||||
let mut renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
|
||||||
let mut canvas = renderer.create_canvas();
|
|
||||||
let mut dialog_cms = CMS::new(Mercator::default().into(), (3000.0, 3000.0));
|
|
||||||
let mut context = Context::new(dialog_cms, canvas);
|
|
||||||
|
|
||||||
use femtovg::Color;
|
use femtovg::Color;
|
||||||
|
let config = GridImpConfig {
|
||||||
let mut runner = Runner::new(
|
|
||||||
imp,
|
|
||||||
Arc::new(GridImpConfig {
|
|
||||||
color_map: ColorMapperComb::BoundaryNormDiscrete(ColorMapper::new(
|
color_map: ColorMapperComb::BoundaryNormDiscrete(ColorMapper::new(
|
||||||
Discrete::new(vec![
|
Discrete::new(vec![
|
||||||
Color::rgb(0, 172, 164),
|
Color::rgb(0, 172, 164),
|
||||||
@ -310,70 +305,47 @@ impl Component for AppModel {
|
|||||||
]),
|
]),
|
||||||
BoundaryNorm::new(
|
BoundaryNorm::new(
|
||||||
vec![
|
vec![
|
||||||
0i8, 5i8, 10i8, 15i8, 20i8, 25i8, 30i8, 35i8, 40i8,
|
0i8, 5i8, 10i8, 15i8, 20i8, 25i8, 30i8, 35i8, 40i8, 45i8,
|
||||||
45i8, 50i8, 55i8, 60i8, 65i8, 70i8, 75i8,
|
50i8, 55i8, 60i8, 65i8, 70i8, 75i8,
|
||||||
],
|
],
|
||||||
false,
|
false,
|
||||||
Some(-125),
|
Some(-125),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
}),
|
};
|
||||||
context,
|
let element = Rc::new(Element::new(
|
||||||
);
|
"CR",
|
||||||
|
dialog_cms.clone(),
|
||||||
let target = runner.run(&data);
|
|
||||||
let data_target = DataTarget::new(Some(data), target);
|
|
||||||
|
|
||||||
let element = Element::create_instant(
|
|
||||||
InstantElementDrawerType::Prepared(data_target),
|
|
||||||
dialog_dispatcher.clone(),
|
dialog_dispatcher.clone(),
|
||||||
"ET".to_string(),
|
|
||||||
)
|
|
||||||
.get_instance();
|
|
||||||
let layer = Layer::new(
|
|
||||||
true,
|
true,
|
||||||
"New Layer".to_string(),
|
Arc::new(config),
|
||||||
AssoElement::Instant(element),
|
path.clone(),
|
||||||
);
|
dialog_buffer.clone(),
|
||||||
|
dialog_file_pool.clone(),
|
||||||
|
imp,
|
||||||
|
));
|
||||||
|
|
||||||
dialog_sidebar_sender.emit(SideBarInputMsg::AddMetaItems(meta.to_map()));
|
dialog_sidebar_sender.emit(SideBarInputMsg::AddMetaItems(meta.to_map()));
|
||||||
dialog_render_sender.emit(MonitorInputMsg::SetRenderRange(
|
dialog_render_sender.emit(MonitorInputMsg::SetRenderRange(
|
||||||
lon_start, lon_end, lat_start, lat_end,
|
lon_start, lon_end, lat_start, lat_end,
|
||||||
));
|
));
|
||||||
|
|
||||||
// let data_target = element_impl.render(&data, &mut canvas, &mut dialog_cms);
|
AppMsg::NewElement(element)
|
||||||
// let data_target = DataTarget::new(Some(data), data_target);
|
|
||||||
// let element = Element::create_instant(
|
|
||||||
// InstantElementDrawerType::Prepared((data_target, element_impl)),
|
|
||||||
// dialog_dispatcher.clone(),
|
|
||||||
// "ET".to_string(),
|
|
||||||
// )
|
|
||||||
// .get_instance();
|
|
||||||
// let layer = Layer::new(
|
|
||||||
// true,
|
|
||||||
// "New Layer".to_string(),
|
|
||||||
// AssoElement::Instant(element),
|
|
||||||
// );
|
|
||||||
// dialog_sidebar_sender.emit(SideBarInputMsg::AddMetaItems(meta.to_map()));
|
|
||||||
// dialog_render_sender.emit(MonitorInputMsg::SetRenderRange(
|
|
||||||
// lon_start, lon_end, lat_start, lat_end,
|
|
||||||
// ));
|
|
||||||
// let layer = Layer::new(true, "New Layer".to_string(), AssoElement::Test);
|
|
||||||
|
|
||||||
AppMsg::LayerManager(LayerMsg::Add(layer))
|
|
||||||
}
|
}
|
||||||
_ => AppMsg::Close,
|
_ => AppMsg::Close,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let buffer: Buffer = Rc::new(RefCell::new(HashMap::new()));
|
|
||||||
let model = AppModel {
|
let model = AppModel {
|
||||||
cms,
|
cms,
|
||||||
dispatcher,
|
dispatcher,
|
||||||
waiting_for: None,
|
waiting_for: None,
|
||||||
elements: Vec::with_capacity(20),
|
buffer,
|
||||||
|
file_pool,
|
||||||
open_dialog: dialog,
|
open_dialog: dialog,
|
||||||
selected_layer: vec![],
|
selected_layer: vec![],
|
||||||
sidebar,
|
sidebar,
|
||||||
|
elements: vec![],
|
||||||
control,
|
control,
|
||||||
render,
|
render,
|
||||||
layers,
|
layers,
|
||||||
@ -386,7 +358,7 @@ 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());
|
// 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::OpenDialog);
|
sender.input(AppMsg::OpenDialog);
|
||||||
@ -411,24 +383,7 @@ impl Component for AppModel {
|
|||||||
(*self.layers).borrow_mut().push(layer);
|
(*self.layers).borrow_mut().push(layer);
|
||||||
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
||||||
}
|
}
|
||||||
LayerMsg::SwitchToTime(idx) => {
|
LayerMsg::SwitchToTime(idx) => {}
|
||||||
let mut layer = (*self.layers).borrow_mut();
|
|
||||||
let switched_layer = layer.get_mut(idx).unwrap();
|
|
||||||
let asso_element = switched_layer.pop_associated_element();
|
|
||||||
|
|
||||||
if let AssoElement::Instant(e) = asso_element {
|
|
||||||
let dispatcher = self.dispatcher.clone();
|
|
||||||
let cms = self.cms.clone();
|
|
||||||
let (mut series, start_time) = e.to_time_series(dispatcher, cms);
|
|
||||||
switched_layer.set_time(start_time);
|
|
||||||
series.register(start_time).unwrap();
|
|
||||||
let element = Arc::new(Mutex::new(series));
|
|
||||||
switched_layer
|
|
||||||
.set_associated_element(AssoElement::TimeSeries(element.clone()));
|
|
||||||
self.elements.push(element);
|
|
||||||
}
|
|
||||||
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerMsg::Select(idx) => {
|
LayerMsg::Select(idx) => {
|
||||||
self.set_selected_layer(idx);
|
self.set_selected_layer(idx);
|
||||||
@ -446,15 +401,23 @@ impl Component for AppModel {
|
|||||||
LayerMsg::Remove(idx) => {
|
LayerMsg::Remove(idx) => {
|
||||||
let mut layers = (*self.layers).borrow_mut();
|
let mut layers = (*self.layers).borrow_mut();
|
||||||
let mut layer = layers.remove(idx);
|
let mut layer = layers.remove(idx);
|
||||||
if let AssoElement::TimeSeries(e) = layer.pop_associated_element() {
|
|
||||||
let size = Arc::strong_count(&e);
|
|
||||||
}
|
|
||||||
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
AppMsg::CloseRequest => {
|
AppMsg::CloseRequest => {
|
||||||
relm4::main_application().quit();
|
relm4::main_application().quit();
|
||||||
}
|
}
|
||||||
|
AppMsg::NewElement(element) => {
|
||||||
|
let new_layer = Layer::new(
|
||||||
|
true,
|
||||||
|
"New Layer".to_string(),
|
||||||
|
element.clone(),
|
||||||
|
ElementType::Indenpendent,
|
||||||
|
);
|
||||||
|
_sender.input(AppMsg::LayerManager(LayerMsg::Add(new_layer)));
|
||||||
|
self.elements.push(element);
|
||||||
|
self.render.sender().send(MonitorInputMsg::RefreshRender);
|
||||||
|
}
|
||||||
AppMsg::Close => {}
|
AppMsg::Close => {}
|
||||||
AppMsg::OpenDialog => {
|
AppMsg::OpenDialog => {
|
||||||
self.open_dialog.emit(OpenDialogMsg::Open);
|
self.open_dialog.emit(OpenDialogMsg::Open);
|
||||||
|
|||||||
@ -22,7 +22,7 @@ use tracing::*;
|
|||||||
use crate::coords::Range;
|
use crate::coords::Range;
|
||||||
use crate::map_tile::MapTile;
|
use crate::map_tile::MapTile;
|
||||||
use crate::map_tile_utils::lat_lon_to_zoom;
|
use crate::map_tile_utils::lat_lon_to_zoom;
|
||||||
use crate::pipeline::element::Target;
|
use crate::pipeline::Target;
|
||||||
use crate::utils::estimate_zoom_level;
|
use crate::utils::estimate_zoom_level;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use femtovg::ImageId;
|
use femtovg::ImageId;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::coords::cms::CMS;
|
use crate::coords::cms::CMS;
|
||||||
use crate::widgets::{Layer, LayerImpl, Render};
|
use crate::widgets::{Layer, Render};
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
use gtk::Align;
|
use gtk::Align;
|
||||||
use std::{fmt::Debug, rc::Rc};
|
use std::{fmt::Debug, rc::Rc};
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
use crate::actions::*;
|
use crate::actions::*;
|
||||||
use crate::widgets::AssoElement;
|
|
||||||
use abi_stable::type_level::trait_marker::Hash;
|
use abi_stable::type_level::trait_marker::Hash;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use glib_macros::clone;
|
use glib_macros::clone;
|
||||||
@ -193,11 +192,7 @@ impl SimpleComponent for SideBarModel {
|
|||||||
v.name.clone(),
|
v.name.clone(),
|
||||||
v.visiable,
|
v.visiable,
|
||||||
v.get_thumbnail(),
|
v.get_thumbnail(),
|
||||||
match v.get_associated_element() {
|
LayerStatus::Instance,
|
||||||
AssoElement::TimeSeries(_) => LayerStatus::BindToTime(Utc::now()),
|
|
||||||
AssoElement::Instant(_) => LayerStatus::Instance,
|
|
||||||
_ => LayerStatus::Instance,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@ -221,11 +216,11 @@ impl SimpleComponent for SideBarModel {
|
|||||||
v.name.clone(),
|
v.name.clone(),
|
||||||
v.visiable,
|
v.visiable,
|
||||||
v.get_thumbnail(),
|
v.get_thumbnail(),
|
||||||
match v.get_associated_element() {
|
LayerStatus::Instance, // match v.get_associated_element() {
|
||||||
AssoElement::TimeSeries(_) => LayerStatus::BindToTime(Utc::now()),
|
// // AssoElement::TimeSeries(_) => LayerStatus::BindToTime(Utc::now()),
|
||||||
AssoElement::Instant(_) => LayerStatus::Instance,
|
// // AssoElement::Instant(_) => LayerStatus::Instance,
|
||||||
_ => LayerStatus::Instance,
|
// _ => LayerStatus::Instance,
|
||||||
},
|
//
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use crate::components::messages::MonitorInputMsg;
|
|||||||
use crate::components::{MonitorCommand, MonitorModel};
|
use crate::components::{MonitorCommand, MonitorModel};
|
||||||
use crate::coords::Range;
|
use crate::coords::Range;
|
||||||
use crate::map_tile_utils::lat_lon_to_zoom;
|
use crate::map_tile_utils::lat_lon_to_zoom;
|
||||||
use crate::pipeline::element::{Target, TargetType};
|
use crate::pipeline::{Target, TargetType};
|
||||||
use dirs::cache_dir;
|
use dirs::cache_dir;
|
||||||
use femtovg::ImageSource;
|
use femtovg::ImageSource;
|
||||||
use futures::future::BoxFuture;
|
use futures::future::BoxFuture;
|
||||||
|
|||||||
@ -1,15 +1,14 @@
|
|||||||
use super::element::TargetType;
|
|
||||||
use super::offscreen_renderer::{CanvasWrapper, OffscreenRenderer};
|
use super::offscreen_renderer::{CanvasWrapper, OffscreenRenderer};
|
||||||
use crate::{
|
use crate::CONFIG;
|
||||||
components::app::{Buffer, FILE_PATH_ROOT},
|
|
||||||
CONFIG,
|
|
||||||
};
|
|
||||||
use chrono::{prelude::*, Duration};
|
use chrono::{prelude::*, Duration};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::{cell::Ref, collections::HashMap, path::PathBuf};
|
use std::{cell::Ref, collections::HashMap, path::PathBuf};
|
||||||
use tracing::*;
|
use tracing::*;
|
||||||
|
|
||||||
|
static DATETIME_FORMAT: Lazy<Regex> =
|
||||||
|
Lazy::new(|| Regex::new(r"(?:%[YHMSmd](?:[-/:_]?%[YHMSmd])*)").unwrap());
|
||||||
|
|
||||||
static REREMAP: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
|
static REREMAP: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert("%Y", r"\d{4}");
|
map.insert("%Y", r"\d{4}");
|
||||||
@ -107,8 +106,8 @@ impl Dispatcher {
|
|||||||
current_time: DateTime<Utc>,
|
current_time: DateTime<Utc>,
|
||||||
check_existed: bool,
|
check_existed: bool,
|
||||||
mut max_retry_time: usize,
|
mut max_retry_time: usize,
|
||||||
|
file_path: &PathBuf,
|
||||||
) -> Option<Vec<(String, DateTime<Utc>)>> {
|
) -> Option<Vec<(String, DateTime<Utc>)>> {
|
||||||
let datetime_format: regex::Regex = Regex::new(r"%[YHMSmd](?:[-/:_]?%[YHMSmd])*").unwrap();
|
|
||||||
let config = CONFIG.lock().unwrap();
|
let config = CONFIG.lock().unwrap();
|
||||||
let path_format = config
|
let path_format = config
|
||||||
.plugins
|
.plugins
|
||||||
@ -121,7 +120,7 @@ impl Dispatcher {
|
|||||||
}
|
}
|
||||||
path_format.unwrap().get(name).map(|s| {
|
path_format.unwrap().get(name).map(|s| {
|
||||||
let path = s.clone();
|
let path = s.clone();
|
||||||
let file_path = { FILE_PATH_ROOT.lock().unwrap().clone() };
|
// let file_path = { file_path_root.lock().unwrap().clone() };
|
||||||
let path = if path.starts_with("./") {
|
let path = if path.starts_with("./") {
|
||||||
let file_root = file_root(&file_path, path.replace("./", ""));
|
let file_root = file_root(&file_path, path.replace("./", ""));
|
||||||
file_root.map(|root| {
|
file_root.map(|root| {
|
||||||
@ -143,7 +142,7 @@ impl Dispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let need_formated = datetime_format.captures_iter(&path_str).collect::<Vec<_>>();
|
let need_formated = DATETIME_FORMAT.captures_iter(&path_str).collect::<Vec<_>>();
|
||||||
let mut fore = self.fore_len;
|
let mut fore = self.fore_len;
|
||||||
let mut back = 1;
|
let mut back = 1;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use super::{offscreen_renderer::CanvasWrapper, Dispatcher, Pipeline};
|
use super::{offscreen_renderer::CanvasWrapper, Dispatcher};
|
||||||
use crate::components::Widget;
|
use crate::components::Widget;
|
||||||
use crate::coords::cms::CMS;
|
use crate::coords::cms::CMS;
|
||||||
use crate::coords::Range;
|
use crate::coords::Range;
|
||||||
|
|||||||
@ -4,11 +4,13 @@ use crate::data::Radar2dRef;
|
|||||||
use crate::pipeline::offscreen_renderer::CanvasWrapper;
|
use crate::pipeline::offscreen_renderer::CanvasWrapper;
|
||||||
use crate::predefined::color_mapper::{CMap, ColorMapper, ColorMapperComb, VMap};
|
use crate::predefined::color_mapper::{CMap, ColorMapper, ColorMapperComb, VMap};
|
||||||
use abi_stable::std_types::RVec;
|
use abi_stable::std_types::RVec;
|
||||||
use femtovg::{Paint, Path};
|
use femtovg::renderer::OpenGl;
|
||||||
|
use femtovg::{Canvas, Paint, Path};
|
||||||
use ndarray::{ArrayBase, ArrayView1, ArrayView2, ArrayView3, ArrayViewD, Axis, Ix2, Ix3};
|
use ndarray::{ArrayBase, ArrayView1, ArrayView2, ArrayView3, ArrayViewD, Axis, Ix2, Ix3};
|
||||||
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
|
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
|
||||||
use radarg_plugin_interface::{DataShape, PluginResult, VecResult};
|
use radarg_plugin_interface::{DataShape, PluginResult, VecResult};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
use std::borrow::BorrowMut;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
const EARTH_RADIUS: f64 = 6371.0;
|
const EARTH_RADIUS: f64 = 6371.0;
|
||||||
@ -16,11 +18,11 @@ 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},)+) => {
|
||||||
impl ElementImpl {
|
impl ElementImpl {
|
||||||
pub fn process<'a, T>(&'a 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
|
context: &mut Context<'b>
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + 'static,
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + 'static,
|
||||||
@ -28,7 +30,7 @@ macro_rules! impl_element_imp_dispatch {
|
|||||||
match self {
|
match self {
|
||||||
$(
|
$(
|
||||||
Self::$Abc(imp) => {
|
Self::$Abc(imp) => {
|
||||||
let config = config.downcast_ref::<<$t as ElementImp>::Config<T>>().unwrap();
|
let config = config.downcast_ref::<<$t as ElementImp>::Config<'a, T>>().unwrap();
|
||||||
if let ElementInput::$Abc(data) = input {
|
if let ElementInput::$Abc(data) = input {
|
||||||
imp.process(dims, data, config, context);
|
imp.process(dims, data, config, context);
|
||||||
} else {
|
} else {
|
||||||
@ -39,6 +41,17 @@ macro_rules! impl_element_imp_dispatch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn output_type(&self,) -> ElementOutput
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
$(
|
||||||
|
Self::$Abc(imp) => {
|
||||||
|
imp.output_type()
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -110,33 +123,56 @@ macro_rules! result_to_array {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context<'a> {
|
||||||
pub cms: CMS,
|
pub cms: CMS,
|
||||||
pub canvas: CanvasWrapper,
|
pub canvas: &'a mut Canvas<OpenGl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl<'a> Context<'a> {
|
||||||
pub fn new(cms: CMS, canvas: CanvasWrapper) -> Self {
|
pub fn new<T>(cms: CMS, canvas: &'a mut T) -> Self
|
||||||
Self { cms, canvas }
|
where
|
||||||
|
T: BorrowMut<Canvas<OpenGl>> + 'a,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
cms,
|
||||||
|
canvas: canvas.borrow_mut(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum ElementOutput {
|
||||||
|
Target,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ElementImp: Debug + TryFrom<ElementImpl> + Into<ElementImpl> {
|
pub trait ElementImp: Debug + TryFrom<ElementImpl> + Into<ElementImpl> {
|
||||||
type Config<T: Sync + Send + Debug + PartialOrd + PartialEq>;
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + 'a>: ElementConfig
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
type Input<'a, T: 'a>
|
type Input<'a, T: 'a>
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
fn process<'a, T>(
|
|
||||||
&'a self,
|
fn process<'a, 'b: 'a, T>(
|
||||||
|
&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
input: Self::Input<'a, T>,
|
input: Self::Input<'a, T>,
|
||||||
config: &Self::Config<T>,
|
config: &Self::Config<'a, T>,
|
||||||
context: &mut Context,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone;
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone;
|
||||||
|
|
||||||
|
fn output_type(&self) -> ElementOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
pub trait ElementConfig {
|
||||||
|
fn upcast_ref<'short, 'long: 'short>(&'long self) -> &'short Self {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct GridImp();
|
pub struct GridImp();
|
||||||
|
|
||||||
pub struct GridImpConfig<T>
|
pub struct GridImpConfig<T>
|
||||||
@ -147,12 +183,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GridImp {
|
impl GridImp {
|
||||||
fn draw_2d<T>(
|
fn draw_2d<'a, 'b: 'a, T>(
|
||||||
&self,
|
&self,
|
||||||
config: &GridImpConfig<T>,
|
config: &GridImpConfig<T>,
|
||||||
data: ArrayView2<T>,
|
data: ArrayView2<'a, T>,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
context: &mut Context,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: PartialEq + PartialOrd + Copy + Clone + Send + Sync + Debug,
|
T: PartialEq + PartialOrd + Copy + Clone + Send + Sync + Debug,
|
||||||
{
|
{
|
||||||
@ -195,14 +231,15 @@ impl GridImp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ElementImp for GridImp {
|
impl ElementImp for GridImp {
|
||||||
type Config<T: Sync + Send + Debug + PartialOrd + PartialEq> = GridImpConfig<T>;
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq> = GridImpConfig<T> where
|
||||||
|
T: 'a;
|
||||||
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
||||||
fn process<'a, T>(
|
fn process<'a, 'b: 'a, T>(
|
||||||
&'a self,
|
&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
input: Self::Input<'a, T>,
|
input: Self::Input<'a, T>,
|
||||||
config: &Self::Config<T>,
|
config: &Self::Config<'a, T>,
|
||||||
context: &mut Context,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: Send + Sync + Debug + PartialOrd + PartialEq + Copy + Clone,
|
T: Send + Sync + Debug + PartialOrd + PartialEq + Copy + Clone,
|
||||||
{
|
{
|
||||||
@ -214,11 +251,33 @@ impl ElementImp for GridImp {
|
|||||||
let data = input.into_dimensionality::<Ix3>().unwrap();
|
let data = input.into_dimensionality::<Ix3>().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn output_type(&self) -> ElementOutput {
|
||||||
|
ElementOutput::Target
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct MultiLayerGridImp();
|
pub struct MultiLayerGridImp();
|
||||||
|
|
||||||
|
impl MultiLayerGridImp {
|
||||||
|
fn draw<'a, 'b: 'a, T>(
|
||||||
|
&self,
|
||||||
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
|
data: ArrayViewD<'a, T>,
|
||||||
|
config: &MultiLayerGridImpConfig<T>,
|
||||||
|
context: &mut Context<'b>,
|
||||||
|
) where
|
||||||
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy,
|
||||||
|
{
|
||||||
|
let two = config.twod.clone();
|
||||||
|
let _layer = data.into_dimensionality::<Ix3>().unwrap();
|
||||||
|
let data = _layer.index_axis(Axis(0), config.layer).into_dyn();
|
||||||
|
|
||||||
|
two.process(dims, data, &config.two_d_config, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct MultiLayerGridImpConfig<T>
|
pub struct MultiLayerGridImpConfig<T>
|
||||||
where
|
where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug,
|
T: PartialOrd + PartialEq + Send + Sync + Debug,
|
||||||
@ -229,29 +288,28 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ElementImp for MultiLayerGridImp {
|
impl ElementImp for MultiLayerGridImp {
|
||||||
type Config<T: Sync + Send + Debug + PartialOrd + PartialEq> = MultiLayerGridImpConfig<T>;
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + 'a> =
|
||||||
|
MultiLayerGridImpConfig<T>;
|
||||||
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
||||||
|
|
||||||
fn process<'a, T>(
|
fn process<'a, 'b: 'a, T>(
|
||||||
&'a self,
|
&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
input: Self::Input<'a, T>,
|
input: Self::Input<'a, T>,
|
||||||
config: &Self::Config<T>,
|
config: &Self::Config<'a, T>,
|
||||||
context: &mut Context,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone,
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone,
|
||||||
{
|
{
|
||||||
let data = input.into_dimensionality::<Ix3>().unwrap();
|
self.draw(dims, input, config.upcast_ref(), context);
|
||||||
let layer = config.layer;
|
}
|
||||||
let layer_data = data.index_axis(Axis(0), layer);
|
|
||||||
|
|
||||||
config
|
fn output_type(&self) -> ElementOutput {
|
||||||
.twod
|
ElementOutput::Target
|
||||||
.process(dims, layer_data.into_dyn(), &config.two_d_config, context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct PolarElementImp();
|
pub struct PolarElementImp();
|
||||||
|
|
||||||
pub struct PolarElementConfig<T>
|
pub struct PolarElementConfig<T>
|
||||||
@ -316,13 +374,13 @@ impl PolarElementImp {
|
|||||||
Some((final_degree, final_distance))
|
Some((final_degree, final_distance))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw<T>(
|
fn draw<'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: &PolarElementConfig<T>,
|
config: &'a PolarElementConfig<T>,
|
||||||
context: &mut Context,
|
context: &mut Context<'a>,
|
||||||
) where
|
) where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy,
|
||||||
{
|
{
|
||||||
@ -364,28 +422,41 @@ impl PolarElementImp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ElementImp for PolarElementImp {
|
impl ElementImp for PolarElementImp {
|
||||||
type Config<T: Sync + Send + Debug + PartialOrd + PartialEq> = PolarElementConfig<T>;
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq> = PolarElementConfig<T> where
|
||||||
|
T: 'a;
|
||||||
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
||||||
fn process<'a, T>(
|
fn process<'a, 'b: 'a, T>(
|
||||||
&'a self,
|
&self,
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
input: Self::Input<'a, T>,
|
input: Self::Input<'a, T>,
|
||||||
config: &Self::Config<T>,
|
config: &Self::Config<'a, T>,
|
||||||
context: &mut Context,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone,
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone,
|
||||||
{
|
{
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn output_type(&self) -> ElementOutput {
|
||||||
|
ElementOutput::Target
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl<T> ElementConfig for GridImpConfig<T> where T: Sync + Send + Debug + PartialOrd + PartialEq {}
|
||||||
|
impl<T> ElementConfig for MultiLayerGridImpConfig<T> where
|
||||||
|
T: Sync + Send + Debug + PartialOrd + PartialEq
|
||||||
|
{
|
||||||
|
}
|
||||||
|
impl<T> ElementConfig for PolarElementConfig<T> where T: Sync + Send + Debug + PartialOrd + PartialEq
|
||||||
|
{}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum ElementImpl {
|
pub enum ElementImpl {
|
||||||
Grid(GridImp),
|
Grid(GridImp),
|
||||||
MultiLayerGrid(MultiLayerGridImp),
|
MultiLayerGrid(MultiLayerGridImp),
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
pub mod dispatcher;
|
pub mod dispatcher;
|
||||||
pub mod element;
|
// pub mod element;
|
||||||
// mod element_impl;
|
// mod element_impl;
|
||||||
// mod new_element;
|
pub mod new_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;
|
||||||
@ -12,7 +12,8 @@ pub mod runner;
|
|||||||
// pub mod utils;
|
// pub mod utils;
|
||||||
|
|
||||||
pub use dispatcher::Dispatcher;
|
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 offscreen_renderer::OffscreenRenderer;
|
pub use offscreen_renderer::OffscreenRenderer;
|
||||||
|
|||||||
@ -1,14 +1,22 @@
|
|||||||
use super::dispatcher;
|
use super::dispatcher;
|
||||||
use super::new_element_impl::ElementConfig;
|
use super::element_imp::Context;
|
||||||
use super::new_element_impl::ElementImp;
|
use super::element_imp::ElementImpl;
|
||||||
|
use super::element_imp::ElementOutput;
|
||||||
|
use super::offscreen_renderer;
|
||||||
use super::offscreen_renderer::CanvasWrapper;
|
use super::offscreen_renderer::CanvasWrapper;
|
||||||
|
use super::runner::Runner;
|
||||||
use super::Dispatcher;
|
use super::Dispatcher;
|
||||||
use super::RenderResult;
|
|
||||||
use super::Target;
|
|
||||||
use crate::coords::cms::CMS;
|
use crate::coords::cms::CMS;
|
||||||
|
use crate::coords::Range;
|
||||||
|
use crate::data::MetaInfo;
|
||||||
use crate::pipeline::OffscreenRenderer;
|
use crate::pipeline::OffscreenRenderer;
|
||||||
|
use crate::widgets::Render;
|
||||||
use crate::PLUGIN_MANAGER;
|
use crate::PLUGIN_MANAGER;
|
||||||
|
use crate::RUNTIME;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
|
use femtovg::ImageFlags;
|
||||||
|
use femtovg::ImageId;
|
||||||
|
use futures::future::BoxFuture;
|
||||||
use num_traits::AsPrimitive;
|
use num_traits::AsPrimitive;
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use num_traits::Num;
|
use num_traits::Num;
|
||||||
@ -16,9 +24,12 @@ use num_traits::NumOps;
|
|||||||
use quick_cache::sync::Cache;
|
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::BorrowMut;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::AtomicI32;
|
use std::sync::atomic::AtomicI32;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -26,171 +37,546 @@ use std::sync::RwLock;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use tokio::sync::{mpsc, Mutex};
|
use tokio::sync::{mpsc, Mutex};
|
||||||
|
use tracing::subscriber;
|
||||||
|
|
||||||
static ELEMENT_ID: AtomicI32 = AtomicI32::new(0);
|
static ELEMENT_ID: AtomicI32 = AtomicI32::new(0);
|
||||||
pub type ElementID = i32;
|
pub type ElementID = i32;
|
||||||
pub type Buffer<T> = Cache<T, Arc<Mutex<RenderResult>>>;
|
pub type KVBuffer<T, V> = Cache<T, V>;
|
||||||
|
pub type Buffer<T> = KVBuffer<T, Arc<Mutex<RenderResult>>>;
|
||||||
|
|
||||||
pub struct Element<T: Eq + Hash + Send + Clone + Copy + 'static, V>
|
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
|
||||||
where
|
pub struct Key {
|
||||||
V: Num + NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
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>,
|
||||||
|
// data: Option<Arc<dyn Any + Send + Sync + 'static>>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
target,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
bounds,
|
||||||
|
thumbnail,
|
||||||
|
// data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
data: Option<PluginResult>,
|
||||||
|
target: Target,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DataTarget {
|
||||||
|
pub fn new(data: Option<PluginResult>, target: Target) -> Self {
|
||||||
|
Self { data, target }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn take_data(&mut self) -> Option<PluginResult> {
|
||||||
|
self.data.take()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn data(&self) -> Option<&PluginResult> {
|
||||||
|
self.data.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mut_data(&mut self) -> Option<&mut PluginResult> {
|
||||||
|
self.data.as_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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 id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub description: String,
|
pub cache: bool,
|
||||||
imp: Arc<ElementImp<V>>,
|
root: std::path::PathBuf,
|
||||||
buffer: Arc<Mutex<Buffer<T>>>,
|
config: Arc<dyn Any + Send + Sync>,
|
||||||
config: Arc<RwLock<Box<ElementConfig>>>,
|
imp: ElementImpl,
|
||||||
subscribers: Arc<Mutex<HashMap<T, Vec<oneshot::Sender<Arc<Mutex<Vec<u8>>>>>>>>,
|
subscribers: Arc<Mutex<HashMap<Key, Vec<oneshot::Sender<Arc<Mutex<RenderResult>>>>>>>,
|
||||||
cancellers: Arc<Mutex<HashMap<T, oneshot::Sender<()>>>>,
|
cancellers: Arc<Mutex<HashMap<Key, oneshot::Sender<()>>>>,
|
||||||
|
current_key: Option<Key>,
|
||||||
dispatcher: Rc<Dispatcher>,
|
dispatcher: Rc<Dispatcher>,
|
||||||
cms: Arc<Mutex<CMS>>,
|
buffer: Arc<Buffer<Key>>,
|
||||||
|
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
||||||
|
cms: CMS,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Eq + Hash + Send + Clone + Copy + 'static, V> Element<T, V>
|
pub enum ElementEvent<'a> {
|
||||||
where
|
Init,
|
||||||
V: Num + NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
DateTime(DateTime<Utc>),
|
||||||
{
|
Key(&'a Key),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Element {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
name: String,
|
name: impl Into<String>,
|
||||||
description: String,
|
|
||||||
imp: ElementImp<V>,
|
|
||||||
config: Box<ElementConfig>,
|
|
||||||
cms: CMS,
|
cms: CMS,
|
||||||
dispatcher: Rc<Dispatcher>,
|
dispatcher: Rc<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 {
|
) -> 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);
|
||||||
Element {
|
Element {
|
||||||
id,
|
id,
|
||||||
name,
|
name: name.into(),
|
||||||
description,
|
cache,
|
||||||
imp: Arc::new(imp),
|
imp,
|
||||||
buffer: Arc::new(Mutex::new(Buffer::new(100))),
|
config,
|
||||||
|
root,
|
||||||
subscribers: Arc::new(Mutex::new(HashMap::new())),
|
subscribers: Arc::new(Mutex::new(HashMap::new())),
|
||||||
config: Arc::new(RwLock::new(config)),
|
|
||||||
cancellers: Arc::new(Mutex::new(HashMap::new())),
|
cancellers: Arc::new(Mutex::new(HashMap::new())),
|
||||||
cms: Arc::new(Mutex::new(cms)),
|
cms: cms,
|
||||||
|
current_key: None,
|
||||||
|
buffer,
|
||||||
|
file_pool,
|
||||||
dispatcher,
|
dispatcher,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_buffer(
|
pub fn r<'a>(&self, event: ElementEvent<'a>, render: &Render) {
|
||||||
name: String,
|
let need_cache = self.cache;
|
||||||
description: String,
|
let format = self.imp.output_type();
|
||||||
imp: ElementImp<V>,
|
|
||||||
buffer: Buffer<T>,
|
match event {
|
||||||
config: Box<ElementConfig>,
|
ElementEvent::Init => {
|
||||||
cms: CMS,
|
let data = self.file_pool.get(&self.root);
|
||||||
dispatcher: Rc<Dispatcher>,
|
if let Some(data) = data {}
|
||||||
) -> Self {
|
}
|
||||||
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
|
||||||
Element {
|
ElementEvent::DateTime(time) => {
|
||||||
id,
|
let path = self.dispatcher.get_single_path(&self.name, time, true);
|
||||||
name,
|
path.map(|path| {
|
||||||
description,
|
let data = self.file_pool.get(&path);
|
||||||
imp: Arc::new(imp),
|
});
|
||||||
buffer: Arc::new(Mutex::new(buffer)),
|
}
|
||||||
subscribers: Arc::new(Mutex::new(HashMap::new())),
|
|
||||||
config: Arc::new(RwLock::new(config)),
|
ElementEvent::Key(key) => {
|
||||||
cancellers: Arc::new(Mutex::new(HashMap::new())),
|
self.buffer.get(key);
|
||||||
cms: Arc::new(Mutex::new(cms)),
|
|
||||||
dispatcher,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get(&self, key: T) -> Arc<Mutex<RenderResult>> {
|
// match key {
|
||||||
|
// ElementEvent::Init => {
|
||||||
|
// let data = self.get_file(&self.root);
|
||||||
|
// }
|
||||||
|
// ElementEvent::DateTime(key) => {
|
||||||
|
// let key = &Key {
|
||||||
|
// id: self.id,
|
||||||
|
// name: self.name.clone(),
|
||||||
|
// root: self.root.clone(),
|
||||||
|
// datetime: Some(key),
|
||||||
|
// };
|
||||||
|
|
||||||
|
// if self.cache {
|
||||||
|
// if let ElementOutput::Target = self.imp.output_type() {
|
||||||
|
// let target = self.run(key.to_owned()).await;
|
||||||
|
// // if let Some(target) = target {
|
||||||
|
// // let mut target = target.lock().await;
|
||||||
|
// // let target = target.get_mut_target();
|
||||||
|
// // render.draw_img(target);
|
||||||
|
// // }
|
||||||
|
// } else {
|
||||||
|
// let path = (&*self.dispatcher).borrow_mut().get_single_path(
|
||||||
|
// &self.name,
|
||||||
|
// key.datetime.to_owned().unwrap(),
|
||||||
|
// true,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// if let Some(path) = path {
|
||||||
|
// let data = self.get_file(path);
|
||||||
|
// let mut _canvas = render.get_canvas();
|
||||||
|
// let mut canvas = _canvas.as_mut().unwrap();
|
||||||
|
// let cms = render.create_cms();
|
||||||
|
// let context = Context::new(cms, canvas);
|
||||||
|
// let mut runner = Runner::new(self.imp, self.config.clone(), context);
|
||||||
|
// runner.run_without_target(&data);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// let path = (&*self.dispatcher).borrow_mut().get_single_path(
|
||||||
|
// &self.name,
|
||||||
|
// key.datetime.to_owned().unwrap(),
|
||||||
|
// true,
|
||||||
|
// );
|
||||||
|
// if let Some(path) = path {
|
||||||
|
// let data = self.get_file(path);
|
||||||
|
// let mut _canvas = render.get_canvas();
|
||||||
|
// let mut canvas = _canvas.as_mut().unwrap();
|
||||||
|
// let cms = render.create_cms();
|
||||||
|
// let context = Context::new(cms, canvas);
|
||||||
|
// let mut runner = Runner::new(self.imp, self.config.clone(), context);
|
||||||
|
// runner.run_without_target(&data);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ElementEvent::Data(data) => {
|
||||||
|
// let mut _canvas = render.get_canvas();
|
||||||
|
// let mut canvas = _canvas.as_mut().unwrap();
|
||||||
|
// let cms = render.create_cms();
|
||||||
|
// let context = Context::new(cms, canvas);
|
||||||
|
// let mut runner = Runner::new(self.imp, self.config.clone(), context);
|
||||||
|
// runner.run_without_target(&data);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _rrrr(&self, data: &PluginResult, need_cache: bool, output_type: ElementOutput) {
|
||||||
|
match output_type {
|
||||||
|
ElementOutput::Target => {}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run(&self, key: Key) -> Option<Arc<Mutex<RenderResult>>> {
|
||||||
{
|
{
|
||||||
let cache = self.buffer.lock().await;
|
let cache = &self.buffer;
|
||||||
if cache.peek(&key).is_some() {
|
if cache.peek(&key).is_some() {
|
||||||
return cache.get(&key).unwrap();
|
return Some(cache.get(&key).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
let datetime = key.datetime.unwrap();
|
||||||
let mut subscribers = self.subscribers.lock().await;
|
|
||||||
|
let dispatcher = (&*self.dispatcher);
|
||||||
|
|
||||||
|
let current_path = dispatcher.get_single_path(&self.name, datetime, true);
|
||||||
|
let paths = dispatcher.get_path(&self.name, datetime, true, 3, &self.root);
|
||||||
|
if let Some(paths) = paths {
|
||||||
|
paths.iter().for_each(|(p, d)| {
|
||||||
|
let key = self.generate_key(d.to_owned());
|
||||||
|
let f = self._run(p, &key);
|
||||||
|
let handle = tokio::task::spawn(f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(path) = current_path {
|
||||||
|
let key = self.generate_key(datetime);
|
||||||
|
let f = self._run(path, &key);
|
||||||
|
let handle = tokio::task::spawn(f);
|
||||||
|
let result = handle.await.unwrap();
|
||||||
|
Some(result)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn generate_key(&self, datetime: DateTime<Utc>) -> Key {
|
||||||
|
Key {
|
||||||
|
id: self.id,
|
||||||
|
name: self.name.clone(),
|
||||||
|
root: self.root.clone(),
|
||||||
|
datetime: Some(datetime),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _run(
|
||||||
|
&self,
|
||||||
|
p: impl AsRef<std::path::Path>,
|
||||||
|
key: &Key,
|
||||||
|
) -> BoxFuture<'static, Arc<Mutex<RenderResult>>> {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
if subscribers.contains_key(&key) {
|
let buffer = self.buffer.clone();
|
||||||
subscribers.get_mut(&key).unwrap().push(tx);
|
let config = self.config.clone();
|
||||||
|
let canceller = self.cancellers.clone();
|
||||||
|
let subscriber = self.subscribers.clone();
|
||||||
|
let mut dialog_cms = self.cms.clone();
|
||||||
|
let mut dialog_config = self.config.clone();
|
||||||
|
let mut dialog_imp = self.imp.clone();
|
||||||
|
|
||||||
|
let _key = key.to_owned();
|
||||||
|
Box::pin(async move {
|
||||||
|
let key = &_key;
|
||||||
|
let mut subscribers = subscriber.lock().await;
|
||||||
|
if subscribers.contains_key(key) {
|
||||||
|
subscribers.get_mut(key).unwrap().push(tx);
|
||||||
drop(subscribers);
|
drop(subscribers);
|
||||||
} else {
|
} else {
|
||||||
let (canceller_tx, canceller_rx) = oneshot::channel();
|
let (canceller_tx, canceller_rx) = oneshot::channel();
|
||||||
subscribers.insert(key, vec![tx]);
|
subscribers.insert(key.to_owned(), vec![tx]);
|
||||||
drop(subscribers);
|
drop(subscribers);
|
||||||
|
|
||||||
{
|
let mut cancellers = canceller.lock().await;
|
||||||
let mut cancellers = self.cancellers.lock().await;
|
cancellers.insert(key.clone(), canceller_tx);
|
||||||
cancellers.insert(key, canceller_tx);
|
drop(cancellers);
|
||||||
}
|
|
||||||
|
|
||||||
let buffer = self.buffer.clone();
|
|
||||||
let config = self.config.clone();
|
|
||||||
let imp = self.imp.clone();
|
|
||||||
let cancellers = self.cancellers.clone();
|
|
||||||
let subscribers = self.subscribers.clone();
|
|
||||||
|
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
|
|
||||||
|
let key = key.to_owned();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
let new_key = key.clone();
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = async move {
|
_ = async move {
|
||||||
|
|
||||||
tokio::time::sleep(Duration::new(5, 0)).await;
|
|
||||||
let handle = task::spawn_blocking(move || {
|
let handle = task::spawn_blocking(move || {
|
||||||
let config = config.read().unwrap();
|
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
||||||
let config: &ElementConfig = &*(*config);
|
let mut canvas = offscreen_renderer.create_canvas();
|
||||||
|
let mut context = Context::new(dialog_cms, &mut canvas);
|
||||||
|
let mut runner = Runner::new(dialog_imp, dialog_config, context);
|
||||||
|
|
||||||
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("".into()).unwrap();
|
||||||
let meta = loaded_data.meta.clone().into();
|
let meta = loaded_data.meta.clone().into();
|
||||||
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
|
||||||
|
|
||||||
// imp.render()
|
let target = runner.run(&loaded_data);
|
||||||
|
|
||||||
|
RenderResult::new(
|
||||||
|
DataTarget::new(Some(loaded_data), target),
|
||||||
|
meta
|
||||||
|
)
|
||||||
});
|
});
|
||||||
let result = handle.await.unwrap();
|
let result = handle.await.unwrap();
|
||||||
|
|
||||||
{
|
|
||||||
let bf = Arc::new(Mutex::new(result));
|
let bf = Arc::new(Mutex::new(result));
|
||||||
buffer.lock().await.insert(key, bf.clone());
|
buffer.insert(key.clone(), bf.clone());
|
||||||
let mut subscribers = subscribers.lock().await;
|
let mut subscribers = subscriber.lock().await;
|
||||||
for tx in subscribers.remove(&key).unwrap() {
|
for tx in subscribers.remove(&key).unwrap() {
|
||||||
let _ = tx.send(bf.clone());
|
let _ = tx.send(bf.clone());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} => {}
|
} => {}
|
||||||
_ = canceller_rx => {}
|
_ = canceller_rx => {}
|
||||||
}
|
}
|
||||||
let mut cancellers = cancellers.lock().await;
|
let mut cancellers = canceller.lock().await;
|
||||||
cancellers.remove(&key);
|
cancellers.remove(&new_key);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
rx.await.unwrap()
|
rx.await.unwrap()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cancel_task_for_timestamp(&self, key: T) {
|
fn key(&self) -> String {
|
||||||
let mut cancellers = self.cancellers.lock().await;
|
format!("{}-{}", self.id, self.name)
|
||||||
if let Some(canceller) = cancellers.remove(&key) {
|
|
||||||
let _ = canceller.send(()); // 发送取消信号
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cancel_all_tasks(&self) {
|
|
||||||
let mut cancellers = self.cancellers.lock().await;
|
|
||||||
for (_timestamp, canceller) in cancellers.drain() {
|
|
||||||
let _ = canceller.send(()); // 发送取消信号
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ElementImpl: Debug + Send + Sync + 'static {
|
|
||||||
type Config;
|
|
||||||
fn render(
|
|
||||||
&self,
|
|
||||||
data: &PluginResult,
|
|
||||||
canvas: &mut CanvasWrapper,
|
|
||||||
cms: &mut CMS,
|
|
||||||
config: &Self::Config,
|
|
||||||
) -> Target;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
use crate::pipeline::element::Target;
|
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
use gl;
|
use gl;
|
||||||
@ -15,6 +14,8 @@ use surfman::{
|
|||||||
NativeConnection, NativeDevice,
|
NativeConnection, NativeDevice,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::Target;
|
||||||
|
|
||||||
pub struct OffscreenRenderer {
|
pub struct OffscreenRenderer {
|
||||||
context: Arc<RwLock<Context>>,
|
context: Arc<RwLock<Context>>,
|
||||||
device: Device,
|
device: Device,
|
||||||
@ -36,7 +37,7 @@ impl OffscreenRenderer {
|
|||||||
let mut device = connection.create_device(&adapter)?;
|
let mut device = connection.create_device(&adapter)?;
|
||||||
|
|
||||||
let descriptor = device.create_context_descriptor(&surfman::ContextAttributes {
|
let descriptor = device.create_context_descriptor(&surfman::ContextAttributes {
|
||||||
version: surfman::GLVersion::new(4, 1),
|
version: surfman::GLVersion::new(3, 3),
|
||||||
flags: ContextAttributeFlags::ALPHA
|
flags: ContextAttributeFlags::ALPHA
|
||||||
.union(ContextAttributeFlags::DEPTH)
|
.union(ContextAttributeFlags::DEPTH)
|
||||||
.union(ContextAttributeFlags::STENCIL),
|
.union(ContextAttributeFlags::STENCIL),
|
||||||
@ -196,3 +197,15 @@ impl BorrowMut<Canvas<OpenGl>> for CanvasWrapper {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsRef<Canvas<OpenGl>> for CanvasWrapper {
|
||||||
|
fn as_ref(&self) -> &Canvas<OpenGl> {
|
||||||
|
&self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<Canvas<OpenGl>> for CanvasWrapper {
|
||||||
|
fn as_mut(&mut self) -> &mut Canvas<OpenGl> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
use crate::coords::cms::CMS;
|
use crate::coords::cms::CMS;
|
||||||
use crate::pipeline::element::Target;
|
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
|
|
||||||
|
use super::Target;
|
||||||
|
|
||||||
pub trait DataRenderer<'a> {
|
pub trait DataRenderer<'a> {
|
||||||
type Data;
|
type Data;
|
||||||
fn render(
|
fn render(
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
use std::{any::Any, sync::Arc};
|
use std::{any::Any, sync::Arc};
|
||||||
|
|
||||||
use femtovg::RenderTarget;
|
use femtovg::{renderer::OpenGl, Canvas, RenderTarget};
|
||||||
use gl::types::GLvoid;
|
use gl::types::GLvoid;
|
||||||
use image::Rgba;
|
use image::Rgba;
|
||||||
use ndarray::{ArrayView1, ArrayViewD};
|
use ndarray::{Array2, ArrayBase, ArrayView1, ArrayViewD};
|
||||||
use radarg_plugin_interface::{PluginResult, VecResult};
|
use radarg_plugin_interface::{PluginResult, VecResult};
|
||||||
|
use smallvec::Array;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{
|
pipeline::{
|
||||||
@ -34,14 +35,14 @@ macro_rules! impl_for_runner {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Runner {
|
pub struct Runner<'a> {
|
||||||
imp: ElementImpl,
|
imp: ElementImpl,
|
||||||
config: Arc<dyn Any>,
|
config: Arc<dyn Any>,
|
||||||
context: Context,
|
context: Context<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Runner {
|
impl<'a> Runner<'a> {
|
||||||
pub fn new(imp: ElementImpl, config: Arc<dyn Any>, context: Context) -> Self {
|
pub fn new(imp: ElementImpl, config: Arc<dyn Any>, context: Context<'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
imp,
|
imp,
|
||||||
config,
|
config,
|
||||||
@ -50,6 +51,49 @@ impl Runner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self, data: &PluginResult) -> Target {
|
pub fn run(&mut self, data: &PluginResult) -> Target {
|
||||||
|
use femtovg::{ImageFlags, PixelFormat::Rgba8};
|
||||||
|
let canvas = &mut self.context.canvas;
|
||||||
|
let (w, h) = (canvas.width(), canvas.height());
|
||||||
|
|
||||||
|
let new_img = canvas
|
||||||
|
.create_image_empty(w as usize, h as usize, Rgba8, ImageFlags::empty())
|
||||||
|
.expect("Can't Create Image");
|
||||||
|
canvas.image_size(new_img).unwrap();
|
||||||
|
canvas.set_render_target(RenderTarget::Image(new_img));
|
||||||
|
|
||||||
|
// Drawing
|
||||||
|
let dims = self.run_without_target(data);
|
||||||
|
|
||||||
|
// Reading Pixels
|
||||||
|
let mut pixels: Vec<u8> = vec![0; w as usize * h as usize * 4];
|
||||||
|
unsafe {
|
||||||
|
gl::ReadPixels(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
w as i32,
|
||||||
|
h as i32,
|
||||||
|
gl::RGBA,
|
||||||
|
gl::UNSIGNED_BYTE,
|
||||||
|
pixels.as_mut_ptr() as *mut GLvoid,
|
||||||
|
);
|
||||||
|
debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
|
||||||
|
}
|
||||||
|
self.context.canvas.set_render_target(RenderTarget::Screen);
|
||||||
|
let d1_start = (dims.0.view()).first().unwrap().clone();
|
||||||
|
let d1_end = (dims.0.view()).last().unwrap().clone();
|
||||||
|
let d2_start = dims.1.view().first().unwrap().clone();
|
||||||
|
let d2_end = dims.1.view().last().unwrap().clone();
|
||||||
|
|
||||||
|
Target::new(
|
||||||
|
TargetType::NativeBuffer(pixels),
|
||||||
|
w as f32,
|
||||||
|
h as f32,
|
||||||
|
((d1_start, d1_end).into(), (d2_start, d2_end).into()),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_without_target(&mut self, data: &PluginResult) -> (Array2<f64>, Array2<f64>) {
|
||||||
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;
|
||||||
@ -71,17 +115,10 @@ impl Runner {
|
|||||||
let size = block.size.to_owned().to_vec();
|
let size = block.size.to_owned().to_vec();
|
||||||
let config = &*self.config;
|
let config = &*self.config;
|
||||||
let imp: &ElementImpl = &self.imp;
|
let imp: &ElementImpl = &self.imp;
|
||||||
let context: &mut Context = &mut self.context;
|
let context = &mut self.context;
|
||||||
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());
|
||||||
use femtovg::{ImageFlags, PixelFormat::Rgba8};
|
|
||||||
|
|
||||||
let new_img = canvas
|
|
||||||
.create_image_empty(w as usize, h as usize, Rgba8, ImageFlags::empty())
|
|
||||||
.expect("Can't Create Image");
|
|
||||||
canvas.image_size(new_img).unwrap();
|
|
||||||
canvas.set_render_target(RenderTarget::Image(new_img));
|
|
||||||
|
|
||||||
let lat_start = dims.1.view().first().unwrap().clone();
|
let lat_start = dims.1.view().first().unwrap().clone();
|
||||||
let lat_end = dims.1.view().last().unwrap().clone();
|
let lat_end = dims.1.view().last().unwrap().clone();
|
||||||
@ -112,35 +149,7 @@ impl Runner {
|
|||||||
{ U64 },
|
{ U64 },
|
||||||
{ U32 },
|
{ U32 },
|
||||||
);
|
);
|
||||||
|
|
||||||
context.canvas.flush();
|
context.canvas.flush();
|
||||||
|
dims
|
||||||
let mut pixels: Vec<u8> = vec![0; w as usize * h as usize * 4];
|
|
||||||
unsafe {
|
|
||||||
gl::ReadPixels(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
w as i32,
|
|
||||||
h as i32,
|
|
||||||
gl::RGBA,
|
|
||||||
gl::UNSIGNED_BYTE,
|
|
||||||
pixels.as_mut_ptr() as *mut GLvoid,
|
|
||||||
);
|
|
||||||
debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
|
|
||||||
}
|
|
||||||
let d1_start = (dims.0.view()).first().unwrap().clone();
|
|
||||||
let d1_end = (dims.0.view()).last().unwrap().clone();
|
|
||||||
|
|
||||||
let d2_start = dims.1.view().first().unwrap().clone();
|
|
||||||
let d2_end = dims.1.view().last().unwrap().clone();
|
|
||||||
context.canvas.set_render_target(RenderTarget::Screen);
|
|
||||||
|
|
||||||
Target::new(
|
|
||||||
TargetType::NativeBuffer(pixels),
|
|
||||||
w as f32,
|
|
||||||
h as f32,
|
|
||||||
((d1_start, d1_end).into(), (d2_start, d2_end).into()),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::components::widget::{Widget, WidgetType};
|
use crate::components::widget::{Widget, WidgetType};
|
||||||
use crate::predefined::color_mapper::ColorMapper;
|
use crate::predefined::color_mapper::ColorMapper;
|
||||||
use crate::widgets::{AssoElement, Layer};
|
use crate::widgets::Layer;
|
||||||
use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
|
use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
|
||||||
use num_traits::*;
|
use num_traits::*;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
@ -39,17 +39,6 @@ impl Widget for ColorBar {
|
|||||||
|
|
||||||
let first = layers.first().unwrap();
|
let first = layers.first().unwrap();
|
||||||
|
|
||||||
match first.get_associated_element() {
|
|
||||||
AssoElement::Instant(i) => {
|
|
||||||
let imp = i.imp();
|
|
||||||
}
|
|
||||||
AssoElement::TimeSeries(t) => {
|
|
||||||
let c = t.lock().unwrap();
|
|
||||||
let imp = c.imp();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// for ((i, color), label) in self
|
// for ((i, color), label) in self
|
||||||
// .color_list
|
// .color_list
|
||||||
// .iter()
|
// .iter()
|
||||||
|
|||||||
@ -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::element::{Target, TargetType};
|
use crate::pipeline::new_element::{Target, TargetType};
|
||||||
use femtovg::{Canvas, Color, FontId, Paint, Renderer};
|
use femtovg::{Canvas, Color, FontId, Paint, Renderer};
|
||||||
use gtk::glib::{self, prelude::*, Properties};
|
use gtk::glib::{self, prelude::*, Properties};
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|||||||
@ -1,30 +1,19 @@
|
|||||||
use super::super::Render;
|
use super::super::Render;
|
||||||
use crate::coords::cms::CMS;
|
|
||||||
use crate::errors::PipelineError;
|
use crate::errors::PipelineError;
|
||||||
use crate::pipeline::element::{self, Target};
|
use crate::pipeline::new_element::{self, Target};
|
||||||
use crate::pipeline::offscreen_renderer::CanvasWrapper;
|
use crate::pipeline::new_element::{Element, ElementEvent};
|
||||||
use chrono::{prelude::*, DateTime};
|
use crate::RUNTIME;
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
|
use std::rc::Rc;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
type PrepareFunc = Arc<
|
#[derive(Clone, Copy, Debug)]
|
||||||
Mutex<
|
pub enum ElementType {
|
||||||
Option<
|
Asso,
|
||||||
Box<dyn FnOnce(LayerImplSync, Arc<Mutex<CanvasWrapper>>, CMS) -> Target + Sync + Send>,
|
Indenpendent,
|
||||||
>,
|
|
||||||
>,
|
|
||||||
>;
|
|
||||||
type DrawFunc = Arc<dyn Fn(&Layer, Render, (f32, f32)) + Send + Sync>;
|
|
||||||
pub type LayerImplSync = Arc<Mutex<Box<dyn LayerImpl + Send + Sync>>>;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum AssoElement {
|
|
||||||
TimeSeries(Arc<Mutex<element::TimeSeriesElement>>),
|
|
||||||
Instant(element::InstantElement),
|
|
||||||
Test,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -32,8 +21,8 @@ pub struct Layer {
|
|||||||
pub visiable: bool,
|
pub visiable: bool,
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
associated_element: AssoElement,
|
element_type: ElementType,
|
||||||
time: Option<DateTime<Utc>>,
|
element: Rc<Element>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Layer {
|
impl Debug for Layer {
|
||||||
@ -44,64 +33,29 @@ impl Debug for Layer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LayerImpl: Debug {
|
|
||||||
fn draw(&self, canvas: &mut Canvas<OpenGl>, cms: &CMS) -> Option<Target>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Layer {
|
impl Layer {
|
||||||
pub fn new(visiable: bool, layer_name: String, element: AssoElement) -> Self {
|
pub fn new(
|
||||||
|
visiable: bool,
|
||||||
|
layer_name: String,
|
||||||
|
element: Rc<Element>,
|
||||||
|
element_type: ElementType,
|
||||||
|
) -> Self {
|
||||||
Layer {
|
Layer {
|
||||||
alpha: 1.0,
|
alpha: 1.0,
|
||||||
visiable,
|
visiable,
|
||||||
name: layer_name,
|
name: layer_name,
|
||||||
associated_element: element,
|
element,
|
||||||
time: None,
|
element_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_time(&mut self, time: DateTime<Utc>) {
|
pub(super) fn draw(
|
||||||
self.time = Some(time);
|
&mut self,
|
||||||
}
|
render: &Render,
|
||||||
|
window_size: (f32, f32),
|
||||||
pub fn draw(&mut self, render: &Render, window_size: (f32, f32)) -> Result<(), PipelineError> {
|
) -> Result<(), PipelineError> {
|
||||||
if self.visiable {
|
if self.visiable {
|
||||||
match self.associated_element {
|
self.element.r(ElementEvent::Init, render);
|
||||||
AssoElement::Instant(ref mut e) => {
|
|
||||||
e.render(render);
|
|
||||||
}
|
|
||||||
AssoElement::TimeSeries(ref e) => {
|
|
||||||
let mut e = e.lock().unwrap();
|
|
||||||
let mut buffer = e.buffer.lock().unwrap();
|
|
||||||
let mut result = buffer.get_mut(&self.time.unwrap()).map(|x| x.as_mut());
|
|
||||||
|
|
||||||
if result.is_none() {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(result) = result.unwrap() {
|
|
||||||
let target = result.get_mut_target();
|
|
||||||
|
|
||||||
// let mut canvas = render.get_canvas();
|
|
||||||
// let mut canvas = canvas.as_mut().unwrap();
|
|
||||||
// let (ox, oy) = target.origin(render);
|
|
||||||
// let (x, y) = target.size(render);
|
|
||||||
|
|
||||||
render.draw_img(target);
|
|
||||||
|
|
||||||
// let result_id = match target.target {
|
|
||||||
// TargetType::ImageId(id) => id,
|
|
||||||
// TargetType::Mem(ref mem) => {
|
|
||||||
// let converted = canvas
|
|
||||||
// .load_image_mem(mem, femtovg::ImageFlags::empty())
|
|
||||||
// .unwrap();
|
|
||||||
// target.set_target(TargetType::ImageId(converted));
|
|
||||||
// converted
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,16 +73,4 @@ impl Layer {
|
|||||||
pub fn change_visiable(&mut self, visiable: bool) {
|
pub fn change_visiable(&mut self, visiable: bool) {
|
||||||
self.visiable = visiable;
|
self.visiable = visiable;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_associated_element(&mut self) -> AssoElement {
|
|
||||||
std::mem::replace(&mut self.associated_element, AssoElement::Test)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_associated_element(&self) -> &AssoElement {
|
|
||||||
&self.associated_element
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_associated_element(&mut self, element: AssoElement) {
|
|
||||||
self.associated_element = element;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use core_extensions::SelfOps;
|
|||||||
use femtovg::{renderer::OpenGl, Canvas, ImageFlags};
|
use femtovg::{renderer::OpenGl, Canvas, ImageFlags};
|
||||||
use femtovg::{Paint, Path};
|
use femtovg::{Paint, Path};
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
pub use layers::{AssoElement, Layer, LayerImpl, LayerImplSync};
|
pub use layers::{ElementType, Layer};
|
||||||
use relm4::channel;
|
use relm4::channel;
|
||||||
use std::cell::Ref;
|
use std::cell::Ref;
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use crate::coords::cms::CMS;
|
|||||||
use crate::coords::{Mapper, Range};
|
use crate::coords::{Mapper, Range};
|
||||||
use crate::errors::PipelineError;
|
use crate::errors::PipelineError;
|
||||||
use crate::map_tile::MapTile;
|
use crate::map_tile::MapTile;
|
||||||
use crate::pipeline::element::{Target, TargetType};
|
use crate::pipeline::{Target, TargetType};
|
||||||
use adw::prelude::{GLAreaExt, GestureDragExt};
|
use adw::prelude::{GLAreaExt, GestureDragExt};
|
||||||
use femtovg::ImageFlags;
|
use femtovg::ImageFlags;
|
||||||
use geo_types::LineString;
|
use geo_types::LineString;
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use crate::coords::Range;
|
|||||||
use std::borrow::BorrowMut;
|
use std::borrow::BorrowMut;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use super::super::{Layer, LayerImpl, Render};
|
use super::super::{Layer, Render};
|
||||||
use crate::coords::Mapper;
|
use crate::coords::Mapper;
|
||||||
use femtovg::renderer::OpenGl;
|
use femtovg::renderer::OpenGl;
|
||||||
use femtovg::{Canvas, Paint};
|
use femtovg::{Canvas, Paint};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use super::Render;
|
use super::Render;
|
||||||
use crate::coords::cms::CMS;
|
use crate::coords::cms::CMS;
|
||||||
use crate::pipeline::element::Target;
|
use crate::pipeline::Target;
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
|
|
||||||
pub trait DataRenderer {
|
pub trait DataRenderer {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user