use super::Labelifier;
use crate::window::Window;
use parking_lot::Mutex;
use std::sync::Arc;
use vulkano::buffer::BufferContents;
use vulkano::descriptor_set::WriteDescriptorSet;
use vulkano::pipeline::cache::PipelineCache;
mod loader;
pub(crate) mod vulkan;
pub(crate) use loader::Loader;
use vulkan::Vulkan;
pub mod textures;
pub mod data;
pub mod materials;
mod model;
pub use model::Model;
mod macros;
pub use macros::*;
const NOT_INITIALIZED_MSG: &str = "Resources are not initialized to a game.";
#[derive(Clone)]
pub struct Resources {
pub(crate) vulkan: Option<Vulkan>,
pub(crate) loader: Option<Arc<Mutex<Loader>>>,
pub(crate) labelifier: Option<Arc<Mutex<Labelifier>>>,
}
impl Resources {
pub fn new() -> Self {
Self {
vulkan: None,
loader: None,
labelifier: None,
}
}
pub(crate) fn init(&mut self, vulkan: Vulkan) {
self.loader = Some(Arc::new(Mutex::new(Loader::init(&vulkan))));
self.vulkan = Some(vulkan);
self.labelifier = Some(Arc::new(Mutex::new(Labelifier::new(self))));
}
pub(crate) fn vulkan(&self) -> &Vulkan {
self.vulkan.as_ref().expect(NOT_INITIALIZED_MSG)
}
pub(crate) fn loader(&self) -> &Arc<Mutex<Loader>> {
self.loader.as_ref().expect(NOT_INITIALIZED_MSG)
}
pub(crate) fn labelifier(&self) -> &Arc<Mutex<Labelifier>> {
self.labelifier.as_ref().expect(NOT_INITIALIZED_MSG)
}
pub(crate) fn update(&self) {
let mut labelifier = self.labelifier().lock();
labelifier.update(self);
}
pub unsafe fn load_pipeline_cache(&self, data: &[u8]) {
let cache = PipelineCache::with_data(self.vulkan().device.clone(), data).unwrap();
self.loader()
.lock()
.pipeline_cache
.merge([&cache].iter())
.unwrap();
}
pub fn get_pipeline_binary(&self) -> Vec<u8> {
self.loader().lock().pipeline_cache.get_data().unwrap()
}
pub fn new_descriptor_write<T: BufferContents>(&self, buf: T, set: u32) -> WriteDescriptorSet {
let loader = self.loader().lock();
loader.write_descriptor(buf, set)
}
pub fn get_window(&self) -> Window {
self.vulkan().window.clone()
}
}
impl Default for Resources {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone)]
pub struct Font {
font: Arc<rusttype::Font<'static>>,
id: usize,
}
impl Font {
pub fn from_bytes(data: &'static [u8], resources: &Resources) -> Option<Self> {
let labelifier = resources.labelifier().lock();
let font = Arc::new(rusttype::Font::try_from_bytes(data)?);
let id = labelifier.increment_id();
Some(Self { font, id })
}
pub fn from_vec(data: impl Into<Vec<u8>>, resources: &Resources) -> Option<Self> {
let labelifier = resources.labelifier().lock();
let font = Arc::new(rusttype::Font::try_from_vec(data.into())?);
let id = labelifier.increment_id();
Some(Self { font, id })
}
pub fn id(&self) -> usize {
self.id
}
pub(crate) fn font(&self) -> &Arc<rusttype::Font<'static>> {
&self.font
}
}
pub struct Sound {
pub data: Arc<[u8]>,
}
#[allow(dead_code)]
pub fn load_sound(sound: &[u8]) -> Sound {
Sound {
data: Arc::from(sound.to_vec().into_boxed_slice()),
}
}