mindustry logic execution, map- and schematic- parsing and rendering
remove once cell
| -rw-r--r-- | src/block/mod.rs | 14 | ||||
| -rw-r--r-- | src/data/schematic.rs | 2 | ||||
| -rw-r--r-- | src/lib.rs | 1 | ||||
| -rw-r--r-- | src/utils/mod.rs | 2 | ||||
| -rw-r--r-- | src/utils/once_cell.rs | 169 |
5 files changed, 4 insertions, 184 deletions
diff --git a/src/block/mod.rs b/src/block/mod.rs index aa8d2bb..74e8c2c 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -8,7 +8,6 @@ use crate::data::dynamic::{DynData, DynType}; use crate::data::GridPos; use crate::item::storage::Storage as ItemStorage; use crate::registry::RegistryEntry; -use crate::utils::OnceCell; pub mod base; pub mod content; @@ -167,7 +166,6 @@ impl Error for SerializeError { pub struct Block { name: Cow<'static, str>, logic: BoxAccess<'static, dyn BlockLogic + Sync>, - build_cost: OnceCell<Option<ItemStorage>>, } impl Block { @@ -176,11 +174,7 @@ impl Block { name: Cow<'static, str>, logic: BoxAccess<'static, dyn BlockLogic + Sync>, ) -> Self { - Self { - name, - logic, - build_cost: OnceCell::new(), - } + Self { name, logic } } pub fn get_size(&self) -> u8 { @@ -191,10 +185,8 @@ impl Block { self.logic.is_symmetric() } - pub fn get_build_cost(&self) -> Option<&ItemStorage> { - self.build_cost - .get_or_init(|| self.logic.as_ref().create_build_cost()) - .as_ref() + pub fn get_build_cost(&self) -> Option<ItemStorage> { + self.logic.as_ref().create_build_cost() } pub fn data_from_i32(&self, config: i32, pos: GridPos) -> Result<DynData, DataConvertError> { diff --git a/src/data/schematic.rs b/src/data/schematic.rs index a3b104d..9927ad2 100644 --- a/src/data/schematic.rs +++ b/src/data/schematic.rs @@ -591,7 +591,7 @@ impl<'l> Schematic<'l> { let mut sandbox = false; for &Placement { block, .. } in &self.blocks { if let Some(curr) = block.get_build_cost() { - cost.add_all(curr, u32::MAX); + cost.add_all(&curr, u32::MAX); } else { sandbox = true; } @@ -9,4 +9,3 @@ pub mod modifier; pub mod registry; pub mod team; pub mod unit; -pub mod utils; diff --git a/src/utils/mod.rs b/src/utils/mod.rs deleted file mode 100644 index 396b1e2..0000000 --- a/src/utils/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod once_cell; -pub use once_cell::OnceCell; diff --git a/src/utils/once_cell.rs b/src/utils/once_cell.rs deleted file mode 100644 index 9dda9ff..0000000 --- a/src/utils/once_cell.rs +++ /dev/null @@ -1,169 +0,0 @@ -use std::cell::UnsafeCell; -use std::mem::MaybeUninit; -use std::ptr; -use std::sync::atomic::{AtomicU8, Ordering}; - -const STATE_INIT: u8 = 0; -const STATE_LOCKED: u8 = STATE_INIT + 1; -const STATE_READY: u8 = STATE_LOCKED + 1; - -pub struct OnceCell<T> { - value: UnsafeCell<MaybeUninit<T>>, - state: AtomicU8, -} - -impl<T> OnceCell<T> { - #[must_use] - pub const fn new() -> Self { - Self { - value: UnsafeCell::new(MaybeUninit::uninit()), - state: AtomicU8::new(STATE_INIT), - } - } - - pub const fn new_init(value: T) -> Self { - Self { - value: UnsafeCell::new(MaybeUninit::new(value)), - state: AtomicU8::new(STATE_READY), - } - } - - pub fn get(&self) -> Option<&T> { - if self.state.load(Ordering::Acquire) == STATE_READY { - // SAFETY: won't be overwritten for the lifetime of this reference - Some(unsafe { (*self.value.get()).assume_init_ref() }) - } else { - None - } - } - - pub fn get_or_wait(&self) -> Option<&T> { - loop { - match self.state.load(Ordering::Acquire) { - STATE_INIT => return None, - STATE_LOCKED => (), // continue - STATE_READY => return Some(unsafe { (*self.value.get()).assume_init_ref() }), - x => unreachable!("invalid state {x}"), - } - } - } - - pub fn get_or_init<F: Fn() -> T>(&self, init: F) -> &T { - loop { - match self.state.compare_exchange( - STATE_INIT, - STATE_LOCKED, - Ordering::AcqRel, - Ordering::Acquire, - ) { - Ok(..) => { - let value = init(); - let written = &*unsafe { &mut *self.value.get() }.write(value); - self.state.store(STATE_READY, Ordering::Release); - return written; - } - Err(STATE_READY) => return unsafe { (*self.value.get()).assume_init_ref() }, - Err(..) => (), // locked or spurious failure - } - } - } - - pub fn set(&self, value: T) -> Result<&T, T> { - // don't set state to STATE_READY on success because we have to release afterward anyway - match self.state.compare_exchange( - STATE_INIT, - STATE_LOCKED, - Ordering::AcqRel, - Ordering::Acquire, - ) { - Ok(..) => { - // SAFETY: unique because only one thread can lock the atomic state - let written = &*unsafe { &mut *self.value.get() }.write(value); - self.state.store(STATE_READY, Ordering::Release); - Ok(written) - } - // SAFETY: guaranteed to be initialized & protected by acquire ordering - Err(STATE_READY) => return Ok(unsafe { (*self.value.get()).assume_init_ref() }), - Err(..) => Err(value), // locked or spurious failure - } - } - - pub fn set_mut(&mut self, mut value: T) -> Result<Option<T>, T> { - // don't set state to STATE_READY on success because we have to release afterward anyway - match self.state.compare_exchange( - STATE_INIT, - STATE_LOCKED, - Ordering::AcqRel, - Ordering::Acquire, - ) { - Ok(..) => { - self.value.get_mut().write(value); - self.state.store(STATE_READY, Ordering::Release); - Ok(None) - } - Err(STATE_READY) => { - // SAFETY: guaranteed to be initialized & protected by acquire ordering - std::mem::swap( - unsafe { self.value.get_mut().assume_init_mut() }, - &mut value, - ); - // ensure changes are visible to others acquiring the atomic state - self.state.store(STATE_READY, Ordering::Release); - // we've swapped the previous value into this variable - Ok(Some(value)) - } - Err(..) => Err(value), // locked or spurious failure - } - } - - pub fn into_inner(mut self) -> Option<T> { - // must be atomic so potential writes during the drop see a valid state - let inner = match self.state.load(Ordering::Acquire) { - STATE_INIT => None, - STATE_LOCKED => unreachable!("consumed cell during initialization"), - // SAFETY: initialized & we'll forget about it afterwards - STATE_READY => Some(unsafe { self.value.get_mut().assume_init_read() }), - x => unreachable!("invalid state {x}"), - }; - // SAFETY: just in case AtomicU8 has a drop handler - unsafe { - ptr::drop_in_place(std::ptr::addr_of_mut!(self.state)); - } - std::mem::forget(self); - inner - } -} - -impl<T> Default for OnceCell<T> { - fn default() -> Self { - OnceCell::new() - } -} - -impl<T> From<T> for OnceCell<T> { - fn from(value: T) -> Self { - OnceCell::new_init(value) - } -} - -impl<T> From<OnceCell<T>> for Option<T> { - fn from(value: OnceCell<T>) -> Self { - value.into_inner() - } -} - -impl<T> Drop for OnceCell<T> { - fn drop(&mut self) { - match *self.state.get_mut() { - STATE_INIT => (), - STATE_LOCKED => unreachable!("dropped cell during initialization"), - // MaybeUninit requires us to manually drop the value - STATE_READY => unsafe { self.value.get_mut().assume_init_drop() }, - x => unreachable!("invalid state {x}"), - } - } -} - -unsafe impl<T: Send> Send for OnceCell<T> {} - -unsafe impl<T: Sync> Sync for OnceCell<T> {} |