mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Improve pool
This commit is contained in:
parent
f029c1efc4
commit
184f37df44
@ -1,12 +1,16 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::io::Cursor;
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
|
||||
use log::info;
|
||||
use lyon::tessellation::VertexBuffers;
|
||||
|
||||
use vector_tile::parse_tile_reader;
|
||||
use vector_tile::tile::Tile;
|
||||
|
||||
use crate::io::{static_database, TileCoords};
|
||||
use crate::render::shader_ffi::GpuVertexUniform;
|
||||
use crate::tesselation::{IndexDataType, Tesselated};
|
||||
use lyon::tessellation::VertexBuffers;
|
||||
use std::collections::VecDeque;
|
||||
use std::io::Cursor;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use vector_tile::parse_tile_reader;
|
||||
use vector_tile::tile::Tile;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TesselatedTile {
|
||||
@ -16,61 +20,68 @@ pub struct TesselatedTile {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Pool {
|
||||
requests: WorkQueue<TileCoords>,
|
||||
responses: WorkQueue<TesselatedTile>,
|
||||
requests: Arc<WorkQueue<TileCoords>>,
|
||||
responses: Arc<WorkQueue<TesselatedTile>>,
|
||||
}
|
||||
|
||||
impl Pool {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
requests: WorkQueue::new(),
|
||||
responses: WorkQueue::new(),
|
||||
requests: Arc::new(WorkQueue::new()),
|
||||
responses: Arc::new(WorkQueue::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fetch(&self, coords: TileCoords) {
|
||||
info!("new tile request: {:?}", &coords);
|
||||
self.requests.push(coords);
|
||||
}
|
||||
|
||||
pub fn get_available(&self) -> Vec<TesselatedTile> {
|
||||
self.responses.pop_all()
|
||||
pub fn pop_all(&self) -> Vec<TesselatedTile> {
|
||||
self.responses.try_pop_all()
|
||||
}
|
||||
|
||||
pub fn run_loop(&self) {
|
||||
while let Some(coords) = self.requests.pop() {
|
||||
if let Some(file) = static_database::get_tile(&coords) {
|
||||
let tile = parse_tile_reader(&mut Cursor::new(file.contents()))
|
||||
.expect("failed to load tile");
|
||||
let mut geometry: VertexBuffers<GpuVertexUniform, IndexDataType> =
|
||||
VertexBuffers::new();
|
||||
loop {
|
||||
while let Some(coords) = self.requests.pop() {
|
||||
if let Some(file) = static_database::get_tile(&coords) {
|
||||
let tile = parse_tile_reader(&mut Cursor::new(file.contents()))
|
||||
.expect("failed to load tile");
|
||||
let mut geometry: VertexBuffers<GpuVertexUniform, IndexDataType> =
|
||||
VertexBuffers::new();
|
||||
|
||||
let (_tile_stroke_range, _tile_fill_range) = {
|
||||
(
|
||||
tile.tesselate_stroke(&mut geometry, coords.hash()),
|
||||
tile.tesselate_fill(&mut geometry, coords.hash()),
|
||||
)
|
||||
};
|
||||
self.responses.push(TesselatedTile { coords, geometry });
|
||||
let (_tile_stroke_range, _tile_fill_range) = {
|
||||
(
|
||||
tile.tesselate_stroke(&mut geometry, coords.hash()),
|
||||
tile.tesselate_fill(&mut geometry, coords.hash()),
|
||||
)
|
||||
};
|
||||
self.responses.push(TesselatedTile { coords, geometry });
|
||||
info!("tile ready: {:?}", &coords);
|
||||
} else {
|
||||
info!("tile failed: {:?}", &coords);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct WorkQueue<T: Send> {
|
||||
inner: Arc<Mutex<VecDeque<T>>>,
|
||||
inner: Mutex<VecDeque<T>>,
|
||||
cvar: Condvar,
|
||||
}
|
||||
|
||||
impl<T: Send> WorkQueue<T> {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
inner: Arc::new(Mutex::new(VecDeque::new())),
|
||||
inner: Mutex::new(VecDeque::new()),
|
||||
cvar: Condvar::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn pop_all(&self) -> Vec<T> {
|
||||
fn try_pop_all(&self) -> Vec<T> {
|
||||
let mut result = Vec::new();
|
||||
if let Ok(mut queue) = self.inner.lock() {
|
||||
if let Ok(mut queue) = self.inner.try_lock() {
|
||||
while let Some(element) = queue.pop_front() {
|
||||
result.push(element);
|
||||
}
|
||||
@ -87,7 +98,12 @@ impl<T: Send> WorkQueue<T> {
|
||||
|
||||
fn pop(&self) -> Option<T> {
|
||||
if let Ok(mut queue) = self.inner.lock() {
|
||||
queue.pop_front()
|
||||
loop {
|
||||
match queue.pop_front() {
|
||||
Some(element) => return Some(element),
|
||||
None => queue = self.cvar.wait(queue).unwrap(),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic!("locking failed");
|
||||
}
|
||||
@ -96,6 +112,7 @@ impl<T: Send> WorkQueue<T> {
|
||||
fn push(&self, work: T) -> usize {
|
||||
if let Ok(mut queue) = self.inner.lock() {
|
||||
queue.push_back(work);
|
||||
self.cvar.notify_all();
|
||||
queue.len()
|
||||
} else {
|
||||
panic!("locking failed");
|
||||
|
||||
@ -10,7 +10,11 @@ use crate::render::state::State;
|
||||
pub async fn setup(window: winit::window::Window, event_loop: EventLoop<()>, pool: Pool) {
|
||||
info!("== mapr ==");
|
||||
|
||||
pool.fetch((2179, 1421, 12).into());
|
||||
for x in 0..10 {
|
||||
for y in 0..10 {
|
||||
pool.fetch((2179 + x, 1421 + y, 12).into())
|
||||
}
|
||||
}
|
||||
|
||||
let mut input = InputHandler::new();
|
||||
let mut state = State::new(&window).await;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user