This commit is contained in:
Tsuki 2024-03-19 18:37:13 +08:00
parent 1e8a90aebe
commit 18b7d2d3d8
15 changed files with 128 additions and 120 deletions

6
src/actions.rs Normal file
View File

@ -0,0 +1,6 @@
use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt};
use relm4::actions::{AccelsPlus, ActionablePlus, RelmAction, RelmActionGroup};
use relm4::{ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent};
relm4::new_action_group!(LayerActionGroup, "layer");
relm4::new_stateful_action!(AddLayerAction, LayerActionGroup, "add", u8, u8);

View File

@ -5,7 +5,6 @@ use super::{
setting::SettingModel,
ControlPanelOutputMsg, TimelineMsg,
};
use crate::data_utils::plugin_result_impl;
use crate::pipeline::element::{
Element, InstantElement, InstantElementDrawerType, TimeSeriesElement,
};
@ -24,6 +23,7 @@ use crate::{
widgets::render::Layer,
CONFIG, PLUGIN_MANAGER,
};
use crate::{data_utils::plugin_result_impl, pipeline::element::DataTarget};
use abi_stable::std_types::RStr;
use adw::prelude::*;
use chrono::{prelude::*, Duration};
@ -228,11 +228,10 @@ impl Component for AppModel {
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 data_target = element_impl.render(&data, &mut canvas, &mut dialog_cms);
data_target.data = Some(Arc::new(data) as Arc<dyn Any + Send + Sync + 'static>);
let data_target = element_impl.render(&data, &mut canvas, &mut dialog_cms);
let data_target = DataTarget::new(Some(data), data_target);
let element = Element::create_instant(
InstantElementDrawerType::Prepared((data_target, Arc::new(element_impl))),
InstantElementDrawerType::Prepared((data_target, element_impl)),
dialog_dispatcher.clone(),
"ET".to_string(),
)

View File

@ -161,7 +161,7 @@ impl Component for MonitorModel {
let current_rate = widgets.renderer.scale_rate();
self.set_render_range((lat_start, lat_end, lon_start, lon_end));
let new_rate = widgets.renderer.scale_rate();
let zoom: f64 = (current_rate / new_rate).log2();
let zoom: f64 = (new_rate / current_rate).log2();
sender.input(MonitorInputMsg::ChangeZoom(zoom));
}
MonitorInputMsg::ClearMetaItems => self.sidebar.emit(SideBarInputMsg::ClearMetaItems),

View File

@ -1,3 +0,0 @@
button {
color: magenta;
}

View File

@ -1,14 +1,15 @@
use radarg_plugin_interface::{CoordType, PluginResult, PluginResultType};
use crate::pipeline::element::ElementImpl;
use crate::pipeline::GridElementImpl;
use crate::utils::*;
use radarg_plugin_interface::{CoordType, PluginResult, PluginResultType};
use std::sync::Arc;
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)
Arc::new(element_impl)
}
),+
_ => panic!("Invalid type")
@ -16,7 +17,7 @@ macro_rules! data_to_grid {
};
}
pub fn plugin_result_impl(a: &PluginResult) -> Box<dyn ElementImpl> {
pub fn plugin_result_impl(a: &PluginResult) -> Arc<dyn ElementImpl> {
let block = a.blocks.first().unwrap();
match block.coord_type {
CoordType::Cartesian => {
@ -41,4 +42,3 @@ pub fn plugin_result_impl(a: &PluginResult) -> Box<dyn ElementImpl> {
}
}
}

View File

@ -12,6 +12,7 @@ use gtk::{
use plugin_system::{init_plugin, PluginManager};
use std::{ptr, sync::Mutex};
use tokio::runtime::Runtime;
mod actions;
mod chart;
mod components;
mod config;
@ -20,13 +21,13 @@ mod data;
mod errors;
mod pipeline;
mod plugin_system;
use crate::components::app::AppMsg;
use components::app::AppModel;
use once_cell::{sync::Lazy as SafeLazy, unsync::Lazy as UnsafeLazy};
use relm4::RelmApp;
use surfman::declare_surfman;
use tracing::info;
use tracing_subscriber;
use crate::components::app::AppMsg;
mod data_utils;
mod map_tile;
@ -67,11 +68,7 @@ fn main() {
});
}
let app = adw::Application::builder()
.application_id(APP_ID)
.build();
let app = adw::Application::builder().application_id(APP_ID).build();
let relm: RelmApp<AppMsg> = relm4::RelmApp::from_app(app.clone());
relm4_icons::initialize_icons();
info!("Init plugin system");

View File

@ -144,7 +144,7 @@ impl MapTile {
(origin.lon() as f64..rb.lon() as f64).into(),
(origin.lat() as f64..rb.lat() as f64).into(),
);
let result = Target::new(TargetType::Mem(result), 256.0, 256.0, bounds, None,None);
let result = Target::new(TargetType::Mem(result), 256.0, 256.0, bounds, None);
let cache = cache.lock().unwrap();
cache.insert(tile, Arc::new(std::sync::Mutex::new(result)));
}

