From 1371619d8418c63e986ecddb5c62c163fabf1b5b Mon Sep 17 00:00:00 2001 From: Zachary Harrold Date: Wed, 18 Dec 2024 09:42:42 +1100 Subject: [PATCH] Remove `OnceLock` usage from `bevy_ecs` (#16870) # Objective - Fixes #16868 ## Solution - Replaced several usages of `OnceLock` within `bevy_ecs` with `const`s ## Testing - CI --- crates/bevy_ecs/Cargo.toml | 1 - crates/bevy_ecs/src/intern.rs | 24 +++++------- crates/bevy_ecs/src/query/access.rs | 4 +- .../bevy_ecs/src/world/filtered_resource.rs | 39 ++++--------------- 4 files changed, 19 insertions(+), 49 deletions(-) diff --git a/crates/bevy_ecs/Cargo.toml b/crates/bevy_ecs/Cargo.toml index 229fe89891600..df8d850d7ac87 100644 --- a/crates/bevy_ecs/Cargo.toml +++ b/crates/bevy_ecs/Cargo.toml @@ -130,7 +130,6 @@ portable-atomic-util = { version = "0.2.4", features = [ spin = { version = "0.9.8", default-features = false, features = [ "spin_mutex", "rwlock", - "once", ] } tracing = { version = "0.1", default-features = false, optional = true } log = { version = "0.4", default-features = false } diff --git a/crates/bevy_ecs/src/intern.rs b/crates/bevy_ecs/src/intern.rs index 7c163b03f41c7..e606b0d546315 100644 --- a/crates/bevy_ecs/src/intern.rs +++ b/crates/bevy_ecs/src/intern.rs @@ -8,12 +8,12 @@ use alloc::{borrow::ToOwned, boxed::Box}; use core::{fmt::Debug, hash::Hash, ops::Deref}; #[cfg(feature = "std")] -use std::sync::{OnceLock, PoisonError, RwLock}; +use std::sync::{PoisonError, RwLock}; #[cfg(not(feature = "std"))] -use spin::{once::Once as OnceLock, rwlock::RwLock}; +use spin::rwlock::RwLock; -use bevy_utils::HashSet; +use bevy_utils::{FixedHasher, HashSet}; /// An interned value. Will stay valid until the end of the program and will not drop. /// @@ -126,12 +126,12 @@ impl Internable for str { /// The implementation ensures that two equal values return two equal [`Interned`] values. /// /// To use an [`Interner`], `T` must implement [`Internable`]. -pub struct Interner(OnceLock>>); +pub struct Interner(RwLock>); impl Interner { /// Creates a new empty interner pub const fn new() -> Self { - Self(OnceLock::new()) + Self(RwLock::new(HashSet::with_hasher(FixedHasher))) } } @@ -142,18 +142,12 @@ impl Interner { /// [`Interned`] using the obtained static reference. Subsequent calls for the same `value` /// will return [`Interned`] using the same static reference. pub fn intern(&self, value: &T) -> Interned { - #[cfg(feature = "std")] - let lock = self.0.get_or_init(Default::default); - - #[cfg(not(feature = "std"))] - let lock = self.0.call_once(Default::default); - { #[cfg(feature = "std")] - let set = lock.read().unwrap_or_else(PoisonError::into_inner); + let set = self.0.read().unwrap_or_else(PoisonError::into_inner); #[cfg(not(feature = "std"))] - let set = lock.read(); + let set = self.0.read(); if let Some(value) = set.get(value) { return Interned(*value); @@ -162,10 +156,10 @@ impl Interner { { #[cfg(feature = "std")] - let mut set = lock.write().unwrap_or_else(PoisonError::into_inner); + let mut set = self.0.write().unwrap_or_else(PoisonError::into_inner); #[cfg(not(feature = "std"))] - let mut set = lock.write(); + let mut set = self.0.write(); if let Some(value) = set.get(value) { Interned(*value) diff --git a/crates/bevy_ecs/src/query/access.rs b/crates/bevy_ecs/src/query/access.rs index 70921ff90b84d..1ee7c188775c1 100644 --- a/crates/bevy_ecs/src/query/access.rs +++ b/crates/bevy_ecs/src/query/access.rs @@ -338,13 +338,13 @@ impl Access { /// Sets this as having access to all resources (i.e. `&World`). #[inline] - pub fn read_all_resources(&mut self) { + pub const fn read_all_resources(&mut self) { self.reads_all_resources = true; } /// Sets this as having mutable access to all resources (i.e. `&mut World`). #[inline] - pub fn write_all_resources(&mut self) { + pub const fn write_all_resources(&mut self) { self.reads_all_resources = true; self.writes_all_resources = true; } diff --git a/crates/bevy_ecs/src/world/filtered_resource.rs b/crates/bevy_ecs/src/world/filtered_resource.rs index 659d9d9ab7206..66eac2fdb9f95 100644 --- a/crates/bevy_ecs/src/world/filtered_resource.rs +++ b/crates/bevy_ecs/src/world/filtered_resource.rs @@ -1,9 +1,3 @@ -#[cfg(feature = "std")] -use std::sync::OnceLock; - -#[cfg(not(feature = "std"))] -use spin::once::Once as OnceLock; - use crate::{ change_detection::{Mut, MutUntyped, Ref, Ticks, TicksMut}, component::{ComponentId, Tick}, @@ -220,21 +214,13 @@ impl<'w, 's> From<&'w FilteredResourcesMut<'_, 's>> for FilteredResources<'w, 's impl<'w> From<&'w World> for FilteredResources<'w, 'static> { fn from(value: &'w World) -> Self { - static READ_ALL_RESOURCES: OnceLock> = OnceLock::new(); - let access = { - let init = || { + const READ_ALL_RESOURCES: &Access = { + const ACCESS: Access = { let mut access = Access::new(); access.read_all_resources(); access }; - - #[cfg(feature = "std")] - let access = READ_ALL_RESOURCES.get_or_init(init); - - #[cfg(not(feature = "std"))] - let access = READ_ALL_RESOURCES.call_once(init); - - access + &ACCESS }; let last_run = value.last_change_tick(); @@ -243,7 +229,7 @@ impl<'w> From<&'w World> for FilteredResources<'w, 'static> { unsafe { Self::new( value.as_unsafe_world_cell_readonly(), - access, + READ_ALL_RESOURCES, last_run, this_run, ) @@ -507,22 +493,13 @@ impl<'w, 's> FilteredResourcesMut<'w, 's> { impl<'w> From<&'w mut World> for FilteredResourcesMut<'w, 'static> { fn from(value: &'w mut World) -> Self { - static WRITE_ALL_RESOURCES: OnceLock> = OnceLock::new(); - - let access = { - let init = || { + const WRITE_ALL_RESOURCES: &Access = { + const ACCESS: Access = { let mut access = Access::new(); access.write_all_resources(); access }; - - #[cfg(feature = "std")] - let access = WRITE_ALL_RESOURCES.get_or_init(init); - - #[cfg(not(feature = "std"))] - let access = WRITE_ALL_RESOURCES.call_once(init); - - access + &ACCESS }; let last_run = value.last_change_tick(); @@ -531,7 +508,7 @@ impl<'w> From<&'w mut World> for FilteredResourcesMut<'w, 'static> { unsafe { Self::new( value.as_unsafe_world_cell_readonly(), - access, + WRITE_ALL_RESOURCES, last_run, this_run, )