Remove indentation in fill.rs helper

This commit is contained in:
Mads Marquart
2025-12-13 22:01:56 +01:00
parent 0f2d59cbba
commit 7864d02077

View File

@@ -7,123 +7,109 @@
//! The `softbuffer` crate is used, largely because of its ease of use. `glutin` or `wgpu` could //! The `softbuffer` crate is used, largely because of its ease of use. `glutin` or `wgpu` could
//! also be used to fill the window buffer, but they are more complicated to use. //! also be used to fill the window buffer, but they are more complicated to use.
#[allow(unused_imports)] use std::cell::RefCell;
pub use platform::cleanup_window; use std::collections::HashMap;
#[allow(unused_imports)] use std::mem;
pub use platform::fill_window; use std::mem::ManuallyDrop;
#[allow(unused_imports)] use std::num::NonZeroU32;
pub use platform::fill_window_with_animated_color; #[cfg(not(web_platform))]
#[allow(unused_imports)] use std::time::Instant;
pub use platform::fill_window_with_color;
mod platform { use softbuffer::{Context, Surface};
use std::cell::RefCell; #[cfg(web_platform)]
use std::collections::HashMap; use web_time::Instant;
use std::mem; use winit::window::{Window, WindowId};
use std::mem::ManuallyDrop;
use std::num::NonZeroU32;
#[cfg(not(web_platform))]
use std::time::Instant;
use softbuffer::{Context, Surface}; thread_local! {
#[cfg(web_platform)] // NOTE: You should never do things like that, create context and drop it before
use web_time::Instant; // you drop the event loop. We do this for brevity to not blow up examples. We use
use winit::window::{Window, WindowId}; // ManuallyDrop to prevent destructors from running.
//
// A static, thread-local map of graphics contexts to open windows.
static GC: ManuallyDrop<RefCell<Option<GraphicsContext>>> = const { ManuallyDrop::new(RefCell::new(None)) };
}
thread_local! { /// The graphics context used to draw to a window.
// NOTE: You should never do things like that, create context and drop it before struct GraphicsContext {
// you drop the event loop. We do this for brevity to not blow up examples. We use /// The global softbuffer context.
// ManuallyDrop to prevent destructors from running. context: RefCell<Context<&'static dyn Window>>,
//
// A static, thread-local map of graphics contexts to open windows.
static GC: ManuallyDrop<RefCell<Option<GraphicsContext>>> = const { ManuallyDrop::new(RefCell::new(None)) };
}
/// The graphics context used to draw to a window. /// The hash map of window IDs to surfaces.
struct GraphicsContext { surfaces: HashMap<WindowId, Surface<&'static dyn Window, &'static dyn Window>>,
/// The global softbuffer context. }
context: RefCell<Context<&'static dyn Window>>,
/// The hash map of window IDs to surfaces. impl GraphicsContext {
surfaces: HashMap<WindowId, Surface<&'static dyn Window, &'static dyn Window>>, fn new(w: &dyn Window) -> Self {
} Self {
context: RefCell::new(
impl GraphicsContext { Context::new(unsafe { mem::transmute::<&'_ dyn Window, &'static dyn Window>(w) })
fn new(w: &dyn Window) -> Self {
Self {
context: RefCell::new(
Context::new(unsafe {
mem::transmute::<&'_ dyn Window, &'static dyn Window>(w)
})
.expect("Failed to create a softbuffer context"), .expect("Failed to create a softbuffer context"),
), ),
surfaces: HashMap::new(), surfaces: HashMap::new(),
}
}
fn create_surface(
&mut self,
window: &dyn Window,
) -> &mut Surface<&'static dyn Window, &'static dyn Window> {
self.surfaces.entry(window.id()).or_insert_with(|| {
Surface::new(&self.context.borrow(), unsafe {
mem::transmute::<&'_ dyn Window, &'static dyn Window>(window)
})
.expect("Failed to create a softbuffer surface")
})
}
fn destroy_surface(&mut self, window: &dyn Window) {
self.surfaces.remove(&window.id());
} }
} }
pub fn fill_window_with_color(window: &dyn Window, color: u32) { fn create_surface(
GC.with(|gc| { &mut self,
let size = window.surface_size(); window: &dyn Window,
let (Some(width), Some(height)) = ) -> &mut Surface<&'static dyn Window, &'static dyn Window> {
(NonZeroU32::new(size.width), NonZeroU32::new(size.height)) self.surfaces.entry(window.id()).or_insert_with(|| {
else { Surface::new(&self.context.borrow(), unsafe {
return; mem::transmute::<&'_ dyn Window, &'static dyn Window>(window)
}; })
.expect("Failed to create a softbuffer surface")
// Either get the last context used or create a new one.
let mut gc = gc.borrow_mut();
let surface =
gc.get_or_insert_with(|| GraphicsContext::new(window)).create_surface(window);
// Fill a buffer with a solid color
surface.resize(width, height).expect("Failed to resize the softbuffer surface");
let mut buffer = surface.buffer_mut().expect("Failed to get the softbuffer buffer");
buffer.fill(color);
buffer.present().expect("Failed to present the softbuffer buffer");
}) })
} }
#[allow(dead_code)] fn destroy_surface(&mut self, window: &dyn Window) {
pub fn fill_window(window: &dyn Window) { self.surfaces.remove(&window.id());
fill_window_with_color(window, 0xff181818);
}
#[allow(dead_code)]
pub fn fill_window_with_animated_color(window: &dyn Window, start: Instant) {
let time = start.elapsed().as_secs_f32() * 1.5;
let blue = (time.sin() * 255.0) as u32;
let green = ((time.cos() * 255.0) as u32) << 8;
let red = ((1.0 - time.sin() * 255.0) as u32) << 16;
let color = red | green | blue;
fill_window_with_color(window, color);
}
#[allow(dead_code)]
pub fn cleanup_window(window: &dyn Window) {
GC.with(|gc| {
let mut gc = gc.borrow_mut();
if let Some(context) = gc.as_mut() {
context.destroy_surface(window);
}
});
} }
} }
pub fn fill_window_with_color(window: &dyn Window, color: u32) {
GC.with(|gc| {
let size = window.surface_size();
let (Some(width), Some(height)) =
(NonZeroU32::new(size.width), NonZeroU32::new(size.height))
else {
return;
};
// Either get the last context used or create a new one.
let mut gc = gc.borrow_mut();
let surface = gc.get_or_insert_with(|| GraphicsContext::new(window)).create_surface(window);
// Fill a buffer with a solid color
surface.resize(width, height).expect("Failed to resize the softbuffer surface");
let mut buffer = surface.buffer_mut().expect("Failed to get the softbuffer buffer");
buffer.fill(color);
buffer.present().expect("Failed to present the softbuffer buffer");
})
}
#[allow(dead_code)]
pub fn fill_window(window: &dyn Window) {
fill_window_with_color(window, 0xff181818);
}
#[allow(dead_code)]
pub fn fill_window_with_animated_color(window: &dyn Window, start: Instant) {
let time = start.elapsed().as_secs_f32() * 1.5;
let blue = (time.sin() * 255.0) as u32;
let green = ((time.cos() * 255.0) as u32) << 8;
let red = ((1.0 - time.sin() * 255.0) as u32) << 16;
let color = red | green | blue;
fill_window_with_color(window, color);
}
#[allow(dead_code)]
pub fn cleanup_window(window: &dyn Window) {
GC.with(|gc| {
let mut gc = gc.borrow_mut();
if let Some(context) = gc.as_mut() {
context.destroy_surface(window);
}
});
}