View File

@ -17,6 +17,7 @@ use std::any::Any;
use std::borrow::Borrow;
use std::collections::{BTreeMap, HashMap};
use std::fmt::Formatter;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use std::sync::atomic::AtomicUsize;
use std::{
@ -48,7 +49,7 @@ pub enum Element {
impl Element {
pub fn create_time_series(
imp: Arc<Box<dyn ElementImpl>>,
imp: Arc<dyn ElementImpl>,
dispatcher: Rc<Dispatcher>,
key: String,
cms: CMS,
@ -95,7 +96,7 @@ pub struct TimeSeriesElement {
pub id: ElementID,
pub key: String,
cms: CMS,
imp: Arc<Box<dyn ElementImpl>>,
imp: Arc<dyn ElementImpl>,
registers: Arc<Mutex<HashMap<DateTime<Utc>, Vec<Arc<Notify>>>>>,
pipeline: Pipeline,
pub buffer: Buffer,
@ -105,7 +106,7 @@ pub struct TimeSeriesElement {
#[derive(Clone)]
pub enum InstantElementDrawerType {
Draw(DrawFunc),
Prepared((Target, Arc<Box<dyn ElementImpl>>)),
Prepared((DataTarget, Arc<dyn ElementImpl>)),
}
impl Debug for InstantElementDrawerType {
@ -141,33 +142,7 @@ impl InstantElement {
func(render);
}
InstantElementDrawerType::Prepared((ref 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);
let result_id = match target.target {
TargetType::ImageId(id) => id,
TargetType::Mem(ref mem) => {
let gl_bind = render.get_context();
let gl = gl_bind.as_ref().unwrap();
let flags = ImageFlags::empty();
let texture = target.mem_to_native_texture(gl, flags);
let converted = canvas
.create_image_from_native_texture(
texture,
ImageInfo::new(flags, 3000, 3000, PixelFormat::Rgba8),
)
.unwrap();
target.set_target(TargetType::ImageId(converted));
converted
}
};
let paint = femtovg::Paint::image(result_id, ox, oy, x, y, 0.0, 1.0);
let mut path = femtovg::Path::new();
path.rect(ox, oy, x, y);
canvas.fill_path(&path, &paint);
render.draw_img(target);
}
}
}
@ -178,14 +153,9 @@ impl InstantElement {
cms: CMS,
) -> (TimeSeriesElement, DateTime<Utc>) {
// let imp = Arc::new(InstantElementImpl::new(self));
if let InstantElementDrawerType::Prepared((target, imp)) = self.draw_type {
if let InstantElementDrawerType::Prepared((mut target, imp)) = self.draw_type {
let mut time_series = TimeSeriesElement::new(imp, dispatcher, cms, self.key);
let data = target
.data
.clone()
.unwrap()
.downcast::<PluginResult>()
.unwrap();
let data = target.take_data().unwrap();
let time_stamp = data.blocks.first().unwrap().datetime;
let meta_info: MetaInfo = data.meta.clone().into();
use chrono::prelude::*;
@ -202,12 +172,7 @@ impl InstantElement {
}
impl TimeSeriesElement {
fn new(
imp: Arc<Box<dyn ElementImpl>>,
dispatcher: Rc<Dispatcher>,
cms: CMS,
key: String,
) -> Self {
fn new(imp: Arc<dyn ElementImpl>, dispatcher: Rc<Dispatcher>, cms: CMS, key: String) -> Self {
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let mut pipeline = Pipeline::new(20, key.clone());
pipeline.set_dispatcher(dispatcher.clone());
@ -329,12 +294,12 @@ impl TimeSeriesElement {
#[derive(Debug, Clone)]
pub struct RenderResult {
target: Target,
target: DataTarget,
meta_info: MetaInfo,
}
impl RenderResult {
pub fn new(target: Target, meta_info: MetaInfo) -> Self {
pub fn new(target: DataTarget, meta_info: MetaInfo) -> Self {
Self { target, meta_info }
}
@ -354,13 +319,14 @@ pub struct Target {
pub width: f32,
pub height: f32,
pub bounds: (Range, Range),
pub data: Option<Arc<dyn Any + Send + Sync + 'static>>,
// pub data: Option<Arc<dyn Any + Send + Sync + 'static>>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub enum TargetType {
ImageId(ImageId),
Mem(Vec<u8>),
NativeBuffer(Vec<u8>),
}
impl Target {
@ -370,7 +336,7 @@ impl Target {
height: f32,
bounds: (Range, Range),
thumbnail: Option<gtk::gdk::Texture>,
data: Option<Arc<dyn Any + Send + Sync + 'static>>,
// data: Option<Arc<dyn Any + Send + Sync + 'static>>,
) -> Self {
Self {
target,
@ -378,7 +344,7 @@ impl Target {
height,
bounds,
thumbnail,
data,
// data,
}
}
@ -394,12 +360,12 @@ impl Target {
((x2 - x1).abs(), (y2 - y1).abs())
}
pub fn mem_to_native_texture(
pub fn native_buffer_to_native_texture(
&self,
gl: &glow::Context,
flags: ImageFlags,
) -> glow::NativeTexture {
if let TargetType::Mem(ref mem) = self.target {
if let TargetType::NativeBuffer(ref mem) = self.target {
use glow::*;
let texture = unsafe {
let id = gl.create_texture().unwrap();
@ -549,3 +515,41 @@ impl Target {
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()
}
}
impl Deref for DataTarget {
type Target = Target;
fn deref(&self) -> &Self::Target {
&self.target
}
}
impl DerefMut for DataTarget {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.target
}
}

View File

@ -1,6 +1,6 @@
use super::{
dispatcher::Dispatcher,
element::RenderResult,
element::{DataTarget, RenderResult},
offscreen_renderer::{CanvasWrapper, OffscreenRenderer},
utils::data_to_element,
};
@ -16,6 +16,7 @@ use crate::{
use chrono::prelude::*;
use femtovg::{renderer::OpenGl, Canvas, ImageId};
use futures::{future::BoxFuture, Future};
use radarg_plugin_interface::PluginResult;
use smallvec::SmallVec;
use std::fmt::{Debug, Formatter};
use std::{
@ -23,7 +24,6 @@ use std::{
rc::Rc,
sync::{Arc, Mutex},
};
use radarg_plugin_interface::PluginResult;
use tokio::{
sync::{mpsc, oneshot},
task,
@ -136,7 +136,7 @@ impl Pipeline {
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
let mut canvas_wrapper = offscreen_renderer.create_canvas();
let target = task(&loaded_data, &mut canvas_wrapper, &mut cms);
target
DataTarget::new(Some(loaded_data), target)
});
let target = handle.await.unwrap();

View File

@ -9,11 +9,11 @@ use femtovg::{
};
use geo_types::LineString;
use gl::types::GLvoid;
use gtk::ResponseType::No;
use image::{imageops::resize, ImageBuffer, Rgba};
use ndarray::ArrayView2;
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
use std::{fmt::Debug, io::Cursor, marker::PhantomData};
use gtk::ResponseType::No;
use tracing::info;
#[derive(Debug)]
@ -183,12 +183,10 @@ where
canvas.set_render_target(RenderTarget::Screen);
Target::new(
TargetType::Mem(pixels),
TargetType::NativeBuffer(pixels),
w,
h,
((d1_start, d1_end).into(), (d2_start, d2_end).into()),
// Some(thumbnail_tex),
None,
None,
)
}

View File

@ -25,7 +25,7 @@ macro_rules! match_in_macro {
match $block.data_type {
$(
$branch => {
let element = Element::create_time_series(Arc::new(Box::new(GridElementImpl::new($color))), $dispatcher, $name.to_string(), $cms);
let element = Element::create_time_series(Arc::new(GridElementImpl::new($color)), $dispatcher, $name.to_string(), $cms);
Some(element)
},
)+
@ -36,11 +36,7 @@ macro_rules! match_in_macro {
};
}
pub fn data_to_element(
block: &Block,
dispatcher: Rc<Dispatcher>,
cms: CMS,
) -> Option<Element> {
pub fn data_to_element(block: &Block, dispatcher: Rc<Dispatcher>, cms: CMS) -> Option<Element> {
use crate::utils::*;
use radarg_plugin_interface::PluginResultType;
match block.shape {

View File

@ -95,7 +95,6 @@ impl ObjectSubclass for Render {
}
impl ObjectImpl for Render {
fn constructed(&self) {
self.parent_constructed();
let area = self.obj();
@ -340,6 +339,20 @@ impl Render {
target.set_target(TargetType::ImageId(converted));
converted
}
TargetType::NativeBuffer(ref mem) => {
let gl_bind = self.glow_context.borrow();
let gl = gl_bind.as_ref().unwrap();
let flags = femtovg::ImageFlags::empty();
let texture = target.native_buffer_to_native_texture(gl, flags);
let converted = canvas
.create_image_from_native_texture(
texture,
femtovg::ImageInfo::new(flags, 3000, 3000, femtovg::PixelFormat::Rgba8),
)
.unwrap();
target.set_target(TargetType::ImageId(converted));
converted
}
};
let painter = Paint::image(id, ox, oy, x, y, 0.0, 1.0);

View File

@ -1,9 +1,11 @@
use super::super::Render;
use crate::coords::cms::CMS;
use crate::errors::PipelineError;
use crate::pipeline::element::{self, Element, ElementID, Target, TargetType};
use crate::pipeline::offscreen_renderer::CanvasWrapper;
use crate::{coords::Range, widgets::widget::Widget};
use chrono::{prelude::*, DateTime};
use core_extensions::SelfOps;
use femtovg::{renderer::OpenGl, Canvas, ImageId};
use std::{
cell::{Ref, RefCell},
@ -12,8 +14,6 @@ use std::{
pin::Pin,
sync::{Arc, Mutex},
};
use core_extensions::SelfOps;
use crate::errors::PipelineError;
type PrepareFunc = Arc<
Mutex<
@ -29,7 +29,7 @@ pub type LayerImplSync = Arc<Mutex<Box<dyn LayerImpl + Send + Sync>>>;
pub enum AssoElement {
TimeSeries(Arc<Mutex<element::TimeSeriesElement>>),
Instant(element::InstantElement),
Test
Test,
}
#[derive(Clone)]
@ -86,27 +86,23 @@ impl Layer {
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);
// 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);
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
}
};
let paint = femtovg::Paint::image(result_id, ox, oy, x, y, 0.0, self.alpha);
let mut path = femtovg::Path::new();
path.rect(ox, oy, x, y);
canvas.fill_path(&path, &paint);
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
// }
// };
}
}
_ => {}
@ -140,5 +136,4 @@ impl Layer {
pub fn set_associated_element(&mut self, element: AssoElement) {
self.associated_element = element;
}
}

View File

@ -251,7 +251,6 @@ impl Render {
height,
bounds,
None,
None
))
}
@ -263,6 +262,10 @@ impl Render {
}
}
pub fn draw_img(&self, img: &mut Target) {
self.imp().draw_target(img);
}
pub fn scale_rate(&self) -> f64 {
let status = self.imp().status.borrow();
status.scale_rate.unwrap()

View File

@ -13,8 +13,8 @@ use std::{fmt::Debug, io::Cursor, marker::PhantomData};
use super::super::renders::DataRenderer;
use super::super::{LayerImpl, Render};
use crate::{data::Radar2d, utils::meshgrid};
use crate::coords::cms::CMS;
use crate::{data::Radar2d, utils::meshgrid};
#[derive(Debug)]
pub struct GridFieldRenderer<CMAP, T>
@ -175,7 +175,7 @@ where
let d2_end = data.dim2.view().last().unwrap().clone();
Target::new(
TargetType::Mem(png_data),
TargetType::NativeBuffer(png_data),
w,
h,
((d1_start, d1_end).into(), (d2_start, d2_end).into()),