use crate::core;
use crate::core::Color;
use crate::core::font;
use crate::core::renderer;
use crate::futures::{MaybeSend, MaybeSync};
use crate::{Antialiasing, Error, Shell, Viewport};
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use thiserror::Error;
use std::borrow::Cow;
pub trait Compositor: Sized {
type Renderer;
type Surface;
fn new(
settings: Settings,
display: impl Display + Clone,
compatible_window: impl Window + Clone,
shell: Shell,
) -> impl Future<Output = Result<Self, Error>> {
Self::with_backend(settings, display, compatible_window, shell, None)
}
fn with_backend(
settings: Settings,
display: impl Display + Clone,
compatible_window: impl Window + Clone,
shell: Shell,
backend: Option<&str>,
) -> impl Future<Output = Result<Self, Error>>;
fn create_renderer(&self, settings: renderer::Settings) -> Self::Renderer;
fn create_surface<W: Window + Clone>(
&mut self,
window: W,
width: u32,
height: u32,
) -> Self::Surface;
fn configure_surface(&mut self, surface: &mut Self::Surface, width: u32, height: u32);
fn information(&self) -> Information;
fn load_font(&mut self, font: Cow<'static, [u8]>) -> Result<(), font::Error> {
crate::text::font_system()
.write()
.expect("Write to font system")
.load_font(font);
Ok(())
}
fn list_fonts(&mut self) -> Result<Vec<font::Family>, font::Error> {
use std::collections::BTreeSet;
let font_system = crate::text::font_system()
.read()
.expect("Read from font system");
let families = BTreeSet::from_iter(font_system.families());
Ok(families.into_iter().map(font::Family::name).collect())
}
fn present(
&mut self,
renderer: &mut Self::Renderer,
surface: &mut Self::Surface,
viewport: &Viewport,
background_color: Color,
on_pre_present: impl FnOnce(),
) -> Result<(), SurfaceError>;
fn screenshot(
&mut self,
renderer: &mut Self::Renderer,
viewport: &Viewport,
background_color: Color,
) -> Vec<u8>;
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Settings {
pub antialiasing: Option<Antialiasing>,
pub vsync: bool,
}
impl ::core::default::Default for Settings {
fn default() -> Settings {
Settings {
antialiasing: None,
vsync: true,
}
}
}
impl From<&core::Settings> for Settings {
fn from(settings: &core::Settings) -> Self {
Self {
antialiasing: settings.antialiasing.then_some(Antialiasing::MSAAx4),
vsync: settings.vsync,
}
}
}
pub trait Window: HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
impl<T> Window for T where T: HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
pub trait Display: HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
impl<T> Display for T where T: HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
pub trait Default {
type Compositor: Compositor<Renderer = Self>;
}
#[derive(Clone, PartialEq, Eq, Debug, Error)]
pub enum SurfaceError {
#[error("A timeout was encountered while trying to acquire the next frame")]
Timeout,
#[error("The underlying surface has changed, and therefore the surface must be updated.")]
Outdated,
#[error("The surface has been lost and needs to be recreated")]
Lost,
#[error("There is no more memory left to allocate a new frame")]
OutOfMemory,
#[error("Acquiring a texture failed with a generic error")]
Other,
}
#[derive(Debug)]
pub struct Information {
pub adapter: String,
pub backend: String,
}
impl Compositor for () {
type Renderer = ();
type Surface = ();
async fn with_backend(
_settings: Settings,
_display: impl Display,
_compatible_window: impl Window + Clone,
_shell: Shell,
_preferred_backend: Option<&str>,
) -> Result<Self, Error> {
Ok(())
}
fn create_renderer(&self, _settings: renderer::Settings) -> Self::Renderer {}
fn create_surface<W: Window + Clone>(
&mut self,
_window: W,
_width: u32,
_height: u32,
) -> Self::Surface {
}
fn configure_surface(&mut self, _surface: &mut Self::Surface, _width: u32, _height: u32) {}
fn load_font(&mut self, _font: Cow<'static, [u8]>) -> Result<(), font::Error> {
Ok(())
}
fn list_fonts(&mut self) -> Result<Vec<font::Family>, font::Error> {
Ok(Vec::new())
}
fn information(&self) -> Information {
Information {
adapter: String::from("Null Renderer"),
backend: String::from("Null"),
}
}
fn present(
&mut self,
_renderer: &mut Self::Renderer,
_surface: &mut Self::Surface,
_viewport: &Viewport,
_background_color: Color,
_on_pre_present: impl FnOnce(),
) -> Result<(), SurfaceError> {
Ok(())
}
fn screenshot(
&mut self,
_renderer: &mut Self::Renderer,
_viewport: &Viewport,
_background_color: Color,
) -> Vec<u8> {
vec![]
}
}
impl Default for () {
type Compositor = ();
}