diff --git a/src/global_tables/objects.rs b/src/global_tables/objects.rs index 4ca4482..577b122 100644 --- a/src/global_tables/objects.rs +++ b/src/global_tables/objects.rs @@ -1,74 +1,82 @@ use std::{cell::UnsafeCell, ops::Index, ptr::NonNull, sync::RwLock}; -use rayon::prelude::ParallelIterator; - -use crate::v2_types::{ - self, - traits::{AsUObject, UObjectTrait}, -}; +use crate::v2_types::{self, traits::AsUObject}; lazy_static::lazy_static! { - pub static ref GOBJECTS: RwLock = RwLock::new(GObjects::new()); + pub static ref GOBJECTS: RwLock> = RwLock::new(GObjects::new()); } #[derive(Debug, Default)] -pub struct GObjects { - objects: Option>>, +pub struct GObjects { + objects: Option>>>, } -impl GObjects { +impl GObjects +where + Object: Sized, +{ pub const fn new() -> Self { Self { objects: None } } - pub fn set_objects(&mut self, objects: NonNull) { + pub fn set_objects(&mut self, objects: NonNull>) { self.objects = Some(objects.cast()); } - pub fn as_objects(&self) -> Option<&ObjectArray> { + pub fn as_objects(&self) -> Option<&ObjectArray> { self.objects .map(|objects| unsafe { &*objects.as_ref().get() }) } } -unsafe impl Send for GObjects {} -unsafe impl Sync for GObjects {} +unsafe impl Send for GObjects {} +unsafe impl Sync for GObjects {} #[repr(C)] #[derive(Debug)] -pub struct ObjectArrayItem { - object: Option, +pub struct ObjectArrayItem { + object: Option, sn: u32, } -unsafe impl Send for ObjectArrayItem {} -unsafe impl Sync for ObjectArrayItem {} +unsafe impl Send for ObjectArrayItem {} +unsafe impl Sync for ObjectArrayItem {} -impl ObjectArrayItem { - pub fn object(&self) -> Option { +impl ObjectArrayItem +where + Object: Sized, +{ + pub fn object(&self) -> Option + where + Object: Copy, + { self.object } + + pub fn get_object(&self) -> &Option { + &self.object + } } #[repr(C)] #[derive(Debug)] -pub struct ObjectArrayInner { - objects: NonNull>>, - pre_allocated_objects: Option>, +pub struct ObjectArrayInner { + objects: NonNull>>>, + pre_allocated_objects: Option>>, max_elements: u32, num_elements: u32, max_chunks: u32, num_chunks: u32, } -impl ObjectArrayInner { +impl ObjectArrayInner { const ELEMENTS_PER_CHUNK: usize = 64 * 1024; - fn chunks_as_slice(&self) -> &[Option>] { + fn chunks_as_slice(&self) -> &[Option>>] { unsafe { std::slice::from_raw_parts(self.objects.as_ptr(), self.num_chunks as usize) } } - pub fn get_chunks(&self) -> Vec<&[ObjectArrayItem]> { + pub fn get_chunks(&self) -> Vec<&[ObjectArrayItem]> { (0..self.num_chunks as usize) .filter_map(|i| self.chunk_as_slice(i)) .collect() @@ -86,7 +94,7 @@ impl ObjectArrayInner { } } - fn chunk_as_slice(&self, chunk_index: usize) -> Option<&[ObjectArrayItem]> { + fn chunk_as_slice(&self, chunk_index: usize) -> Option<&[ObjectArrayItem]> { let chunks = self.chunks_as_slice(); let chunk = unsafe { chunks[chunk_index].map(|ptr| { @@ -109,7 +117,7 @@ impl ObjectArrayInner { } } - pub fn get_index(&self, i: usize) -> Option<&ObjectArrayItem> { + pub fn get_index(&self, i: usize) -> Option<&ObjectArrayItem> { if let Some((chunk, within_chunk)) = self.get_chunked_index(i) { self.chunk_as_slice(chunk)?.get(within_chunk) } else { @@ -120,43 +128,33 @@ impl ObjectArrayInner { #[repr(C)] #[derive(Debug)] -pub struct ObjectArray { +pub struct ObjectArray { first_gc_index: u32, last_non_gc_index: u32, max_objects_not_considered_by_gc: u32, open_for_disregard_for_gc: bool, - inner: ObjectArrayInner, + inner: ObjectArrayInner, } -unsafe impl Send for ObjectArray {} -unsafe impl Sync for ObjectArray {} +unsafe impl Send for ObjectArray {} +unsafe impl Sync for ObjectArray {} -impl ObjectArray { +impl ObjectArray { pub fn len(&self) -> usize { self.inner.num_elements as usize } - pub fn iter(&self) -> iter::ObjectArrayIterator<'_> { + pub fn iter(&self) -> iter::ObjectArrayIterator<'_, Object> { iter::ObjectArrayIterator::new(self) } - pub fn iter_package_objects(&self) -> impl Iterator { - self.iter() - .filter(|entry| matches!(entry.object(), Some(object) if object.is_package_object())) - } - - pub fn par_iter(&self) -> par_iter::ObjectArrayChunkedParallelIterator<'_> { + pub fn par_iter(&self) -> par_iter::ObjectArrayChunkedParallelIterator<'_, Object> { par_iter::ObjectArrayChunkedParallelIterator::new(self.inner.get_chunks()) } - - pub fn par_iter_package_objects(&self) -> impl ParallelIterator { - self.par_iter() - .filter(|entry| matches!(entry.object(), Some(object) if object.is_package_object())) - } } -impl Index for ObjectArray { - type Output = ObjectArrayItem; +impl Index for ObjectArray { + type Output = ObjectArrayItem; fn index(&self, i: usize) -> &Self::Output { self.inner.get_index(i).expect("Out of bounds access") @@ -166,19 +164,28 @@ impl Index for ObjectArray { pub mod iter { use super::{ObjectArray, ObjectArrayItem}; - pub struct ObjectArrayIterator<'a> { - objects: &'a ObjectArray, + pub struct ObjectArrayIterator<'a, Object> + where + Object: Sized, + { + objects: &'a ObjectArray, index: usize, } - impl<'a> ObjectArrayIterator<'a> { - pub(super) fn new(objects: &'a ObjectArray) -> Self { + impl<'a, Object> ObjectArrayIterator<'a, Object> + where + Object: Sized, + { + pub(super) fn new(objects: &'a ObjectArray) -> Self { Self { objects, index: 0 } } } - impl<'a> Iterator for ObjectArrayIterator<'a> { - type Item = &'a ObjectArrayItem; + impl<'a, Object> Iterator for ObjectArrayIterator<'a, Object> + where + Object: Sized, + { + type Item = &'a ObjectArrayItem; fn next(&mut self) -> Option { let item = if self.index < self.objects.len() { @@ -193,9 +200,12 @@ pub mod iter { } } - impl<'a> IntoIterator for &'a ObjectArray { - type Item = &'a ObjectArrayItem; - type IntoIter = ObjectArrayIterator<'a>; + impl<'a, Object> IntoIterator for &'a ObjectArray + where + Object: Sized, + { + type Item = &'a ObjectArrayItem; + type IntoIter = ObjectArrayIterator<'a, Object>; fn into_iter(self) -> Self::IntoIter { ObjectArrayIterator { @@ -211,18 +221,27 @@ pub mod par_iter { use super::ObjectArrayItem; - pub struct ObjectArrayChunkedParallelIterator<'a> { - chunks: Vec<&'a [ObjectArrayItem]>, + pub struct ObjectArrayChunkedParallelIterator<'a, Object> + where + Object: Sized, + { + chunks: Vec<&'a [ObjectArrayItem]>, } - impl<'a> ObjectArrayChunkedParallelIterator<'a> { - pub fn new(chunks: Vec<&'a [ObjectArrayItem]>) -> Self { + impl<'a, Object> ObjectArrayChunkedParallelIterator<'a, Object> + where + Object: Sized, + { + pub fn new(chunks: Vec<&'a [ObjectArrayItem]>) -> Self { Self { chunks } } } - impl<'a> ParallelIterator for ObjectArrayChunkedParallelIterator<'a> { - type Item = &'a ObjectArrayItem; + impl<'a, Object> ParallelIterator for ObjectArrayChunkedParallelIterator<'a, Object> + where + Object: Sized, + { + type Item = &'a ObjectArrayItem; fn drive_unindexed(self, consumer: C) -> C::Result where @@ -242,7 +261,7 @@ pub trait FindClass { S: Into; } -impl FindClass for ObjectArray { +impl FindClass for ObjectArray { fn find_class(&self, class_name: S) -> Option where S: Into,