From 364ad3145372df4a4142c642d6a0f6375d461bc7 Mon Sep 17 00:00:00 2001 From: nanoqsh Date: Wed, 10 Jan 2024 01:29:57 +0600 Subject: [PATCH] Refactor --- dunge/src/init.rs | 31 ++++++++++-------------- dunge/src/window.rs | 44 +++++++++++++++++++++++++++++++---- examples/triangle/src/main.rs | 6 ++--- 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/dunge/src/init.rs b/dunge/src/init.rs index b7e2163..f555bb4 100644 --- a/dunge/src/init.rs +++ b/dunge/src/init.rs @@ -7,36 +7,29 @@ use { }; #[cfg(feature = "winit")] -use crate::window::{self, Window, WindowBuilder}; +use crate::window::WindowBuilder; -fn instance() -> Instance { +pub(crate) async fn make() -> Result<(Context, Instance), context::Error> { use wgpu::{Backends, InstanceDescriptor}; - let desc = InstanceDescriptor { - backends: Backends::PRIMARY, - ..Default::default() + let instance = { + let desc = InstanceDescriptor { + backends: Backends::PRIMARY, + ..Default::default() + }; + + Instance::new(desc) }; - Instance::new(desc) + let state = State::new(&instance).await?; + Ok((Context::new(state), instance)) } pub async fn context() -> Result { - let instance = instance(); - let state = State::new(&instance).await?; - Ok(Context::new(state)) + make().await.map(|(cx, _)| cx) } #[cfg(feature = "winit")] pub fn window() -> WindowBuilder { WindowBuilder::new() } - -#[cfg(feature = "winit")] -impl WindowBuilder { - pub async fn make(self) -> Result { - let instance = instance(); - let state = State::new(&instance).await?; - let cx = Context::new(state); - self.build(cx, &instance) - } -} diff --git a/dunge/src/window.rs b/dunge/src/window.rs index be157a9..b93d368 100644 --- a/dunge/src/window.rs +++ b/dunge/src/window.rs @@ -3,10 +3,16 @@ use { context::{self, Context}, el::Loop, format::Format, + init, state::{RenderView, State}, update::Update, }, - std::{error, fmt}, + std::{ + error, fmt, + future::{Future, IntoFuture}, + pin::Pin, + task::{self, Poll}, + }, wgpu::{ CreateSurfaceError, Instance, Surface, SurfaceConfiguration, SurfaceError, SurfaceTexture, TextureView, @@ -51,12 +57,16 @@ impl WindowBuilder { self } - pub(crate) fn build(self, cx: Context, instance: &Instance) -> Result { - use winit::{dpi::PhysicalSize, window::Fullscreen}; + fn build(&mut self, cx: Context, instance: &Instance) -> Result { + use { + std::mem, + winit::{dpi::PhysicalSize, window::Fullscreen}, + }; let el = Loop::new()?; let inner = { - let builder = window::WindowBuilder::new().with_title(self.title); + let title = mem::take(&mut self.title); + let builder = window::WindowBuilder::new().with_title(title); let builder = match self.size { Some((width, height)) => builder.with_inner_size(PhysicalSize::new(width, height)), None => builder.with_fullscreen(Some(Fullscreen::Borderless(None))), @@ -70,6 +80,32 @@ impl WindowBuilder { } } +impl IntoFuture for WindowBuilder { + type Output = Result; + type IntoFuture = Build; + + fn into_future(mut self) -> Self::IntoFuture { + let fut = async move { + let (cx, instance) = init::make().await?; + self.build(cx, &instance) + }; + + Build(Box::pin(fut)) + } +} + +type BoxFuture = Pin>>; + +pub struct Build(BoxFuture>); + +impl Future for Build { + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll { + self.get_mut().0.as_mut().poll(cx) + } +} + pub struct Window { cx: Context, el: Loop, diff --git a/examples/triangle/src/main.rs b/examples/triangle/src/main.rs index b66aa8f..0b9cc1d 100644 --- a/examples/triangle/src/main.rs +++ b/examples/triangle/src/main.rs @@ -2,12 +2,12 @@ type Error = Box; fn main() { env_logger::init(); - if let Err(err) = run() { + if let Err(err) = helpers::block_on(run()) { eprintln!("error: {err}"); } } -fn run() -> Result<(), Error> { +async fn run() -> Result<(), Error> { use { dunge::{ color::Rgba, @@ -32,7 +32,7 @@ fn run() -> Result<(), Error> { } }; - let window = helpers::block_on(dunge::window().with_title("Triangle").make())?; + let window = dunge::window().with_title("Triangle").await?; let cx = window.context(); let shader = cx.make_shader(triangle); let layer = cx.make_layer(window.format(), &shader);