use std::rc::Rc;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
use std::time::Duration;
use cgmath::{Deg, Quaternion, Rotation3, Vector3};
use crate::model::*;
use crate::ui::{StatsWindow, UILoop};
use crate::util::StatsRc;
mod game;
pub use game::*;
mod menu;
pub use menu::*;
const STATS_BORDER: f32 = 0.01;
const STATS_REFRESH: f32 = 1.0;
const SABER_HANDLE_PHONG_PARAM: PhongParam = PhongParam::new(0.1, 0.2, 0.3, 64.0);
const SABER_RAY_PHONG_PARAM: PhongParam = PhongParam::new(1.0, 0.0, 0.0, 0.0);
pub fn create_floor(model_reg: &mut ModelRegistry) {
let floor_param = FloorParam::new(&COLOR_WHITE);
let floor = model_reg.create(floor_param);
floor.set_visible(true);
floor.set_pos(&Vector3::new(0.0, 0.0, 0.0));
}
pub fn create_stats_window(model_reg: &mut ModelRegistry, stats: StatsRc, ui_loop: &UILoop) {
let window_param = WindowParam::new(500, 250, {
let stats_inner = stats.get_inner();
move || {
let window = StatsWindow::new().unwrap();
window.set_comment(stats_inner.comment.into());
window
}
});
let window = model_reg.create(window_param);
window.set_visible(true);
window.set_scale(2.0 - 2.0 * STATS_BORDER, 1.0 - 2.0 * STATS_BORDER);
window.set_pos(&Vector3::new(0.0, 2.5, 0.001));
window.set_rot(&Quaternion::from_angle_x(Deg(-90.0)));
thread::spawn({
let ui_loop = ui_loop.clone();
let window_weak = window.as_weak::<StatsWindow>();
move || {
let alive = Arc::new(AtomicBool::new(true));
while alive.load(Ordering::Relaxed) {
ui_loop.add_callback({
let window_weak = window_weak.clone();
let stats_inner = stats.get_inner();
let alive = Arc::clone(&alive);
move || {
match window_weak.upgrade() {
Some(window) => { window.set_fps(stats_inner.fps.try_into().unwrap());
window.set_frame_time(stats_inner.frame_time.try_into().unwrap());
window.set_draw_calls(stats_inner.draw_calls.try_into().unwrap());
window.set_inst_num(stats_inner.inst_num.try_into().unwrap());
window.set_inst_buf(stats_inner.inst_buf.try_into().unwrap());
},
None => alive.store(false, Ordering::Relaxed),
}
}
});
thread::sleep(Duration::from_secs_f32(STATS_REFRESH));
}
}
});
}
pub fn create_saber(model_reg: &mut ModelRegistry, color_l: &Color, color_r: &Color) -> (Rc<Saber>, Rc<Saber>) {
let saber_param = SaberParam::new(color_l, &SABER_HANDLE_PHONG_PARAM, color_l, &SABER_RAY_PHONG_PARAM);
let saber_l = model_reg.create(saber_param);
let saber_param = SaberParam::new(color_r, &SABER_HANDLE_PHONG_PARAM, color_r, &SABER_RAY_PHONG_PARAM);
let saber_r = model_reg.create(saber_param);
(saber_l, saber_r)
}