Skip to content

Commit

Permalink
update winit to 0.30 (SecondHalfGames#178)
Browse files Browse the repository at this point in the history
* update winit to 0.30

* fully commenting out the is_init stuff until further notice

* remove fixmes

* regroup winit imports

* cleanup some

* fix build

* revert removal of is_init bugfix and rename handle_event to handle_window_event

* simplify is_init logic
  • Loading branch information
msparkles authored Jul 13, 2024
1 parent 2536770 commit ed67a94
Show file tree
Hide file tree
Showing 11 changed files with 242 additions and 235 deletions.
3 changes: 2 additions & 1 deletion crates/bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ log = "0.4.17"
pollster = "0.3.0"
profiling = "1.0.6"
tracy-client = { version = "0.15.1", optional = true }

winit = "0.30.0"
wgpu = "0.20.1"
winit = "0.29.2"
297 changes: 170 additions & 127 deletions crates/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ mod custom_texture;
use std::fmt::Write;
use std::time::Instant;

use winit::dpi::LogicalSize;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::WindowBuilder;
use winit::{
application::ApplicationHandler,
event::{StartCause, WindowEvent},
event_loop::{ActiveEventLoop, ControlFlow, EventLoop},
};

use winit::window::{Window, WindowAttributes, WindowId};
use yakui::font::{Font, FontSettings, Fonts};
use yakui::paint::{Texture, TextureFilter, TextureFormat};
use yakui::{ManagedTextureId, Rect, TextureId, UVec2, Vec2};
use yakui::{ManagedTextureId, Rect, TextureId, UVec2, Vec2, Yakui};
use yakui_app::Graphics;

const MONKEY_PNG: &[u8] = include_bytes!("../assets/monkey.png");
const MONKEY_BLURRED_PNG: &[u8] = include_bytes!("../assets/monkey-blurred.png");
Expand All @@ -34,7 +37,150 @@ pub struct ExampleState {
/// `TextureId` represents either a managed texture or a texture owned by
/// the renderer. This image is generated in `custom_texture.rs` and
/// uploaded with wgpu directly.
pub custom: TextureId,
pub custom: Option<TextureId>,
}

struct App<T: ExampleBody> {
state: ExampleState,
yak: Yakui,

attributes: WindowAttributes,
start: Instant,

window: Option<Window>,
app: Option<Graphics>,

body: T,
}

impl<T: ExampleBody> ApplicationHandler for App<T> {
// This is a common indicator that you can create a window.
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
let window = event_loop.create_window(self.attributes.clone()).unwrap();
window.set_ime_allowed(true);

let sample_count = get_sample_count();

let mut app = pollster::block_on(yakui_app::Graphics::new(&window, sample_count));

// By default, yakui_winit will measure the system's scale factor and pass
// it to yakui.
//
// Sometimes, it might be desirable to scale the UI by a different factor,
// like if your game has a "UI scale" option, if you're writing tests, or
// you want to ensure your widgets work at a different scale.
//
// In these examples, setting the YAKUI_FORCE_SCALE environment variable to
// a number will override the automatic scaling.
if let Some(scale) = get_scale_override() {
app.window_mut().set_automatic_scale_factor(false);
self.yak.set_scale_factor(scale);
}

// In these examples, set YAKUI_INSET to force the UI to be contained within
// a sub-viewport with the given edge inset on all sides.
let inset = get_inset_override();
if inset.is_some() {
app.window_mut().set_automatic_viewport(false);
}

let custom = app.renderer.add_texture(
custom_texture::generate(&app.device, &app.queue),
wgpu::FilterMode::Nearest,
wgpu::FilterMode::Nearest,
wgpu::FilterMode::Nearest,
wgpu::AddressMode::ClampToEdge,
);
self.state.custom = Some(custom);

self.app = Some(app);
self.window = Some(window);
}

fn new_events(&mut self, _event_loop: &ActiveEventLoop, cause: winit::event::StartCause) {
if let Some(app) = self.app.as_mut() {
app.is_init = cause == StartCause::Init;
}
}

fn window_event(
&mut self,
event_loop: &ActiveEventLoop,
_window_id: WindowId,
event: WindowEvent,
) {
if self
.app
.as_mut()
.unwrap()
.handle_window_event(&mut self.yak, &event, event_loop)
{
return;
}

// Handle window event.
match event {
WindowEvent::RedrawRequested => {
self.state.time = (Instant::now() - self.start).as_secs_f32();

{
profiling::scope!("Build UI");

// Every frame, call yak.start() to begin building the UI for
// this frame. Any yakui widget calls that happen on this thread
// between start() and finish() will be applied to this yakui
// State.
self.yak.start();

// Call out to the body of the program, passing in a bit of
// shared state that all the examples can use.
self.body.run(&mut self.state);

// Finish building the UI and compute this frame's layout.
self.yak.finish();
}

// The example graphics abstraction calls yak.paint() to get
// access to the underlying PaintDom, which holds all the state
// about how to paint widgets.
self.app.as_mut().unwrap().paint(&mut self.yak, {
let bg = yakui::colors::BACKGROUND_1.to_linear();
wgpu::Color {
r: bg.x.into(),
g: bg.y.into(),
b: bg.z.into(),
a: 1.0,
}
});

profiling::finish_frame!();

self.window.as_ref().unwrap().request_redraw();
}

WindowEvent::MouseInput { state, button, .. } => {
// This print is a handy way to show which mouse events are
// handled by yakui, and which ones will make it to the
// underlying application.
if button == winit::event::MouseButton::Left {
println!("Left mouse button {state:?}");
}
}

WindowEvent::Resized(size) => {
let inset = get_inset_override();
if let Some(inset) = inset {
let size = Vec2::new(size.width as f32, size.height as f32);
self.yak.set_unscaled_viewport(Rect::from_pos_size(
Vec2::splat(inset),
size - Vec2::splat(inset * 2.0),
));
}
}

_ => (),
}
}
}

