Struct thyme::ContextBuilder

source ·
pub struct ContextBuilder { /* private fields */ }
Expand description

Structure to register resources and ultimately build the main Thyme Context.

You pass resources to it to register them with Thyme. Once this process is complete, call build to create your Context.

Implementations§

source§

impl ContextBuilder

source

pub fn with_defaults() -> ContextBuilder

Creates a new ContextBuilder, using the default BuildOptions

Example
    let mut context_builder = thyme::ContextBuilder::with_defaults();
    context_builder.register_theme(theme)?;
    ...
Examples found in repository?
examples/demo_glium.rs (line 30)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
fn main() -> Result<(), Box<dyn std::error::Error>> {
    use glium::glutin::{window::WindowBuilder};
    use glium::{Display, Surface};

    // initialize our very basic logger so error messages go to stdout
    thyme::log::init(log::Level::Warn).unwrap();

    let window_size = [1280.0, 720.0];
    let events_loop = EventLoop::new();

    // create glium display
    let builder = WindowBuilder::new()
        .with_title("Thyme Demo")
        .with_inner_size(glium::glutin::dpi::LogicalSize::new(window_size[0], window_size[1]));
    let context = glium::glutin::ContextBuilder::new();
    let display = Display::new(builder, context, &events_loop)?;

    // create thyme backend
    let mut renderer = thyme::GliumRenderer::new(&display)?;
    let mut io = thyme::WinitIo::new(&events_loop, window_size.into())?;
    let mut context_builder = thyme::ContextBuilder::with_defaults();

    demo::register_assets(&mut context_builder);

    let mut context = context_builder.build(&mut renderer, &mut io)?;

    let mut party = demo::Party::default();

    let mut last_frame = std::time::Instant::now();
    let frame_time = std::time::Duration::from_millis(16);
    
    // run main loop
    events_loop.run(move |event, _, control_flow| match event {
        Event::MainEventsCleared => {
            if std::time::Instant::now() > last_frame + frame_time {
                display.gl_window().window().request_redraw();
            }
            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
        },
        Event::RedrawRequested(_) => {
            last_frame = std::time::Instant::now();

            party.check_context_changes(&mut context, &mut renderer);

            let mut target = display.draw();
            target.clear_color(0.21404, 0.21404, 0.21404, 1.0); // manual sRGB conversion for 0.5

            bench::run("thyme", || {
                display.gl_window().window().set_cursor_visible(!party.theme_has_mouse_cursor());

                let mut ui = context.create_frame();

                bench::run("frame", || {
                    demo::build_ui(&mut ui, &mut party);
                });

                bench::run("draw", || {
                    renderer.draw_frame(&mut target, ui).unwrap();
                });
            });

            target.finish().unwrap();
        },
        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit,
        event => {
            io.handle_event(&mut context, &event);
        }
    })
}
More examples
Hide additional examples
examples/demo_gl.rs (line 45)
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
fn main() -> Result<(), Box<dyn std::error::Error>> {
    // initialize our very basic logger so error messages go to stdout
    thyme::log::init(log::Level::Warn).unwrap();

    // create glium display
    let event_loop = glutin::event_loop::EventLoop::new();
    let window_builder = glutin::window::WindowBuilder::new()
        .with_title("Hello world!")
        .with_inner_size(glutin::dpi::LogicalSize::new(1280.0, 720.0));

    let windowed_context = glutin::ContextBuilder::new()
        .with_gl(glutin::GlRequest::Specific(
            glutin::Api::OpenGl,
            (OPENGL_MAJOR_VERSION, OPENGL_MINOR_VERSION),
        ))
        .build_windowed(window_builder, &event_loop)?;

    let windowed_context = unsafe {
        windowed_context
            .make_current().map_err(|(_context, e)| e)?
    };

    {
        let gl_context = windowed_context.context();
        gl::load_with(|ptr| gl_context.get_proc_address(ptr) as *const _)
    }

    // create thyme backend
    let mut renderer = thyme::GLRenderer::new();
    let mut context_builder = thyme::ContextBuilder::with_defaults();

    demo::register_assets(&mut context_builder);

    let window_size = [1280.0, 720.0];
    let mut io = thyme::WinitIo::new(&event_loop, window_size.into())?;
    let mut context = context_builder.build(&mut renderer, &mut io)?;
    let mut party = demo::Party::default();

    let mut last_frame = std::time::Instant::now();
    let frame_time = std::time::Duration::from_millis(16);

    // run main loop
    event_loop.run(move |event, _, control_flow| match event {
        Event::MainEventsCleared => {
            if std::time::Instant::now() > last_frame + frame_time {
                windowed_context.window().request_redraw();
            }
            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
        }
        Event::RedrawRequested(_) => {
            last_frame = std::time::Instant::now();

            party.check_context_changes(&mut context, &mut renderer);

            renderer.clear_color(0.5, 0.5, 0.5, 1.0);

            bench::run("thyme", || {
                windowed_context.window().set_cursor_visible(!party.theme_has_mouse_cursor());

                let mut ui = context.create_frame();

                bench::run("frame", || {
                    demo::build_ui(&mut ui, &mut party);
                });

                bench::run("draw", || {
                    renderer.draw_frame(ui);
                });
            });

            windowed_context.swap_buffers().unwrap();
        }
        Event::WindowEvent {
            event: WindowEvent::CloseRequested,
            ..
        } => *control_flow = ControlFlow::Exit,
        event => {
            io.handle_event(&mut context, &event);
        }
    })
}
examples/demo_wgpu.rs (line 41)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
fn main() -> Result<(), Box<dyn std::error::Error>> {
    use winit::{ window::WindowBuilder };

    // initialize our very basic logger so error messages go to stdout
    thyme::log::init(log::Level::Warn).unwrap();

    let window_size = [1280.0, 720.0];
    let events_loop = EventLoop::new();

    // create winit window
    let window = WindowBuilder::new()
        .with_title("Thyme WGPU Demo")
        .with_inner_size(winit::dpi::LogicalSize::new(window_size[0], window_size[1]))
        .build(&events_loop)?;

    // setup WGPU
    let instance_desc = wgpu::InstanceDescriptor {
        backends: wgpu::Backends::PRIMARY,
        dx12_shader_compiler: wgpu::Dx12Compiler::Fxc,
    };
    let instance = wgpu::Instance::new(instance_desc);
    let surface = unsafe { instance.create_surface(&window).map_err(thyme::Error::WgpuSurface)? };
    let (_adapter, device, queue) = futures::executor::block_on(setup_wgpu(&instance, &surface));
    let surface_config = get_surface_config(window_size[0] as u32, window_size[1] as u32);
    surface.configure(&device, &surface_config);

    // create thyme backend
    let mut renderer = thyme::WgpuRenderer::new(Arc::clone(&device), Arc::clone(&queue));
    let mut io = thyme::WinitIo::new(&events_loop, window_size.into())?;
    let mut context_builder = thyme::ContextBuilder::with_defaults();

    demo::register_assets(&mut context_builder);

    let mut context = context_builder.build(&mut renderer, &mut io)?;

    let mut party = demo::Party::default();

    let mut last_frame = std::time::Instant::now();
    let frame_time = std::time::Duration::from_millis(16);

    // run main loop
    events_loop.run(move |event, _, control_flow| match event {
        Event::MainEventsCleared => {
            if std::time::Instant::now() > last_frame + frame_time {
                window.request_redraw();
            }
            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
        },
        Event::RedrawRequested(_) => {
            last_frame = std::time::Instant::now();

            party.check_context_changes(&mut context, &mut renderer);

            let frame = surface.get_current_texture().unwrap();
            let view = frame.texture.create_view(&wgpu::TextureViewDescriptor::default());
            let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });

            bench::run("thyme", || {
                window.set_cursor_visible(!party.theme_has_mouse_cursor());

                let mut ui = context.create_frame();

                bench::run("frame", || {
                    demo::build_ui(&mut ui, &mut party);
                });

                bench::run("draw", || {
                    {
                        let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
                            label: None,
                            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                                view: &view,
                                resolve_target: None,
                                ops: wgpu::Operations {
                                    load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.5, g: 0.5, b: 0.5, a: 1.0 }),
                                    store: true,
                                },
                            })],
                            depth_stencil_attachment: None,
                        });

                        renderer.draw_frame(ui, &mut render_pass);
                    }

                    queue.submit(Some(encoder.finish()));
                    frame.present();
                });
            });
        },
        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit,
        event => {
            // recreate swap chain on resize, but also still pass the event to thyme
            if let Event::WindowEvent { event: WindowEvent::Resized(_), ..} = event {
                let size: (u32, u32) = window.inner_size().into();

                let surface_config = get_surface_config(size.0, size.1);
                surface.configure(&device, &surface_config);
            }

            io.handle_event(&mut context, &event);
        }
    })
}
source

