Skip to content
Merged
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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ rust-version = "1.59.0"
[dependencies]
ahash = "0.7.6"
arrayvec = "0.7.2"
atomic_refcell = "0.1.10" # part of public API
rayon = { version = "1.5.0", optional = true }
shred-derive = { path = "shred-derive", version = "0.6.3", optional = true }
smallvec = "1.6.1"
Expand Down
21 changes: 13 additions & 8 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,14 @@ fn bench_fetching(b: &mut Bencher) {

#[bench]
fn bench_indirection_refs(b: &mut Bencher) {
use shred::cell::{Ref, TrustCell};
use shred::cell::{AtomicRef, AtomicRefCell};
use std::ops::Deref;

let cell = TrustCell::new(Box::new(10));
let refs: Vec<Ref<'_, Box<usize>>> = std::iter::repeat(cell.borrow()).take(10000).collect();
let cell = AtomicRefCell::new(Box::new(10));
let borrow = cell.borrow();
let refs: Vec<AtomicRef<'_, Box<usize>>> = std::iter::repeat_with(|| AtomicRef::clone(&borrow))
.take(10000)
.collect();

b.iter(|| {
let sum: usize = refs.iter().map(|v| v.deref().deref()).sum();
Expand All @@ -255,13 +258,15 @@ fn bench_indirection_refs(b: &mut Bencher) {

#[bench]
fn bench_direct_refs(b: &mut Bencher) {
use shred::cell::{Ref, TrustCell};
use shred::cell::{AtomicRef, AtomicRefCell};
use std::ops::Deref;

let cell = TrustCell::new(Box::new(10));
let refs: Vec<Ref<'_, usize>> = std::iter::repeat(cell.borrow().map(Box::as_ref))
.take(10000)
.collect();
let cell = AtomicRefCell::new(Box::new(10));
let mapped_borrow = AtomicRef::map(cell.borrow(), Box::as_ref);
let refs: Vec<AtomicRef<'_, usize>> =
std::iter::repeat_with(|| AtomicRef::clone(&mapped_borrow))
.take(10000)
.collect();

b.iter(|| {
let sum: usize = refs.iter().map(|v| v.deref()).sum();
Expand Down
52 changes: 25 additions & 27 deletions examples/dyn_sys_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern crate shred;
use ahash::AHashMap as HashMap;

use shred::{
cell::{Ref, RefMut},
cell::{AtomicRef, AtomicRefMut},
Accessor, AccessorCow, CastFrom, DispatcherBuilder, DynamicSystemData, MetaTable, Read,
Resource, ResourceId, System, SystemData, World,
};
Expand Down Expand Up @@ -54,32 +54,20 @@ impl<'a> System<'a> for DynamicSystem {
let reads: Vec<&dyn Reflection> = data
.reads
.iter()
.map(|resource| {
// explicitly use the type because we're dealing with `&Resource` which is
// implemented by a lot of types; we don't want to accidentally
// get a `&Box<Resource>` and cast it to a `&Resource`.
let res = Box::as_ref(resource);

meta.get(res).expect("Not registered in meta table")
})
.map(|resource| meta.get(&**resource).expect("Not registered in meta table"))
.collect();

let writes: Vec<&mut dyn Reflection> = data
.writes
.iter_mut()
.map(|resource| {
// explicitly use the type because we're dealing with `&mut Resource` which is
// implemented by a lot of types; we don't want to accidentally get a
// `&mut Box<Resource>` and cast it to a `&mut Resource`.
let res = Box::as_mut(resource);

// For some reason this needs a type ascription, otherwise Rust will think it's
// a `&mut (Reflection + '_)` (as opposed to `&mut (Reflection + 'static)`.
let res: &mut dyn Reflection = meta.get_mut(res).expect(
// a `&mut (Reflaction + '_)` (as opposed to `&mut (Reflection + 'static)`. (Note this
// isn't needed in newer rust version but fails on the MSRV of 1.59.0).
let res: &mut dyn Reflection = meta.get_mut(&mut **resource).expect(
"Not registered in meta \
table",
);

res
})
.collect();
Expand Down Expand Up @@ -150,37 +138,47 @@ struct ScriptInput<'a> {

struct ScriptSystemData<'a> {
meta_table: Read<'a, ReflectionTable>,
reads: Vec<Ref<'a, Box<dyn Resource + 'static>>>,
writes: Vec<RefMut<'a, Box<dyn Resource + 'static>>>,
reads: Vec<AtomicRef<'a, dyn Resource + 'static>>,
writes: Vec<AtomicRefMut<'a, dyn Resource + 'static>>,
}

impl<'a> DynamicSystemData<'a> for ScriptSystemData<'a> {
type Accessor = Dependencies;

fn setup(_accessor: &Dependencies, _res: &mut World) {}

fn fetch(access: &Dependencies, res: &'a World) -> Self {
fn fetch(access: &Dependencies, world: &'a World) -> Self {
let reads = access
.reads
.iter()
.map(|id| {
res.try_fetch_internal(id.clone())
.expect("bug: the requested resource does not exist")
.borrow()
let id = id.clone();
// SAFETY: We don't expose mutable reference to the Box or swap it out.
let res = unsafe { world.try_fetch_internal(id) };
AtomicRef::map(
res.expect("bug: the requested resource does not exist")
.borrow(),
Box::as_ref,
)
})
.collect();
let writes = access
.writes
.iter()
.map(|id| {
res.try_fetch_internal(id.clone())
.expect("bug: the requested resource does not exist")
.borrow_mut()
let id = id.clone();
// SAFETY: We don't expose mutable reference to the Box or swap it out.
let res = unsafe { world.try_fetch_internal(id) };
AtomicRefMut::map(
res.expect("bug: the requested resource does not exist")
.borrow_mut(),
Box::as_mut,
)
})
.collect();

ScriptSystemData {
meta_table: SystemData::fetch(res),
meta_table: SystemData::fetch(world),
reads,
writes,
}
Expand Down
Loading