use miniquad::*;
use std::any::Any;
mod shader;
mod render;
use render::*;
pub mod node;
pub use node::*;
pub mod draw;
pub use draw::*;
pub mod app;
pub use app::*;
pub mod node2d;
pub use node2d::*;
pub mod node3d;
pub use node3d::*;
pub mod info;
pub use info::*;
pub mod cross;
pub use cross::*;
pub mod event;
pub use event::*;
pub struct Engine {
pub app: App,
pub modules: ModulesEngine,
}
impl Engine {
pub fn new() -> Self {
Self {
app: App::new(date::now()),
modules: ModulesEngine::default(),
}
}
pub fn run(self, title: &str) {
let conf = conf::Conf {
window_title: title.to_string(),
high_dpi: true,
#[cfg(debug_assertions)]
window_resizable: true,
#[cfg(debug_assertions)]
fullscreen: false,
#[cfg(not(debug_assertions))]
window_resizable: false,
#[cfg(not(debug_assertions))]
fullscreen: true,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
sample_count: 4,
#[cfg(any(target_os = "android", target_os = "ios"))]
sample_count: 2,
#[cfg(target_arch = "wasm32")]
sample_count: 1,
..Default::default()
};
start(conf, || Box::new(EventEngine::new(self.app, self.modules)));
}
}
struct EventEngine {
app: App,
modules: ModulesEngine,
render: Render,
}
impl EventEngine {
pub fn new(mut app: App, modules: ModulesEngine) -> Self {
app.post_update();
Self {
app,
modules,
render: Render::new(),
}
}
}
impl EventHandler for EventEngine {
fn update(&mut self) {
let t = Timer::new("Info update app");
self.app.pre_update(date::now()); t.stop();
let t = Timer::new("Engine modules update");
self.modules.update(&mut self.app); t.stop();
let t = Timer::new("Objects modules update");
self.app.post_update(); t.stop();
}
fn draw(&mut self) {
let t = Timer::new("Frame");
self.render.pre_update(); t.stop();
let window = window::screen_size();
let t = Timer::new("Draw 3d");
self.app.draw_3d(&mut self.render.ctx, window); t.stop();
let t = Timer::new("Draw 2d");
self.app.draw_2d(&mut self.render.ctx, window); t.stop();
let t = Timer::new("Commit");
self.render.post_update(); t.stop();
println!("Fps: {}", self.app.info.fps() as usize);
}
fn key_down_event(&mut self, keycode: KeyCode, _keymods: KeyMods, repeat: bool) {
if !repeat {
self.app.event_send_set(EventChange::Press(keycode));
}
}
fn key_up_event(&mut self, keycode: KeyCode, _keymods: KeyMods) {
self.app.event_send_set(EventChange::Release(keycode));
}
fn mouse_motion_event(&mut self, x: f32, y: f32) {
self.app.event_send_set(EventChange::Mouse(vec2(x, y)));
}
fn raw_mouse_motion(&mut self, dx: f32, dy: f32) {
self.app.event_send_set(EventChange::MouseDelta(vec2(dx, dy)));
}
fn touch_event(&mut self, _phase: TouchPhase, _id: u64, x: f32, y: f32) {
self.app.event_send_set(EventChange::Mouse(vec2(x, y)));
}
}
struct Timer {
time: std::time::Instant,
name: String,
}
impl Timer {
fn new(name: &str) -> Self {
Self {
time: std::time::Instant::now(),
name: name.to_string(),
}
}
fn stop(&self) {
println!("{}: {:?}", self.name, self.time.elapsed());
}
}
#[derive(Default)]
pub struct ModulesEngine {
module_list: Vec<Box<dyn ModuleEngine>>,
module_list_len: usize,
}
impl ModulesEngine {
pub(crate) fn update(&mut self, app: &mut App) {
for module in &mut self.module_list[self.module_list_len..] {
module.ready(app);
}
self.module_list_len = self.module_list.len();
for module in &mut self.module_list {
module.procces(app);
}
}
pub fn add(&mut self, module: impl ModuleEngine) {
self.module_list.push(Box::new(module));
}
}
pub trait ModuleEngine: Any + Sync + Send {
fn ready(&mut self, _app: &mut App) {}
fn procces(&mut self, _app: &mut App) {}
}