use crate::{
model::{ModelBuilder, ModelData, ModelHandleMessage, SourceOrShape},
render::LightState,
};
use cgmath::{Matrix4, SquareMatrix};
use parking_lot::RwLock;
use std::{
collections::{HashMap, HashSet},
sync::{mpsc::Sender, Arc},
};
use vulkano::{
device::{Device, Queue},
swapchain::Surface,
};
use winit::event::VirtualKeyCode;
pub struct GameState {
pub(crate) device: Arc<Device>,
pub(crate) queue: Arc<Queue>,
pub(crate) model_handles: HashMap<u64, Arc<RwLock<ModelData>>>,
pub(crate) model_handle_sender: Sender<ModelHandleMessage>,
pub(crate) is_running: bool,
pub camera: Matrix4<f32>,
pub keyboard: KeyboardState,
pub light: LightState,
surface: Arc<Surface<winit::window::Window>>,
}
impl GameState {
pub(crate) fn new(
device: Arc<Device>,
queue: Arc<Queue>,
sender: Sender<ModelHandleMessage>,
surface: Arc<Surface<winit::window::Window>>,
) -> Self {
Self {
device,
queue,
model_handles: HashMap::new(),
model_handle_sender: sender,
is_running: true,
camera: Matrix4::identity(),
keyboard: KeyboardState {
pressed: HashSet::default(),
},
light: LightState::new(),
surface,
}
}
pub(crate) fn add_model_data(&mut self, new_id: u64, handle: Arc<RwLock<ModelData>>) {
self.model_handles.insert(new_id, handle);
}
pub(crate) fn remove_model_handle(&mut self, handle: u64) {
self.model_handles.remove(&handle);
}
pub fn window(&self) -> &winit::window::Window {
self.surface.window()
}
#[cfg(target = "ios")]
pub fn set_cursor_position<P: winit::dpi::Pixel>(&self, _position: (P, P)) {}
#[cfg(not(target = "ios"))]
pub fn set_cursor_position<P: winit::dpi::Pixel>(&self, position: (P, P)) {
self.window()
.set_cursor_position(winit::dpi::PhysicalPosition::new(position.0, position.1))
.unwrap();
}
pub fn terminate_game(&mut self) {
self.is_running = false;
}
pub fn new_triangle_model(&mut self) -> ModelBuilder {
ModelBuilder::new(self, SourceOrShape::Triangle)
}
pub fn new_rectangle_model(&mut self) -> ModelBuilder {
ModelBuilder::new(self, SourceOrShape::Rectangle)
}
#[cfg(feature = "format-obj")]
pub fn new_obj_model<'a>(&'a mut self, path: &'a str) -> ModelBuilder<'a> {
ModelBuilder::new(self, SourceOrShape::Obj(path))
}
#[cfg(feature = "format-fbx")]
pub fn new_fbx_model<'a>(&'a mut self, path: &'a str) -> ModelBuilder<'a> {
ModelBuilder::new(self, SourceOrShape::Fbx(path))
}
}
pub struct KeyboardState {
pub(crate) pressed: HashSet<VirtualKeyCode>,
}
impl KeyboardState {
pub fn is_pressed(&self, key: VirtualKeyCode) -> bool {
self.pressed.contains(&key)
}
}