use inputs::winit_input::EngineInput;
use render::render_engine::RenderEngine;
use winit::{event_loop::EventLoop, window::WindowBuilder, event::{Event, WindowEvent}, dpi::PhysicalSize};
pub mod component_app;
pub mod egui;
pub mod inputs;
pub mod lights;
pub mod math;
pub mod models;
pub mod primitives;
pub mod render;
pub mod ui;
pub mod utils;
#[cfg(target_arch="wasm32")]
use wasm_bindgen::prelude::*;
pub trait EngineApp {
fn create(engine: RenderEngine) -> Self;
fn start(&mut self);
fn input(&mut self, input: EngineInput);
fn update(&mut self);
fn resize(&mut self, new_size: PhysicalSize<u32>);
fn exit(&mut self);
}
pub async fn run_app<T: EngineApp + 'static>() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
console_log::init_with_level(log::Level::Warn).expect("Couldn't initialize logger");
} else {
env_logger::init();
}
}
log!("Creating window and event loop...");
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new()
.with_title("Forte Engine App")
.with_inner_size(PhysicalSize::new(1280, 720))
.build(&event_loop).unwrap();
#[cfg(target_arch = "wasm32")]
{
use winit::dpi::PhysicalSize;
window.set_min_inner_size(Some(PhysicalSize::new(1280, 720)));
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("forte")?;
let canvas = window.canvas().unwrap();
canvas.set_width(1280);
canvas.set_height(720);
let canvas = web_sys::Element::from(canvas);
dst.append_child(&canvas).ok()?;
Some(())
})
.expect("Couldn't append canvas to document body.");
}
log!("Creating RenderEngine...");
let engine = RenderEngine::new(window).await;
log!("Creating app...");
let mut app = T::create(engine);
app.start();
log!("Starting event loop...");
let _ = event_loop.run(move |event, target| {
match event {
Event::WindowEvent { ref event, .. } => {
match event {
WindowEvent::CloseRequested => target.exit(),
WindowEvent::Resized(size) => app.resize(*size),
WindowEvent::RedrawRequested => {
app.update();
},
_ => {
let input = EngineInput::from_winit_input(event);
if input.is_some() { app.input(input.unwrap()); }
}
}
},
Event::NewEvents(_) => {},
Event::DeviceEvent { device_id: _, event: _ } => {},
Event::UserEvent(_) => {},
Event::Suspended => {},
Event::Resumed => {},
Event::AboutToWait => {},
Event::LoopExiting => app.exit(),
Event::MemoryWarning => panic!("Out of memory!"),
}
});
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
#[wasm_bindgen(js_namespace = console, js_name = log)]
fn log_u32(a: u32);
#[wasm_bindgen(js_namespace = console, js_name = log)]
fn log_many(a: &str, b: &str);
}
#[macro_export]
macro_rules! log {
($($t:tt)*) => {
#[cfg(target_arch = "wasm32")]
log(&format_args!($($t)*).to_string());
#[cfg(not(target_arch = "wasm32"))]
println!("{}", format_args!($($t)*).to_string());
}
}