pub fn new(options: BuildOptions) -> ContextBuilder

Creates a new ContextBuilder, using the specified BuildOptions

source

pub fn register_theme<'a, T: Deserializer<'a>>( &mut self, theme: T ) -> Result<(), T::Error>

Sets the theme for this context. The theme for your UI will be deserialized from theme. For example, theme could be a serde_json Value or serde_yaml Value. See the crate root for a discussion of the theme format. If this method is called multiple times, only the last theme is used

source

pub fn register_theme_from_file(&mut self, path: &Path) -> Result<(), Error>

Sets the theme for this context by reading from the file at the specified path. The file is deserialized as serde YAML files. See register_theme

source

pub fn register_theme_from_files( &mut self, paths: &[&Path] ) -> Result<(), Error>

Sets the theme for this context by reading from the specified list of files. The files are each read into a string and then concatenated together. The string is then deserialized as serde YAML. See register_theme

Examples found in repository?
examples/demo.rs (lines 12-19)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pub fn register_assets(context_builder: &mut ContextBuilder) {
    // register resources in thyme by reading from files.  this enables live reload.
    context_builder.register_theme_from_files(
        &[
            Path::new("examples/data/themes/base.yml"),
            Path::new("examples/data/themes/demo.yml"),
            // note we dynamically add/remove from this list later if the user selects a new theme
            Path::new("examples/data/themes/pixel.yml"),
        ],
    ).unwrap();
    context_builder.register_texture_from_file("pixel", Path::new("examples/data/images/pixel.png"));
    context_builder.register_texture_from_file("fantasy", Path::new("examples/data/images/fantasy.png"));
    context_builder.register_texture_from_file("transparent", Path::new("examples/data/images/transparent.png"));
    context_builder.register_texture_from_file("golden", Path::new("examples/data/images/golden.png"));
    context_builder.register_font_from_file("Roboto-Medium", Path::new("examples/data/fonts/Roboto-Medium.ttf"));
    context_builder.register_font_from_file("Roboto-Italic", Path::new("examples/data/fonts/Roboto-Italic.ttf"));
    context_builder.register_font_from_file("Roboto-Bold", Path::new("examples/data/fonts/Roboto-Bold.ttf"));
    context_builder.register_font_from_file("Roboto-BoldItalic", Path::new("examples/data/fonts/Roboto-BoldItalic.ttf"));
}
source

