use crate::geom::{Transform, Vector};
use crate::graphics::Graphics;
use crate::input::Input;
use std::error::Error;
use std::future::Future;
pub struct Settings {
pub size: Vector,
pub cursor_icon: Option<crate::CursorIcon>,
pub fullscreen: bool,
pub icon_path: Option<&'static str>,
pub multisampling: Option<u16>,
pub vsync: bool,
pub resizable: bool,
pub title: &'static str,
pub log_level: log::Level,
pub use_static_dir: bool,
}
impl Default for Settings {
fn default() -> Settings {
Settings {
size: Vector::new(1024.0, 768.0),
cursor_icon: Some(blinds::CursorIcon::Default),
fullscreen: false,
icon_path: None,
multisampling: None,
vsync: true,
resizable: false,
title: "",
log_level: log::Level::Warn,
use_static_dir: true,
}
}
}
pub fn run<E, F, T>(settings: Settings, app: F) -> !
where
E: Into<Box<dyn Error + Send + Sync>>,
T: 'static + Future<Output = Result<(), E>>,
F: 'static + FnOnce(crate::Window, Graphics, Input) -> T,
{
#[cfg(feature = "easy-log")]
set_logger(settings.log_level);
blinds::run_gl((&settings).into(), move |window, ctx, events| {
#[cfg(not(target_arch = "wasm32"))]
{
if settings.use_static_dir && std::env::set_current_dir("static").is_err() {
log::warn!("Warning: no asset directory found. Please place all your assets inside a directory called 'static' so they can be loaded");
log::warn!("Execution continuing, but any asset-not-found errors are likely due to the lack of a 'static' directory.")
}
}
let ctx = golem::Context::from_glow(ctx).unwrap();
let mut graphics = Graphics::new(ctx, settings.size).unwrap();
graphics.set_view(Transform::IDENTITY);
async {
match app(crate::Window(window), graphics, Input::new(events)).await {
Ok(()) => log::info!("Exited successfully"),
Err(err) => {
let err = err.into();
log::error!("Error: {:?}", err);
panic!("{:?}", err);
}
}
}
});
}
#[cfg(feature = "easy-log")]
fn set_logger(level: log::Level) {
#[cfg(target_arch = "wasm32")]
let _ = web_logger::try_init(web_logger::Config { level });
#[cfg(not(target_arch = "wasm32"))]
let _ = simple_logger::init_with_level(level);
}
impl From<&Settings> for blinds::Settings {
fn from(settings: &Settings) -> blinds::Settings {
blinds::Settings {
size: settings.size.into(),
cursor_icon: settings.cursor_icon,
fullscreen: settings.fullscreen,
icon_path: settings.icon_path,
multisampling: settings.multisampling,
vsync: settings.vsync,
resizable: settings.resizable,
title: settings.title,
}
}
}
impl From<blinds::Settings> for Settings {
fn from(settings: blinds::Settings) -> Settings {
Settings {
size: settings.size.into(),
cursor_icon: settings.cursor_icon,
fullscreen: settings.fullscreen,
icon_path: settings.icon_path,
multisampling: settings.multisampling,
vsync: settings.vsync,
resizable: settings.resizable,
title: settings.title,
..Settings::default()
}
}
}