Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/bevy_ecs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ trace = []
default = ["bevy_reflect"]

[dependencies]
bevy_ptr = { path = "../bevy_ptr", version = "0.8.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.8.0-dev", optional = true }
bevy_tasks = { path = "../bevy_tasks", version = "0.8.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.8.0-dev" }
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use crate::{
archetype::{AddBundle, Archetype, ArchetypeId, Archetypes, ComponentStatus},
component::{Component, ComponentId, ComponentTicks, Components, StorageType},
entity::{Entities, Entity, EntityLocation},
ptr::OwningPtr,
storage::{SparseSetIndex, SparseSets, Storages, Table},
};
use bevy_ecs_macros::all_tuples;
use bevy_ptr::OwningPtr;
use std::{any::TypeId, collections::HashMap};

/// An ordered collection of [`Component`]s.
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/component.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! Types for declaring and storing [`Component`]s.

use crate::{
ptr::OwningPtr,
storage::{SparseSetIndex, Storages},
system::Resource,
};
pub use bevy_ecs_macros::Component;
use bevy_ptr::OwningPtr;
use std::{
alloc::Layout,
any::{Any, TypeId},
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_ecs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub mod change_detection;
pub mod component;
pub mod entity;
pub mod event;
pub mod ptr;
pub mod query;
#[cfg(feature = "bevy_reflect")]
pub mod reflect;
Expand All @@ -15,6 +14,8 @@ pub mod storage;
pub mod system;
pub mod world;

pub use bevy_ptr as ptr;

/// Most commonly used re-exported types.
pub mod prelude {
#[doc(hidden)]
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/query/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use crate::{
change_detection::Ticks,
component::{Component, ComponentId, ComponentStorage, ComponentTicks, StorageType},
entity::Entity,
ptr::{ThinSlicePtr, UnsafeCellDeref},
query::{debug_checked_unreachable, Access, FilteredAccess},
storage::{ComponentSparseSet, Table, Tables},
world::{Mut, World},
};
use bevy_ecs_macros::all_tuples;
pub use bevy_ecs_macros::WorldQuery;
use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
use std::{cell::UnsafeCell, marker::PhantomData};

/// Types that can be queried from a [`World`].
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/query/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use crate::{
archetype::{Archetype, ArchetypeComponentId},
component::{Component, ComponentId, ComponentStorage, ComponentTicks, StorageType},
entity::Entity,
ptr::{ThinSlicePtr, UnsafeCellDeref},
query::{
debug_checked_unreachable, Access, Fetch, FetchState, FilteredAccess, QueryFetch,
ROQueryFetch, WorldQuery, WorldQueryGats,
Expand All @@ -11,6 +10,7 @@ use crate::{
world::World,
};
use bevy_ecs_macros::all_tuples;
use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
use std::{cell::UnsafeCell, marker::PhantomData};

use super::ReadOnlyFetch;
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/storage/blob_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
ptr::NonNull,
};

use crate::ptr::{OwningPtr, Ptr, PtrMut};
use bevy_ptr::{OwningPtr, Ptr, PtrMut};

/// A flat, type-erased data storage type
///
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/storage/sparse_set.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{
component::{ComponentId, ComponentInfo, ComponentTicks},
entity::Entity,
ptr::{OwningPtr, Ptr},
storage::BlobVec,
};
use bevy_ptr::{OwningPtr, Ptr};
use std::{cell::UnsafeCell, marker::PhantomData};

#[derive(Debug)]
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/storage/table.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{
component::{ComponentId, ComponentInfo, ComponentTicks, Components},
entity::Entity,
ptr::{OwningPtr, Ptr, PtrMut},
storage::{BlobVec, SparseSet},
};
use bevy_ptr::{OwningPtr, Ptr, PtrMut};
use bevy_utils::HashMap;
use std::{
cell::UnsafeCell,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/system/system_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::{
change_detection::Ticks,
component::{Component, ComponentId, ComponentTicks, Components},
entity::{Entities, Entity},
ptr::UnsafeCellDeref,
query::{
Access, FilteredAccess, FilteredAccessSet, QueryFetch, QueryState, ReadOnlyFetch,
WorldQuery,
Expand All @@ -15,6 +14,7 @@ use crate::{
};
pub use bevy_ecs_macros::SystemParam;
use bevy_ecs_macros::{all_tuples, impl_param_set};
use bevy_ptr::UnsafeCellDeref;
use std::{
fmt::Debug,
marker::PhantomData,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/world/entity_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use crate::{
change_detection::Ticks,
component::{Component, ComponentId, ComponentTicks, Components, StorageType},
entity::{Entities, Entity, EntityLocation},
ptr::{OwningPtr, Ptr, UnsafeCellDeref},
storage::{SparseSet, Storages},
world::{Mut, World},
};
use bevy_ptr::{OwningPtr, Ptr, UnsafeCellDeref};
use std::{any::TypeId, cell::UnsafeCell};

/// A read-only reference to a particular [`Entity`] and all of its components
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ use crate::{
change_detection::Ticks,
component::{Component, ComponentId, ComponentTicks, Components, StorageType},
entity::{AllocAtWithoutReplacement, Entities, Entity},
ptr::{OwningPtr, UnsafeCellDeref},
query::{QueryState, WorldQuery},
storage::{Column, SparseSet, Storages},
system::Resource,
};
use bevy_ptr::{OwningPtr, UnsafeCellDeref};
use bevy_utils::tracing::debug;
use std::{
any::TypeId,
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.8.0-dev" }
bevy_input = { path = "../bevy_input", version = "0.8.0-dev" }
bevy_log = { path = "../bevy_log", version = "0.8.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.8.0-dev" }
bevy_ptr = { path = "../bevy_ptr", version = "0.8.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.8.0-dev", features = ["bevy"] }
bevy_scene = { path = "../bevy_scene", version = "0.8.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.8.0-dev" }
Expand Down
5 changes: 5 additions & 0 deletions crates/bevy_internal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ pub mod math {
pub use bevy_math::*;
}

pub mod ptr {
//! Utilities for working with untyped pointers in a more safe way.
pub use bevy_ptr::*;
}

pub mod reflect {
// TODO: remove these renames once TypeRegistryArc is no longer required
//! Type reflection used for dynamically interacting with rust types.
Expand Down
11 changes: 11 additions & 0 deletions crates/bevy_ptr/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "bevy_ptr"
version = "0.8.0-dev"
edition = "2021"
description = "Utilities for working with untyped pointers in a more safe way"
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
license = "MIT OR Apache-2.0"
keywords = ["bevy"]

[dependencies]
7 changes: 7 additions & 0 deletions crates/bevy_ptr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# `bevy_ptr`

The `bevy_ptr` crate provides low-level abstractions for working with pointers in a more safe way than using rust's raw pointers.

Rust has lifetimed and typed references (`&'a T`), unlifetimed and typed references (`*const T`), but no lifetimed but untyped references.
`bevy_ptr` adds them, called `Ptr<'a>`, `PtrMut<'a>` and `OwningPtr<'a>`.
These types are lifetime-checked so can never lead to problems like use-after-frees and must always point to valid data.
25 changes: 24 additions & 1 deletion crates/bevy_ecs/src/ptr.rs → crates/bevy_ptr/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![doc = include_str!("../README.md")]
use std::{cell::UnsafeCell, marker::PhantomData, mem::MaybeUninit, ptr::NonNull};

/// Type-erased borrow of some unknown type chosen when constructing this type.
Expand Down Expand Up @@ -249,13 +250,35 @@ impl<'a, T> From<&'a [T]> for ThinSlicePtr<'a, T> {
}
}

pub(crate) trait UnsafeCellDeref<'a, T> {
mod private {
use std::cell::UnsafeCell;

pub trait SealedUnsafeCell {}
impl<'a, T> SealedUnsafeCell for &'a UnsafeCell<T> {}
}

/// Extension trait for helper methods on [`UnsafeCell`]
pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell {
/// # Safety
/// - The returned value must be unique and not alias any mutable or immutable references to the contents of the [`UnsafeCell`].
/// - At all times, you must avoid data races. If multiple threads have access to the same [`UnsafeCell`], then any writes must have a proper happens-before relation to all other accesses or use atomics ([`UnsafeCell`] docs for reference).
unsafe fn deref_mut(self) -> &'a mut T;

/// # Safety
/// - For the lifetime `'a` of the returned value you must not construct a mutable reference to the contents of the [`UnsafeCell`].
/// - At all times, you must avoid data races. If multiple threads have access to the same [`UnsafeCell`], then any writes must have a proper happens-before relation to all other accesses or use atomics ([`UnsafeCell`] docs for reference).
unsafe fn deref(self) -> &'a T;

/// Returns a copy of the contained value.
///
/// # Safety
/// - The [`UnsafeCell`] must not currently have a mutable reference to its content.
/// - At all times, you must avoid data races. If multiple threads have access to the same [`UnsafeCell`], then any writes must have a proper happens-before relation to all other accesses or use atomics ([`UnsafeCell`] docs for reference).
unsafe fn read(self) -> T
where
T: Copy;
}

impl<'a, T> UnsafeCellDeref<'a, T> for &'a UnsafeCell<T> {
#[inline]
unsafe fn deref_mut(self) -> &'a mut T {
Expand Down
1 change: 1 addition & 0 deletions tools/publish.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# if crate A depends on crate B, B must come before A in this list
crates=(
bevy_utils
bevy_ptr
bevy_macro_utils
bevy_derive
bevy_math
Expand Down