pub fn register_font_from_file<T: Into<String>>(&mut self, id: T, path: &Path)

Registers the font data located in the file at the specified path with Thyme via the specified id. See register_font

Examples found in repository?
examples/demo.rs (line 24)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pub fn register_assets(context_builder: &mut ContextBuilder) {
    // register resources in thyme by reading from files.  this enables live reload.
    context_builder.register_theme_from_files(
        &[
            Path::new("examples/data/themes/base.yml"),
            Path::new("examples/data/themes/demo.yml"),
            // note we dynamically add/remove from this list later if the user selects a new theme
            Path::new("examples/data/themes/pixel.yml"),
        ],
    ).unwrap();
    context_builder.register_texture_from_file("pixel", Path::new("examples/data/images/pixel.png"));
    context_builder.register_texture_from_file("fantasy", Path::new("examples/data/images/fantasy.png"));
    context_builder.register_texture_from_file("transparent", Path::new("examples/data/images/transparent.png"));
    context_builder.register_texture_from_file("golden", Path::new("examples/data/images/golden.png"));
    context_builder.register_font_from_file("Roboto-Medium", Path::new("examples/data/fonts/Roboto-Medium.ttf"));
    context_builder.register_font_from_file("Roboto-Italic", Path::new("examples/data/fonts/Roboto-Italic.ttf"));
    context_builder.register_font_from_file("Roboto-Bold", Path::new("examples/data/fonts/Roboto-Bold.ttf"));
    context_builder.register_font_from_file("Roboto-BoldItalic", Path::new("examples/data/fonts/Roboto-BoldItalic.ttf"));
}
source

