use std::ops::{Deref, DerefMut};
use raylib_sys::ffi;
macro_rules! impl_wrapper {
($name:ident, $t:ty, $dropfunc:expr, $rawfield:tt) => (
impl Drop for $name {
#[allow(unused_unsafe)]
fn drop(&mut self) {
unsafe { ($dropfunc)(self.$rawfield); }
}
}
impl Deref for $name {
type Target = $t;
#[inline]
fn deref(&self) -> &Self::Target { &self.$rawfield }
}
impl DerefMut for $name {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.$rawfield }
}
)
}
macro_rules! make_thin_wrapper {
($name:ident, $t:ty, $dropfunc:expr) => (
#[repr(transparent)]
#[derive(Debug)]
pub struct $name(pub(crate) $t);
impl_wrapper!($name, $t, $dropfunc, 0);
)
}
make_thin_wrapper!(Image, ffi::Image, ffi::UnloadImage);
make_thin_wrapper!(Texture2D, ffi::Texture2D, ffi::UnloadTexture);
make_thin_wrapper!(RenderTexture2D, ffi::RenderTexture2D, ffi::UnloadRenderTexture);
make_thin_wrapper!(Font, ffi::Font, ffi::UnloadFont);
make_thin_wrapper!(Mesh, ffi::Mesh, |mut mesh| ffi::UnloadMesh(&mut mesh));
make_thin_wrapper!(Shader, ffi::Shader, ffi::UnloadShader);
make_thin_wrapper!(Material, ffi::Material, ffi::UnloadMaterial);
make_thin_wrapper!(Model, ffi::Model, ffi::UnloadModel);
make_thin_wrapper!(Wave, ffi::Wave, ffi::UnloadWave);
make_thin_wrapper!(Sound, ffi::Sound, ffi::UnloadSound);
make_thin_wrapper!(Music, ffi::Music, ffi::UnloadMusicStream);
make_thin_wrapper!(AudioStream, ffi::AudioStream, ffi::CloseAudioStream);
pub trait FontExt {
fn from_data(chars: &[ffi::CharInfo], base_size: i32, padding: i32, pack_method: i32) -> Font;
fn set_chars(&mut self, chars: &[ffi::CharInfo]);
fn set_texture(&mut self, tex: Texture2D);
}
impl FontExt for ffi::Font {
fn from_data(chars: &[ffi::CharInfo], base_size: i32, padding: i32, pack_method: i32) -> Font {
unsafe {
let mut f = std::mem::zeroed::<ffi::Font>();
f.baseSize = base_size;
f.set_chars(chars);
let atlas = ffi::GenImageFontAtlas(f.chars, f.baseSize, f.charsCount, padding, pack_method);
f.texture = ffi::LoadTextureFromImage(atlas);
ffi::UnloadImage(atlas);
Font(f)
}
}
fn set_chars(&mut self, chars: &[ffi::CharInfo]) {
unsafe {
self.charsCount = chars.len() as i32;
let data_size = self.charsCount as usize * std::mem::size_of::<ffi::CharInfo>();
let ci_arr_ptr = libc::malloc(data_size); std::ptr::copy(chars.as_ptr(), ci_arr_ptr as *mut ffi::CharInfo, chars.len());
self.chars = ci_arr_ptr as *mut ffi::CharInfo;
}
}
fn set_texture(&mut self, tex: Texture2D) {
self.texture = tex.0;
std::mem::forget(tex); }
}
pub trait MaterialMapExt {
fn set_texture(&mut self, tex: Texture2D);
}
impl MaterialMapExt for ffi::MaterialMap {
fn set_texture(&mut self, tex: Texture2D) {
self.texture = tex.0;
std::mem::forget(tex); }
}
pub trait MaterialExt {
fn set_shader(&mut self, shader: Shader);
}
impl MaterialExt for ffi::Material {
fn set_shader(&mut self, shader: Shader) {
self.shader = shader.0;
std::mem::forget(shader); }
}
pub trait ModelExt {
fn set_material(&mut self, material: Material);
}
impl ModelExt for ffi::Model {
fn set_material(&mut self, material: Material) {
self.material = material.0;
std::mem::forget(material); }
}
unsafe impl Sync for Font {}
unsafe impl Sync for Material {}