Skip to content

Commit

Permalink
feat: add sealed trait GlutinEventLoop to abstract over `{,Active}E…
Browse files Browse the repository at this point in the history
…ventLoop` in `winit` 0.30.0

Co-Authored-By: Erich Gubler <erichdongubler@gmail.com>
  • Loading branch information
marc2332 and ErichDonGubler committed May 31, 2024
1 parent b12c7ee commit bd053c1
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 6 deletions.
1 change: 1 addition & 0 deletions glutin-winit/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Unreleased

- **Breaking:** Update _winit_ to `0.30`. See [winit's CHANGELOG](https://github.com/rust-windowing/winit/releases/tag/v0.30.0) for more info.
- Add the `GlutinEventLoop` trait to maintain compatibility with the now deprecated `EventLoop` but also support the new `ActiveEventLoop`.
- Update `DisplayBuilder` to use `WindowAttributes` instead of `WindowBuilder`.

# Version 0.4.2
Expand Down
51 changes: 51 additions & 0 deletions glutin-winit/src/event_loop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use raw_window_handle::{DisplayHandle, HandleError, HasDisplayHandle};
use winit::error::OsError;
use winit::event_loop::{ActiveEventLoop, EventLoop};
use winit::window::{Window, WindowAttributes};

use crate::private::Sealed;

/// [`ActiveEventLoop`] is the recommended way to interact with the event
/// loop, but for compatibility purposes [`EventLoop`] is also supported
/// although not recommended anymore as it has been deprecated by Winit.
pub trait GlutinEventLoop: Sealed {
/// Create the window.
///
/// Possible causes of error include denied permission, incompatible system,
/// and lack of memory.
///
/// ## Platform-specific
///
/// - **Web:** The window is created but not inserted into the web page
/// automatically. Please see the web platform module for more
/// information.
fn create_window(&self, window_attributes: WindowAttributes) -> Result<Window, OsError>;

/// Get a handle to the display controller of the windowing system.
fn glutin_display_handle(&self) -> Result<DisplayHandle<'_>, HandleError>;
}

impl Sealed for ActiveEventLoop {}

impl GlutinEventLoop for ActiveEventLoop {
fn create_window(&self, window_attributes: WindowAttributes) -> Result<Window, OsError> {
self.create_window(window_attributes)
}

fn glutin_display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
self.display_handle()
}
}

impl<T> Sealed for EventLoop<T> {}

impl<T> GlutinEventLoop for EventLoop<T> {
#[allow(deprecated)]
fn create_window(&self, window_attributes: WindowAttributes) -> Result<Window, OsError> {
self.create_window(window_attributes)
}

fn glutin_display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
self.display_handle()
}
}
20 changes: 14 additions & 6 deletions glutin-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
#![deny(missing_docs)]
#![cfg_attr(clippy, deny(warnings))]

mod event_loop;
mod window;

use event_loop::GlutinEventLoop;
pub use window::GlWindow;

use std::error::Error;
Expand All @@ -23,9 +25,8 @@ use glutin::prelude::*;
#[cfg(wgl_backend)]
use raw_window_handle::HasWindowHandle;

use raw_window_handle::{HasDisplayHandle, RawWindowHandle};
use raw_window_handle::RawWindowHandle;
use winit::error::OsError;
use winit::event_loop::ActiveEventLoop;
use winit::window::{Window, WindowAttributes};

#[cfg(glx_backend)]
Expand All @@ -36,6 +37,13 @@ use winit::platform::x11::WindowAttributesExtX11;
#[cfg(all(not(egl_backend), not(glx_backend), not(wgl_backend), not(cgl_backend)))]
compile_error!("Please select at least one api backend");

pub(crate) mod private {
/// Prevent traits from being implemented downstream, since those are used
/// purely for documentation organization and simplify platform api
/// implementation maintenance.
pub trait Sealed {}
}

/// The helper to perform [`Display`] creation and OpenGL platform
/// bootstrapping with the help of [`winit`] with little to no platform specific
/// code.
Expand Down Expand Up @@ -88,7 +96,7 @@ impl DisplayBuilder {
/// otherwise only builtin functions like `glClear` will be available.
pub fn build<Picker>(
mut self,
event_loop: &ActiveEventLoop,
event_loop: &impl GlutinEventLoop,
template_builder: ConfigTemplateBuilder,
config_picker: Picker,
) -> Result<(Option<Window>, Config), Box<dyn Error>>
Expand Down Expand Up @@ -141,7 +149,7 @@ impl DisplayBuilder {
}

fn create_display(
event_loop: &ActiveEventLoop,
event_loop: &impl GlutinEventLoop,
_api_preference: ApiPreference,
_raw_window_handle: Option<RawWindowHandle>,
) -> Result<Display, Box<dyn Error>> {
Expand Down Expand Up @@ -173,7 +181,7 @@ fn create_display(
ApiPreference::FallbackEgl => DisplayApiPreference::WglThenEgl(_raw_window_handle),
};

let handle = event_loop.display_handle()?.as_raw();
let handle = event_loop.glutin_display_handle()?.as_raw();
unsafe { Ok(Display::new(handle, _preference)?) }
}

Expand All @@ -184,7 +192,7 @@ fn create_display(
/// [`Window`]: winit::window::Window
/// [`Config`]: glutin::config::Config
pub fn finalize_window(
event_loop: &ActiveEventLoop,
event_loop: &impl GlutinEventLoop,
mut attributes: WindowAttributes,
gl_config: &Config,
) -> Result<Window, OsError> {
Expand Down

0 comments on commit bd053c1

Please sign in to comment.