use super::core::Image;
use image::Pixel;
use std::{
cell::UnsafeCell,
marker::{Send, Sync},
ops::Deref,
};
pub struct ImageCell<P: Pixel, U: image::GenericImage<Pixel = P>> {
underlying: UnsafeCell<Image<P, U>>,
}
pub struct Handout<'a, P: Pixel, U: image::GenericImage<Pixel = P>> {
ic: &'a ImageCell<P, U>,
x: u32,
y: u32,
}
impl<P: Pixel, U: image::GenericImage<Pixel = P>> ImageCell<P, U> {
pub fn new(image: Image<P, U>) -> Self {
Self {
underlying: UnsafeCell::new(image),
}
}
pub fn into_inner(self) -> Image<P, U> {
self.underlying.into_inner()
}
#[allow(clippy::mut_from_ref)]
pub(crate) fn get_image_mut(&self) -> &mut Image<P, U> {
unsafe { &mut *self.underlying.get() }
}
pub unsafe fn request_handout(&self, x: u32, y: u32) -> Handout<P, U> {
Handout { ic: self, x, y }
}
}
impl<P: Pixel, U: image::GenericImage<Pixel = P>> Deref for ImageCell<P, U> {
type Target = Image<P, U>;
fn deref(&self) -> &Self::Target {
unsafe { &*self.underlying.get() }
}
}
unsafe impl<P: Pixel, U: image::GenericImage<Pixel = P>> Sync for ImageCell<P, U> {}
unsafe impl<P: Pixel, U: image::GenericImage<Pixel = P>> Send for ImageCell<P, U> {}
impl<'a, P: Pixel, U: image::GenericImage<Pixel = P>> Handout<'a, P, U> {
pub fn put_pixel(&mut self, pixel: P) {
let image = self.ic.get_image_mut();
image.put_pixel(self.x, self.y, pixel);
}
pub unsafe fn unsafe_put_pixel(&mut self, pixel: P) {
let image = self.ic.get_image_mut();
image.unsafe_put_pixel(self.x, self.y, pixel);
}
}