use super::HasDisplayAndWindowHandle;
use crate::draw::color::Rgba;
use crate::draw::{DrawIface, DrawSharedImpl, WindowCommon};
use crate::geom::Size;
use std::time::Instant;
use thiserror::Error;
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum Error {
#[error("config load/save error")]
Config(#[from] kas::config::Error),
#[error("event loop")]
EventLoop(#[from] winit::error::EventLoopError),
}
pub type Result<T> = std::result::Result<T, Error>;
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum RunError {
#[error("error from graphics sub-system")]
Graphics(Box<dyn std::error::Error + 'static>),
#[error("operation failed")]
RequestError(#[from] winit::error::RequestError),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Platform {
#[cfg(target_os = "android")]
Android,
#[cfg(target_os = "ios")]
IOS,
#[cfg(target_os = "macos")]
MacOS,
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
Wayland,
#[cfg(target_arch = "wasm32")]
Web,
#[cfg(target_os = "windows")]
Windows,
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
X11,
}
impl Platform {
pub fn is_android(&self) -> bool {
cfg_if::cfg_if! {
if #[cfg(target_os = "android")] {
true
} else {
false
}
}
}
pub fn is_ios(&self) -> bool {
cfg_if::cfg_if! {
if #[cfg(target_os = "ios")] {
true
} else {
false
}
}
}
pub fn is_macos(&self) -> bool {
cfg_if::cfg_if! {
if #[cfg(target_os = "macos")] {
true
} else {
false
}
}
}
pub fn is_wayland(&self) -> bool {
cfg_if::cfg_if! {
if #[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))] {
matches!(self, Platform::Wayland)
} else {
false
}
}
}
pub fn is_web(&self) -> bool {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
true
} else {
false
}
}
}
pub fn is_windows(&self) -> bool {
cfg_if::cfg_if! {
if #[cfg(target_os = "windows")] {
true
} else {
false
}
}
}
pub fn is_x11(&self) -> bool {
cfg_if::cfg_if! {
if #[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))] {
matches!(self, Platform::X11)
} else {
false
}
}
}
}
pub struct GraphicsFeatures {
pub subpixel_rendering: bool,
}
pub trait GraphicsInstance {
type Shared: DrawSharedImpl;
type Surface: WindowSurface<Shared = Self::Shared>;
fn new_shared(
&mut self,
surface: Option<&Self::Surface>,
features: GraphicsFeatures,
) -> std::result::Result<Self::Shared, RunError>;
fn new_surface(
&mut self,
window: std::sync::Arc<dyn HasDisplayAndWindowHandle + Send + Sync>,
transparent: bool,
) -> std::result::Result<Self::Surface, RunError>
where
Self: Sized;
}
pub trait WindowSurface {
type Shared: kas::draw::DrawSharedImpl;
fn size(&self) -> Size;
fn configure(&mut self, shared: &mut Self::Shared, size: Size) -> bool;
fn draw_iface<'iface>(
&'iface mut self,
shared: &'iface mut kas::draw::SharedState<Self::Shared>,
) -> DrawIface<'iface, Self::Shared>;
fn common_mut(&mut self) -> &mut WindowCommon;
fn present(&mut self, shared: &mut Self::Shared, clear_color: Rgba) -> Instant;
}