Struct WinitIo

Source
pub struct WinitIo { /* private fields */ }
Expand description

A Thyme Input/Output adapter for winit.

This adapter handles events from winit and sends them to the Thyme Context. WindowEvents should be passed to this handler, assuming Context.wants_mouse returns true for the given frame.

§Example

fn main_loop(event_loop: winit::EventLoop<()>, thyme: thyme::Context) {
    event_loop.run(move |event, _, control_flow| match event {
        Event::MainEventsCleared => {
            // Renderer specific code here

            let mut ui = context.create_frame();
            // create UI here

            // draw the frame and finish up rendering here
        }
        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit,
        event => {
            io.handle_event(&mut context, &event);
        }
    })
}

Implementations§

Source§

impl WinitIo

Source

pub fn new<T>( event_loop: &EventLoop<T>, logical_display_size: Point, ) -> Result<WinitIo, WinitError>

Creates a new adapter from the given EventLoop, with the specified initial display size, in logical pixels. This may change over time.

Examples found in repository?
examples/demo_glium.rs (line 29)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    use glium::glutin::{window::WindowBuilder};
12    use glium::{Display, Surface};
13
14    // initialize our very basic logger so error messages go to stdout
15    thyme::log::init(log::Level::Warn).unwrap();
16
17    let window_size = [1280.0, 720.0];
18    let events_loop = EventLoop::new();
19
20    // create glium display
21    let builder = WindowBuilder::new()
22        .with_title("Thyme Demo")
23        .with_inner_size(glium::glutin::dpi::LogicalSize::new(window_size[0], window_size[1]));
24    let context = glium::glutin::ContextBuilder::new();
25    let display = Display::new(builder, context, &events_loop)?;
26
27    // create thyme backend
28    let mut renderer = thyme::GliumRenderer::new(&display)?;
29    let mut io = thyme::WinitIo::new(&events_loop, window_size.into())?;
30    let mut context_builder = thyme::ContextBuilder::with_defaults();
31
32    demo::register_assets(&mut context_builder);
33
34    let mut context = context_builder.build(&mut renderer, &mut io)?;
35
36    let mut party = demo::Party::default();
37
38    let mut last_frame = std::time::Instant::now();
39    let frame_time = std::time::Duration::from_millis(16);
40    
41    // run main loop
42    events_loop.run(move |event, _, control_flow| match event {
43        Event::MainEventsCleared => {
44            if std::time::Instant::now() > last_frame + frame_time {
45                display.gl_window().window().request_redraw();
46            }
47            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
48        },
49        Event::RedrawRequested(_) => {
50            last_frame = std::time::Instant::now();
51
52            party.check_context_changes(&mut context, &mut renderer);
53
54            let mut target = display.draw();
55            target.clear_color(0.21404, 0.21404, 0.21404, 1.0); // manual sRGB conversion for 0.5
56
57            bench::run("thyme", || {
58                display.gl_window().window().set_cursor_visible(!party.theme_has_mouse_cursor());
59
60                let mut ui = context.create_frame();
61
62                bench::run("frame", || {
63                    demo::build_ui(&mut ui, &mut party);
64                });
65
66                bench::run("draw", || {
67                    renderer.draw_frame(&mut target, ui).unwrap();
68                });
69            });
70
71            target.finish().unwrap();
72        },
73        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit,
74        event => {
75            io.handle_event(&mut context, &event);
76        }
77    })
78}
More examples
Hide additional examples
examples/demo_gl.rs (line 50)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    // initialize our very basic logger so error messages go to stdout
18    thyme::log::init(log::Level::Warn).unwrap();
19
20    // create glium display
21    let event_loop = glutin::event_loop::EventLoop::new();
22    let window_builder = glutin::window::WindowBuilder::new()
23        .with_title("Hello world!")
24        .with_inner_size(glutin::dpi::LogicalSize::new(1280.0, 720.0));
25
26    let windowed_context = glutin::ContextBuilder::new()
27        .with_gl(glutin::GlRequest::Specific(
28            glutin::Api::OpenGl,
29            (OPENGL_MAJOR_VERSION, OPENGL_MINOR_VERSION),
30        ))
31        .build_windowed(window_builder, &event_loop)?;
32
33    let windowed_context = unsafe {
34        windowed_context
35            .make_current().map_err(|(_context, e)| e)?
36    };
37
38    {
39        let gl_context = windowed_context.context();
40        gl::load_with(|ptr| gl_context.get_proc_address(ptr) as *const _)
41    }
42
43    // create thyme backend
44    let mut renderer = thyme::GLRenderer::new();
45    let mut context_builder = thyme::ContextBuilder::with_defaults();
46
47    demo::register_assets(&mut context_builder);
48
49    let window_size = [1280.0, 720.0];
50    let mut io = thyme::WinitIo::new(&event_loop, window_size.into())?;
51    let mut context = context_builder.build(&mut renderer, &mut io)?;
52    let mut party = demo::Party::default();
53
54    let mut last_frame = std::time::Instant::now();
55    let frame_time = std::time::Duration::from_millis(16);
56
57    // run main loop
58    event_loop.run(move |event, _, control_flow| match event {
59        Event::MainEventsCleared => {
60            if std::time::Instant::now() > last_frame + frame_time {
61                windowed_context.window().request_redraw();
62            }
63            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
64        }
65        Event::RedrawRequested(_) => {
66            last_frame = std::time::Instant::now();
67
68            party.check_context_changes(&mut context, &mut renderer);
69
70            renderer.clear_color(0.5, 0.5, 0.5, 1.0);
71
72            bench::run("thyme", || {
73                windowed_context.window().set_cursor_visible(!party.theme_has_mouse_cursor());
74
75                let mut ui = context.create_frame();
76
77                bench::run("frame", || {
78                    demo::build_ui(&mut ui, &mut party);
79                });
80
81                bench::run("draw", || {
82                    renderer.draw_frame(ui);
83                });
84            });
85
86            windowed_context.swap_buffers().unwrap();
87        }
88        Event::WindowEvent {
89            event: WindowEvent::CloseRequested,
90            ..
91        } => *control_flow = ControlFlow::Exit,
92        event => {
93            io.handle_event(&mut context, &event);
94        }
95    })
96}
examples/demo_wgpu.rs (line 40)
12fn main() -> Result<(), Box<dyn std::error::Error>> {
13    use winit::{ window::WindowBuilder };
14
15    // initialize our very basic logger so error messages go to stdout
16    thyme::log::init(log::Level::Warn).unwrap();
17
18    let window_size = [1280.0, 720.0];
19    let events_loop = EventLoop::new();
20
21    // create winit window
22    let window = WindowBuilder::new()
23        .with_title("Thyme WGPU Demo")
24        .with_inner_size(winit::dpi::LogicalSize::new(window_size[0], window_size[1]))
25        .build(&events_loop)?;
26
27    // setup WGPU
28    let instance_desc = wgpu::InstanceDescriptor {
29        backends: wgpu::Backends::PRIMARY,
30        dx12_shader_compiler: wgpu::Dx12Compiler::Fxc,
31    };
32    let instance = wgpu::Instance::new(instance_desc);
33    let surface = unsafe { instance.create_surface(&window).map_err(thyme::Error::WgpuSurface)? };
34    let (_adapter, device, queue) = futures::executor::block_on(setup_wgpu(&instance, &surface));
35    let surface_config = get_surface_config(window_size[0] as u32, window_size[1] as u32);
36    surface.configure(&device, &surface_config);
37
38    // create thyme backend
39    let mut renderer = thyme::WgpuRenderer::new(Arc::clone(&device), Arc::clone(&queue));
40    let mut io = thyme::WinitIo::new(&events_loop, window_size.into())?;
41    let mut context_builder = thyme::ContextBuilder::with_defaults();
42
43    demo::register_assets(&mut context_builder);
44
45    let mut context = context_builder.build(&mut renderer, &mut io)?;
46
47    let mut party = demo::Party::default();
48
49    let mut last_frame = std::time::Instant::now();
50    let frame_time = std::time::Duration::from_millis(16);
51
52    // run main loop
53    events_loop.run(move |event, _, control_flow| match event {
54        Event::MainEventsCleared => {
55            if std::time::Instant::now() > last_frame + frame_time {
56                window.request_redraw();
57            }
58            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
59        },
60        Event::RedrawRequested(_) => {
61            last_frame = std::time::Instant::now();
62
63            party.check_context_changes(&mut context, &mut renderer);
64
65            let frame = surface.get_current_texture().unwrap();
66            let view = frame.texture.create_view(&wgpu::TextureViewDescriptor::default());
67            let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
68
69            bench::run("thyme", || {
70                window.set_cursor_visible(!party.theme_has_mouse_cursor());
71
72                let mut ui = context.create_frame();
73
74                bench::run("frame", || {
75                    demo::build_ui(&mut ui, &mut party);
76                });
77
78                bench::run("draw", || {
79                    {
80                        let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
81                            label: None,
82                            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
83                                view: &view,
84                                resolve_target: None,
85                                ops: wgpu::Operations {
86                                    load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.5, g: 0.5, b: 0.5, a: 1.0 }),
87                                    store: true,
88                                },
89                            })],
90                            depth_stencil_attachment: None,
91                        });
92
93                        renderer.draw_frame(ui, &mut render_pass);
94                    }
95
96                    queue.submit(Some(encoder.finish()));
97                    frame.present();
98                });
99            });
100        },
101        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit,
102        event => {
103            // recreate swap chain on resize, but also still pass the event to thyme
104            if let Event::WindowEvent { event: WindowEvent::Resized(_), ..} = event {
105                let size: (u32, u32) = window.inner_size().into();
106
107                let surface_config = get_surface_config(size.0, size.1);
108                surface.configure(&device, &surface_config);
109            }
110
111            io.handle_event(&mut context, &event);
112        }
113    })
114}
Source

