diff --git a/dunge/src/el.rs b/dunge/src/el.rs index 05d24e8..2c2b3e8 100644 --- a/dunge/src/el.rs +++ b/dunge/src/el.rs @@ -12,7 +12,7 @@ use { application::ApplicationHandler, error::EventLoopError, event::{self, StartCause, WindowEvent}, - event_loop::{self, ActiveEventLoop, ControlFlow, EventLoop}, + event_loop::{self, ActiveEventLoop, ControlFlow}, keyboard, window::WindowId, }, @@ -66,51 +66,6 @@ where Ok(()) } -#[deprecated] -pub(crate) struct Loop(EventLoop) -where - V: 'static; - -impl Loop { - pub fn new() -> Result { - let inner = EventLoop::with_user_event().build()?; - Ok(Self(inner)) - } - - pub fn inner(&self) -> &EventLoop { - &self.0 - } - - #[cfg(not(target_arch = "wasm32"))] - pub fn run(self, cx: Context, view: View, upd: U) -> Result<(), LoopError> - where - U: Update, - { - let mut fail = Ok(()); - let mut handle = handle(cx, view, upd); - let wrap = |ev, target: &_| { - if let Some(err) = handle(ev, target) { - fail = Err(LoopError::Failed(err)); - } - }; - - let out = self.0.run(wrap).map_err(LoopError::EventLoop); - fail.or(out) - } - - #[cfg(target_arch = "wasm32")] - pub fn spawn(self, cx: Context, view: View, upd: U) - where - U: Update + 'static, - { - use winit::platform::web::EventLoopExtWebSys; - - let mut handle = handle(cx, view, upd); - let wrap = move |ev, target: &_| _ = handle(ev, target); - self.0.spawn(wrap); - } -} - /// The event loop error. #[derive(Debug)] pub enum LoopError { @@ -375,211 +330,6 @@ where } } -type Event = event::Event; -type Target = event_loop::ActiveEventLoop; -type Failure = Option>; - -#[deprecated] -#[allow(dead_code)] -fn handle(cx: Context, view: View, mut upd: U) -> impl FnMut(Event, &Target) -> Failure -where - U: Update, -{ - use { - event::{ElementState, KeyEvent, MouseScrollDelta, StartCause, WindowEvent}, - event_loop::ControlFlow, - keyboard::PhysicalKey, - winit::dpi::{PhysicalPosition, PhysicalSize}, - }; - - const WAIT_TIME: Duration = Duration::from_millis(100); - - let mut ctrl = Control { - view: unimplemented!(), - resized: None, - min_delta_time: Cell::new(Duration::from_secs_f32(1. / 60.)), - delta_time: Duration::ZERO, - fps: 0, - pressed_keys: vec![], - released_keys: vec![], - cursor_position: None, - mouse: Mouse { - wheel_delta: (0., 0.), - pressed_buttons: Buttons(vec![]), - released_buttons: Buttons(vec![]), - }, - }; - - // Initial state - let mut active = false; - let mut time = Time::now(); - let mut fps = Fps::default(); - move |ev, target| { - match ev { - Event::NewEvents(cause) => match cause { - StartCause::ResumeTimeReached { .. } => { - log::debug!("resume time reached"); - ctrl.view.set_window_size(); - ctrl.view.request_redraw(); - } - StartCause::WaitCancelled { - requested_resume, .. - } => { - log::debug!("wait cancelled"); - let flow = match requested_resume { - Some(resume) => ControlFlow::WaitUntil(resume), - None => ControlFlow::wait_duration(WAIT_TIME), - }; - - target.set_control_flow(flow); - } - StartCause::Poll => log::debug!("poll"), - StartCause::Init => { - // TODO: create the window here - log::debug!("init"); - } - }, - Event::WindowEvent { event, window_id } if window_id == ctrl.view.id() => match event { - WindowEvent::Resized(PhysicalSize { width, height }) => { - log::debug!("resized: {width}, {height}"); - ctrl.resize(cx.state()); - } - WindowEvent::CloseRequested => { - log::debug!("close requested"); - target.exit(); - } - WindowEvent::Focused(true) => { - log::debug!("focused"); - ctrl.view.request_redraw(); - } - WindowEvent::KeyboardInput { - event: - KeyEvent { - physical_key, - text, - location, - state, - .. - }, - is_synthetic: false, - .. - } => { - let code = match physical_key { - PhysicalKey::Code(code) => { - log::debug!("keyboard input: {code:?}"); - code - } - PhysicalKey::Unidentified(code) => { - log::debug!("keyboard input: (unidentified) {code:?}"); - return None; - } - }; - - // TODO: Support key location - _ = location; - - let key = Key { code, text }; - match state { - ElementState::Pressed => ctrl.pressed_keys.push(key), - ElementState::Released => ctrl.released_keys.push(key), - } - } - WindowEvent::CursorMoved { - position: PhysicalPosition { x, y }, - .. - } => ctrl.cursor_position = Some((x as f32, y as f32)), - WindowEvent::CursorLeft { .. } => ctrl.cursor_position = None, - WindowEvent::MouseWheel { - delta: MouseScrollDelta::LineDelta(x, y), - .. - } => { - ctrl.mouse.wheel_delta.0 += x; - ctrl.mouse.wheel_delta.1 += y; - } - WindowEvent::MouseInput { state, button, .. } => match state { - ElementState::Pressed => ctrl.mouse.pressed_buttons.push(button), - ElementState::Released => ctrl.mouse.released_buttons.push(button), - }, - WindowEvent::RedrawRequested => { - if active { - log::debug!("redraw requested"); - } else { - log::debug!("redraw requested (non-active)"); - - // Wait a while to become active - target.set_control_flow(ControlFlow::wait_duration(WAIT_TIME)); - return None; - } - - let delta_time = time.delta(); - let min_delta_time = ctrl.min_delta_time.get(); - if delta_time < min_delta_time { - let wait = min_delta_time - delta_time; - target.set_control_flow(ControlFlow::wait_duration(wait)); - return None; - } - - time.reset(); - ctrl.delta_time = delta_time; - if let Some(fps) = fps.count(delta_time) { - ctrl.fps = fps; - } - - match upd.update(&ctrl).flow() { - Then::Run => {} - Then::Close => { - log::debug!("close"); - target.exit(); - return None; - } - Then::Fail(err) => { - log::error!("failed: {err:?}"); - target.exit(); - return Some(err); - } - } - - ctrl.clear_state(); - match ctrl.view.output() { - Ok(output) => { - let target = output.target(); - cx.state().draw(target, &upd); - output.present(); - } - Err(SurfaceError::Timeout) => log::info!("suface error: timeout"), - Err(SurfaceError::Outdated) => log::info!("suface error: outdated"), - Err(SurfaceError::Lost) => { - log::info!("suface error: lost"); - ctrl.resize(cx.state()); - } - Err(SurfaceError::OutOfMemory) => { - log::error!("suface error: out of memory"); - target.exit(); - } - } - } - _ => {} - }, - Event::UserEvent(ev) => upd.event(ev), - Event::Suspended => { - log::debug!("suspended"); - active = false; - } - Event::Resumed => { - log::debug!("resumed"); - active = true; - ctrl.view.request_redraw(); - - // Reset the timer before start the loop - time.reset(); - } - _ => {} - } - - None - } -} - /// The control type of the main event loop. pub struct Control { view: View, diff --git a/dunge/src/lib.rs b/dunge/src/lib.rs index 56c780a..cbb8659 100644 --- a/dunge/src/lib.rs +++ b/dunge/src/lib.rs @@ -49,10 +49,10 @@ pub use { }; #[cfg(all(feature = "winit", not(target_arch = "wasm32")))] -pub use crate::window::{window, window_state}; +pub use crate::window::window; #[cfg(all(feature = "winit", target_arch = "wasm32"))] -pub use crate::window::{from_element, window_state_from_element}; +pub use crate::window::from_element; #[cfg(feature = "winit")] pub use crate::{ diff --git a/dunge/src/window.rs b/dunge/src/window.rs index e736c33..2759e1b 100644 --- a/dunge/src/window.rs +++ b/dunge/src/window.rs @@ -3,21 +3,13 @@ use { crate::{ context::{Context, FailedMakeContext}, - el::{self, Loop, LoopError}, + el::{self, LoopError}, element::Element, format::Format, state::{State, Target}, update::Update, }, - std::{ - error, fmt, - future::{Future, IntoFuture}, - marker::PhantomData, - ops, - pin::Pin, - sync::Arc, - task::{self, Poll}, - }, + std::{error, fmt, sync::Arc}, wgpu::{ CreateSurfaceError, Surface, SurfaceConfiguration, SurfaceError, SurfaceTexture, TextureView, @@ -29,226 +21,11 @@ use { }, }; -/// Creates the [window builder](WindowBuilder) to -/// construct the [window](Window). -/// -/// # Example -/// ```rust -/// # fn t() -> impl std::future::Future> { -/// async { -/// let window = dunge::window().with_title("Hello").await?; -/// Ok(window) -/// } -/// # } -/// ``` -#[cfg(all(feature = "winit", not(target_arch = "wasm32")))] -#[deprecated] -pub fn window() -> WindowBuilder { - WindowBuilder::new(Element(())) -} - -/// Creates the [window builder](WindowBuilder) to -/// construct the [window](Window) -/// in the given html element. -#[cfg(all(feature = "winit", target_arch = "wasm32"))] -#[deprecated] -pub fn from_element(id: &str) -> WindowBuilder { - use web_sys::Window; - - let document = web_sys::window() - .as_ref() - .and_then(Window::document) - .expect("get document"); - - let Some(inner) = document.get_element_by_id(id) else { - panic!("an element with id {id:?} not found"); - }; - - let element = Element(inner); - WindowBuilder::new(element) -} - -/// The [window](Window) builder. -/// -/// This builder completes asynchronously, so to create -/// the window object, call `.await` at the end of configuration. -/// -/// # Example -/// ```rust -/// # fn t() -> impl std::future::Future> { -/// async { -/// let window = dunge::window().with_title("Hello").await?; -/// Ok(window) -/// } -/// # } -/// ``` -pub struct WindowBuilder { - element: Option, - title: String, - size: Option<(u32, u32)>, - evty: PhantomData, -} - -impl WindowBuilder { - pub(crate) fn new(element: Element) -> Self { - Self { - element: Some(element), - title: String::default(), - size: Some((600, 600)), - evty: PhantomData, - } - } - - /// Set the title to the window. - pub fn with_title(mut self, title: S) -> Self - where - S: Into, - { - self.title = title.into(); - self - } - - /// Set the window size. - pub fn with_size(mut self, size: (u32, u32)) -> Self { - self.size = Some(size); - self - } - - /// Enables fullscreen for the window. - pub fn with_fullscreen(mut self) -> Self { - self.size = None; - self - } - - fn build(&mut self, cx: Context) -> Result, Error> { - use { - std::mem, - winit::{dpi::PhysicalSize, window::Fullscreen}, - }; - - let lu = Loop::new()?; - let title = mem::take(&mut self.title); - let attrs = window::Window::default_attributes().with_title(title); - let attrs = match self.size { - Some((width, height)) => attrs.with_inner_size(PhysicalSize::new(width, height)), - None => attrs.with_fullscreen(Some(Fullscreen::Borderless(None))), - }; - - let view = todo!(); - Ok(Window { cx, lu, view }) - } -} - -impl IntoFuture for WindowBuilder -where - V: 'static, -{ - type Output = Result, Error>; - type IntoFuture = Build; - - fn into_future(mut self) -> Self::IntoFuture { - let fut = async move { - let cx = Context::new().await?; - self.build(cx) - }; - - Build(Box::pin(fut)) - } -} - -type BoxedFuture = Pin>>; - -pub struct Build(BoxedFuture, Error>>) -where - V: 'static; - -impl Future for Build -where - V: 'static, -{ - type Output = Result, Error>; - - fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll { - self.get_mut().0.as_mut().poll(cx) - } -} - -/// The application window type. -#[deprecated] -pub struct Window -where - V: 'static, -{ - cx: Context, - lu: Loop, - view: View, -} - -impl Window -where - V: 'static, -{ - /// Returns the main dunge context. - pub fn context(&self) -> Context { - self.cx.clone() - } - - /// Creates an event notifier. - pub fn notifier(&self) -> Notifier { - Notifier(self.lu.inner().create_proxy()) - } - - /// Runs the main event loop locally. - /// - /// # Errors - /// Returns [`LoopError`] if the main loop is stopped due to an error. - #[cfg(not(target_arch = "wasm32"))] - pub fn run_local(self, upd: U) -> Result<(), LoopError> - where - U: Update, - { - self.lu.run(self.cx, self.view, upd) - } - - /// Runs the main event loop. - /// - /// # Errors - /// Returns [`LoopError`] if the main loop is stopped due to an error. - /// Note, on wasm platform this method will return `Ok(())` immediately - /// without blocking and will never return an error from here. - pub fn run(self, upd: U) -> Result<(), LoopError> - where - U: Update + 'static, - { - #[cfg(not(target_arch = "wasm32"))] - { - self.lu.run(self.cx, self.view, upd) - } - - #[cfg(target_arch = "wasm32")] - { - self.lu.spawn(self.cx, self.view, upd); - Ok(()) - } - } -} - -impl ops::Deref for Window { - type Target = View; - - fn deref(&self) -> &Self::Target { - &self.view - } -} - pub struct Notifier(EventLoopProxy) where V: 'static; -impl Notifier -where - V: 'static, -{ +impl Notifier { /// Sends a new event to the main loop. /// /// # Errors @@ -330,12 +107,12 @@ impl WindowState { } #[cfg(all(feature = "winit", not(target_arch = "wasm32")))] -pub fn window_state() -> WindowState { +pub fn window() -> WindowState { state(Element(())) } #[cfg(all(feature = "winit", target_arch = "wasm32"))] -pub fn window_state_from_element(id: &str) -> WindowState { +pub fn from_element(id: &str) -> WindowState { use web_sys::Window; let document = web_sys::window() diff --git a/examples/cube/src/main.rs b/examples/cube/src/main.rs index b410612..ac3d214 100644 --- a/examples/cube/src/main.rs +++ b/examples/cube/src/main.rs @@ -1,6 +1,6 @@ fn main() { env_logger::init(); - let ws = dunge::window_state().with_title("Cube"); + let ws = dunge::window().with_title("Cube"); if let Err(err) = helpers::block_on(cube::run(ws)) { eprintln!("error: {err}"); } diff --git a/examples/ssaa/src/main.rs b/examples/ssaa/src/main.rs index 417ac93..4e05b94 100644 --- a/examples/ssaa/src/main.rs +++ b/examples/ssaa/src/main.rs @@ -1,6 +1,6 @@ fn main() { env_logger::init(); - let ws = dunge::window_state().with_title("SSAA"); + let ws = dunge::window().with_title("SSAA"); if let Err(err) = helpers::block_on(ssaa::run(ws)) { eprintln!("error: {err}"); } diff --git a/examples/triangle/src/main.rs b/examples/triangle/src/main.rs index abc5070..e688b07 100644 --- a/examples/triangle/src/main.rs +++ b/examples/triangle/src/main.rs @@ -1,6 +1,6 @@ fn main() { env_logger::init(); - let ws = dunge::window_state().with_title("Triangle"); + let ws = dunge::window().with_title("Triangle"); if let Err(err) = helpers::block_on(triangle::run(ws)) { eprintln!("error: {err}"); } diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs index f370516..af85462 100644 --- a/examples/wasm/src/lib.rs +++ b/examples/wasm/src/lib.rs @@ -24,7 +24,7 @@ pub async fn start() { run = triangle::run; } - let ws = dunge::window_state_from_element("root"); + let ws = dunge::from_element("root"); if let Err(err) = run(ws).await { panic!("error: {err}"); } diff --git a/examples/window/src/main.rs b/examples/window/src/main.rs index da84f06..f0f4b87 100644 --- a/examples/window/src/main.rs +++ b/examples/window/src/main.rs @@ -105,6 +105,6 @@ async fn run() -> Result<(), Error> { }; // Run the window with handlers - dunge::window_state().run_local(cx, dunge::update(upd, draw))?; + dunge::window().run_local(cx, dunge::update(upd, draw))?; Ok(()) }