Fix window size (#62)

* Add a MapWindow traid which exposes the window dimensions.

* Remove broken run configs

* Fix run config

* Adjust FromCanvas
This commit is contained in:
Max Ammann 2022-05-02 16:18:38 +02:00 committed by GitHub
parent 720e1f95f1
commit 7df6ca49d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 79 additions and 86 deletions

View File

@ -1,12 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Build WASM" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="build -p maplibre-web --features web-webgl --lib --release --target wasm32-unknown-unknown -Z build-std=std,panic_abort" />
<option name="command" value="build -p web --features web-webgl --lib --release --target wasm32-unknown-unknown -Z build-std=std,panic_abort" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<envs>
<env name="RUSTUP_TOOLCHAIN" value="nightly-2022-04-04-x86_64-unknown-linux-gnu" />

View File

@ -1,17 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Pack WASM (WebGPU) (Release)" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/justfile" />
<option name="SCRIPT_OPTIONS" value="build-wasm-bindgen" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/usr/bin/env" />
<option name="INTERPRETER_OPTIONS" value="just --justfile" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_SCRIPT_FILE" value="true" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run web (webgl) " type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/maplibre-web/web/package.json" />
<command value="run" />
<scripts>
<script value="webgl-start" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run web (webgpu)" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/maplibre-web/web/package.json" />
<command value="run" />
<scripts>
<script value="start" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@ -12,6 +12,7 @@ use crate::input::shift_handler::ShiftHandler;
use crate::input::tilt_handler::TiltHandler;
use crate::input::zoom_handler::ZoomHandler;
use crate::map_state::MapState;
use crate::MapWindow;
mod pan_handler;
mod pinch_handler;
@ -124,12 +125,12 @@ impl InputController {
}
pub trait UpdateState {
fn update_state<W>(&mut self, state: &mut MapState<W>, dt: Duration);
fn update_state<W: MapWindow>(&mut self, state: &mut MapState<W>, dt: Duration);
}
impl UpdateState for InputController {
#[tracing::instrument(skip_all)]
fn update_state<W>(&mut self, state: &mut MapState<W>, dt: Duration) {
fn update_state<W: MapWindow>(&mut self, state: &mut MapState<W>, dt: Duration) {
self.pan_handler.update_state(state, dt);
self.pinch_handler.update_state(state, dt);
self.zoom_handler.update_state(state, dt);

View File

@ -3,6 +3,7 @@ use super::UpdateState;
use crate::map_state::MapState;
use crate::render::camera::Camera;
use crate::MapWindow;
use cgmath::{EuclideanSpace, Point3, Vector2, Vector3, Zero};
use std::time::Duration;
use winit::event::{ElementState, MouseButton};
@ -16,7 +17,7 @@ pub struct PanHandler {
}
impl UpdateState for PanHandler {
fn update_state<W>(&mut self, state: &mut MapState<W>, _dt: Duration) {
fn update_state<W: MapWindow>(&mut self, state: &mut MapState<W>, _dt: Duration) {
if !self.is_panning {
return;
}

View File

@ -1,12 +1,12 @@
use super::UpdateState;
use crate::MapState;
use crate::{MapState, MapWindow};
use std::time::Duration;
pub struct PinchHandler {}
impl UpdateState for PinchHandler {
fn update_state<W>(&mut self, _state: &mut MapState<W>, _dt: Duration) {
fn update_state<W: MapWindow>(&mut self, _state: &mut MapState<W>, _dt: Duration) {
// TODO
}
}

View File

@ -2,6 +2,7 @@ use cgmath::Vector2;
use crate::input::UpdateState;
use crate::map_state::MapState;
use crate::MapWindow;
use std::time::Duration;
use winit::event::{ElementState, MouseButton};
@ -56,7 +57,7 @@ impl QueryHandler {
}
impl UpdateState for QueryHandler {
fn update_state<W>(&mut self, state: &mut MapState<W>, _dt: Duration) {
fn update_state<W: MapWindow>(&mut self, state: &mut MapState<W>, _dt: Duration) {
if self.clicking {
if let Some(window_position) = self.window_position {
let perspective = &state.perspective();

View File

@ -1,6 +1,6 @@
use super::UpdateState;
use crate::MapState;
use crate::{MapState, MapWindow};
use cgmath::{Vector3, Zero};
use std::time::Duration;
@ -12,7 +12,7 @@ pub struct ShiftHandler {
}
impl UpdateState for ShiftHandler {
fn update_state<W>(&mut self, state: &mut MapState<W>, dt: Duration) {
fn update_state<W: MapWindow>(&mut self, state: &mut MapState<W>, dt: Duration) {
let dt = dt.as_secs_f64() * (1.0 / self.speed);
let delta = self.camera_translate * dt;

View File

@ -2,6 +2,7 @@ use super::UpdateState;
use crate::map_state::MapState;
use crate::MapWindow;
use cgmath::{Deg, Rad, Zero};
use std::time::Duration;
@ -13,7 +14,7 @@ pub struct TiltHandler {
}
impl UpdateState for TiltHandler {
fn update_state<W>(&mut self, state: &mut MapState<W>, dt: Duration) {
fn update_state<W: MapWindow>(&mut self, state: &mut MapState<W>, dt: Duration) {
let dt = dt.as_secs_f64() * (1.0 / self.speed);
let delta = self.delta_pitch * dt;

View File

@ -3,6 +3,7 @@ use super::UpdateState;
use crate::coords::Zoom;
use crate::map_state::MapState;
use crate::MapWindow;
use cgmath::{Vector2, Vector3};
use std::time::Duration;
@ -13,7 +14,7 @@ pub struct ZoomHandler {
}
impl UpdateState for ZoomHandler {
fn update_state<W>(&mut self, state: &mut MapState<W>, _dt: Duration) {
fn update_state<W: MapWindow>(&mut self, state: &mut MapState<W>, _dt: Duration) {
if let Some(zoom_delta) = self.zoom_delta {
if let Some(window_position) = self.window_position {
let current_zoom = state.zoom();

View File

@ -25,12 +25,16 @@ use crate::window::{WindowFactory, WindowSize};
pub use io::scheduler::ScheduleMethod;
pub use platform::schedule_method::*;
pub struct Map<W, E> {
pub trait MapWindow {
fn size(&self) -> Option<WindowSize>;
}
pub struct Map<W: MapWindow, E> {
map_state: MapState<W>,
event_loop: E,
}
impl<W, E> Map<W, E>
impl<W: MapWindow, E> Map<W, E>
where
MapState<W>: Runnable<E>,
{
@ -49,7 +53,6 @@ where
pub struct UninitializedMap<W, E> {
window: W,
window_size: WindowSize,
event_loop: E,
scheduler: Scheduler,
style: Style,
@ -57,14 +60,25 @@ pub struct UninitializedMap<W, E> {
impl<W, E> UninitializedMap<W, E>
where
W: raw_window_handle::HasRawWindowHandle,
W: MapWindow + raw_window_handle::HasRawWindowHandle,
{
pub async fn initialize(self) -> Map<W, E> {
let render_state = RenderState::initialize(&self.window, self.window_size).await;
#[cfg(target_os = "android")]
// On android we can not get the dimensions of the window initially. Therefore, we use a
// fallback until the window is ready to deliver its correct bounds.
let window_size = self.window.size().unwrap_or_default();
#[cfg(not(target_os = "android"))]
let window_size = self
.window
.size()
.expect("failed to get window dimensions.");
let render_state = RenderState::initialize(&self.window, window_size).await;
Map {
map_state: MapState::new(
self.window,
self.window_size,
window_size,
render_state,
self.scheduler,
self.style,
@ -77,7 +91,7 @@ where
#[cfg(not(target_arch = "wasm32"))]
impl<W, E> UninitializedMap<W, E>
where
W: raw_window_handle::HasRawWindowHandle,
W: MapWindow + raw_window_handle::HasRawWindowHandle,
MapState<W>: Runnable<E>,
{
pub fn run_sync(self) {
@ -117,7 +131,7 @@ pub struct MapBuilder<W, E> {
impl<W, E> MapBuilder<W, E>
where
MapState<W>: Runnable<E>,
W: raw_window_handle::HasRawWindowHandle,
W: MapWindow + raw_window_handle::HasRawWindowHandle,
{
pub(crate) fn new(create_window: Box<WindowFactory<W, E>>) -> Self {
Self {
@ -144,7 +158,7 @@ where
}
pub fn build(self) -> UninitializedMap<W, E> {
let (window, window_size, event_loop) = (self.window_factory)();
let (window, event_loop) = (self.window_factory)();
let scheduler = self
.scheduler
@ -153,7 +167,6 @@ where
UninitializedMap {
window,
window_size,
event_loop,
scheduler,
style,

View File

@ -6,7 +6,7 @@ use crate::render::camera;
use crate::render::camera::{Camera, Perspective};
use crate::render::render_state::RenderState;
use crate::util::ChangeObserver;
use crate::WindowSize;
use crate::{MapWindow, WindowSize};
use std::collections::HashSet;
use std::sync::{mpsc, Arc, Mutex};
@ -24,12 +24,12 @@ pub trait Runnable<E> {
fn run(self, event_loop: E, max_frames: Option<u64>);
}
pub struct MapState<W> {
pub struct MapState<W: MapWindow> {
window: W,
zoom: ChangeObserver<Zoom>,
camera: ChangeObserver<camera::Camera>,
perspective: camera::Perspective,
camera: ChangeObserver<Camera>,
perspective: Perspective,
render_state: Option<RenderState>,
scheduler: Scheduler,
@ -42,7 +42,7 @@ pub struct MapState<W> {
try_failed: bool,
}
impl<W> MapState<W> {
impl<W: MapWindow> MapState<W> {
pub fn new(
window: W,
window_size: WindowSize,
@ -310,7 +310,7 @@ impl<W> MapState<W> {
}
}
impl<W> MapState<W>
impl<W: MapWindow> MapState<W>
where
W: raw_window_handle::HasRawWindowHandle,
{
@ -327,9 +327,14 @@ where
pub async fn reinitialize(&mut self) {
if self.render_state.is_none() {
let window_size = WindowSize::new(100, 100).unwrap(); // TODO get size
let render_state = RenderState::initialize(&self.window, window_size);
self.render_state = Some(render_state.await.unwrap())
let window_size = self
.window
.size()
.expect("Window size should be known when reinitializing.");
let render_state = RenderState::initialize(&self.window, window_size)
.await
.unwrap();
self.render_state = Some(render_state)
}
}
}

View File

@ -22,7 +22,7 @@ use crate::render::options::{
use crate::render::tile_view_pattern::{TileInView, TileViewPattern};
use crate::tessellation::IndexDataType;
use crate::util::FPSMeter;
use crate::WindowSize;
use crate::{MapWindow, WindowSize};
use super::piplines::*;
use super::shaders;
@ -71,8 +71,8 @@ impl RenderState {
) -> Option<Self> {
let sample_count = 4;
//let instance = wgpu::Instance::new(wgpu::Backends::GL);
let instance = wgpu::Instance::new(wgpu::Backends::all());
//let instance = wgpu::Instance::new(wgpu::Backends::GL);
//let instance = wgpu::Instance::new(wgpu::Backends::VULKAN);
let surface = unsafe { instance.create_surface(&window) };

View File

@ -21,7 +21,19 @@ impl WindowSize {
}
}
pub type WindowFactory<W, E> = dyn FnOnce() -> (W, WindowSize, E);
#[cfg(target_os = "android")]
/// On android we can not get the dimensions of the window initially. Therefore, we use a fallback
/// until the window is ready to deliver its correct bounds.
impl Default for WindowSize {
fn default() -> Self {
WindowSize {
width: 100,
height: 100,
}
}
}
pub type WindowFactory<W, E> = dyn FnOnce() -> (W, E);
pub trait FromWindow {
fn from_window(title: &'static str) -> Self;

View File

@ -13,7 +13,14 @@ use crate::map_state::{MapState, Runnable};
use crate::platform::Instant;
use crate::window::FromWindow;
use crate::{MapBuilder, WindowSize};
use crate::{MapBuilder, MapWindow, WindowSize};
impl MapWindow for winit::window::Window {
fn size(&self) -> Option<WindowSize> {
let size = self.inner_size();
WindowSize::new(size.width, size.height)
}
}
impl Runnable<winit::event_loop::EventLoop<()>> for MapState<winit::window::Window> {
fn run(mut self, event_loop: winit::event_loop::EventLoop<()>, max_frames: Option<u64>) {
@ -132,8 +139,7 @@ impl FromWindow for MapBuilder<winit::window::Window, winit::event_loop::EventLo
.with_title(title)
.build(&event_loop)
.unwrap();
let size = window.inner_size();
(window, WindowSize::new(100, 100).unwrap(), event_loop)
(window, event_loop)
}))
}
}
@ -178,15 +184,7 @@ impl crate::window::FromCanvas
let size = get_body_size().unwrap();
window.set_inner_size(size);
(
window,
WindowSize::new(
size.width.try_into().unwrap(),
size.height.try_into().unwrap(),
)
.unwrap(),
event_loop,
)
(window, event_loop)
}))
}
}