Skip to main content

pebble/rendering/
window_plugin.rs

1use crate::prelude::{Plugin, WindowConfig, WindowResource, WindowRunner};
2
3/// Plugin that creates the platform window and installs it as a runner.
4///
5/// On build it:
6/// 1. Creates the window via [`WindowProvider::create`](crate::rendering::window::WindowProvider::create).
7/// 2. Inserts a [`WindowResource`] containing the handle and exposed value.
8/// 3. Inserts the exposed value again on its own (`W::Exposed`, e.g. `Input`
9///    for the winit backend) so systems can fetch it directly with
10///    `Res<W::Exposed>` instead of reaching through `WindowResource<W>` and
11///    naming the concrete backend type.
12/// 4. Sets the app runner to `W::run`, which drives the frame loop.
13pub struct WindowPlugin<W: WindowRunner> {
14    pub config: WindowConfig,
15    _marker: std::marker::PhantomData<W>,
16}
17
18impl<W> WindowPlugin<W>
19where
20    W: WindowRunner,
21{
22    pub fn new(config: WindowConfig) -> Self {
23        Self {
24            config,
25            _marker: std::marker::PhantomData,
26        }
27    }
28}
29
30impl<W> Plugin for WindowPlugin<W>
31where
32    W: WindowRunner,
33    W::Handle: 'static + Send + Sync + Clone,
34{
35    fn build(&self, app: &mut crate::prelude::App) {
36        let window_source = W::create(&self.config);
37        let window_handle = window_source.handle().clone();
38        let window_exposed = window_source.exposed().clone();
39
40        app.add_resource(window_exposed.clone());
41        app.add_resource(WindowResource::<W> {
42            handle: window_handle,
43            exposed: window_exposed,
44        });
45        app.set_runner(move |mut app| {
46            window_source.run(move || app.update());
47        });
48    }
49}