mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Add the possibility to late initialize the renderer
This commit is contained in:
parent
d0cefe69de
commit
fdd09e0b19
@ -18,7 +18,7 @@ use maplibre::{
|
|||||||
kernel::{Kernel, KernelBuilder},
|
kernel::{Kernel, KernelBuilder},
|
||||||
platform::{http_client::ReqwestHttpClient, run_multithreaded, scheduler::TokioScheduler},
|
platform::{http_client::ReqwestHttpClient, run_multithreaded, scheduler::TokioScheduler},
|
||||||
render::{
|
render::{
|
||||||
builder::{InitializedRenderer, RenderBuilder},
|
builder::{InitializedRenderer, RendererBuilder},
|
||||||
settings::{RendererSettings, TextureFormat},
|
settings::{RendererSettings, TextureFormat},
|
||||||
},
|
},
|
||||||
style::Style,
|
style::Style,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use maplibre::{
|
|||||||
kernel::KernelBuilder,
|
kernel::KernelBuilder,
|
||||||
platform::{http_client::ReqwestHttpClient, scheduler::TokioScheduler},
|
platform::{http_client::ReqwestHttpClient, scheduler::TokioScheduler},
|
||||||
render::{
|
render::{
|
||||||
builder::RenderBuilder,
|
builder::RendererBuilder,
|
||||||
settings::{RendererSettings, TextureFormat},
|
settings::{RendererSettings, TextureFormat},
|
||||||
},
|
},
|
||||||
style::Style,
|
style::Style,
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
pub mod input;
|
pub mod input;
|
||||||
|
|
||||||
use std::{cell::RefCell, marker::PhantomData, ops::Deref, rc::Rc};
|
use std::{cell::RefCell, fmt::Debug, marker::PhantomData, ops::Deref, rc::Rc};
|
||||||
|
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
|
use log::info;
|
||||||
use maplibre::{
|
use maplibre::{
|
||||||
environment::Environment,
|
environment::Environment,
|
||||||
error::Error,
|
error::Error,
|
||||||
@ -14,6 +15,10 @@ use maplibre::{
|
|||||||
transferables::{DefaultTransferables, Transferables},
|
transferables::{DefaultTransferables, Transferables},
|
||||||
},
|
},
|
||||||
map::Map,
|
map::Map,
|
||||||
|
render::{
|
||||||
|
builder::RendererBuilder,
|
||||||
|
settings::{Backends, WgpuSettings},
|
||||||
|
},
|
||||||
window::{HeadedMapWindow, MapWindowConfig},
|
window::{HeadedMapWindow, MapWindowConfig},
|
||||||
};
|
};
|
||||||
use winit::{
|
use winit::{
|
||||||
@ -69,15 +74,11 @@ pub struct WinitEventLoop<ET: 'static> {
|
|||||||
event_loop: RawWinitEventLoop<ET>,
|
event_loop: RawWinitEventLoop<ET>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ET: 'static> EventLoop<ET> for WinitEventLoop<ET> {
|
impl<ET: 'static + PartialEq + Debug> EventLoop<ET> for WinitEventLoop<ET> {
|
||||||
type EventLoopProxy = WinitEventLoopProxy<ET>;
|
type EventLoopProxy = WinitEventLoopProxy<ET>;
|
||||||
|
|
||||||
fn run<E>(
|
fn run<E>(mut self, mut map: Map<E>, max_frames: Option<u64>)
|
||||||
mut self,
|
where
|
||||||
mut window: <E::MapWindowConfig as MapWindowConfig>::MapWindow,
|
|
||||||
mut map: Map<E>,
|
|
||||||
max_frames: Option<u64>,
|
|
||||||
) where
|
|
||||||
E: Environment,
|
E: Environment,
|
||||||
<E::MapWindowConfig as MapWindowConfig>::MapWindow: HeadedMapWindow,
|
<E::MapWindowConfig as MapWindowConfig>::MapWindow: HeadedMapWindow,
|
||||||
{
|
{
|
||||||
@ -89,12 +90,16 @@ impl<ET: 'static> EventLoop<ET> for WinitEventLoop<ET> {
|
|||||||
self.event_loop
|
self.event_loop
|
||||||
.run(move |event, window_target, control_flow| {
|
.run(move |event, window_target, control_flow| {
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
if !map.is_initialized() && event == Event::Resumed {
|
if !map.has_renderer() && event == Event::Resumed {
|
||||||
use tokio::{runtime::Handle, task};
|
use tokio::{runtime::Handle, task};
|
||||||
|
|
||||||
task::block_in_place(|| {
|
task::block_in_place(|| {
|
||||||
Handle::current().block_on(async {
|
Handle::current().block_on(async {
|
||||||
map.late_init().await;
|
map.initialize_renderer(RendererBuilder::new()
|
||||||
|
.with_wgpu_settings(WgpuSettings {
|
||||||
|
backends: Some(Backends::VULKAN),
|
||||||
|
..WgpuSettings::default()
|
||||||
|
})).await.unwrap();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -111,7 +116,7 @@ impl<ET: 'static> EventLoop<ET> for WinitEventLoop<ET> {
|
|||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
ref event,
|
ref event,
|
||||||
window_id,
|
window_id,
|
||||||
} if window_id == window.id().into() => {
|
} if window_id == map.window().id().into() => {
|
||||||
if !input_controller.window_input(event) {
|
if !input_controller.window_input(event) {
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::CloseRequested
|
WindowEvent::CloseRequested
|
||||||
@ -125,10 +130,14 @@ impl<ET: 'static> EventLoop<ET> for WinitEventLoop<ET> {
|
|||||||
..
|
..
|
||||||
} => *control_flow = ControlFlow::Exit,
|
} => *control_flow = ControlFlow::Exit,
|
||||||
WindowEvent::Resized(physical_size) => {
|
WindowEvent::Resized(physical_size) => {
|
||||||
map.context_mut().resize(physical_size.width, physical_size.height);
|
if let Ok(map_context) = map.context_mut() {
|
||||||
|
map_context.resize(physical_size.width, physical_size.height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||||
map.context_mut().resize(new_inner_size.width, new_inner_size.height);
|
if let Ok(map_context) = map.context_mut() {
|
||||||
|
map_context.resize(new_inner_size.width, new_inner_size.height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -139,7 +148,9 @@ impl<ET: 'static> EventLoop<ET> for WinitEventLoop<ET> {
|
|||||||
let dt = now - last_render_time;
|
let dt = now - last_render_time;
|
||||||
last_render_time = now;
|
last_render_time = now;
|
||||||
|
|
||||||
input_controller.update_state(map.context_mut().world.view_state_mut(), dt);
|
if let Ok(map_context) = map.context_mut() {
|
||||||
|
input_controller.update_state(map_context.world.view_state_mut(), dt);
|
||||||
|
}
|
||||||
|
|
||||||
match map.run_schedule() {
|
match map.run_schedule() {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
@ -170,7 +181,7 @@ impl<ET: 'static> EventLoop<ET> for WinitEventLoop<ET> {
|
|||||||
Event::MainEventsCleared => {
|
Event::MainEventsCleared => {
|
||||||
// RedrawRequested will only trigger once, unless we manually
|
// RedrawRequested will only trigger once, unless we manually
|
||||||
// request it.
|
// request it.
|
||||||
window.request_redraw();
|
map.window().request_redraw();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,10 @@ use maplibre::{
|
|||||||
kernel::{Kernel, KernelBuilder},
|
kernel::{Kernel, KernelBuilder},
|
||||||
map::Map,
|
map::Map,
|
||||||
platform::{http_client::ReqwestHttpClient, run_multithreaded, scheduler::TokioScheduler},
|
platform::{http_client::ReqwestHttpClient, run_multithreaded, scheduler::TokioScheduler},
|
||||||
render::builder::{InitializedRenderer, RenderBuilder},
|
render::{
|
||||||
|
builder::{InitializationResult, InitializedRenderer, RendererBuilder},
|
||||||
|
settings::{Backends, RendererSettings, WgpuSettings},
|
||||||
|
},
|
||||||
style::Style,
|
style::Style,
|
||||||
window::{HeadedMapWindow, MapWindow, MapWindowConfig, WindowSize},
|
window::{HeadedMapWindow, MapWindow, MapWindowConfig, WindowSize},
|
||||||
};
|
};
|
||||||
@ -83,23 +86,21 @@ pub fn run_headed_map(cache_path: Option<String>) {
|
|||||||
.with_scheduler(TokioScheduler::new())
|
.with_scheduler(TokioScheduler::new())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let InitializedRenderer {
|
let mut map = Map::new(Style::default(), kernel).unwrap();
|
||||||
mut window,
|
|
||||||
renderer,
|
|
||||||
} = RenderBuilder::new()
|
|
||||||
.build()
|
|
||||||
.initialize_with(&kernel)
|
|
||||||
.await
|
|
||||||
.expect("Failed to initialize renderer")
|
|
||||||
.unwarp();
|
|
||||||
|
|
||||||
window
|
#[cfg(not(target_os = "android"))]
|
||||||
|
{
|
||||||
|
map.initialize_renderer(RendererBuilder::new().with_wgpu_settings(WgpuSettings {
|
||||||
|
backends: Some(Backends::VULKAN),
|
||||||
|
..WgpuSettings::default()
|
||||||
|
}))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
map.window_mut()
|
||||||
.take_event_loop()
|
.take_event_loop()
|
||||||
.expect("Event loop is not available")
|
.expect("Event loop is not available")
|
||||||
.run(
|
.run(map, None)
|
||||||
window,
|
|
||||||
Map::new(Style::default(), kernel, renderer).unwrap(),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
//! Errors which can happen in various parts of the library.
|
//! Errors which can happen in various parts of the library.
|
||||||
|
|
||||||
use std::{fmt, fmt::Formatter, sync::mpsc::SendError};
|
use std::{borrow::Cow, fmt, fmt::Formatter, sync::mpsc::SendError};
|
||||||
|
|
||||||
use lyon::tessellation::TessellationError;
|
use lyon::tessellation::TessellationError;
|
||||||
|
|
||||||
@ -14,6 +14,7 @@ pub enum Error {
|
|||||||
Network(String),
|
Network(String),
|
||||||
Tesselation(TessellationError),
|
Tesselation(TessellationError),
|
||||||
Render(RenderError),
|
Render(RenderError),
|
||||||
|
Generic(Cow<'static, str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> From<E> for Error
|
impl<E> From<E> for Error
|
||||||
|
|||||||
@ -15,15 +15,11 @@ pub trait EventLoopProxy<T: 'static> {
|
|||||||
fn send_event(&self, event: T);
|
fn send_event(&self, event: T);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EventLoop<T: 'static> {
|
pub trait EventLoop<ET: 'static + PartialEq> {
|
||||||
type EventLoopProxy: EventLoopProxy<T>;
|
type EventLoopProxy: EventLoopProxy<ET>;
|
||||||
|
|
||||||
fn run<E>(
|
fn run<E>(self, map: Map<E>, max_frames: Option<u64>)
|
||||||
self,
|
where
|
||||||
window: <E::MapWindowConfig as MapWindowConfig>::MapWindow,
|
|
||||||
map: Map<E>,
|
|
||||||
max_frames: Option<u64>,
|
|
||||||
) where
|
|
||||||
E: Environment,
|
E: Environment,
|
||||||
<E::MapWindowConfig as MapWindowConfig>::MapWindow: HeadedMapWindow;
|
<E::MapWindowConfig as MapWindowConfig>::MapWindow: HeadedMapWindow;
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,16 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
headless::{environment::HeadlessEnvironment, window::HeadlessMapWindowConfig},
|
headless::{
|
||||||
|
environment::HeadlessEnvironment,
|
||||||
|
window::{HeadlessMapWindow, HeadlessMapWindowConfig},
|
||||||
|
},
|
||||||
io::apc::SchedulerAsyncProcedureCall,
|
io::apc::SchedulerAsyncProcedureCall,
|
||||||
kernel::{Kernel, KernelBuilder},
|
kernel::{Kernel, KernelBuilder},
|
||||||
platform::{http_client::ReqwestHttpClient, scheduler::TokioScheduler},
|
platform::{http_client::ReqwestHttpClient, scheduler::TokioScheduler},
|
||||||
render::{builder::RenderBuilder, Renderer},
|
render::{
|
||||||
window::WindowSize,
|
builder::{InitializedRenderer, RendererBuilder},
|
||||||
|
Renderer,
|
||||||
|
},
|
||||||
|
window::{MapWindowConfig, WindowSize},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod graph_node;
|
mod graph_node;
|
||||||
@ -31,9 +37,12 @@ pub async fn create_headless_renderer(
|
|||||||
.with_scheduler(TokioScheduler::new())
|
.with_scheduler(TokioScheduler::new())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let renderer = RenderBuilder::new()
|
let mwc: &HeadlessMapWindowConfig = kernel.map_window_config();
|
||||||
|
let window: HeadlessMapWindow = mwc.create();
|
||||||
|
|
||||||
|
let renderer = RendererBuilder::new()
|
||||||
.build()
|
.build()
|
||||||
.initialize_headless_with(&kernel)
|
.initialize_headless::<HeadlessMapWindowConfig>(&window)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to initialize renderer");
|
.expect("Failed to initialize renderer");
|
||||||
|
|
||||||
|
|||||||
@ -6,31 +6,38 @@ use crate::{
|
|||||||
environment::Environment,
|
environment::Environment,
|
||||||
error::Error,
|
error::Error,
|
||||||
kernel::Kernel,
|
kernel::Kernel,
|
||||||
render::{create_default_render_graph, register_default_render_stages, Renderer},
|
render::{
|
||||||
|
builder::{
|
||||||
|
InitializationResult, InitializedRenderer, RendererBuilder, UninitializedRenderer,
|
||||||
|
},
|
||||||
|
create_default_render_graph, register_default_render_stages,
|
||||||
|
settings::{RendererSettings, WgpuSettings},
|
||||||
|
Renderer,
|
||||||
|
},
|
||||||
schedule::{Schedule, Stage},
|
schedule::{Schedule, Stage},
|
||||||
stages::register_stages,
|
stages::register_stages,
|
||||||
style::Style,
|
style::Style,
|
||||||
|
window::{HeadedMapWindow, MapWindow, MapWindowConfig, WindowSize},
|
||||||
world::World,
|
world::World,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub enum MapContextState {
|
||||||
|
Ready(MapContext),
|
||||||
|
Pending { style: Style },
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Map<E: Environment> {
|
pub struct Map<E: Environment> {
|
||||||
kernel: Rc<Kernel<E>>,
|
kernel: Rc<Kernel<E>>,
|
||||||
schedule: Schedule,
|
schedule: Schedule,
|
||||||
map_context: MapContext,
|
map_context: MapContextState,
|
||||||
|
window: <E::MapWindowConfig as MapWindowConfig>::MapWindow,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Environment> Map<E> {
|
impl<E: Environment> Map<E>
|
||||||
pub fn new(style: Style, kernel: Kernel<E>, renderer: Renderer) -> Result<Self, Error> {
|
where
|
||||||
let window_size = renderer.state().surface().size();
|
<<E as Environment>::MapWindowConfig as MapWindowConfig>::MapWindow: HeadedMapWindow,
|
||||||
|
{
|
||||||
let center = style.center.unwrap_or_default();
|
pub fn new(style: Style, kernel: Kernel<E>) -> Result<Self, Error> {
|
||||||
let world = World::new_at(
|
|
||||||
window_size,
|
|
||||||
LatLon::new(center[0], center[1]),
|
|
||||||
style.zoom.map(|zoom| Zoom::new(zoom)).unwrap_or_default(),
|
|
||||||
cgmath::Deg::<f64>(style.pitch.unwrap_or_default()),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut schedule = Schedule::default();
|
let mut schedule = Schedule::default();
|
||||||
|
|
||||||
let graph = create_default_render_graph().unwrap(); // TODO: Remove unwrap
|
let graph = create_default_render_graph().unwrap(); // TODO: Remove unwrap
|
||||||
@ -40,29 +47,100 @@ impl<E: Environment> Map<E> {
|
|||||||
|
|
||||||
register_stages::<E>(&mut schedule, kernel.clone());
|
register_stages::<E>(&mut schedule, kernel.clone());
|
||||||
|
|
||||||
Ok(Self {
|
let mut window = kernel.map_window_config().create();
|
||||||
|
|
||||||
|
let map = Self {
|
||||||
kernel,
|
kernel,
|
||||||
map_context: MapContext {
|
map_context: MapContextState::Pending { style },
|
||||||
style,
|
|
||||||
world,
|
|
||||||
renderer,
|
|
||||||
},
|
|
||||||
schedule,
|
schedule,
|
||||||
})
|
window,
|
||||||
|
};
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn initialize_renderer(
|
||||||
|
&mut self,
|
||||||
|
render_builder: RendererBuilder,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let result = render_builder
|
||||||
|
.build()
|
||||||
|
.initialize_renderer::<E::MapWindowConfig>(&self.window)
|
||||||
|
.await
|
||||||
|
.expect("Failed to initialize renderer");
|
||||||
|
|
||||||
|
match &mut self.map_context {
|
||||||
|
MapContextState::Ready(_) => Err(Error::Generic("Renderer is already set".into())),
|
||||||
|
MapContextState::Pending { style } => {
|
||||||
|
let window_size = self.window.size();
|
||||||
|
|
||||||
|
let center = style.center.unwrap_or_default();
|
||||||
|
|
||||||
|
let world = World::new_at(
|
||||||
|
window_size,
|
||||||
|
LatLon::new(center[0], center[1]),
|
||||||
|
style.zoom.map(|zoom| Zoom::new(zoom)).unwrap_or_default(),
|
||||||
|
cgmath::Deg::<f64>(style.pitch.unwrap_or_default()),
|
||||||
|
);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
InitializationResult::Initialized(InitializedRenderer { renderer, .. }) => {
|
||||||
|
*&mut self.map_context = MapContextState::Ready(MapContext {
|
||||||
|
world,
|
||||||
|
style: std::mem::take(style),
|
||||||
|
renderer,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
InitializationResult::Uninizalized(UninitializedRenderer { .. }) => {}
|
||||||
|
_ => panic!("Rendering context gone"),
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn window_mut(&mut self) -> &mut <E::MapWindowConfig as MapWindowConfig>::MapWindow {
|
||||||
|
&mut self.window
|
||||||
|
}
|
||||||
|
pub fn window(&self) -> &<E::MapWindowConfig as MapWindowConfig>::MapWindow {
|
||||||
|
&self.window
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_renderer(&self) -> bool {
|
||||||
|
match &self.map_context {
|
||||||
|
MapContextState::Ready(_) => true,
|
||||||
|
MapContextState::Pending { .. } => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(name = "update_and_redraw", skip_all)]
|
#[tracing::instrument(name = "update_and_redraw", skip_all)]
|
||||||
pub fn run_schedule(&mut self) -> Result<(), Error> {
|
pub fn run_schedule(&mut self) -> Result<(), Error> {
|
||||||
self.schedule.run(&mut self.map_context);
|
match &mut self.map_context {
|
||||||
Ok(())
|
MapContextState::Ready(map_context) => {
|
||||||
|
self.schedule.run(map_context);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
MapContextState::Pending { .. } => {
|
||||||
|
Err(Error::Generic("Renderer is already set".into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context(&self) -> &MapContext {
|
pub fn context(&self) -> Result<&MapContext, Error> {
|
||||||
&self.map_context
|
match &self.map_context {
|
||||||
|
MapContextState::Ready(map_context) => Ok(map_context),
|
||||||
|
MapContextState::Pending { .. } => {
|
||||||
|
Err(Error::Generic("Renderer is already set".into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context_mut(&mut self) -> &mut MapContext {
|
pub fn context_mut(&mut self) -> Result<&mut MapContext, Error> {
|
||||||
&mut self.map_context
|
match &mut self.map_context {
|
||||||
|
MapContextState::Ready(map_context) => Ok(map_context),
|
||||||
|
MapContextState::Pending { .. } => {
|
||||||
|
Err(Error::Generic("Renderer is already set".into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kernel(&self) -> &Rc<Kernel<E>> {
|
pub fn kernel(&self) -> &Rc<Kernel<E>> {
|
||||||
|
|||||||
@ -12,18 +12,16 @@ use crate::{
|
|||||||
window::{HeadedMapWindow, MapWindow, MapWindowConfig},
|
window::{HeadedMapWindow, MapWindow, MapWindowConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct RenderBuilder<MWC: MapWindowConfig> {
|
pub struct RendererBuilder {
|
||||||
wgpu_settings: Option<WgpuSettings>,
|
wgpu_settings: Option<WgpuSettings>,
|
||||||
renderer_settings: Option<RendererSettings>,
|
renderer_settings: Option<RendererSettings>,
|
||||||
phatom_mwc: PhantomData<MWC>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MWC: MapWindowConfig> RenderBuilder<MWC> {
|
impl RendererBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
wgpu_settings: None,
|
wgpu_settings: None,
|
||||||
renderer_settings: None,
|
renderer_settings: None,
|
||||||
phatom_mwc: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,97 +35,92 @@ impl<MWC: MapWindowConfig> RenderBuilder<MWC> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> UninitializedRenderer<MWC> {
|
pub fn build(self) -> UninitializedRenderer {
|
||||||
UninitializedRenderer {
|
UninitializedRenderer {
|
||||||
window: None,
|
|
||||||
wgpu_settings: self.wgpu_settings.unwrap_or_default(),
|
wgpu_settings: self.wgpu_settings.unwrap_or_default(),
|
||||||
renderer_settings: self.renderer_settings.unwrap_or_default(),
|
renderer_settings: self.renderer_settings.unwrap_or_default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum InitializationResult<MWC: MapWindowConfig> {
|
pub enum InitializationResult {
|
||||||
Initialized(InitializedRenderer<MWC>),
|
Initialized(InitializedRenderer),
|
||||||
Uninizalized(UninitializedRenderer<MWC>),
|
Uninizalized(UninitializedRenderer),
|
||||||
|
Gone,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MWC: MapWindowConfig> InitializationResult<MWC> {
|
impl Default for InitializationResult {
|
||||||
pub fn unwarp(self) -> InitializedRenderer<MWC> {
|
fn default() -> Self {
|
||||||
|
Self::Gone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InitializationResult {
|
||||||
|
pub fn unwarp_renderer(self) -> InitializedRenderer {
|
||||||
match self {
|
match self {
|
||||||
InitializationResult::Initialized(renderer) => renderer,
|
InitializationResult::Initialized(renderer) => renderer,
|
||||||
InitializationResult::Uninizalized(_) => panic!("Renderer is not initialized"),
|
InitializationResult::Uninizalized(_) => panic!("Renderer is not initialized"),
|
||||||
|
InitializationResult::Gone => panic!("Initialization context is gone"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_option(self) -> Option<Renderer> {
|
||||||
|
match self {
|
||||||
|
InitializationResult::Initialized(InitializedRenderer { renderer, .. }) => {
|
||||||
|
Some(renderer)
|
||||||
|
}
|
||||||
|
InitializationResult::Uninizalized(_) => None,
|
||||||
|
InitializationResult::Gone => panic!("Initialization context is gone"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UninitializedRenderer<MWC: MapWindowConfig> {
|
pub struct UninitializedRenderer {
|
||||||
window: Option<MWC::MapWindow>,
|
pub wgpu_settings: WgpuSettings,
|
||||||
wgpu_settings: WgpuSettings,
|
pub renderer_settings: RendererSettings,
|
||||||
renderer_settings: RendererSettings,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MWC: MapWindowConfig> UninitializedRenderer<MWC>
|
impl UninitializedRenderer {
|
||||||
where
|
|
||||||
MWC::MapWindow: MapWindow + HeadedMapWindow,
|
|
||||||
{
|
|
||||||
/// Initializes the whole rendering pipeline for the given configuration.
|
/// Initializes the whole rendering pipeline for the given configuration.
|
||||||
/// Returns the initialized map, ready to be run.
|
/// Returns the initialized map, ready to be run.
|
||||||
async fn initialize(self, map_window_config: &MWC) -> Result<InitializationResult<MWC>, Error> {
|
pub async fn initialize_renderer<MWC>(
|
||||||
let window = map_window_config.create();
|
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
{
|
|
||||||
Ok(InitializationResult::Uninizalized(self))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
|
||||||
{
|
|
||||||
let renderer = Renderer::initialize(
|
|
||||||
&window,
|
|
||||||
self.wgpu_settings.clone(),
|
|
||||||
self.renderer_settings.clone(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(InitializationResult::Initialized(InitializedRenderer {
|
|
||||||
window,
|
|
||||||
renderer,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn initialize_with<E>(
|
|
||||||
self,
|
self,
|
||||||
kernel: &Kernel<E>,
|
existing_window: &MWC::MapWindow,
|
||||||
) -> Result<InitializationResult<MWC>, Error>
|
) -> Result<InitializationResult, Error>
|
||||||
where
|
where
|
||||||
E: Environment<MapWindowConfig = MWC>,
|
MWC: MapWindowConfig,
|
||||||
|
<MWC as MapWindowConfig>::MapWindow: HeadedMapWindow,
|
||||||
{
|
{
|
||||||
self.initialize(kernel.map_window_config()).await
|
let renderer = Renderer::initialize(
|
||||||
|
existing_window,
|
||||||
|
self.wgpu_settings.clone(),
|
||||||
|
self.renderer_settings.clone(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(InitializationResult::Initialized(InitializedRenderer {
|
||||||
|
renderer,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "headless")]
|
#[cfg(feature = "headless")]
|
||||||
impl<MWC: MapWindowConfig> UninitializedRenderer<MWC> {
|
impl UninitializedRenderer {
|
||||||
async fn initialize_headless(self, map_window_config: &MWC) -> Result<Renderer, Error> {
|
pub(crate) async fn initialize_headless<MWC>(
|
||||||
let window = map_window_config.create();
|
self,
|
||||||
|
existing_window: &MWC::MapWindow,
|
||||||
|
) -> Result<Renderer, Error>
|
||||||
|
where
|
||||||
|
MWC: MapWindowConfig,
|
||||||
|
{
|
||||||
Ok(Renderer::initialize_headless(
|
Ok(Renderer::initialize_headless(
|
||||||
&window,
|
existing_window,
|
||||||
self.wgpu_settings.clone(),
|
self.wgpu_settings.clone(),
|
||||||
self.renderer_settings.clone(),
|
self.renderer_settings.clone(),
|
||||||
)
|
)
|
||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn initialize_headless_with<E>(self, kernel: &Kernel<E>) -> Result<Renderer, Error>
|
|
||||||
where
|
|
||||||
E: Environment<MapWindowConfig = MWC>,
|
|
||||||
{
|
|
||||||
self.initialize_headless(kernel.map_window_config()).await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InitializedRenderer<MWC: MapWindowConfig> {
|
pub struct InitializedRenderer {
|
||||||
pub window: MWC::MapWindow,
|
|
||||||
pub renderer: Renderer,
|
pub renderer: Renderer,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,8 +7,9 @@ use maplibre::{
|
|||||||
io::{apc::SchedulerAsyncProcedureCall, scheduler::NopScheduler},
|
io::{apc::SchedulerAsyncProcedureCall, scheduler::NopScheduler},
|
||||||
kernel::{Kernel, KernelBuilder},
|
kernel::{Kernel, KernelBuilder},
|
||||||
map::Map,
|
map::Map,
|
||||||
render::builder::{InitializedRenderer, RenderBuilder},
|
render::builder::{InitializedRenderer, RendererBuilder},
|
||||||
style::Style,
|
style::Style,
|
||||||
|
window::MapWindowConfig,
|
||||||
};
|
};
|
||||||
use maplibre_winit::{WinitEnvironment, WinitMapWindowConfig};
|
use maplibre_winit::{WinitEnvironment, WinitMapWindowConfig};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
@ -66,13 +67,8 @@ type CurrentEnvironment = WinitEnvironment<
|
|||||||
|
|
||||||
pub type MapType = Map<CurrentEnvironment>;
|
pub type MapType = Map<CurrentEnvironment>;
|
||||||
|
|
||||||
pub struct InitResult {
|
|
||||||
initialized: InitializedRenderer<WinitMapWindowConfig<()>>,
|
|
||||||
kernel: Kernel<CurrentEnvironment>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub async fn init_maplibre(new_worker: js_sys::Function) -> u32 {
|
pub async fn run_maplibre(new_worker: js_sys::Function) {
|
||||||
let mut kernel_builder = KernelBuilder::new()
|
let mut kernel_builder = KernelBuilder::new()
|
||||||
.with_map_window_config(WinitMapWindowConfig::new("maplibre".to_string()))
|
.with_map_window_config(WinitMapWindowConfig::new("maplibre".to_string()))
|
||||||
.with_http_client(WHATWGFetchHttpClient::new());
|
.with_http_client(WHATWGFetchHttpClient::new());
|
||||||
@ -100,31 +96,15 @@ pub async fn init_maplibre(new_worker: js_sys::Function) -> u32 {
|
|||||||
|
|
||||||
let kernel: Kernel<WinitEnvironment<_, _, _, ()>> = kernel_builder.build();
|
let kernel: Kernel<WinitEnvironment<_, _, _, ()>> = kernel_builder.build();
|
||||||
|
|
||||||
Box::into_raw(Box::new(InitResult {
|
let mut map: MapType = Map::new(Style::default(), kernel).unwrap();
|
||||||
initialized: RenderBuilder::new()
|
map.initialize_renderer(RendererBuilder::new())
|
||||||
.build()
|
.await
|
||||||
.initialize_with(&kernel)
|
.unwrap();
|
||||||
.await
|
|
||||||
.expect("Failed to initialize renderer")
|
|
||||||
.unwarp(),
|
|
||||||
kernel,
|
|
||||||
})) as u32
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
map.window_mut()
|
||||||
pub unsafe fn run(init_ptr: *mut InitResult) {
|
|
||||||
let mut init_result = Box::from_raw(init_ptr);
|
|
||||||
|
|
||||||
let InitializedRenderer {
|
|
||||||
mut window,
|
|
||||||
renderer,
|
|
||||||
} = init_result.initialized;
|
|
||||||
let map: MapType = Map::new(Style::default(), init_result.kernel, renderer).unwrap();
|
|
||||||
|
|
||||||
window
|
|
||||||
.take_event_loop()
|
.take_event_loop()
|
||||||
.expect("Event loop is not available")
|
.expect("Event loop is not available")
|
||||||
.run(window, map, None)
|
.run(map, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user