#![doc = document_features::document_features!()]
#![warn(missing_docs)]
#[cfg(all(
target_os = "android",
feature = "accesskit",
feature = "android-native-activity"
))]
compile_error!("`accesskit` feature is only available with `android-game-activity`");
pub use {egui, egui::emath, egui::epaint};
#[cfg(feature = "glow")]
pub use {egui_glow, glow};
#[cfg(feature = "wgpu_no_default_features")]
pub use {egui_wgpu, egui_wgpu::wgpu};
mod epi;
pub use epi::*;
pub(crate) mod stopwatch;
#[cfg(target_arch = "wasm32")]
pub use wasm_bindgen;
#[cfg(target_arch = "wasm32")]
pub use web_sys;
#[cfg(target_arch = "wasm32")]
pub mod web;
#[cfg(target_arch = "wasm32")]
pub use web::{WebLogger, WebRunner};
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
mod native;
#[cfg(target_os = "macos")]
pub use native::macos::WindowChromeMetrics;
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
pub use native::run::EframeWinitApplication;
#[cfg(not(any(target_arch = "wasm32", target_os = "ios")))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
pub use native::run::EframePumpStatus;
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
#[cfg(feature = "persistence")]
pub use native::file_storage::storage_dir;
#[cfg(not(target_arch = "wasm32"))]
pub mod icon_data;
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
#[allow(clippy::allow_attributes, clippy::needless_pass_by_value)]
pub fn run_native(
app_name: &str,
mut native_options: NativeOptions,
app_creator: AppCreator<'_>,
) -> Result {
let renderer = init_native(app_name, &mut native_options);
match renderer {
#[cfg(feature = "glow")]
Renderer::Glow => {
log::debug!("Using the glow renderer");
native::run::run_glow(app_name, native_options, app_creator)
}
#[cfg(feature = "wgpu_no_default_features")]
Renderer::Wgpu => {
log::debug!("Using the wgpu renderer");
native::run::run_wgpu(app_name, native_options, app_creator)
}
}
}
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
pub fn create_native<'a>(
app_name: &str,
mut native_options: NativeOptions,
app_creator: AppCreator<'a>,
event_loop: &winit::event_loop::EventLoop<UserEvent>,
) -> EframeWinitApplication<'a> {
let renderer = init_native(app_name, &mut native_options);
match renderer {
#[cfg(feature = "glow")]
Renderer::Glow => {
log::debug!("Using the glow renderer");
EframeWinitApplication::new(native::run::create_glow(
app_name,
native_options,
app_creator,
event_loop,
))
}
#[cfg(feature = "wgpu_no_default_features")]
Renderer::Wgpu => {
log::debug!("Using the wgpu renderer");
EframeWinitApplication::new(native::run::create_wgpu(
app_name,
native_options,
app_creator,
event_loop,
))
}
}
}
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
fn init_native(app_name: &str, native_options: &mut NativeOptions) -> Renderer {
#[cfg(not(feature = "__screenshot"))]
assert!(
std::env::var("EFRAME_SCREENSHOT_TO").is_err(),
"EFRAME_SCREENSHOT_TO found without compiling with the '__screenshot' feature"
);
if native_options.viewport.title.is_none() {
native_options.viewport.title = Some(app_name.to_owned());
}
let renderer = native_options.renderer;
#[cfg(all(feature = "glow", feature = "wgpu_no_default_features"))]
{
match native_options.renderer {
Renderer::Glow => "glow",
Renderer::Wgpu => "wgpu",
};
log::info!("Both the glow and wgpu renderers are available. Using {renderer}.");
}
renderer
}
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
pub fn run_ui_native(
app_name: &str,
native_options: NativeOptions,
ui_fun: impl FnMut(&mut egui::Ui, &mut Frame) + 'static,
) -> Result {
struct SimpleApp<U> {
ui_fun: U,
}
impl<U: FnMut(&mut egui::Ui, &mut Frame) + 'static> App for SimpleApp<U> {
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut Frame) {
(self.ui_fun)(ui, frame);
}
}
run_native(
app_name,
native_options,
Box::new(|_cc| Ok(Box::new(SimpleApp { ui_fun }))),
)
}
#[deprecated = "Use run_ui_native instead"]
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
pub fn run_simple_native(
app_name: &str,
native_options: NativeOptions,
update_fun: impl FnMut(&egui::Context, &mut Frame) + 'static,
) -> Result {
struct SimpleApp<U> {
update_fun: U,
}
impl<U: FnMut(&egui::Context, &mut Frame) + 'static> App for SimpleApp<U> {
fn ui(&mut self, _ui: &mut egui::Ui, _frame: &mut Frame) {}
fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) {
(self.update_fun)(ctx, frame);
}
}
run_native(
app_name,
native_options,
Box::new(|_cc| Ok(Box::new(SimpleApp { update_fun }))),
)
}
#[derive(Debug)]
pub enum Error {
AppCreation(Box<dyn std::error::Error + Send + Sync>),
#[cfg(not(target_arch = "wasm32"))]
Winit(winit::error::OsError),
#[cfg(not(target_arch = "wasm32"))]
WinitEventLoop(winit::error::EventLoopError),
#[cfg(all(feature = "glow", not(target_arch = "wasm32")))]
Glutin(glutin::error::Error),
#[cfg(all(feature = "glow", not(target_arch = "wasm32")))]
NoGlutinConfigs(glutin::config::ConfigTemplate, Box<dyn std::error::Error>),
#[cfg(feature = "glow")]
OpenGL(egui_glow::PainterError),
#[cfg(feature = "wgpu_no_default_features")]
Wgpu(egui_wgpu::WgpuError),
}
impl std::error::Error for Error {}
#[cfg(not(target_arch = "wasm32"))]
impl From<winit::error::OsError> for Error {
#[inline]
fn from(err: winit::error::OsError) -> Self {
Self::Winit(err)
}
}
#[cfg(not(target_arch = "wasm32"))]
impl From<winit::error::EventLoopError> for Error {
#[inline]
fn from(err: winit::error::EventLoopError) -> Self {
Self::WinitEventLoop(err)
}
}
#[cfg(all(feature = "glow", not(target_arch = "wasm32")))]
impl From<glutin::error::Error> for Error {
#[inline]
fn from(err: glutin::error::Error) -> Self {
Self::Glutin(err)
}
}
#[cfg(feature = "glow")]
impl From<egui_glow::PainterError> for Error {
#[inline]
fn from(err: egui_glow::PainterError) -> Self {
Self::OpenGL(err)
}
}
#[cfg(feature = "wgpu_no_default_features")]
impl From<egui_wgpu::WgpuError> for Error {
#[inline]
fn from(err: egui_wgpu::WgpuError) -> Self {
Self::Wgpu(err)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::AppCreation(err) => write!(f, "app creation error: {err}"),
#[cfg(not(target_arch = "wasm32"))]
Self::Winit(err) => {
write!(f, "winit error: {err}")
}
#[cfg(not(target_arch = "wasm32"))]
Self::WinitEventLoop(err) => {
write!(f, "winit EventLoopError: {err}")
}
#[cfg(all(feature = "glow", not(target_arch = "wasm32")))]
Self::Glutin(err) => {
write!(f, "glutin error: {err}")
}
#[cfg(all(feature = "glow", not(target_arch = "wasm32")))]
Self::NoGlutinConfigs(template, err) => {
write!(
f,
"Found no glutin configs matching the template: {template:?}. Error: {err}"
)
}
#[cfg(feature = "glow")]
Self::OpenGL(err) => {
write!(f, "egui_glow: {err}")
}
#[cfg(feature = "wgpu_no_default_features")]
Self::Wgpu(err) => {
write!(f, "WGPU error: {err}")
}
}
}
}
pub type Result<T = (), E = Error> = std::result::Result<T, E>;