pub fn register_font<T: Into<String>>(&mut self, id: T, data: Vec<u8>)

Registers the font data for use with Thyme via the specified id. The data must consist of the full binary for a valid TTF or OTF file. Once the font has been registered, it can be accessed in your theme file via the font source.

source

pub fn register_texture_from_file<T: Into<String>>( &mut self, id: T, path: &Path )

Reads a texture from the specified image file. See register_texture. Requires you to enable the image feature in Cargo.toml to enable the dependancy on the image crate.

Examples found in repository?
examples/demo.rs (line 20)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pub fn register_assets(context_builder: &mut ContextBuilder) {
    // register resources in thyme by reading from files.  this enables live reload.
    context_builder.register_theme_from_files(
        &[
            Path::new("examples/data/themes/base.yml"),
            Path::new("examples/data/themes/demo.yml"),
            // note we dynamically add/remove from this list later if the user selects a new theme
            Path::new("examples/data/themes/pixel.yml"),
        ],
    ).unwrap();
    context_builder.register_texture_from_file("pixel", Path::new("examples/data/images/pixel.png"));
    context_builder.register_texture_from_file("fantasy", Path::new("examples/data/images/fantasy.png"));
    context_builder.register_texture_from_file("transparent", Path::new("examples/data/images/transparent.png"));
    context_builder.register_texture_from_file("golden", Path::new("examples/data/images/golden.png"));
    context_builder.register_font_from_file("Roboto-Medium", Path::new("examples/data/fonts/Roboto-Medium.ttf"));
    context_builder.register_font_from_file("Roboto-Italic", Path::new("examples/data/fonts/Roboto-Italic.ttf"));
    context_builder.register_font_from_file("Roboto-Bold", Path::new("examples/data/fonts/Roboto-Bold.ttf"));
    context_builder.register_font_from_file("Roboto-BoldItalic", Path::new("examples/data/fonts/Roboto-BoldItalic.ttf"));
}
source

pub fn register_texture<T: Into<String>>( &mut self, id: T, data: Vec<u8>, dimensions: (u32, u32) )

Registers the image data for use with Thyme via the specified id. The data must consist of raw binary image data in RGBA format, with 4 bytes per pixel. The data must start at the bottom-left hand corner pixel and progress left-to-right and bottom-to-top. data.len() must equal dimensions.0 * dimensions.1 * 4 Once the image has been registered, it can be accessed in your theme file via the image source.

source

pub fn build<R: Renderer, I: IO>( self, renderer: &mut R, io: &mut I ) -> Result<Context, Error>

Consumes this builder and releases the borrows on the Renderer and IO, so they can be used further. Builds a Context.