pub trait ExampleBody: 'static {
Expand All @@ -61,10 +207,10 @@ pub fn start(body: impl ExampleBody) {

init_logging();

pollster::block_on(run(body));
run(body);
}

async fn run(body: impl ExampleBody) {
fn run(body: impl ExampleBody) {
let mut title = "yakui demo".to_owned();

if let Some(scale) = get_scale_override() {
Expand All @@ -73,55 +219,16 @@ async fn run(body: impl ExampleBody) {

// Normal winit setup for an EventLoop and Window.
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new()
.with_title(title)
.with_inner_size(LogicalSize::new(800.0, 600.0))
.build(&event_loop)
.unwrap();

window.set_ime_allowed(true);

let sample_count = get_sample_count();

// yakui_app has a helper for setting up winit and wgpu.
let mut app = yakui_app::Graphics::new(&window, sample_count).await;
let window_attribute = Window::default_attributes().with_title(title);

// Create our yakui state. This is where our UI will be built, laid out, and
// calculations for painting will happen.
let mut yak = yakui::Yakui::new();

// By default, yakui_winit will measure the system's scale factor and pass
// it to yakui.
//
// Sometimes, it might be desirable to scale the UI by a different factor,
// like if your game has a "UI scale" option, if you're writing tests, or
// you want to ensure your widgets work at a different scale.
//
// In these examples, setting the YAKUI_FORCE_SCALE environment variable to
// a number will override the automatic scaling.
if let Some(scale) = get_scale_override() {
app.window_mut().set_automatic_scale_factor(false);
yak.set_scale_factor(scale);
}

// In these examples, set YAKUI_INSET to force the UI to be contained within
// a sub-viewport with the given edge inset on all sides.
let inset = get_inset_override();
if inset.is_some() {
app.window_mut().set_automatic_viewport(false);
}

// Preload some textures for the examples to use.
let monkey = yak.add_texture(load_texture(MONKEY_PNG, TextureFilter::Linear));
let monkey_blurred = yak.add_texture(load_texture(MONKEY_BLURRED_PNG, TextureFilter::Linear));
let brown_inlay = yak.add_texture(load_texture(BROWN_INLAY_PNG, TextureFilter::Nearest));
let custom = app.renderer.add_texture(
custom_texture::generate(&app.device, &app.queue),
wgpu::FilterMode::Nearest,
wgpu::FilterMode::Nearest,
wgpu::FilterMode::Nearest,
wgpu::AddressMode::ClampToEdge,
);

// Add a custom font for some of the examples.
let fonts = yak.dom().get_global_or_init(Fonts::default);
Expand All @@ -134,89 +241,25 @@ async fn run(body: impl ExampleBody) {
fonts.add(font, Some("monospace"));

// Set up some default state that we'll modify later.
let mut state = ExampleState {
time: 0.0,
monkey,
monkey_blurred,
brown_inlay,
custom,
let mut app = App {
yak,
attributes: window_attribute,
start: Instant::now(),
state: ExampleState {
time: 0.0,
monkey,
monkey_blurred,
brown_inlay,
custom: None,
},
window: None,
app: None,
body,
};

let start = Instant::now();

event_loop.set_control_flow(ControlFlow::Poll);
event_loop
.run(move |event, elwt| {
if app.handle_event(&mut yak, &event, elwt) {
return;
}

match event {
Event::AboutToWait => {
state.time = (Instant::now() - start).as_secs_f32();

{
profiling::scope!("Build UI");

// Every frame, call yak.start() to begin building the UI for
// this frame. Any yakui widget calls that happen on this thread
// between start() and finish() will be applied to this yakui
// State.
yak.start();

// Call out to the body of the program, passing in a bit of
// shared state that all the examples can use.
body.run(&mut state);

// Finish building the UI and compute this frame's layout.
yak.finish();
}

// The example graphics abstraction calls yak.paint() to get
// access to the underlying PaintDom, which holds all the state
// about how to paint widgets.
app.paint(&mut yak, {
let bg = yakui::colors::BACKGROUND_1.to_linear();
wgpu::Color {
r: bg.x.into(),
g: bg.y.into(),
b: bg.z.into(),
a: 1.0,
}
});

profiling::finish_frame!();
}

Event::WindowEvent {
event: WindowEvent::MouseInput { state, button, .. },
..
} => {
// This print is a handy way to show which mouse events are
// handled by yakui, and which ones will make it to the
// underlying application.
if button == winit::event::MouseButton::Left {
println!("Left mouse button {state:?}");
}
}

Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
if let Some(inset) = inset {
let size = Vec2::new(size.width as f32, size.height as f32);
yak.set_unscaled_viewport(Rect::from_pos_size(
Vec2::splat(inset),
size - Vec2::splat(inset * 2.0),
));
}
}

_ => (),
}
})
.unwrap();
event_loop.run_app(&mut app).unwrap();
}

/// This function takes some bytes and turns it into a yakui `Texture` object so
Expand Down
2 changes: 1 addition & 1 deletion crates/demo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ env_logger = "0.10.0"
log = "0.4.17"
pollster = "0.3.0"
wgpu = { version = "0.20.1", features = ["webgl"] }
winit = "0.29.2"
winit = "0.30.0"

[target.'cfg(target_arch = "wasm32")'.dependencies]
console_log = "0.2.1"
Expand Down
Loading

0 comments on commit ed67a94

Please sign in to comment.