mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Replace bevy_utils::CowArc
with atomicow
(#14977)
# Objective - Fixes https://github.com/bevyengine/bevy/issues/14975 ## Solution - Replace usages of `bevy_utils::CowArc` with `atomicow::CowArc` - Remove bevy_utils::CowArc ## Testing - `bevy_asset` test suite continues to pass. --- ## Migration Guide `bevy_utils::CowArc` has moved to a new crate called [atomicow](https://crates.io/crates/atomicow).
This commit is contained in:
parent
9e78433427
commit
e08497dc8f
9 changed files with 12 additions and 199 deletions
|
@ -29,6 +29,7 @@ bevy_tasks = { path = "../bevy_tasks", version = "0.15.0-dev" }
|
|||
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
|
||||
|
||||
stackfuture = "0.3"
|
||||
atomicow = "1.0"
|
||||
async-broadcast = "0.5"
|
||||
async-fs = "2.0"
|
||||
async-lock = "3.0"
|
||||
|
|
|
@ -2,9 +2,10 @@ use crate::{
|
|||
io::{processor_gated::ProcessorGatedReader, AssetSourceEvent, AssetWatcher},
|
||||
processor::AssetProcessorData,
|
||||
};
|
||||
use atomicow::CowArc;
|
||||
use bevy_ecs::system::Resource;
|
||||
use bevy_utils::tracing::{error, warn};
|
||||
use bevy_utils::{CowArc, Duration, HashMap};
|
||||
use bevy_utils::{Duration, HashMap};
|
||||
use std::{fmt::Display, hash::Hash, sync::Arc};
|
||||
use thiserror::Error;
|
||||
|
||||
|
|
|
@ -6,8 +6,9 @@ use crate::{
|
|||
Asset, AssetLoadError, AssetServer, AssetServerMode, Assets, Handle, UntypedAssetId,
|
||||
UntypedHandle,
|
||||
};
|
||||
use atomicow::CowArc;
|
||||
use bevy_ecs::world::World;
|
||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture, CowArc, HashMap, HashSet};
|
||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture, HashMap, HashSet};
|
||||
use downcast_rs::{impl_downcast, Downcast};
|
||||
use ron::error::SpannedError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::io::AssetSourceId;
|
||||
use atomicow::CowArc;
|
||||
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||
use bevy_utils::CowArc;
|
||||
use serde::{de::Visitor, Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::transformer::TransformedAsset;
|
||||
use crate::{io::Writer, meta::Settings, Asset, ErasedLoadedAsset};
|
||||
use crate::{AssetLoader, Handle, LabeledAsset, UntypedHandle};
|
||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture, CowArc, HashMap};
|
||||
use atomicow::CowArc;
|
||||
use bevy_utils::{BoxedFuture, ConditionalSendFuture, HashMap};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{borrow::Borrow, hash::Hash, ops::Deref};
|
||||
|
||||
|
|
|
@ -17,10 +17,11 @@ use crate::{
|
|||
DeserializeMetaError, ErasedLoadedAsset, Handle, LoadedUntypedAsset, UntypedAssetId,
|
||||
UntypedAssetLoadFailedEvent, UntypedHandle,
|
||||
};
|
||||
use atomicow::CowArc;
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_tasks::IoTaskPool;
|
||||
use bevy_utils::tracing::{error, info};
|
||||
use bevy_utils::{CowArc, HashSet};
|
||||
use bevy_utils::HashSet;
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
use futures_lite::{FutureExt, StreamExt};
|
||||
use info::*;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::{meta::Settings, Asset, ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle};
|
||||
use bevy_utils::{ConditionalSendFuture, CowArc, HashMap};
|
||||
use atomicow::CowArc;
|
||||
use bevy_utils::{ConditionalSendFuture, HashMap};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
|
|
|
@ -1,191 +0,0 @@
|
|||
use std::{
|
||||
borrow::Borrow,
|
||||
fmt::{Debug, Display},
|
||||
hash::Hash,
|
||||
ops::Deref,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
/// Much like a [`Cow`](std::borrow::Cow), but owned values are Arc-ed to make clones cheap. This should be used for values that
|
||||
/// are cloned for use across threads and change rarely (if ever).
|
||||
///
|
||||
/// This also makes an opinionated tradeoff by adding a [`CowArc::Static`] and implementing [`From<&'static T>`] instead of
|
||||
/// [`From<'a T>`]. This preserves the static context and prevents conversion to [`CowArc::Owned`] in cases where a reference
|
||||
/// is known to be static. This is an optimization that prevents allocations and atomic ref-counting.
|
||||
///
|
||||
/// This means that static references should prefer [`From::from`] or [`CowArc::Static`] and non-static references must
|
||||
/// use [`CowArc::Borrowed`].
|
||||
pub enum CowArc<'a, T: ?Sized + 'static> {
|
||||
/// A borrowed value
|
||||
Borrowed(&'a T),
|
||||
/// A static value reference. This exists to avoid conversion to [`CowArc::Owned`] in cases where a reference is
|
||||
/// known to be static. This is an optimization that prevents allocations and atomic ref-counting.
|
||||
Static(&'static T),
|
||||
/// An owned [`Arc`]-ed value
|
||||
Owned(Arc<T>),
|
||||
}
|
||||
|
||||
impl<T: ?Sized> CowArc<'static, T> {
|
||||
/// Indicates this [`CowArc`] should have a static lifetime.
|
||||
/// This ensures if this was created with a value `Borrowed(&'static T)`, it is replaced with `Static(&'static T)`.
|
||||
#[inline]
|
||||
pub fn as_static(self) -> Self {
|
||||
match self {
|
||||
Self::Borrowed(value) | Self::Static(value) => Self::Static(value),
|
||||
Self::Owned(value) => Self::Owned(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> Deref for CowArc<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
CowArc::Borrowed(v) | CowArc::Static(v) => v,
|
||||
CowArc::Owned(v) => v,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> Borrow<T> for CowArc<'a, T> {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &T {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> AsRef<T> for CowArc<'a, T> {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &T {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> CowArc<'a, T>
|
||||
where
|
||||
&'a T: Into<Arc<T>>,
|
||||
{
|
||||
/// Converts this into an "owned" value. If internally a value is borrowed, it will be cloned into an "owned [`Arc`]".
|
||||
/// If it is already a [`CowArc::Owned`] or a [`CowArc::Static`], it will remain unchanged.
|
||||
#[inline]
|
||||
pub fn into_owned(self) -> CowArc<'static, T> {
|
||||
match self {
|
||||
CowArc::Borrowed(value) => CowArc::Owned(value.into()),
|
||||
CowArc::Static(value) => CowArc::Static(value),
|
||||
CowArc::Owned(value) => CowArc::Owned(value),
|
||||
}
|
||||
}
|
||||
|
||||
/// Clones into an owned [`CowArc<'static>`]. If internally a value is borrowed, it will be cloned into an "owned [`Arc`]".
|
||||
/// If it is already a [`CowArc::Owned`] or [`CowArc::Static`], the value will be cloned.
|
||||
/// This is equivalent to `.clone().into_owned()`.
|
||||
#[inline]
|
||||
pub fn clone_owned(&self) -> CowArc<'static, T> {
|
||||
self.clone().into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> Clone for CowArc<'a, T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Self::Borrowed(value) => Self::Borrowed(value),
|
||||
Self::Static(value) => Self::Static(value),
|
||||
Self::Owned(value) => Self::Owned(value.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: PartialEq + ?Sized> PartialEq for CowArc<'a, T> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.deref().eq(other.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: PartialEq + ?Sized> Eq for CowArc<'a, T> {}
|
||||
|
||||
impl<'a, T: Hash + ?Sized> Hash for CowArc<'a, T> {
|
||||
#[inline]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.deref().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Debug + ?Sized> Debug for CowArc<'a, T> {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Debug::fmt(self.deref(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Display + ?Sized> Display for CowArc<'a, T> {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Display::fmt(self.deref(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: PartialOrd + ?Sized> PartialOrd for CowArc<'a, T> {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
self.deref().partial_cmp(other.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CowArc<'static, str> {
|
||||
fn default() -> Self {
|
||||
CowArc::Static(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CowArc<'static, Path> {
|
||||
fn default() -> Self {
|
||||
CowArc::Static(Path::new(""))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Ord + ?Sized> Ord for CowArc<'a, T> {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.deref().cmp(other.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PathBuf> for CowArc<'static, Path> {
|
||||
#[inline]
|
||||
fn from(value: PathBuf) -> Self {
|
||||
CowArc::Owned(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'static str> for CowArc<'static, Path> {
|
||||
#[inline]
|
||||
fn from(value: &'static str) -> Self {
|
||||
CowArc::Static(Path::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for CowArc<'static, str> {
|
||||
#[inline]
|
||||
fn from(value: String) -> Self {
|
||||
CowArc::Owned(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a String> for CowArc<'a, str> {
|
||||
#[inline]
|
||||
fn from(value: &'a String) -> Self {
|
||||
CowArc::Borrowed(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> From<&'static T> for CowArc<'static, T> {
|
||||
#[inline]
|
||||
fn from(value: &'static T) -> Self {
|
||||
CowArc::Static(value)
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ pub use short_names::get_short_name;
|
|||
pub mod synccell;
|
||||
pub mod syncunsafecell;
|
||||
|
||||
mod cow_arc;
|
||||
mod default;
|
||||
mod object_safe;
|
||||
pub use object_safe::assert_object_safe;
|
||||
|
@ -30,7 +29,6 @@ mod parallel_queue;
|
|||
|
||||
pub use ahash::{AHasher, RandomState};
|
||||
pub use bevy_utils_proc_macros::*;
|
||||
pub use cow_arc::*;
|
||||
pub use default::default;
|
||||
pub use hashbrown;
|
||||
pub use parallel_queue::*;
|
||||
|
|
Loading…
Reference in a new issue