From f860aadfa8302bdb09063b535a065d6a6b73274e Mon Sep 17 00:00:00 2001 From: tsuki Date: Wed, 13 Mar 2024 01:04:03 +0800 Subject: [PATCH] sync --- src/components/monitor/messages.rs | 2 + src/components/monitor/mod.rs | 2 +- src/components/monitor/monitor.rs | 78 +++++++----------------------- src/map_tile.rs | 50 ++++++++++++------- src/widgets/render/imp.rs | 18 ++++--- src/widgets/render/mod.rs | 6 +-- 6 files changed, 66 insertions(+), 90 deletions(-) diff --git a/src/components/monitor/messages.rs b/src/components/monitor/messages.rs index c24252a..2207053 100644 --- a/src/components/monitor/messages.rs +++ b/src/components/monitor/messages.rs @@ -7,6 +7,7 @@ use crate::{ }; pub enum MonitorInputMsg { + RefreshRender, AddWidget(Box), RemoveWidget, AddMetaItem(HashMap), @@ -22,6 +23,7 @@ pub enum MonitorInputMsg { impl Debug for MonitorInputMsg { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + MonitorInputMsg::RefreshRender => write!(f, "MonitorInputMsg::RefreshRender"), MonitorInputMsg::RefreshTiles => write!(f, "MonitorInputMsg::RefreshTiles"), MonitorInputMsg::ChangeZoom(_) => write!(f, "MonitorInputMsg::ChangeZoom"), MonitorInputMsg::SetRenderRange(_, _, _, _) => write!(f, "MonitorInputMsg::SetRenderRange"), diff --git a/src/components/monitor/mod.rs b/src/components/monitor/mod.rs index 03cdc97..ee7e130 100644 --- a/src/components/monitor/mod.rs +++ b/src/components/monitor/mod.rs @@ -1,4 +1,4 @@ pub mod messages; pub mod monitor; pub mod sidebar; -pub use monitor::MonitorModel; +pub use monitor::*; diff --git a/src/components/monitor/monitor.rs b/src/components/monitor/monitor.rs index e6c1d15..07a5f9c 100644 --- a/src/components/monitor/monitor.rs +++ b/src/components/monitor/monitor.rs @@ -26,7 +26,6 @@ use crate::map_tile_utils::lat_lon_to_zoom; use crate::pipeline::element::Target; use adw::prelude::*; use femtovg::ImageId; -use quick_cache::unsync::Cache; use relm4::{component::Component, *}; use slippy_map_tiles::Tile; use tokio::task; @@ -34,7 +33,7 @@ use tracing::instrument::WithSubscriber; #[derive(Debug)] pub enum MonitorCommand { - LoadTile(Tile, Vec, (f64, f64), (Range, Range)), + LoadedTile(Tile), None, } #[tracker::track] @@ -45,11 +44,7 @@ pub struct MonitorModel { sidebar_width: i32, zoom: u8, #[do_not_track] - tile_cache: Cache, - #[do_not_track] - map_tile_getter: Arc>, - #[do_not_track] - tiles: Rc>>>, + map_tile_getter: Rc, new_layer: i8, #[no_eq] widgets: Vec, @@ -100,10 +95,10 @@ impl Component for MonitorModel { set_cfg: model.render_cfg, #[track = "model.changed(MonitorModel::render_range())"] set_view: model.render_range, + set_tiles: model.map_tile_getter.clone(), connect_render_status_notify[sender] => move |r| { sender.output(MonitorOutputMsg::LayerRenderFinished); }, - set_tiles: model.tiles.clone(), connect_range_changing_notify[sender] => move |r| { sender.input(MonitorInputMsg::RefreshTiles); }, @@ -145,9 +140,12 @@ impl Component for MonitorModel { ) { self.reset(); match message { + MonitorInputMsg::RefreshRender => { + widgets.renderer.queue_render(); + } MonitorInputMsg::RefreshLayerList => { self.sidebar.sender().send(SideBarInputMsg::RefreshList); - widgets.renderer.queue_render(); + sender.input(MonitorInputMsg::RefreshRender); } MonitorInputMsg::AddMetaItem(map) => { self.sidebar.emit(SideBarInputMsg::AddMetaItems(map)) @@ -162,7 +160,7 @@ impl Component for MonitorModel { } MonitorInputMsg::RefreshTiles => { let ((x1 , x2), (y1,y2)) = widgets.renderer.render_range(); - // Self::load_cache_tile(&mut self.tile_cache,&sender, &self.map_tile_getter, self.zoom, ((y1 as f32, y2 as f32),(x1 as f32,x2 as f32))); + self.load_tile(&sender, ((y1 as f32, y2 as f32), (x1 as f32, x2 as f32))); } MonitorInputMsg::AddWidget(widget) => match widget.widget_type() { WidgetType::Cairo => { @@ -176,6 +174,7 @@ impl Component for MonitorModel { MonitorInputMsg::ChangeZoom(zoom) => { if self.zoom != zoom { self.zoom = zoom; + self.map_tile_getter.set_zoom(zoom); sender.input(MonitorInputMsg::RefreshTiles); } } @@ -211,20 +210,16 @@ impl Component for MonitorModel { render_range: (4.0, 53.3, 73.3, 135.0), new_layer: 0, widgets: vec![], - tiles: Rc::new(RefCell::new(HashMap::new())), render_cfg, - tile_cache: Cache::new(32), sidebar_open: true, sidebar_width: 400, layers: init, zoom: 4, - map_tile_getter: Arc::new(tokio::sync::Mutex::new( MapTile::default())), + map_tile_getter: Rc::new(MapTile::default()), sidebar, tracker: 0, }; - let map_tile_getter = model.map_tile_getter.clone(); - let tiles = model.tiles.clone(); let widgets = view_output! {}; ComponentParts { model, widgets } } @@ -238,17 +233,8 @@ impl Component for MonitorModel { ) { self.reset(); match message { - MonitorCommand::LoadTile(key, ref tile, origin, bounds) => { - let target = widgets - .renderer - .load_img_mem(&tile, origin, (256f32, 256f32), bounds) - .unwrap(); - let mut binding = self.tiles.borrow_mut(); - if !binding.contains_key(&key) { - return ; - } - binding.entry(key).and_modify(|x| *x = Some(target)); - widgets.renderer.queue_draw(); + MonitorCommand::LoadedTile(tile) => { + sender.input(MonitorInputMsg::RefreshRender); } _ => {} } @@ -258,41 +244,13 @@ impl Component for MonitorModel { impl MonitorModel { - fn load_tile(tiles: &Rc>>> ,sender: &ComponentSender, map_tile_getter: &Arc, zoom:u8, range:((f32,f32), (f32,f32))) { + fn load_tile(&self, sender: &ComponentSender, range:((f32,f32), (f32,f32))) { - let map_tile_getter = map_tile_getter.clone(); - let new_tiles = map_tile_getter.new_tiles(zoom ,range.0, range.1); - let mut tiles = (*tiles).borrow_mut(); - let new_tiles = new_tiles.filter(|x| !tiles.contains_key(x)).collect::>(); - tiles.extend(new_tiles.iter().map(|x| (*x, None))); - - if new_tiles.len() > 0 { - let new_sender = sender.clone(); - sender.oneshot_command(async move { - for tile in new_tiles { - let map_tile_getter = map_tile_getter.clone(); - let sender = new_sender.clone(); - task::spawn(async move { - let result = map_tile_getter.get_tile(&tile).await; - if let Ok(result) = result { - let origin = tile.nw_corner(); - let rb = tile.se_corner(); - let bounds = ((origin.lon() as f64..rb.lon() as f64).into(), (origin.lat() as f64..rb.lat() as f64).into()); - sender.command_sender().emit(MonitorCommand::LoadTile(tile, result,(origin.lon() as f64, origin.lat() as f64), bounds)); - } - }).await; - } - MonitorCommand::None - }); - } - } - - fn load_tiles(&self, sender: &ComponentSender,range:((f32,f32), (f32,f32))) { - - // sender.oneshot_command(async move { - // MapTile::load_tiles(self.map_tile_getter.clone(), self.zoom, range).await; - // MonitorCommand::None - // }); + let task = self.map_tile_getter.load_tiles(range, sender.clone()); + sender.oneshot_command(async move { + task.await; + MonitorCommand::None + }); } } \ No newline at end of file diff --git a/src/map_tile.rs b/src/map_tile.rs index a663dab..a6049c8 100644 --- a/src/map_tile.rs +++ b/src/map_tile.rs @@ -1,3 +1,4 @@ +use std::cell::{Cell, RefCell}; use crate::coords::Range; use crate::map_tile_utils::lat_lon_to_zoom; use crate::pipeline::element::{Target, TargetType}; @@ -16,15 +17,16 @@ use tokio::sync::Mutex; use tokio::task; use tracing::{debug, info}; use crate::components::messages::MonitorInputMsg; -use crate::components::MonitorModel; +use crate::components::{MonitorCommand, MonitorModel}; pub struct MapTile { server: String, api_key: String, style: String, client: Client, - onloading: HashSet, - cache: Arc>>>, + onloading: Arc>>, + cache: Arc>>>>, + zoom_level: Cell, } impl Default for MapTile { @@ -34,8 +36,9 @@ impl Default for MapTile { api_key: "06f1aeed-5d91-48e3-9ce5-1e99063f7f73".to_string(), style: "stamen_terrain/".to_string(), client: Client::new(), - onloading: HashSet::new(), + onloading: Arc::new(std::sync::Mutex::new( HashSet::new())), cache: Arc::new(std::sync::Mutex::new(Cache::new(32))), + zoom_level: Cell::new(4), } } } @@ -89,23 +92,31 @@ impl MapTile { Ok(bytes.to_vec()) } + pub fn set_zoom(&self, zoom: u8) { + self.zoom_level.set(zoom); + } + pub fn load_tiles( &self, - zoom: u8, range: ((f32, f32), (f32, f32)), sender: ComponentSender, ) -> BoxFuture<'static, ()> { + let zoom = self.zoom_level.get(); let new_tiles = self.new_tiles(zoom, range.0, range.1); let cache = (*self.cache).lock().unwrap(); + let mut bindings = self.onloading.lock().unwrap(); let new_tiles = new_tiles - .filter(|x| cache.peek(x).is_none() && !self.onloading.contains(x)) + .filter(|x| cache.peek(x).is_none() && !bindings.contains(x)) .collect::>(); if new_tiles.len() > 0 { + bindings.extend(new_tiles.iter().cloned()); + info!("Load new tiles"); let tasks = new_tiles.into_iter().map(move |tile| { let _task = self.get_tile_task(&tile); let sender = sender.clone(); let cache = self.cache.clone(); + let onloading = self.onloading.clone(); task::spawn(async move { let result = _task.await; if let Ok(result) = result { @@ -123,24 +134,26 @@ impl MapTile { None, None ); - cache.lock().unwrap().insert(tile, Arc::new(result)); - sender.input(MonitorInputMsg::RefreshTiles); + cache.lock().unwrap().insert(tile, Arc::new(std::sync::Mutex::new(result))); + onloading.lock().unwrap().remove(&tile); + sender.command_sender().emit(MonitorCommand::LoadedTile(tile)); } }) - }); - Box::pin(async move { + }).collect::>(); + return Box::pin(async move { for task in tasks { task.await.unwrap(); } }); } else { - debug!("No new tiles to load"); + info!("No new tiles to load"); } Box::pin(async move {}) } - pub fn current_tiles(&self, zoom: u8, range: ((f32, f32), (f32, f32))) -> Vec> { + pub fn current_tiles(&self, range: ((f32, f32), (f32, f32))) -> Vec>> { + let zoom = self.zoom_level.get(); let current = self.new_tiles(zoom, range.0, range.1); let mut total_len = 0; let mut results = Vec::new(); @@ -160,16 +173,17 @@ impl MapTile { center.lat() as f64, start_zoom, ); - let tile = Tile::new(start_zoom, x, y).unwrap(); + let tile = Tile::new(start_zoom, tile.0, tile.1).unwrap(); if cached.contains(&tile) { break; } else { - cached.push(tile); - } - if let Some(target) = cache.get(&tile) { - results.insert(0, target); - break; + if let Some(target) = cache.get(&tile) { + results.insert(0, target); + cached.push(tile); + break; + } } + start_zoom -= 1; } } diff --git a/src/widgets/render/imp.rs b/src/widgets/render/imp.rs index de49cc0..412e0a6 100644 --- a/src/widgets/render/imp.rs +++ b/src/widgets/render/imp.rs @@ -15,6 +15,7 @@ use std::rc::Rc; use std::sync::{Arc, Mutex}; use slippy_map_tiles::Tile; use tracing::info; +use crate::map_tile::MapTile; #[derive(Debug, Default, Clone, Copy, PartialEq)] pub struct RenderConfig { @@ -61,7 +62,7 @@ pub struct Render { pub(super) interior: RefCell, pub(super) canvas: RefCell>>, pub(super) glow_context: RefCell>, - pub(super) tiles: RefCell>>>>, + pub(super) tiles: RefCell>>, pub config: RefCell, pub status: RefCell, pub mapper: RefCell, @@ -80,7 +81,7 @@ impl Default for Render { interior_layers: RefCell::new(Rc::new(RefCell::new(Vec::new()))), config: RefCell::new(RenderConfig::default()), status: RefCell::new(RenderStatus::default()), - tiles: RefCell::new(Rc::new(RefCell::new(HashMap::new()))), + tiles: RefCell::new(None), mapper: RefCell::new(Mercator::default().into()), canvas: RefCell::new(None), } @@ -165,12 +166,13 @@ impl GLAreaImpl for Render { (w, h) }; - let mut binding = self.tiles.borrow(); - let mut tiles = binding.borrow_mut(); - - for tile in tiles.values_mut(){ - if let Some(tile) = tile.as_mut() { - self.draw_target(tile); + let binding = self.tiles.borrow(); + if let Some(tiles) = binding.as_ref() { + let ((x1 , x2), (y1,y2)) = self.view_range().unwrap(); + let mut tiles = tiles.current_tiles( ((y1 as f32, y2 as f32), (x1 as f32, x2 as f32))); + for tile in tiles.iter_mut() { + let mut binding = (*tile).lock().unwrap(); + self.draw_target(&mut *binding); } } diff --git a/src/widgets/render/mod.rs b/src/widgets/render/mod.rs index 2c0b26e..9102250 100644 --- a/src/widgets/render/mod.rs +++ b/src/widgets/render/mod.rs @@ -23,6 +23,7 @@ use std::sync::{Arc, Mutex}; use femtovg::ImageFlags; use slippy_map_tiles::Tile; use crate::errors::PipelineError; +use crate::map_tile::MapTile; use crate::pipeline::element::{Target, TargetType}; pub type WindowCoord = (f32, f32); @@ -212,12 +213,11 @@ impl Render { pub fn set_view(&self, range: (f64, f64, f64, f64)) { self.imp().set_view(range); self.set_range_changing(range.0 + range.1); - // self.set_range(range); self.queue_render(); } - pub fn set_tiles(&self, tiles: Rc>>>) { - self.imp().tiles.replace(tiles); + pub fn set_tiles(&self, tiles: Rc) { + self.imp().tiles.replace(Some(tiles)); self.queue_render(); }