pub fn handle_event<T>(&mut self, context: &mut Context, event: &Event<'_, T>)

Handles a winit Event and passes it to the Thyme Context.

Examples found in repository?
examples/demo_glium.rs (line 75)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    use glium::glutin::{window::WindowBuilder};
12    use glium::{Display, Surface};
13
14    // initialize our very basic logger so error messages go to stdout
15    thyme::log::init(log::Level::Warn).unwrap();
16
17    let window_size = [1280.0, 720.0];
18    let events_loop = EventLoop::new();
19
20    // create glium display
21    let builder = WindowBuilder::new()
22        .with_title("Thyme Demo")
23        .with_inner_size(glium::glutin::dpi::LogicalSize::new(window_size[0], window_size[1]));
24    let context = glium::glutin::ContextBuilder::new();
25    let display = Display::new(builder, context, &events_loop)?;
26
27    // create thyme backend
28    let mut renderer = thyme::GliumRenderer::new(&display)?;
29    let mut io = thyme::WinitIo::new(&events_loop, window_size.into())?;
30    let mut context_builder = thyme::ContextBuilder::with_defaults();
31
32    demo::register_assets(&mut context_builder);
33
34    let mut context = context_builder.build(&mut renderer, &mut io)?;
35
36    let mut party = demo::Party::default();
37
38    let mut last_frame = std::time::Instant::now();
39    let frame_time = std::time::Duration::from_millis(16);
40    
41    // run main loop
42    events_loop.run(move |event, _, control_flow| match event {
43        Event::MainEventsCleared => {
44            if std::time::Instant::now() > last_frame + frame_time {
45                display.gl_window().window().request_redraw();
46            }
47            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
48        },
49        Event::RedrawRequested(_) => {
50            last_frame = std::time::Instant::now();
51
52            party.check_context_changes(&mut context, &mut renderer);
53
54            let mut target = display.draw();
55            target.clear_color(0.21404, 0.21404, 0.21404, 1.0); // manual sRGB conversion for 0.5
56
57            bench::run("thyme", || {
58                display.gl_window().window().set_cursor_visible(!party.theme_has_mouse_cursor());
59
60                let mut ui = context.create_frame();
61
62                bench::run("frame", || {
63                    demo::build_ui(&mut ui, &mut party);
64                });
65
66                bench::run("draw", || {
67                    renderer.draw_frame(&mut target, ui).unwrap();
68                });
69            });
70
71            target.finish().unwrap();
72        },
73        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit,
74        event => {
75            io.handle_event(&mut context, &event);
76        }
77    })
78}
More examples
Hide additional examples
examples/demo_gl.rs (line 93)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    // initialize our very basic logger so error messages go to stdout
18    thyme::log::init(log::Level::Warn).unwrap();
19
20    // create glium display
21    let event_loop = glutin::event_loop::EventLoop::new();
22    let window_builder = glutin::window::WindowBuilder::new()
23        .with_title("Hello world!")
24        .with_inner_size(glutin::dpi::LogicalSize::new(1280.0, 720.0));
25
26    let windowed_context = glutin::ContextBuilder::new()
27        .with_gl(glutin::GlRequest::Specific(
28            glutin::Api::OpenGl,
29            (OPENGL_MAJOR_VERSION, OPENGL_MINOR_VERSION),
30        ))
31        .build_windowed(window_builder, &event_loop)?;
32
33    let windowed_context = unsafe {
34        windowed_context
35            .make_current().map_err(|(_context, e)| e)?
36    };
37
38    {
39        let gl_context = windowed_context.context();
40        gl::load_with(|ptr| gl_context.get_proc_address(ptr) as *const _)
41    }
42
43    // create thyme backend
44    let mut renderer = thyme::GLRenderer::new();
45    let mut context_builder = thyme::ContextBuilder::with_defaults();
46
47    demo::register_assets(&mut context_builder);
48
49    let window_size = [1280.0, 720.0];
50    let mut io = thyme::WinitIo::new(&event_loop, window_size.into())?;
51    let mut context = context_builder.build(&mut renderer, &mut io)?;
52    let mut party = demo::Party::default();
53
54    let mut last_frame = std::time::Instant::now();
55    let frame_time = std::time::Duration::from_millis(16);
56
57    // run main loop
58    event_loop.run(move |event, _, control_flow| match event {
59        Event::MainEventsCleared => {
60            if std::time::Instant::now() > last_frame + frame_time {
61                windowed_context.window().request_redraw();
62            }
63            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
64        }
65        Event::RedrawRequested(_) => {
66            last_frame = std::time::Instant::now();
67
68            party.check_context_changes(&mut context, &mut renderer);
69
70            renderer.clear_color(0.5, 0.5, 0.5, 1.0);
71
72            bench::run("thyme", || {
73                windowed_context.window().set_cursor_visible(!party.theme_has_mouse_cursor());
74
75                let mut ui = context.create_frame();
76
77                bench::run("frame", || {
78                    demo::build_ui(&mut ui, &mut party);
79                });
80
81                bench::run("draw", || {
82                    renderer.draw_frame(ui);
83                });
84            });
85
86            windowed_context.swap_buffers().unwrap();
87        }
88        Event::WindowEvent {
89            event: WindowEvent::CloseRequested,
90            ..
91        } => *control_flow = ControlFlow::Exit,
92        event => {
93            io.handle_event(&mut context, &event);
94        }
95    })
96}
examples/demo_wgpu.rs (line 111)
12fn main() -> Result<(), Box<dyn std::error::Error>> {
13    use winit::{ window::WindowBuilder };
14
15    // initialize our very basic logger so error messages go to stdout
16    thyme::log::init(log::Level::Warn).unwrap();
17
18    let window_size = [1280.0, 720.0];
19    let events_loop = EventLoop::new();
20
21    // create winit window
22    let window = WindowBuilder::new()
23        .with_title("Thyme WGPU Demo")
24        .with_inner_size(winit::dpi::LogicalSize::new(window_size[0], window_size[1]))
25        .build(&events_loop)?;
26
27    // setup WGPU
28    let instance_desc = wgpu::InstanceDescriptor {
29        backends: wgpu::Backends::PRIMARY,
30        dx12_shader_compiler: wgpu::Dx12Compiler::Fxc,
31    };
32    let instance = wgpu::Instance::new(instance_desc);
33    let surface = unsafe { instance.create_surface(&window).map_err(thyme::Error::WgpuSurface)? };
34    let (_adapter, device, queue) = futures::executor::block_on(setup_wgpu(&instance, &surface));
35    let surface_config = get_surface_config(window_size[0] as u32, window_size[1] as u32);
36    surface.configure(&device, &surface_config);
37
38    // create thyme backend
39    let mut renderer = thyme::WgpuRenderer::new(Arc::clone(&device), Arc::clone(&queue));
40    let mut io = thyme::WinitIo::new(&events_loop, window_size.into())?;
41    let mut context_builder = thyme::ContextBuilder::with_defaults();
42
43    demo::register_assets(&mut context_builder);
44
45    let mut context = context_builder.build(&mut renderer, &mut io)?;
46
47    let mut party = demo::Party::default();
48
49    let mut last_frame = std::time::Instant::now();
50    let frame_time = std::time::Duration::from_millis(16);
51
52    // run main loop
53    events_loop.run(move |event, _, control_flow| match event {
54        Event::MainEventsCleared => {
55            if std::time::Instant::now() > last_frame + frame_time {
56                window.request_redraw();
57            }
58            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
59        },
60        Event::RedrawRequested(_) => {
61            last_frame = std::time::Instant::now();
62
63            party.check_context_changes(&mut context, &mut renderer);
64
65            let frame = surface.get_current_texture().unwrap();
66            let view = frame.texture.create_view(&wgpu::TextureViewDescriptor::default());
67            let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
68
69            bench::run("thyme", || {
70                window.set_cursor_visible(!party.theme_has_mouse_cursor());
71
72                let mut ui = context.create_frame();
73
74                bench::run("frame", || {
75                    demo::build_ui(&mut ui, &mut party);
76                });
77
78                bench::run("draw", || {
79                    {
80                        let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
81                            label: None,
82                            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
83                                view: &view,
84                                resolve_target: None,
85                                ops: wgpu::Operations {
86                                    load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.5, g: 0.5, b: 0.5, a: 1.0 }),
87                                    store: true,
88                                },
89                            })],
90                            depth_stencil_attachment: None,
91                        });
92
93                        renderer.draw_frame(ui, &mut render_pass);
94                    }
95
96                    queue.submit(Some(encoder.finish()));
97                    frame.present();
98                });
99            });
100        },
101        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit,
102        event => {
103            // recreate swap chain on resize, but also still pass the event to thyme
104            if let Event::WindowEvent { event: WindowEvent::Resized(_), ..} = event {
105                let size: (u32, u32) = window.inner_size().into();
106
107                let surface_config = get_surface_config(size.0, size.1);
108                surface.configure(&device, &surface_config);
109            }
110
111            io.handle_event(&mut context, &event);
112        }
113    })
114}

Trait Implementations§

Source§

impl IO for WinitIo

Source§

fn scale_factor(&self) -> f32

Returns the current window scale factor (1.0 for logical pixel size = physical pixel size).
Source§

fn display_size(&self) -> Point

Returns the current window size in logical pixels.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>