mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Fix compilation issues and cleanup
This commit is contained in:
parent
4879d9c0b4
commit
c6eadbf2cc
@ -6,3 +6,10 @@ pub struct MapContext {
|
|||||||
pub world: World,
|
pub world: World,
|
||||||
pub renderer: Renderer,
|
pub renderer: Renderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MapContext {
|
||||||
|
pub fn resize(&mut self, width: u32, height: u32) {
|
||||||
|
self.world.view_state.resize(width, height);
|
||||||
|
self.renderer.resize(width, height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -15,6 +15,15 @@ pub enum Error {
|
|||||||
Render(RenderError),
|
Render(RenderError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E> From<E> for Error
|
||||||
|
where
|
||||||
|
E: Into<RenderError>,
|
||||||
|
{
|
||||||
|
fn from(e: E) -> Self {
|
||||||
|
Error::Render(e.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<TessellationError> for Error {
|
impl From<TessellationError> for Error {
|
||||||
fn from(e: TessellationError) -> Self {
|
fn from(e: TessellationError) -> Self {
|
||||||
Error::Tesselation(e)
|
Error::Tesselation(e)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::io::pipeline::Processable;
|
use crate::io::pipeline::Processable;
|
||||||
|
use crate::render::builder::UninitializedRenderer;
|
||||||
use crate::{
|
use crate::{
|
||||||
context::MapContext,
|
context::MapContext,
|
||||||
coords::{WorldCoords, WorldTileCoords, Zoom, TILE_SIZE},
|
coords::{WorldCoords, WorldTileCoords, Zoom, TILE_SIZE},
|
||||||
@ -28,19 +29,19 @@ use crate::{
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
pub struct HeadlessMap {
|
pub struct HeadlessMap {
|
||||||
window_size: WindowSize,
|
|
||||||
kernel: Kernel<HeadlessEnvironment>,
|
kernel: Kernel<HeadlessEnvironment>,
|
||||||
map_context: MapContext,
|
|
||||||
schedule: Schedule,
|
schedule: Schedule,
|
||||||
|
map_context: MapContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeadlessMap {
|
impl HeadlessMap {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
style: Style,
|
style: Style,
|
||||||
window_size: WindowSize,
|
|
||||||
renderer: Renderer,
|
renderer: Renderer,
|
||||||
kernel: Kernel<HeadlessEnvironment>,
|
kernel: Kernel<HeadlessEnvironment>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let window_size = renderer.state().surface().size();
|
||||||
|
|
||||||
let world = World::new(
|
let world = World::new(
|
||||||
window_size,
|
window_size,
|
||||||
WorldCoords::from((TILE_SIZE / 2., TILE_SIZE / 2.)),
|
WorldCoords::from((TILE_SIZE / 2., TILE_SIZE / 2.)),
|
||||||
@ -67,7 +68,6 @@ impl HeadlessMap {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
window_size,
|
|
||||||
kernel,
|
kernel,
|
||||||
map_context: MapContext {
|
map_context: MapContext {
|
||||||
style,
|
style,
|
||||||
@ -94,7 +94,7 @@ impl HeadlessMap {
|
|||||||
pub async fn fetch_tile(
|
pub async fn fetch_tile(
|
||||||
&self,
|
&self,
|
||||||
coords: WorldTileCoords,
|
coords: WorldTileCoords,
|
||||||
source_layers: HashSet<String>,
|
source_layers: &[&str],
|
||||||
) -> Result<StoredTile, Error> {
|
) -> Result<StoredTile, Error> {
|
||||||
let source_client = &self.kernel.source_client;
|
let source_client = &self.kernel.source_client;
|
||||||
|
|
||||||
@ -107,7 +107,10 @@ impl HeadlessMap {
|
|||||||
(
|
(
|
||||||
TileRequest {
|
TileRequest {
|
||||||
coords: WorldTileCoords::default(),
|
coords: WorldTileCoords::default(),
|
||||||
layers: source_layers,
|
layers: source_layers
|
||||||
|
.iter()
|
||||||
|
.map(|layer| layer.to_string())
|
||||||
|
.collect::<HashSet<String>>(),
|
||||||
},
|
},
|
||||||
data,
|
data,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
mod environment;
|
|
||||||
mod graph_node;
|
mod graph_node;
|
||||||
mod stage;
|
mod stage;
|
||||||
mod window;
|
|
||||||
|
|
||||||
|
pub mod environment;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
|
pub mod window;
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
use crate::window::{MapWindow, MapWindowConfig, WindowSize};
|
use crate::window::{MapWindow, MapWindowConfig, WindowSize};
|
||||||
|
|
||||||
pub struct HeadlessMapWindowConfig {
|
pub struct HeadlessMapWindowConfig {
|
||||||
pub size: WindowSize,
|
size: WindowSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeadlessMapWindowConfig {
|
||||||
|
pub fn new(size: WindowSize) -> Self {
|
||||||
|
Self { size }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MapWindowConfig for HeadlessMapWindowConfig {
|
impl MapWindowConfig for HeadlessMapWindowConfig {
|
||||||
|
|||||||
@ -16,14 +16,15 @@
|
|||||||
//! maplibre = "0.0.2"
|
//! maplibre = "0.0.2"
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
// Internal modules
|
||||||
|
pub(crate) mod tessellation;
|
||||||
|
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod coords;
|
pub mod coords;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
#[cfg(feature = "headless")]
|
#[cfg(feature = "headless")]
|
||||||
pub mod headless;
|
pub mod headless;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
// Exposed because of input handlers in maplibre-winit
|
|
||||||
pub mod map_schedule;
|
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
// TODO: Exposed because of camera
|
// TODO: Exposed because of camera
|
||||||
pub mod render;
|
pub mod render;
|
||||||
@ -41,9 +42,8 @@ pub mod environment;
|
|||||||
// Used for benchmarking
|
// Used for benchmarking
|
||||||
pub mod benchmarking;
|
pub mod benchmarking;
|
||||||
|
|
||||||
// Internal modules
|
pub mod map;
|
||||||
pub(crate) mod tessellation;
|
pub mod world;
|
||||||
mod world;
|
|
||||||
|
|
||||||
// Export tile format
|
// Export tile format
|
||||||
pub use geozero::mvt::tile;
|
pub use geozero::mvt::tile;
|
||||||
|
|||||||
@ -1,47 +1,50 @@
|
|||||||
/// The [`Map`] defines the public interface of the map renderer.
|
use crate::context::MapContext;
|
||||||
// DO NOT IMPLEMENT INTERNALS ON THIS STRUCT.
|
use crate::coords::{LatLon, WorldCoords, Zoom, TILE_SIZE};
|
||||||
|
use crate::environment::{Environment, Kernel};
|
||||||
|
use crate::error::Error;
|
||||||
|
use crate::headless::environment::HeadlessEnvironment;
|
||||||
|
use crate::render::{create_default_render_graph, register_default_render_stages, Renderer};
|
||||||
|
use crate::schedule::{Schedule, Stage};
|
||||||
|
use crate::style::Style;
|
||||||
|
use crate::world::World;
|
||||||
|
|
||||||
pub struct Map<E: Environment> {
|
pub struct Map<E: Environment> {
|
||||||
// FIXME (wasm-executor): Avoid RefCell, change ownership model!
|
kernel: Kernel<E>,
|
||||||
map_schedule: Rc<RefCell<InteractiveMapSchedule<E>>>,
|
schedule: Schedule,
|
||||||
window: RefCell<Option<<E::MapWindowConfig as MapWindowConfig>::MapWindow>>,
|
map_context: MapContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Environment> Map<E>
|
impl<E: Environment> Map<E> {
|
||||||
where
|
pub fn new(style: Style, kernel: Kernel<E>, renderer: Renderer) -> Result<Self, Error> {
|
||||||
<E::MapWindowConfig as MapWindowConfig>::MapWindow: EventLoop<E>,
|
let window_size = renderer.state().surface().size();
|
||||||
{
|
|
||||||
/// Starts the [`crate::map_schedule::MapState`] Runnable with the configured event loop.
|
let center = style.center.unwrap_or_default();
|
||||||
pub fn run(&self) {
|
let world = World::new_at(
|
||||||
self.run_with_optionally_max_frames(None);
|
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 graph = create_default_render_graph().unwrap(); // TODO: Remove unwrap
|
||||||
|
register_default_render_stages(graph, &mut schedule);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
kernel,
|
||||||
|
map_context: MapContext {
|
||||||
|
style,
|
||||||
|
world,
|
||||||
|
renderer,
|
||||||
|
},
|
||||||
|
schedule,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts the [`crate::map_schedule::MapState`] Runnable with the configured event loop.
|
#[tracing::instrument(name = "update_and_redraw", skip_all)]
|
||||||
///
|
pub fn run_schedule(&mut self) -> Result<(), Error> {
|
||||||
/// # Arguments
|
self.schedule.run(&mut self.map_context);
|
||||||
///
|
Ok(())
|
||||||
/// * `max_frames` - Maximum number of frames per second.
|
|
||||||
pub fn run_with_max_frames(&self, max_frames: u64) {
|
|
||||||
self.run_with_optionally_max_frames(Some(max_frames));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts the MapState Runnable with the configured event loop.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `max_frames` - Optional maximum number of frames per second.
|
|
||||||
pub fn run_with_optionally_max_frames(&self, max_frames: Option<u64>) {
|
|
||||||
self.window
|
|
||||||
.borrow_mut()
|
|
||||||
.take()
|
|
||||||
.unwrap() // FIXME (wasm-executor): Remove unwrap
|
|
||||||
.run(self.map_schedule.clone(), max_frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_schedule(&self) -> Rc<RefCell<InteractiveMapSchedule<E>>> {
|
|
||||||
self.map_schedule.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pub fn map_schedule_mut(&mut self) -> &mut InteractiveMapSchedule<E> {
|
|
||||||
&mut self.map_schedule
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,146 +1,14 @@
|
|||||||
use std::{cell::RefCell, marker::PhantomData, mem, rc::Rc};
|
/* pub fn resume(&mut self, window: &<E::MapWindowConfig as MapWindowConfig>::MapWindow) {
|
||||||
|
|
||||||
use crate::{
|
|
||||||
context::MapContext,
|
|
||||||
coords::{LatLon, WorldCoords, Zoom, TILE_SIZE},
|
|
||||||
environment::Environment,
|
|
||||||
error::Error,
|
|
||||||
io::{
|
|
||||||
scheduler::Scheduler,
|
|
||||||
source_client::{HttpClient, HttpSourceClient},
|
|
||||||
tile_repository::TileRepository,
|
|
||||||
},
|
|
||||||
render::{
|
|
||||||
create_default_render_graph, register_default_render_stages,
|
|
||||||
settings::{RendererSettings, WgpuSettings},
|
|
||||||
Renderer,
|
|
||||||
},
|
|
||||||
schedule::{Schedule, Stage},
|
|
||||||
stages::register_stages,
|
|
||||||
style::Style,
|
|
||||||
window::{HeadedMapWindow, MapWindowConfig, WindowSize},
|
|
||||||
world::{ViewState, World},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Stores the state of the map, dispatches tile fetching and caching, tessellation and drawing.
|
|
||||||
pub struct InteractiveMapSchedule<E: Environment> {
|
|
||||||
map_window_config: E::MapWindowConfig,
|
|
||||||
|
|
||||||
// FIXME (wasm-executor): avoid RefCell, change ownership model
|
|
||||||
pub apc: Rc<RefCell<E::AsyncProcedureCall>>,
|
|
||||||
|
|
||||||
map_context: EventuallyMapContext,
|
|
||||||
|
|
||||||
schedule: Schedule,
|
|
||||||
|
|
||||||
suspended: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: Environment> InteractiveMapSchedule<E> {
|
|
||||||
pub fn new(window_size: WindowSize, renderer: Option<Renderer>, style: Style) -> Self {
|
|
||||||
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()),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut schedule = Schedule::default();
|
|
||||||
|
|
||||||
let apc = Rc::new(RefCell::new(apc));
|
|
||||||
|
|
||||||
let http_source_client: HttpSourceClient<E::HttpClient> =
|
|
||||||
HttpSourceClient::new(http_client);
|
|
||||||
register_stages::<E>(&mut schedule, http_source_client, apc.clone());
|
|
||||||
|
|
||||||
let graph = create_default_render_graph().unwrap(); // TODO: Remove unwrap
|
|
||||||
register_default_render_stages(graph, &mut schedule);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
apc,
|
|
||||||
map_window_config,
|
|
||||||
map_context: match renderer {
|
|
||||||
None => EventuallyMapContext::Premature(PrematureMapContext {
|
|
||||||
world,
|
|
||||||
style,
|
|
||||||
wgpu_settings,
|
|
||||||
renderer_settings,
|
|
||||||
}),
|
|
||||||
Some(renderer) => EventuallyMapContext::Full(MapContext {
|
|
||||||
world,
|
|
||||||
style,
|
|
||||||
renderer,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
schedule,
|
|
||||||
suspended: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(name = "update_and_redraw", skip_all)]
|
|
||||||
pub fn update_and_redraw(&mut self) -> Result<(), Error> {
|
|
||||||
if self.suspended {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let EventuallyMapContext::Full(map_context) = &mut self.map_context {
|
|
||||||
self.schedule.run(map_context)
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resize(&mut self, width: u32, height: u32) {
|
|
||||||
if let EventuallyMapContext::Full(map_context) = &mut self.map_context {
|
|
||||||
let view_state = &mut map_context.view_state;
|
|
||||||
view_state.perspective.resize(width, height);
|
|
||||||
view_state.camera.resize(width, height);
|
|
||||||
|
|
||||||
map_context.renderer.resize(width, height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_initialized(&self) -> bool {
|
|
||||||
match &self.map_context {
|
|
||||||
EventuallyMapContext::Full(_) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn view_state_mut(&mut self) -> &mut ViewState {
|
|
||||||
match &mut self.map_context {
|
|
||||||
EventuallyMapContext::Full(MapContext { view_state, .. }) => view_state,
|
|
||||||
EventuallyMapContext::Premature(PrematureMapContext { view_state, .. }) => view_state,
|
|
||||||
_ => panic!("should not happen"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn apc(&self) -> &Rc<RefCell<E::AsyncProcedureCall>> {
|
|
||||||
&self.apc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: Environment> InteractiveMapSchedule<E>
|
|
||||||
where
|
|
||||||
<E::MapWindowConfig as MapWindowConfig>::MapWindow: HeadedMapWindow,
|
|
||||||
{
|
|
||||||
pub fn suspend(&mut self) {
|
|
||||||
self.suspended = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resume(&mut self, window: &<E::MapWindowConfig as MapWindowConfig>::MapWindow) {
|
|
||||||
if let EventuallyMapContext::Full(map_context) = &mut self.map_context {
|
if let EventuallyMapContext::Full(map_context) = &mut self.map_context {
|
||||||
let renderer = &mut map_context.renderer;
|
let renderer = &mut map_context.renderer;
|
||||||
renderer.state.recreate_surface(window, &renderer.instance);
|
renderer.state.recreate_surface(window, &renderer.instance);
|
||||||
self.suspended = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
pub async fn late_init(&mut self) -> bool {
|
/* pub async fn late_init(&mut self) -> bool {
|
||||||
match &self.map_context {
|
match &self.map_context {
|
||||||
EventuallyMapContext::Full(_) => false,
|
EventuallyMapContext::Full(_) => false,
|
||||||
EventuallyMapContext::Premature(PrematureMapContext {
|
EventuallyMapContext::Uninizalized(PrematureMapContext {
|
||||||
wgpu_settings,
|
wgpu_settings,
|
||||||
renderer_settings,
|
renderer_settings,
|
||||||
..
|
..
|
||||||
@ -155,44 +23,4 @@ where
|
|||||||
}
|
}
|
||||||
EventuallyMapContext::_Uninitialized => false,
|
EventuallyMapContext::_Uninitialized => false,
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PrematureMapContext {
|
|
||||||
world: World,
|
|
||||||
|
|
||||||
style: Style,
|
|
||||||
|
|
||||||
wgpu_settings: WgpuSettings,
|
|
||||||
renderer_settings: RendererSettings,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum EventuallyMapContext {
|
|
||||||
Full(MapContext),
|
|
||||||
Premature(PrematureMapContext),
|
|
||||||
_Uninitialized,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventuallyMapContext {
|
|
||||||
pub fn make_full(&mut self, renderer: Renderer) {
|
|
||||||
let context = mem::replace(self, EventuallyMapContext::_Uninitialized);
|
|
||||||
|
|
||||||
match context {
|
|
||||||
EventuallyMapContext::Full(_) => {}
|
|
||||||
EventuallyMapContext::Premature(PrematureMapContext {
|
|
||||||
view_state,
|
|
||||||
style,
|
|
||||||
tile_repository,
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
*self = EventuallyMapContext::Full(MapContext {
|
|
||||||
view_state,
|
|
||||||
style,
|
|
||||||
tile_repository,
|
|
||||||
renderer,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
EventuallyMapContext::_Uninitialized => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use crate::environment::Kernel;
|
||||||
|
use crate::error::Error;
|
||||||
use crate::{
|
use crate::{
|
||||||
environment::Environment,
|
environment::Environment,
|
||||||
render::{
|
render::{
|
||||||
@ -14,6 +16,13 @@ pub struct RenderBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RenderBuilder {
|
impl RenderBuilder {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
wgpu_settings: None,
|
||||||
|
renderer_settings: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_renderer_settings(mut self, renderer_settings: RendererSettings) -> Self {
|
pub fn with_renderer_settings(mut self, renderer_settings: RendererSettings) -> Self {
|
||||||
self.renderer_settings = Some(renderer_settings);
|
self.renderer_settings = Some(renderer_settings);
|
||||||
self
|
self
|
||||||
@ -32,6 +41,20 @@ impl RenderBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum InitializationResult {
|
||||||
|
Initialized(Renderer),
|
||||||
|
Uninizalized(UninitializedRenderer),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InitializationResult {
|
||||||
|
pub fn unwarp(self) -> Renderer {
|
||||||
|
match self {
|
||||||
|
InitializationResult::Initialized(renderer) => renderer,
|
||||||
|
InitializationResult::Uninizalized(_) => panic!("Renderer is not initialized"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct UninitializedRenderer {
|
pub struct UninitializedRenderer {
|
||||||
wgpu_settings: WgpuSettings,
|
wgpu_settings: WgpuSettings,
|
||||||
renderer_settings: RendererSettings,
|
renderer_settings: RendererSettings,
|
||||||
@ -40,41 +63,64 @@ pub struct UninitializedRenderer {
|
|||||||
impl UninitializedRenderer {
|
impl UninitializedRenderer {
|
||||||
/// 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.
|
||||||
pub async fn initialize<MWC: MapWindowConfig>(self, map_window_config: MWC) -> Option<Renderer>
|
async fn initialize<MWC: MapWindowConfig>(
|
||||||
|
self,
|
||||||
|
map_window_config: &MWC,
|
||||||
|
) -> Result<InitializationResult, Error>
|
||||||
where
|
where
|
||||||
MWC::MapWindow: MapWindow + HeadedMapWindow,
|
MWC::MapWindow: MapWindow + HeadedMapWindow,
|
||||||
{
|
{
|
||||||
let window = map_window_config.create();
|
let window = map_window_config.create();
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
let renderer = None;
|
let renderer = Ok(InitializationResult::Uninizalized(self));
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
let renderer = Renderer::initialize(
|
let renderer = Ok(InitializationResult::Initialized(
|
||||||
|
Renderer::initialize(
|
||||||
&window,
|
&window,
|
||||||
self.wgpu_settings.clone(),
|
self.wgpu_settings.clone(),
|
||||||
self.renderer_settings.clone(),
|
self.renderer_settings.clone(),
|
||||||
)
|
)
|
||||||
.await
|
.await?,
|
||||||
.ok();
|
));
|
||||||
|
|
||||||
renderer
|
renderer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn initialize_with<E: Environment>(
|
||||||
|
self,
|
||||||
|
kernel: &Kernel<E>,
|
||||||
|
) -> Result<InitializationResult, Error>
|
||||||
|
where
|
||||||
|
<E::MapWindowConfig as MapWindowConfig>::MapWindow: MapWindow + HeadedMapWindow,
|
||||||
|
{
|
||||||
|
self.initialize(&kernel.map_window_config).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "headless")]
|
#[cfg(feature = "headless")]
|
||||||
impl UninitializedRenderer {
|
impl UninitializedRenderer {
|
||||||
pub async fn initialize_headless<MWC: MapWindowConfig>(
|
async fn initialize_headless<MWC: MapWindowConfig>(
|
||||||
self,
|
self,
|
||||||
map_window_config: MWC,
|
map_window_config: MWC,
|
||||||
) -> Option<Renderer> {
|
) -> Result<Renderer, Error> {
|
||||||
let window = map_window_config.create();
|
let window = map_window_config.create();
|
||||||
|
|
||||||
Renderer::initialize_headless(
|
Ok(Renderer::initialize_headless(
|
||||||
&window,
|
&window,
|
||||||
self.wgpu_settings.clone(),
|
self.wgpu_settings.clone(),
|
||||||
self.renderer_settings.clone(),
|
self.renderer_settings.clone(),
|
||||||
)
|
)
|
||||||
.await
|
.await?)
|
||||||
.ok()
|
}
|
||||||
|
|
||||||
|
pub async fn initialize_headless_with<E: Environment>(
|
||||||
|
self,
|
||||||
|
kernel: &Kernel<E>,
|
||||||
|
) -> Result<InitializationResult, Error>
|
||||||
|
where
|
||||||
|
<E::MapWindowConfig as MapWindowConfig>::MapWindow: MapWindow + HeadedMapWindow,
|
||||||
|
{
|
||||||
|
self.initialize(&kernel.map_window_config).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,13 +6,15 @@ use crate::{error::Error, render::graph::RenderGraphError};
|
|||||||
pub enum RenderError {
|
pub enum RenderError {
|
||||||
Surface(wgpu::SurfaceError),
|
Surface(wgpu::SurfaceError),
|
||||||
Graph(RenderGraphError),
|
Graph(RenderGraphError),
|
||||||
|
Device(wgpu::RequestDeviceError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for RenderError {
|
impl fmt::Display for RenderError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
RenderError::Surface(e) => write!(f, "{}", e),
|
RenderError::Surface(e) => write!(f, "{}", e),
|
||||||
RenderError::Graph(e) => write!(f, "{}", e),
|
RenderError::Graph(e) => write!(f, "{:?}", e),
|
||||||
|
RenderError::Device(e) => write!(f, "{}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,8 +31,20 @@ impl RenderError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<RenderGraphError> for RenderError {
|
||||||
|
fn from(e: RenderGraphError) -> Self {
|
||||||
|
RenderError::Graph(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<wgpu::SurfaceError> for Error {
|
impl From<wgpu::SurfaceError> for Error {
|
||||||
fn from(e: wgpu::SurfaceError) -> Self {
|
fn from(e: wgpu::SurfaceError) -> Self {
|
||||||
Error::Render(RenderError::Surface(e))
|
Error::Render(RenderError::Surface(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<wgpu::RequestDeviceError> for Error {
|
||||||
|
fn from(e: wgpu::RequestDeviceError) -> Self {
|
||||||
|
Error::Render(RenderError::Device(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@ impl WindowHead {
|
|||||||
where
|
where
|
||||||
MW: MapWindow + HeadedMapWindow,
|
MW: MapWindow + HeadedMapWindow,
|
||||||
{
|
{
|
||||||
self.surface = unsafe { instance.create_surface(window.inner()) };
|
self.surface = unsafe { instance.create_surface(window.raw()) };
|
||||||
}
|
}
|
||||||
pub fn surface(&self) -> &wgpu::Surface {
|
pub fn surface(&self) -> &wgpu::Surface {
|
||||||
&self.surface
|
&self.surface
|
||||||
@ -140,7 +140,7 @@ impl Surface {
|
|||||||
present_mode: wgpu::PresentMode::Fifo, // VSync
|
present_mode: wgpu::PresentMode::Fifo, // VSync
|
||||||
};
|
};
|
||||||
|
|
||||||
let surface = unsafe { instance.create_surface(window.inner()) };
|
let surface = unsafe { instance.create_surface(window.raw()) };
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
size,
|
size,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use std::{cell::RefCell, rc::Rc};
|
|||||||
|
|
||||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||||
|
|
||||||
use crate::{environment::Environment, map_schedule::InteractiveMapSchedule};
|
use crate::environment::Environment;
|
||||||
|
|
||||||
/// Window of a certain [`WindowSize`]. This can either be a proper window or a headless one.
|
/// Window of a certain [`WindowSize`]. This can either be a proper window or a headless one.
|
||||||
pub trait MapWindow {
|
pub trait MapWindow {
|
||||||
@ -16,7 +16,7 @@ pub trait MapWindow {
|
|||||||
pub trait HeadedMapWindow: MapWindow {
|
pub trait HeadedMapWindow: MapWindow {
|
||||||
type RawWindow: HasRawWindowHandle + HasRawDisplayHandle;
|
type RawWindow: HasRawWindowHandle + HasRawDisplayHandle;
|
||||||
|
|
||||||
fn inner(&self) -> &Self::RawWindow;
|
fn raw(&self) -> &Self::RawWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A configuration for a window which determines the corresponding implementation of a
|
/// A configuration for a window which determines the corresponding implementation of a
|
||||||
@ -27,13 +27,6 @@ pub trait MapWindowConfig: 'static {
|
|||||||
fn create(&self) -> Self::MapWindow;
|
fn create(&self) -> Self::MapWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The event loop is responsible for processing events and propagating them to the map renderer.
|
|
||||||
/// Only non-headless windows use an [`EventLoop`].
|
|
||||||
pub trait EventLoop<E: Environment> {
|
|
||||||
// FIXME (wasm-executor): Avoid Rc, change ownership model
|
|
||||||
fn run(self, map_schedule: Rc<RefCell<InteractiveMapSchedule<E>>>, max_frames: Option<u64>);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Window size with a width and an height in pixels.
|
/// Window size with a width and an height in pixels.
|
||||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||||
pub struct WindowSize {
|
pub struct WindowSize {
|
||||||
|
|||||||
@ -99,6 +99,11 @@ impl ViewState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resize(&mut self, width: u32, height: u32) {
|
||||||
|
self.perspective.resize(width, height);
|
||||||
|
self.camera.resize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_view_region(&self) -> Option<ViewRegion> {
|
pub fn create_view_region(&self) -> Option<ViewRegion> {
|
||||||
self.camera
|
self.camera
|
||||||
.view_region_bounding_box(&self.view_projection().invert())
|
.view_region_bounding_box(&self.view_projection().invert())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user