diff --git a/dunge/src/el.rs b/dunge/src/el.rs index cf75c29..b588760 100644 --- a/dunge/src/el.rs +++ b/dunge/src/el.rs @@ -4,18 +4,30 @@ use { state::State, time::{Fps, Time}, update::Update, - window::View, + window::{self, View}, }, std::{cell::Cell, error, fmt, ops, time::Duration}, wgpu::SurfaceError, winit::{ + application::ApplicationHandler, error::EventLoopError, event, - event_loop::{self, EventLoop}, + event_loop::{self, ActiveEventLoop, EventLoop}, keyboard, + window::WindowId, }, }; +pub fn run_local(view: View, upd: U) -> Result<(), window::Error> +where + U: Update, +{ + let lu = EventLoop::with_user_event().build()?; + let mut handler = Handler::new(view, upd); + lu.run_app(&mut handler)?; + Ok(()) +} + /// Code representing the location of a physical key. pub type KeyCode = keyboard::KeyCode; @@ -25,6 +37,7 @@ pub type SmolStr = keyboard::SmolStr; /// Describes a button of a mouse controller. pub type MouseButton = event::MouseButton; +#[deprecated] pub(crate) struct Loop(EventLoop) where V: 'static; @@ -94,10 +107,51 @@ impl error::Error for LoopError { } } +struct Handler { + ctrl: Control, + upd: U, +} + +impl Handler { + fn new(view: View, upd: U) -> Self { + let ctrl = Control { + view, + 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![]), + }, + }; + + Self { ctrl, upd } + } +} + +impl ApplicationHandler for Handler +where + U: Update, +{ + fn resumed(&mut self, el: &ActiveEventLoop) { + todo!() + } + + fn window_event(&mut self, el: &ActiveEventLoop, id: WindowId, ev: event::WindowEvent) { + todo!() + } +} + type Event = event::Event; type Target = event_loop::ActiveEventLoop; type Failure = Option>; +#[deprecated] fn handle(cx: Context, view: View, mut upd: U) -> impl FnMut(Event, &Target) -> Failure where U: Update, @@ -112,7 +166,7 @@ where const WAIT_TIME: Duration = Duration::from_millis(100); let mut ctrl = Control { - view, + view: View::new(unimplemented!()), resized: None, min_delta_time: Cell::new(Duration::from_secs_f32(1. / 60.)), delta_time: Duration::ZERO, diff --git a/dunge/src/update.rs b/dunge/src/update.rs index df15031..eecb0d9 100644 --- a/dunge/src/update.rs +++ b/dunge/src/update.rs @@ -86,7 +86,7 @@ use crate::{ /// pub trait Update: Draw { type Flow: Flow; - type Event; + type Event: 'static; fn update(&mut self, ctrl: &Control) -> Self::Flow; fn event(&mut self, _: Self::Event) {} } @@ -129,6 +129,7 @@ pub fn update_with_event( where U: FnMut(&mut S, &Control) -> F, E: FnMut(&mut S, V), + V: 'static, F: Flow, D: Fn(&S, Frame), { @@ -155,6 +156,7 @@ where where U: FnMut(&mut S, &Control) -> F, E: FnMut(&mut S, V), + V: 'static, F: Flow, D: Fn(&S, Frame), { diff --git a/dunge/src/window.rs b/dunge/src/window.rs index e2df436..9811bb6 100644 --- a/dunge/src/window.rs +++ b/dunge/src/window.rs @@ -24,8 +24,8 @@ use { }, winit::{ error::{EventLoopError, OsError}, - event_loop::{EventLoopClosed, EventLoopProxy}, - window::{self, WindowId}, + event_loop::{ActiveEventLoop, EventLoopClosed, EventLoopProxy}, + window::{self, WindowAttributes, WindowId}, }, }; @@ -80,6 +80,7 @@ pub fn from_element(id: &str) -> WindowBuilder { /// } /// # } /// ``` +#[deprecated] pub struct WindowBuilder { element: Option, title: String, @@ -125,22 +126,18 @@ impl WindowBuilder { }; let lu = Loop::new()?; - let inner = { - 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))), - }; - - Arc::new(lu.inner().create_window(attrs)?) + 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 = { let el = self.element.take().expect("take the element once"); - el.set_canvas(&inner); - el.set_window_size(&inner); - View::new(cx.state(), Inner(Some(inner)), el)? + // el.set_canvas(&inner); + // el.set_window_size(&inner); + View::new(WindowState { attrs, el }) }; Ok(Window { cx, lu, view }) @@ -182,6 +179,7 @@ where } /// The application window type. +#[deprecated] pub struct Window where V: 'static, @@ -248,14 +246,6 @@ impl ops::Deref for Window { } } -struct Inner(Option>); - -impl Inner { - fn get(&self) -> &Arc { - self.0.as_ref().expect("the window should be initialized") - } -} - pub struct Notifier(EventLoopProxy) where V: 'static; @@ -273,15 +263,135 @@ where } } +pub struct WindowState { + attrs: WindowAttributes, + el: Element, +} + +enum Init { + Empty(Box), + Active(Inner), +} + +impl Init { + fn get(&self) -> &Inner { + match self { + Self::Empty(_) => panic!("the window should be initialized"), + Self::Active(inner) => inner, + } + } + + fn get_mut(&mut self) -> &mut Inner { + match self { + Self::Empty(_) => panic!("the window should be initialized"), + Self::Active(inner) => inner, + } + } +} + pub struct View { - conf: SurfaceConfiguration, - surface: Surface<'static>, - inner: Inner, + init: Init, + id: WindowId, el: Element, + format: Format, + size: (u32, u32), } impl View { - fn new(state: &State, inner: Inner, el: Element) -> Result { + pub fn new(state: WindowState) -> Self { + Self { + init: Init::Empty(Box::new(state.attrs)), + id: WindowId::from(u64::MAX), + el: state.el, + format: Format::default(), + size: (0, 0), + } + } + + fn init(&mut self, state: &State, active: &ActiveEventLoop) -> Result<&mut Inner, Error> { + match &mut self.init { + Init::Empty(attrs) => { + let attrs = (**attrs).clone(); + let window = active.create_window(attrs)?; + self.id = window.id(); + + let inner = Inner::new(state, window)?; + self.format = inner.format(); + self.size = inner.size(); + self.init = Init::Active(inner); + } + Init::Active(_) => {} + } + + match &mut self.init { + Init::Empty(_) => unreachable!(), + Init::Active(inner) => Ok(inner), + } + } + + pub fn window(&self) -> &Arc { + &self.init.get().window + } + + pub fn format(&self) -> Format { + self.format + } + + pub fn size(&self) -> (u32, u32) { + self.size + } + + pub(crate) fn id(&self) -> WindowId { + self.id + } + + pub(crate) fn request_redraw(&self) { + self.init.get().window.request_redraw(); + } + + pub(crate) fn output(&self) -> Result { + use wgpu::TextureViewDescriptor; + + let inner = self.init.get(); + let format = Format::from_wgpu(inner.conf.format); + let output = inner.surface.get_current_texture()?; + let view = { + let desc = TextureViewDescriptor::default(); + output.texture.create_view(&desc) + }; + + Ok(Output { + view, + format, + output, + }) + } + + pub(crate) fn set_window_size(&self) { + let inner = self.init.get(); + self.el.set_window_size(&inner.window); + } + + pub(crate) fn resize(&mut self, state: &State) { + let inner = self.init.get_mut(); + let size = inner.window.inner_size(); + if size.width > 0 && size.height > 0 { + inner.conf.width = size.width; + inner.conf.height = size.height; + inner.surface.configure(state.device(), &inner.conf); + self.size = inner.size(); + } + } +} + +struct Inner { + conf: SurfaceConfiguration, + surface: Surface<'static>, + window: Arc, +} + +impl Inner { + fn new(state: &State, window: window::Window) -> Result { use wgpu::*; const SUPPORTED_FORMATS: [Format; 4] = [ @@ -291,7 +401,8 @@ impl View { Format::BgrAlpha, ]; - let surface = state.instance().create_surface(Arc::clone(inner.get()))?; + let window = Arc::new(window); + let surface = state.instance().create_surface(Arc::clone(&window))?; let conf = { let caps = surface.get_capabilities(state.adapter()); let format = SUPPORTED_FORMATS.into_iter().find_map(|format| { @@ -304,7 +415,7 @@ impl View { return Err(ErrorKind::UnsupportedSurface.into()); }; - let size = inner.get().inner_size(); + let size = window.inner_size(); SurfaceConfiguration { usage: TextureUsages::RENDER_ATTACHMENT, format, @@ -321,59 +432,17 @@ impl View { Ok(Self { conf, surface, - inner, - el, + window, }) } - pub fn window(&self) -> &Arc { - self.inner.get() - } - - pub fn format(&self) -> Format { + fn format(&self) -> Format { Format::from_wgpu(self.conf.format) } - pub fn size(&self) -> (u32, u32) { + fn size(&self) -> (u32, u32) { (self.conf.width, self.conf.height) } - - pub(crate) fn id(&self) -> WindowId { - self.inner.get().id() - } - - pub(crate) fn request_redraw(&self) { - self.inner.get().request_redraw(); - } - - pub(crate) fn output(&self) -> Result { - use wgpu::TextureViewDescriptor; - - let output = self.surface.get_current_texture()?; - let view = { - let desc = TextureViewDescriptor::default(); - output.texture.create_view(&desc) - }; - - Ok(Output { - view, - format: self.format(), - output, - }) - } - - pub(crate) fn set_window_size(&self) { - self.el.set_window_size(self.inner.get()); - } - - pub(crate) fn resize(&mut self, state: &State) { - let size = self.inner.get().inner_size(); - if size.width > 0 && size.height > 0 { - self.conf.width = size.width; - self.conf.height = size.height; - self.surface.configure(state.device(), &self.conf); - } - } } pub(crate) struct Output {