Examples found in repository?
examples/demo_glium.rs (line 34)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
fn main() -> Result<(), Box<dyn std::error::Error>> {
    use glium::glutin::{window::WindowBuilder};
    use glium::{Display, Surface};

    // initialize our very basic logger so error messages go to stdout
    thyme::log::init(log::Level::Warn).unwrap();

    let window_size = [1280.0, 720.0];
    let events_loop = EventLoop::new();

    // create glium display
    let builder = WindowBuilder::new()
        .with_title("Thyme Demo")
        .with_inner_size(glium::glutin::dpi::LogicalSize::new(window_size[0], window_size[1]));
    let context = glium::glutin::ContextBuilder::new();
    let display = Display::new(builder, context, &events_loop)?;

    // create thyme backend
    let mut renderer = thyme::GliumRenderer::new(&display)?;
    let mut io = thyme::WinitIo::new(&events_loop, window_size.into())?;
    let mut context_builder = thyme::ContextBuilder::with_defaults();

    demo::register_assets(&mut context_builder);

    let mut context = context_builder.build(&mut renderer, &mut io)?;

    let mut party = demo::Party::default();

    let mut last_frame = std::time::Instant::now();
    let frame_time = std::time::Duration::from_millis(16);
    
    // run main loop
    events_loop.run(move |event, _, control_flow| match event {
        Event::MainEventsCleared => {
            if std::time::Instant::now() > last_frame + frame_time {
                display.gl_window().window().request_redraw();
            }
            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
        },
        Event::RedrawRequested(_) => {
            last_frame = std::time::Instant::now();

            party.check_context_changes(&mut context, &mut renderer);

            let mut target = display.draw();
            target.clear_color(0.21404, 0.21404, 0.21404, 1.0); // manual sRGB conversion for 0.5

            bench::run("thyme", || {
                display.gl_window().window().set_cursor_visible(!party.theme_has_mouse_cursor());

                let mut ui = context.create_frame();

                bench::run("frame", || {
                    demo::build_ui(&mut ui, &mut party);
                });

                bench::run("draw", || {
                    renderer.draw_frame(&mut target, ui).unwrap();
                });
            });

            target.finish().unwrap();
        },
        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit,
        event => {
            io.handle_event(&mut context, &event);
        }
    })
}
More examples
Hide additional examples
examples/demo_gl.rs (line 51)
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
fn main() -> Result<(), Box<dyn std::error::Error>> {
    // initialize our very basic logger so error messages go to stdout
    thyme::log::init(log::Level::Warn).unwrap();

    // create glium display
    let event_loop = glutin::event_loop::EventLoop::new();
    let window_builder = glutin::window::WindowBuilder::new()
        .with_title("Hello world!")
        .with_inner_size(glutin::dpi::LogicalSize::new(1280.0, 720.0));

    let windowed_context = glutin::ContextBuilder::new()
        .with_gl(glutin::GlRequest::Specific(
            glutin::Api::OpenGl,
            (OPENGL_MAJOR_VERSION, OPENGL_MINOR_VERSION),
        ))
        .build_windowed(window_builder, &event_loop)?;

    let windowed_context = unsafe {
        windowed_context
            .make_current().map_err(|(_context, e)| e)?
    };

    {
        let gl_context = windowed_context.context();
        gl::load_with(|ptr| gl_context.get_proc_address(ptr) as *const _)
    }

    // create thyme backend
    let mut renderer = thyme::GLRenderer::new();
    let mut context_builder = thyme::ContextBuilder::with_defaults();

    demo::register_assets(&mut context_builder);

    let window_size = [1280.0, 720.0];
    let mut io = thyme::WinitIo::new(&event_loop, window_size.into())?;
    let mut context = context_builder.build(&mut renderer, &mut io)?;
    let mut party = demo::Party::default();

    let mut last_frame = std::time::Instant::now();
    let frame_time = std::time::Duration::from_millis(16);

    // run main loop
    event_loop.run(move |event, _, control_flow| match event {
        Event::MainEventsCleared => {
            if std::time::Instant::now() > last_frame + frame_time {
                windowed_context.window().request_redraw();
            }
            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
        }
        Event::RedrawRequested(_) => {
            last_frame = std::time::Instant::now();

            party.check_context_changes(&mut context, &mut renderer);

            renderer.clear_color(0.5, 0.5, 0.5, 1.0);

            bench::run("thyme", || {
                windowed_context.window().set_cursor_visible(!party.theme_has_mouse_cursor());

                let mut ui = context.create_frame();

                bench::run("frame", || {
                    demo::build_ui(&mut ui, &mut party);
                });

                bench::run("draw", || {
                    renderer.draw_frame(ui);
                });
            });

            windowed_context.swap_buffers().unwrap();
        }
        Event::WindowEvent {
            event: WindowEvent::CloseRequested,
            ..
        } => *control_flow = ControlFlow::Exit,
        event => {
            io.handle_event(&mut context, &event);
        }
    })
}
examples/demo_wgpu.rs (line 45)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
fn main() -> Result<(), Box<dyn std::error::Error>> {
    use winit::{ window::WindowBuilder };

    // initialize our very basic logger so error messages go to stdout
    thyme::log::init(log::Level::Warn).unwrap();

    let window_size = [1280.0, 720.0];
    let events_loop = EventLoop::new();

    // create winit window
    let window = WindowBuilder::new()
        .with_title("Thyme WGPU Demo")
        .with_inner_size(winit::dpi::LogicalSize::new(window_size[0], window_size[1]))
        .build(&events_loop)?;

    // setup WGPU
    let instance_desc = wgpu::InstanceDescriptor {
        backends: wgpu::Backends::PRIMARY,
        dx12_shader_compiler: wgpu::Dx12Compiler::Fxc,
    };
    let instance = wgpu::Instance::new(instance_desc);
    let surface = unsafe { instance.create_surface(&window).map_err(thyme::Error::WgpuSurface)? };
    let (_adapter, device, queue) = futures::executor::block_on(setup_wgpu(&instance, &surface));
    let surface_config = get_surface_config(window_size[0] as u32, window_size[1] as u32);
    surface.configure(&device, &surface_config);

    // create thyme backend
    let mut renderer = thyme::WgpuRenderer::new(Arc::clone(&device), Arc::clone(&queue));
    let mut io = thyme::WinitIo::new(&events_loop, window_size.into())?;
    let mut context_builder = thyme::ContextBuilder::with_defaults();

    demo::register_assets(&mut context_builder);

    let mut context = context_builder.build(&mut renderer, &mut io)?;

    let mut party = demo::Party::default();

    let mut last_frame = std::time::Instant::now();
    let frame_time = std::time::Duration::from_millis(16);

    // run main loop
    events_loop.run(move |event, _, control_flow| match event {
        Event::MainEventsCleared => {
            if std::time::Instant::now() > last_frame + frame_time {
                window.request_redraw();
            }
            *control_flow = ControlFlow::WaitUntil(last_frame + frame_time);
        },
        Event::RedrawRequested(_) => {
            last_frame = std::time::Instant::now();

            party.check_context_changes(&mut context, &mut renderer);

            let frame = surface.get_current_texture().unwrap();
            let view = frame.texture.create_view(&wgpu::TextureViewDescriptor::default());
            let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });

            bench::run("thyme", || {
                window.set_cursor_visible(!party.theme_has_mouse_cursor());

                let mut ui = context.create_frame();

                bench::run("frame", || {
                    demo::build_ui(&mut ui, &mut party);
                });

                bench::run("draw", || {
                    {
                        let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
                            label: None,
                            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                                view: &view,
                                resolve_target: None,
                                ops: wgpu::Operations {
                                    load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.5, g: 0.5, b: 0.5, a: 1.0 }),
                                    store: true,
                                },
                            })],
                            depth_stencil_attachment: None,
                        });

                        renderer.draw_frame(ui, &mut render_pass);
                    }

                    queue.submit(Some(encoder.finish()));
                    frame.present();
                });
            });
        },
        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => *control_flow = ControlFlow::Exit,
        event => {
            // recreate swap chain on resize, but also still pass the event to thyme
            if let Event::WindowEvent { event: WindowEvent::Resized(_), ..} = event {
                let size: (u32, u32) = window.inner_size().into();

                let surface_config = get_surface_config(size.0, size.1);
                surface.configure(&device, &surface_config);
            }

            io.handle_event(&mut context, &event);
        }
    })
}

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Downcast<T> for T

§

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 Twhere 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 Twhere U: Into<T>,

§

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 Twhere U: TryFrom<T>,

§

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.
§

impl<T> Upcast<T> for T

§

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