use crate::fonts::ScalableFont;
use cotis::renders::RenderCompatibleWith;
use raylib::color::Color;
use raylib::consts::TextureFilter;
use raylib::error::RaylibError;
use raylib::prelude::Texture2D;
use raylib::{RaylibBuilder, RaylibHandle, RaylibThread};
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, Mutex, MutexGuard};
pub mod render_trait;
pub type SharedRaylibHandle = Arc<Mutex<RayRenderHandle>>;
pub struct RayRenderHandle(pub(crate) RaylibHandle);
impl Deref for RayRenderHandle {
type Target = RaylibHandle;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for RayRenderHandle {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub struct RaylibRender {
rl: Arc<Mutex<RayRenderHandle>>,
thread: RaylibThread,
fonts: Arc<Mutex<HashMap<usize, ScalableFont>>>,
font_max_id: usize,
image_cache: HashMap<String, Arc<Texture2D>>,
pub background_color: Color,
}
impl<Manager> RenderCompatibleWith<Manager> for RaylibRender {
fn init(&mut self, _layout_manager: &mut Manager) {}
}
impl RaylibRender {
pub fn auto_start() -> Self {
Self::new(Color::new(100, 100, 100, 0))
}
pub fn new(background_color: Color) -> Self {
let (rl, thread) = raylib::init()
.resizable()
.size(1000, 1000)
.title("Raylib")
.build();
Self {
rl: Arc::new(Mutex::new(RayRenderHandle(rl))),
thread,
fonts: Default::default(),
font_max_id: 0,
image_cache: Default::default(),
background_color,
}
}
pub fn new_custom(raylib_builder: RaylibBuilder, background_color: Color) -> Self {
let (rl, thread) = raylib_builder.build();
Self {
rl: Arc::new(Mutex::new(RayRenderHandle(rl))),
thread,
fonts: Default::default(),
font_max_id: 0,
image_cache: Default::default(),
background_color,
}
}
pub fn get_handle(&mut self) -> MutexGuard<'_, RayRenderHandle> {
self.rl.lock().unwrap()
}
pub fn lock_handle(&self) -> MutexGuard<'_, RayRenderHandle> {
self.rl.lock().unwrap()
}
pub fn get_thread(&self) -> &RaylibThread {
&self.thread
}
pub fn thread(&self) -> &RaylibThread {
&self.thread
}
pub fn get_raylib(&mut self) -> (MutexGuard<'_, RayRenderHandle>, &mut RaylibThread) {
(self.rl.lock().unwrap(), &mut self.thread)
}
pub fn window_should_close(&self) -> bool {
self.rl.lock().unwrap().window_should_close()
}
pub fn load_font_and_keep(&mut self, file_name: &str) -> Result<usize, RaylibError> {
self.load_font_ex_and_keep(file_name, 16, None, None)
}
pub(crate) fn load_new_font_sizes(&mut self) {
let mut fonts = self.fonts.lock().unwrap();
for font in fonts.values_mut() {
font.load_queued_fonts(&mut self.rl.lock().unwrap(), &self.thread)
.unwrap();
}
}
pub fn load_font_ex_and_keep(
&mut self,
file_name: &str,
font_size: i32,
chars: Option<&str>,
filter: Option<TextureFilter>,
) -> Result<usize, RaylibError> {
let mut rl = self.rl.lock().unwrap();
self.fonts.lock().unwrap().insert(
self.font_max_id,
ScalableFont::new(
file_name.to_string(),
chars.map(|s| s.to_string()),
filter,
&mut rl,
&self.thread,
font_size as usize,
)?,
);
self.font_max_id += 1;
Ok(self.font_max_id - 1)
}
pub fn delta_time(&self) -> f32 {
self.rl.lock().unwrap().get_frame_time()
}
pub fn get_shared_handle(&self) -> SharedRaylibHandle {
self.rl.clone()
}
pub fn shared_handle(&self) -> SharedRaylibHandle {
self.get_shared_handle()
}
pub fn image_cache(&self) -> &HashMap<String, Arc<Texture2D>> {
&self.image_cache
}
pub fn image_cache_mut(&mut self) -> &mut HashMap<String, Arc<Texture2D>> {
&mut self.image_cache
}
pub fn fonts(&self) -> Arc<Mutex<HashMap<usize, ScalableFont>>> {
self.fonts.clone()
}
}