jay-compositor 1.15.0

The Jay compositor
use crate::utils::numcell::NumCell;
use crate::utils::ptr_ext::MutPtrExt;
use crate::utils::ptr_ext::PtrExt;
use std::cell::UnsafeCell;
use std::mem;
use std::ops::Deref;

pub struct RefCounted<T> {
    map: UnsafeCell<Vec<(T, usize)>>,
    version: NumCell<u64>,
}

impl<T> Default for RefCounted<T> {
    fn default() -> Self {
        Self {
            map: UnsafeCell::new(vec![]),
            version: NumCell::new(1),
        }
    }
}

impl<T: Eq> RefCounted<T> {
    pub fn version(&self) -> u64 {
        self.version.get()
    }

    pub fn add(&self, t: T) -> bool {
        unsafe {
            let map = self.map.get().deref_mut();
            for (k, v) in &mut *map {
                if k == &t {
                    *v += 1;
                    return false;
                }
            }
            map.push((t, 1));
            self.version.fetch_add(1);
            true
        }
    }

    pub fn remove(&self, t: &T) -> bool {
        unsafe {
            let map = self.map.get().deref_mut();
            let idx = 'idx: {
                for (idx, (k, v)) in map.iter_mut().enumerate() {
                    if k == t {
                        *v -= 1;
                        if *v > 0 {
                            return false;
                        } else {
                            break 'idx idx;
                        }
                    }
                }
                return false;
            };
            let _v = map.swap_remove(idx);
            self.version.fetch_add(1);
            true
        }
    }

    pub fn to_vec(&self) -> Vec<T>
    where
        T: Copy,
    {
        unsafe { self.map.get().deref().iter().map(|k| k.0).collect() }
    }

    #[expect(unused)]
    pub fn lock(&self) -> Locked<'_, T> {
        unsafe {
            Locked {
                vec: mem::take(self.map.get().deref_mut()),
                rc: self,
            }
        }
    }
}

pub struct Locked<'a, T> {
    rc: &'a RefCounted<T>,
    vec: Vec<(T, usize)>,
}

impl<T> Deref for Locked<'_, T> {
    type Target = [(T, usize)];

    fn deref(&self) -> &Self::Target {
        &self.vec
    }
}

impl<T> Drop for Locked<'_, T> {
    fn drop(&mut self) {
        unsafe {
            *self.rc.map.get().deref_mut() = mem::take(&mut self.vec);
        }
    }
}