mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Add MapBuilder
This commit is contained in:
parent
4fe23acfb4
commit
14cf5f31d5
@ -1,5 +1,12 @@
|
|||||||
use mapr::platform::mapr_generic_main;
|
use mapr::{MapBuilder, ScheduleMethod, TokioScheduleMethod};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
mapr_generic_main()
|
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
|
||||||
|
|
||||||
|
MapBuilder::from_window("A fantastic window!")
|
||||||
|
.with_schedule_method(ScheduleMethod::Tokio(TokioScheduleMethod::new(Some(
|
||||||
|
"/tmp/mapr_cache".to_string(),
|
||||||
|
))))
|
||||||
|
.build()
|
||||||
|
.run_sync();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,9 +22,9 @@ pub enum ScheduleMethod {
|
|||||||
all(target_arch = "aarch64", not(target_os = "android")),
|
all(target_arch = "aarch64", not(target_os = "android")),
|
||||||
target_arch = "wasm32"
|
target_arch = "wasm32"
|
||||||
)))]
|
)))]
|
||||||
Tokio(crate::platform::TokioScheduleMethod),
|
Tokio(crate::platform::scheduler::TokioScheduleMethod),
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
WebWorker(crate::platform::WebWorkerScheduleMethod),
|
WebWorker(crate::platform::scheduler::WebWorkerScheduleMethod),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScheduleMethod {
|
impl ScheduleMethod {
|
||||||
|
|||||||
100
src/lib.rs
100
src/lib.rs
@ -1,15 +1,109 @@
|
|||||||
|
use crate::io::scheduler::IOScheduler;
|
||||||
|
use winit::event_loop::EventLoop;
|
||||||
|
use winit::window::WindowBuilder;
|
||||||
|
|
||||||
mod input;
|
mod input;
|
||||||
|
|
||||||
pub(crate) mod coords;
|
pub(crate) mod coords;
|
||||||
pub(crate) mod error;
|
pub(crate) mod error;
|
||||||
pub(crate) mod io;
|
pub(crate) mod io;
|
||||||
pub(crate) mod main_loop;
|
pub(crate) mod main_loop;
|
||||||
|
pub(crate) mod platform;
|
||||||
pub(crate) mod render;
|
pub(crate) mod render;
|
||||||
pub(crate) mod tessellation;
|
pub(crate) mod tessellation;
|
||||||
pub(crate) mod util;
|
pub(crate) mod util;
|
||||||
|
|
||||||
// Used from outside to initialize mapr
|
|
||||||
pub mod platform;
|
|
||||||
|
|
||||||
// Used for benchmarking
|
// Used for benchmarking
|
||||||
pub mod benchmarking;
|
pub mod benchmarking;
|
||||||
|
|
||||||
|
pub use io::scheduler::ScheduleMethod;
|
||||||
|
pub use platform::scheduler::*;
|
||||||
|
|
||||||
|
pub struct Map {
|
||||||
|
window: winit::window::Window,
|
||||||
|
event_loop: EventLoop<()>,
|
||||||
|
scheduler: Box<IOScheduler>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Map {
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
pub async fn run_async(self) {
|
||||||
|
main_loop::setup(self.window, self.event_loop, self.scheduler).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
pub fn run_sync(self) {
|
||||||
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
|
.worker_threads(2)
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(async {
|
||||||
|
main_loop::setup(self.window, self.event_loop, self.scheduler).await;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MapBuilder {
|
||||||
|
create_window: Box<dyn FnOnce(&EventLoop<()>) -> winit::window::Window>,
|
||||||
|
schedule_method: Option<ScheduleMethod>,
|
||||||
|
scheduler: Option<Box<IOScheduler>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MapBuilder {
|
||||||
|
pub fn with_schedule_method(mut self, schedule_method: ScheduleMethod) -> Self {
|
||||||
|
self.schedule_method = Some(schedule_method);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_existing_scheduler(mut self, scheduler: Box<IOScheduler>) -> Self {
|
||||||
|
self.scheduler = Some(scheduler);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
pub fn from_window(title: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
create_window: Box::new(move |event_loop| {
|
||||||
|
WindowBuilder::new()
|
||||||
|
.with_title(title)
|
||||||
|
.build(&event_loop)
|
||||||
|
.unwrap()
|
||||||
|
}),
|
||||||
|
schedule_method: None,
|
||||||
|
scheduler: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
pub fn from_canvas(dom_id: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
create_window: Box::new(move |event_loop| {
|
||||||
|
use crate::platform::{get_body_size, get_canvas};
|
||||||
|
use winit::platform::web::WindowBuilderExtWebSys;
|
||||||
|
|
||||||
|
let window: winit::window::Window = WindowBuilder::new()
|
||||||
|
.with_canvas(Some(get_canvas(dom_id)))
|
||||||
|
.build(&event_loop)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
window.set_inner_size(get_body_size().unwrap());
|
||||||
|
window
|
||||||
|
}),
|
||||||
|
schedule_method: None,
|
||||||
|
scheduler: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(self) -> Map {
|
||||||
|
let event_loop = EventLoop::new();
|
||||||
|
|
||||||
|
Map {
|
||||||
|
window: (self.create_window)(&event_loop),
|
||||||
|
event_loop,
|
||||||
|
scheduler: self
|
||||||
|
.scheduler
|
||||||
|
.unwrap_or_else(|| Box::new(IOScheduler::new(self.schedule_method.unwrap()))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,35 +1,17 @@
|
|||||||
use crate::io::scheduler::IOScheduler;
|
use crate::io::scheduler::ScheduleMethod;
|
||||||
use crate::main_loop;
|
use crate::platform::scheduler::TokioScheduleMethod;
|
||||||
pub use std::time::Instant;
|
pub use std::time::Instant;
|
||||||
use tokio::task;
|
|
||||||
|
|
||||||
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8Unorm;
|
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8Unorm;
|
||||||
|
|
||||||
#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
|
#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
|
||||||
#[tokio::main]
|
pub fn main() {
|
||||||
pub async fn main() {
|
|
||||||
use winit::event_loop::EventLoop;
|
|
||||||
use winit::window::WindowBuilder;
|
|
||||||
|
|
||||||
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
|
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
MapBuilder::from_window("A fantastic window!")
|
||||||
let window = WindowBuilder::new()
|
.with_schedule_method(ScheduleMethod::Tokio(TokioScheduleMethod::new(Some(
|
||||||
.with_title("A fantastic window!")
|
"/tmp/mapr_cache".to_string(),
|
||||||
.build(&event_loop)
|
))))
|
||||||
.unwrap();
|
.build()
|
||||||
|
.run_sync();
|
||||||
let mut scheduler = IOScheduler::new();
|
|
||||||
let download_tessellate_loop = scheduler.take_download_loop();
|
|
||||||
|
|
||||||
let join_handle = task::spawn_blocking(move || {
|
|
||||||
Handle::current().block_on(async move {
|
|
||||||
if let Err(e) = download_tessellate_loop.run_loop().await {
|
|
||||||
error!("Worker loop errored {:?}", e)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
main_loop::setup(window, event_loop, Box::new(scheduler)).await;
|
|
||||||
join_handle.await.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,36 +1,18 @@
|
|||||||
use winit::event_loop::EventLoop;
|
use crate::io::scheduler::ScheduleMethod;
|
||||||
use winit::window::WindowBuilder;
|
use crate::platform::scheduler::TokioScheduleMethod;
|
||||||
|
|
||||||
use crate::io::scheduler::IOScheduler;
|
|
||||||
use crate::main_loop;
|
|
||||||
pub use std::time::Instant;
|
pub use std::time::Instant;
|
||||||
use tokio::task;
|
|
||||||
|
|
||||||
// macOS and iOS (Metal)
|
// macOS and iOS (Metal)
|
||||||
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[tokio::main]
|
pub fn mapr_apple_main() {
|
||||||
pub async fn mapr_apple_main() {
|
|
||||||
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
|
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
MapBuilder::from_window("A fantastic window!")
|
||||||
let window = WindowBuilder::new()
|
.with_schedule_method(ScheduleMethod::Tokio(TokioScheduleMethod::new(Some(
|
||||||
.with_title("A fantastic window!")
|
"/tmp/mapr_cache".to_string(),
|
||||||
.build(&event_loop)
|
))))
|
||||||
.unwrap();
|
.build()
|
||||||
|
.run_sync();
|
||||||
let mut scheduler = IOScheduler::new();
|
|
||||||
let download_tessellate_loop = scheduler.take_download_loop();
|
|
||||||
|
|
||||||
let join_handle = task::spawn_blocking(move || {
|
|
||||||
Handle::current().block_on(async move {
|
|
||||||
if let Err(e) = download_tessellate_loop.run_loop().await {
|
|
||||||
error!("Worker loop errored {:?}", e)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
main_loop::setup(window, event_loop, Box::new(scheduler)).await;
|
|
||||||
join_handle.await.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,39 +0,0 @@
|
|||||||
//! Module which is used if android, apple and web is not used.
|
|
||||||
|
|
||||||
use crate::io::scheduler::{IOScheduler, ScheduleMethod};
|
|
||||||
use crate::main_loop;
|
|
||||||
use crate::platform::TokioScheduleMethod;
|
|
||||||
|
|
||||||
pub use std::time::Instant;
|
|
||||||
|
|
||||||
use winit::event_loop::EventLoop;
|
|
||||||
use winit::window::WindowBuilder;
|
|
||||||
|
|
||||||
// Vulkan/OpenGL
|
|
||||||
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
pub async fn mapr_generic_main() {
|
|
||||||
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
|
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
|
||||||
let window = WindowBuilder::new()
|
|
||||||
.with_title("A fantastic window!")
|
|
||||||
.build(&event_loop)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let scheduler = IOScheduler::new(ScheduleMethod::Tokio(TokioScheduleMethod::new(
|
|
||||||
"/tmp/mapr_cache".to_string(),
|
|
||||||
)));
|
|
||||||
|
|
||||||
/* let join_handle = task::spawn_blocking(move || {
|
|
||||||
Handle::current().block_on(async move {
|
|
||||||
if let Err(e) = download_tessellate_loop.run_loop().await {
|
|
||||||
error!("Worker loop errored {:?}", e)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});*/
|
|
||||||
|
|
||||||
main_loop::setup(window, event_loop, Box::new(scheduler)).await;
|
|
||||||
/* join_handle.await.unwrap()*/
|
|
||||||
}
|
|
||||||
@ -13,12 +13,13 @@ mod android;
|
|||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
mod noweb;
|
mod noweb;
|
||||||
|
|
||||||
|
/// For Vulkan/OpenGL
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
all(target_arch = "aarch64", not(target_os = "android")),
|
all(target_arch = "aarch64", not(target_os = "android")),
|
||||||
target_arch = "wasm32"
|
target_arch = "wasm32"
|
||||||
)))]
|
)))]
|
||||||
mod generic;
|
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
pub use web::*;
|
pub use web::*;
|
||||||
@ -32,13 +33,6 @@ pub use android::*;
|
|||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub use noweb::*;
|
pub use noweb::*;
|
||||||
|
|
||||||
#[cfg(not(any(
|
|
||||||
target_os = "android",
|
|
||||||
all(target_arch = "aarch64", not(target_os = "android")),
|
|
||||||
target_arch = "wasm32"
|
|
||||||
)))]
|
|
||||||
pub use generic::*;
|
|
||||||
|
|
||||||
// FIXME: This limit is enforced by WebGL. Actually this makes sense!
|
// FIXME: This limit is enforced by WebGL. Actually this makes sense!
|
||||||
// FIXME: This can also be achieved by _pad attributes in shader_ffi.rs
|
// FIXME: This can also be achieved by _pad attributes in shader_ffi.rs
|
||||||
pub const MIN_BUFFER_SIZE: u64 = 32;
|
pub const MIN_BUFFER_SIZE: u64 = 32;
|
||||||
|
|||||||
@ -1,87 +1,90 @@
|
|||||||
//! Module which is used target platform is not web related.
|
//! Module which is used target platform is not web related.
|
||||||
|
|
||||||
use crate::coords::TileCoords;
|
pub use std::time::Instant;
|
||||||
|
|
||||||
use reqwest::{Client, StatusCode};
|
pub mod scheduler {
|
||||||
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
|
use reqwest::{Client, StatusCode};
|
||||||
use reqwest_middleware_cache::managers::CACacheManager;
|
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
|
||||||
use reqwest_middleware_cache::{Cache, CacheMode};
|
use reqwest_middleware_cache::managers::CACacheManager;
|
||||||
|
use reqwest_middleware_cache::{Cache, CacheMode};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::coords::TileCoords;
|
||||||
use crate::io::scheduler::IOScheduler;
|
use crate::error::Error;
|
||||||
use crate::io::TileRequestID;
|
use crate::io::scheduler::IOScheduler;
|
||||||
|
use crate::io::TileRequestID;
|
||||||
|
use crate::{MapBuilder, ScheduleMethod};
|
||||||
|
|
||||||
impl From<reqwest::Error> for Error {
|
impl From<reqwest::Error> for Error {
|
||||||
fn from(err: reqwest::Error) -> Self {
|
fn from(err: reqwest::Error) -> Self {
|
||||||
Error::Network(err.to_string())
|
Error::Network(err.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl From<reqwest_middleware::Error> for Error {
|
impl From<reqwest_middleware::Error> for Error {
|
||||||
fn from(err: reqwest_middleware::Error) -> Self {
|
fn from(err: reqwest_middleware::Error) -> Self {
|
||||||
Error::Network(err.to_string())
|
Error::Network(err.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TokioScheduleMethod {
|
pub struct TokioScheduleMethod {
|
||||||
client: ClientWithMiddleware,
|
client: ClientWithMiddleware,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokioScheduleMethod {
|
impl TokioScheduleMethod {
|
||||||
/// cache_path: Under which path should we cache requests.
|
/// cache_path: Under which path should we cache requests.
|
||||||
pub fn new(cache_path: String) -> Self {
|
pub fn new(cache_path: Option<String>) -> Self {
|
||||||
let mut builder = ClientBuilder::new(Client::new());
|
let mut builder = ClientBuilder::new(Client::new());
|
||||||
|
|
||||||
// FIXME: Cache only works on desktop so far
|
if let Some(cache_path) = cache_path {
|
||||||
if cfg!(not(any(target_os = "android", target_arch = "aarch64"))) {
|
builder = builder.with(Cache {
|
||||||
builder = builder.with(Cache {
|
mode: CacheMode::Default,
|
||||||
mode: CacheMode::Default,
|
cache_manager: CACacheManager { path: cache_path },
|
||||||
cache_manager: CACacheManager { path: cache_path },
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
client: builder.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn fetch(client: &ClientWithMiddleware, url: &str) -> Result<Vec<u8>, Error> {
|
||||||
|
let response = client.get(url).send().await?;
|
||||||
|
if response.status() != StatusCode::OK {
|
||||||
|
return Err(Error::Network("response code not 200".to_string()));
|
||||||
|
}
|
||||||
|
let body = response.bytes().await?;
|
||||||
|
Ok(Vec::from(body.as_ref()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn schedule_tile_request(
|
||||||
|
&self,
|
||||||
|
scheduler: &IOScheduler,
|
||||||
|
request_id: TileRequestID,
|
||||||
|
coords: TileCoords,
|
||||||
|
) {
|
||||||
|
let state = scheduler.new_tessellator_state();
|
||||||
|
let client = self.client.clone();
|
||||||
|
|
||||||
|
tokio::task::spawn(async move {
|
||||||
|
if let Ok(data) = Self::fetch(
|
||||||
|
&client,
|
||||||
|
format!(
|
||||||
|
"https://maps.tuerantuer.org/europe_germany/{z}/{x}/{y}.pbf",
|
||||||
|
x = coords.x,
|
||||||
|
y = coords.y,
|
||||||
|
z = coords.z
|
||||||
|
)
|
||||||
|
.as_str(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
state
|
||||||
|
.tessellate_layers(request_id, data.into_boxed_slice())
|
||||||
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
// TODO Error
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
|
||||||
client: builder.build(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn fetch(client: &ClientWithMiddleware, url: &str) -> Result<Vec<u8>, Error> {
|
|
||||||
let response = client.get(url).send().await?;
|
|
||||||
if response.status() != StatusCode::OK {
|
|
||||||
return Err(Error::Network("response code not 200".to_string()));
|
|
||||||
}
|
|
||||||
let body = response.bytes().await?;
|
|
||||||
Ok(Vec::from(body.as_ref()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn schedule_tile_request(
|
|
||||||
&self,
|
|
||||||
scheduler: &IOScheduler,
|
|
||||||
request_id: TileRequestID,
|
|
||||||
coords: TileCoords,
|
|
||||||
) {
|
|
||||||
let state = scheduler.new_tessellator_state();
|
|
||||||
let client = self.client.clone();
|
|
||||||
|
|
||||||
tokio::task::spawn(async move {
|
|
||||||
if let Ok(data) = Self::fetch(
|
|
||||||
&client,
|
|
||||||
format!(
|
|
||||||
"https://maps.tuerantuer.org/europe_germany/{z}/{x}/{y}.pbf",
|
|
||||||
x = coords.x,
|
|
||||||
y = coords.y,
|
|
||||||
z = coords.z
|
|
||||||
)
|
|
||||||
.as_str(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
state
|
|
||||||
.tessellate_layers(request_id, data.into_boxed_slice())
|
|
||||||
.unwrap();
|
|
||||||
} else {
|
|
||||||
// TODO Error
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,11 @@ use winit::event_loop::EventLoop;
|
|||||||
use winit::platform::web::WindowBuilderExtWebSys;
|
use winit::platform::web::WindowBuilderExtWebSys;
|
||||||
use winit::window::{Window, WindowBuilder};
|
use winit::window::{Window, WindowBuilder};
|
||||||
|
|
||||||
|
use crate::io::scheduler::IOScheduler;
|
||||||
|
use crate::io::scheduler::ScheduleMethod;
|
||||||
|
use crate::io::scheduler::ThreadLocalTessellatorState;
|
||||||
|
use crate::MapBuilder;
|
||||||
|
use crate::WebWorkerScheduleMethod;
|
||||||
use console_error_panic_hook;
|
use console_error_panic_hook;
|
||||||
pub use instant::Instant;
|
pub use instant::Instant;
|
||||||
use style_spec::source::TileAdressingScheme;
|
use style_spec::source::TileAdressingScheme;
|
||||||
@ -16,11 +21,6 @@ use wasm_bindgen::prelude::*;
|
|||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use web_sys::Window as WebSysWindow;
|
use web_sys::Window as WebSysWindow;
|
||||||
|
|
||||||
use crate::coords::{TileCoords, WorldTileCoords};
|
|
||||||
use crate::io::scheduler::{IOScheduler, ScheduleMethod, ThreadLocalTessellatorState};
|
|
||||||
use crate::io::tile_cache::TileCache;
|
|
||||||
use crate::io::TileRequestID;
|
|
||||||
|
|
||||||
// WebGPU
|
// WebGPU
|
||||||
#[cfg(not(feature = "web-webgl"))]
|
#[cfg(not(feature = "web-webgl"))]
|
||||||
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8Unorm;
|
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8Unorm;
|
||||||
@ -61,32 +61,6 @@ pub fn new_tessellator_state(workflow_ptr: *mut IOScheduler) -> *mut ThreadLocal
|
|||||||
return tessellator_state_ptr;
|
return tessellator_state_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WebWorkerScheduleMethod;
|
|
||||||
|
|
||||||
impl WebWorkerScheduleMethod {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn schedule_tile_request(
|
|
||||||
&self,
|
|
||||||
_scheduler: &IOScheduler,
|
|
||||||
request_id: TileRequestID,
|
|
||||||
coords: TileCoords,
|
|
||||||
) {
|
|
||||||
schedule_tile_request(
|
|
||||||
format!(
|
|
||||||
"https://maps.tuerantuer.org/europe_germany/{z}/{x}/{y}.pbf",
|
|
||||||
x = coords.x,
|
|
||||||
y = coords.y,
|
|
||||||
z = coords.z,
|
|
||||||
)
|
|
||||||
.as_str(),
|
|
||||||
request_id,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn tessellate_layers(
|
pub fn tessellate_layers(
|
||||||
tessellator_state_ptr: *mut ThreadLocalTessellatorState,
|
tessellator_state_ptr: *mut ThreadLocalTessellatorState,
|
||||||
@ -104,36 +78,74 @@ pub fn tessellate_layers(
|
|||||||
std::mem::forget(tessellator_state);
|
std::mem::forget(tessellator_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
pub fn get_body_size() -> Option<LogicalSize<i32>> {
|
||||||
pub async fn run(workflow_ptr: *mut IOScheduler) {
|
|
||||||
let workflow: Box<IOScheduler> = unsafe { Box::from_raw(workflow_ptr) };
|
|
||||||
let event_loop = EventLoop::new();
|
|
||||||
|
|
||||||
let web_window: WebSysWindow = web_sys::window().unwrap();
|
let web_window: WebSysWindow = web_sys::window().unwrap();
|
||||||
let document = web_window.document().unwrap();
|
let document = web_window.document().unwrap();
|
||||||
let body = document.body().unwrap();
|
let body = document.body().unwrap();
|
||||||
let builder = WindowBuilder::new();
|
Some(LogicalSize {
|
||||||
let canvas: web_sys::HtmlCanvasElement = document
|
|
||||||
.get_element_by_id("mapr")
|
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<web_sys::HtmlCanvasElement>()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let window: Window = builder
|
|
||||||
.with_canvas(Some(canvas))
|
|
||||||
.build(&event_loop)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
window.set_inner_size(LogicalSize {
|
|
||||||
width: body.client_width(),
|
width: body.client_width(),
|
||||||
height: body.client_height(),
|
height: body.client_height(),
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_canvas(element_id: &'static str) -> web_sys::HtmlCanvasElement {
|
||||||
|
let web_window: WebSysWindow = web_sys::window().unwrap();
|
||||||
|
let document = web_window.document().unwrap();
|
||||||
|
document
|
||||||
|
.get_element_by_id(element_id)
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<web_sys::HtmlCanvasElement>()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub async fn run(workflow_ptr: *mut IOScheduler) {
|
||||||
|
let scheduler: Box<IOScheduler> = unsafe { Box::from_raw(workflow_ptr) };
|
||||||
|
|
||||||
// Either call forget or the main loop to keep worker loop alive
|
// Either call forget or the main loop to keep worker loop alive
|
||||||
crate::main_loop::setup(window, event_loop, workflow).await;
|
MapBuilder::from_canvas("mapr")
|
||||||
|
.with_existing_scheduler(scheduler)
|
||||||
|
.build()
|
||||||
|
.run_async()
|
||||||
|
.await;
|
||||||
|
|
||||||
// std::mem::forget(workflow);
|
// std::mem::forget(workflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod scheduler {
|
||||||
|
use super::schedule_tile_request;
|
||||||
|
use crate::coords::{TileCoords, WorldTileCoords};
|
||||||
|
use crate::io::scheduler::{IOScheduler, ScheduleMethod, ThreadLocalTessellatorState};
|
||||||
|
use crate::io::tile_cache::TileCache;
|
||||||
|
use crate::io::TileRequestID;
|
||||||
|
|
||||||
|
pub struct WebWorkerScheduleMethod;
|
||||||
|
|
||||||
|
impl WebWorkerScheduleMethod {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn schedule_tile_request(
|
||||||
|
&self,
|
||||||
|
_scheduler: &IOScheduler,
|
||||||
|
request_id: TileRequestID,
|
||||||
|
coords: TileCoords,
|
||||||
|
) {
|
||||||
|
schedule_tile_request(
|
||||||
|
format!(
|
||||||
|
"https://maps.tuerantuer.org/europe_germany/{z}/{x}/{y}.pbf",
|
||||||
|
x = coords.x,
|
||||||
|
y = coords.y,
|
||||||
|
z = coords.z,
|
||||||
|
)
|
||||||
|
.as_str(),
|
||||||
|
request_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*use crate::error::Error;
|
/*use crate::error::Error;
|
||||||
use js_sys::{ArrayBuffer, Error as JSError, Uint8Array};
|
use js_sys::{ArrayBuffer, Error as JSError, Uint8Array};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user