Skip to content

Commit

Permalink
Merge #116
Browse files Browse the repository at this point in the history
116: Even more cleanup r=torkleyy a=torkleyy

Fixes #111 

Co-authored-by: Thomas Schaller <torkleyy@gmail.com>
  • Loading branch information
bors[bot] and torkleyy committed Mar 29, 2019
2 parents d2a74f1 + d2be338 commit 9b5b027
Show file tree
Hide file tree
Showing 30 changed files with 342 additions and 291 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shred"
version = "0.7.1"
version = "0.8.0"
authors = ["torkleyy <torkleyy@gmail.com>"]
description = """
Dispatches systems in parallel which need read access to some resources,
Expand All @@ -13,6 +13,7 @@ keywords = ["parallel", "systems", "resources", "ecs"]
categories = ["concurrency"]
license = "MIT/Apache-2.0"
exclude = ["bors.toml", ".travis.yml"]
edition = "2018"

[badges]
travis-ci = { repository = "torkleyy/shred" }
Expand Down
2 changes: 1 addition & 1 deletion benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ fn basic(b: &mut Bencher) {
.with(SpringForce, "spring", &[])
.with(IntegrationSystem, "integration", &[])
.with(ClearForceAccum, "clear_force", &["integration"]) // clear_force is executed after
// the integration
// the integration
.build();

let mut res = World::new();
Expand Down
2 changes: 1 addition & 1 deletion examples/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extern crate shred;
#[macro_use]
extern crate shred_derive;

use shred::{DispatcherBuilder, Read, ResourceId, World, System, SystemData, Write};
use shred::{DispatcherBuilder, Read, ResourceId, System, SystemData, World, Write};

#[derive(Debug, Default)]
struct ResA;
Expand Down
2 changes: 1 addition & 1 deletion examples/basic_dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extern crate shred;

use shred::{DispatcherBuilder, Read, World, System, Write};
use shred::{DispatcherBuilder, Read, System, World, Write};

#[derive(Debug, Default)]
struct ResA;
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_bundle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extern crate shred;

use shred::{Read, ResourceId, World, SystemData, Write};
use shred::{Read, ResourceId, SystemData, World, Write};

#[derive(Debug, Default)]
struct ResA;
Expand Down
2 changes: 1 addition & 1 deletion examples/derive_bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extern crate shred;
#[macro_use]
extern crate shred_derive;

use shred::{Read, ResourceId, World, SystemData, Write};
use shred::{Read, ResourceId, SystemData, World, Write};

#[derive(Debug, Default)]
struct ResA;
Expand Down
96 changes: 54 additions & 42 deletions examples/dyn_sys_data.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Warning: this example is a lot more advanced than the others.
//!
//! This example shows a possible way to make shred interact with a scripting language.
//! This example shows a possible way to make shred interact with a scripting
//! language.
//!
//! It does that by implementing `DynamicSystemData` and using `MetaTable`.

Expand All @@ -9,10 +10,11 @@ extern crate shred;
// in a real application you would use `fnv`
use std::collections::HashMap;

use shred::{Accessor, AccessorCow, CastFrom, DispatcherBuilder, DynamicSystemData, MetaTable, Read, Resource,
ResourceId, World,
System, SystemData};
use shred::cell::{Ref, RefMut};
use shred::{
cell::{Ref, RefMut},
Accessor, AccessorCow, CastFrom, DispatcherBuilder, DynamicSystemData, MetaTable, Read,
Resource, ResourceId, System, SystemData, World,
};

struct Dependencies {
reads: Vec<ResourceId>,
Expand Down Expand Up @@ -49,32 +51,37 @@ impl<'a> System<'a> for DynamicSystem {

fn run(&mut self, mut data: Self::SystemData) {
let meta = data.meta_table;
let reads: Vec<&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")
}).collect();

let writes: Vec<&mut 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 Reflection = meta.get_mut(res).expect("Not registered in meta table");
let reads: Vec<&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")
})
.collect();

res
}).collect();
let writes: Vec<&mut 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 Reflection = meta.get_mut(res).expect("Not registered in meta table");

res
})
.collect();

let input = ScriptInput {
reads,
writes,
};
let input = ScriptInput { reads, writes };

// call the script with the input
(self.script)(input);
Expand All @@ -90,7 +97,8 @@ impl<'a> System<'a> for DynamicSystem {
}

/// Some trait that all of your dynamic resources should implement.
/// This trait should be able to register / transfer it to the scripting framework.
/// This trait should be able to register / transfer it to the scripting
/// framework.
trait Reflection {
fn call_method(&self, s: &str);
}
Expand Down Expand Up @@ -153,21 +161,21 @@ impl<'a> DynamicSystemData<'a> for ScriptSystemData<'a> {
.reads
.iter()
.map(|id| id.0)
.map(|id| res
.try_fetch_internal(id)
.expect("bug: the requested resource does not exist")
.borrow()
)
.map(|id| {
res.try_fetch_internal(id)
.expect("bug: the requested resource does not exist")
.borrow()
})
.collect();
let writes = access
.writes
.iter()
.map(|id| id.0)
.map(|id| res
.try_fetch_internal(id)
.expect("bug: the requested resource does not exist")
.borrow_mut()
)
.map(|id| {
res.try_fetch_internal(id)
.expect("bug: the requested resource does not exist")
.borrow_mut()
})
.collect();

ScriptSystemData {
Expand Down Expand Up @@ -258,14 +266,18 @@ fn main() {
table.register::<Bar>("Bar");
}

let mut dispatcher = DispatcherBuilder::new().with(NormalSys, "normal", &[]).build();
let mut dispatcher = DispatcherBuilder::new()
.with(NormalSys, "normal", &[])
.build();
dispatcher.setup(&mut res);

let script0 = create_script_sys(&res);

// it is recommended you create a second dispatcher dedicated to scripts,
// that'll allow you to rebuild if necessary
let mut scripts = DispatcherBuilder::new().with(script0, "script0", &[]).build();
let mut scripts = DispatcherBuilder::new()
.with(script0, "script0", &[])
.build();
scripts.setup(&mut res);

// Game loop
Expand Down
2 changes: 1 addition & 1 deletion examples/fetch_opt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extern crate shred;

use shred::{DispatcherBuilder, Read, ReadExpect, World, System, Write};
use shred::{DispatcherBuilder, Read, ReadExpect, System, World, Write};

#[derive(Debug, Default)]
struct ResA;
Expand Down
2 changes: 1 addition & 1 deletion examples/generic_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern crate shred_derive;

use std::fmt::Debug;

use shred::{Read, Resource, ResourceId, World, SystemData, Write};
use shred::{Read, Resource, ResourceId, SystemData, World, Write};

trait Hrtb<'a> {}

Expand Down
2 changes: 1 addition & 1 deletion examples/par_seq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ extern crate shred;

use rayon::ThreadPoolBuilder;

use shred::{ParSeq, Read, World, System};
use shred::{ParSeq, Read, System, World};

macro_rules! impl_sys {
($( $id:ident )*) => {
Expand Down
2 changes: 1 addition & 1 deletion examples/seq_dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extern crate shred;
#[macro_use]
extern crate shred_derive;

use shred::{DispatcherBuilder, Read, ResourceId, World, System, SystemData, Write};
use shred::{DispatcherBuilder, Read, ResourceId, System, SystemData, World, Write};

#[derive(Debug, Default)]
struct ResA;
Expand Down
2 changes: 1 addition & 1 deletion examples/thread_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extern crate shred;
#[macro_use]
extern crate shred_derive;

use shred::{DispatcherBuilder, Read, ResourceId, World, System, SystemData, Write};
use shred::{DispatcherBuilder, Read, ResourceId, System, SystemData, World, Write};

#[derive(Debug, Default)]
struct ResA;
Expand Down
11 changes: 9 additions & 2 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
reorder_imports = true
reorder_imports_in_group = true
hard_tabs = false
merge_imports = true
reorder_impl_items = true
use_field_init_shorthand = true
use_try_shorthand = true
format_doc_comments = true
wrap_comments = true
#edition = "2018"
version = "Two"
6 changes: 2 additions & 4 deletions shred-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ extern crate quote;
extern crate syn;

use proc_macro::TokenStream;
use syn::punctuated::Punctuated;
use syn::token::Comma;
use syn::{
Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed, Ident, Lifetime,
Type, WhereClause, WherePredicate,
punctuated::Punctuated, token::Comma, Data, DataStruct, DeriveInput, Field, Fields,
FieldsNamed, FieldsUnnamed, Ident, Lifetime, Type, WhereClause, WherePredicate,
};

/// Used to `#[derive]` the trait `SystemData`.
Expand Down
43 changes: 23 additions & 20 deletions src/cell.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! Helper module for some internals, most users don't need to interact with it.

use std::cell::UnsafeCell;
use std::error::Error;
use std::fmt::{Display, Error as FormatError, Formatter};
use std::ops::{Deref, DerefMut};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::usize;
use std::{
cell::UnsafeCell,
error::Error,
fmt::{Display, Error as FormatError, Formatter},
ops::{Deref, DerefMut},
sync::atomic::{AtomicUsize, Ordering},
usize,
};

/// Marker struct for an invalid borrow error
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
Expand Down Expand Up @@ -98,7 +100,8 @@ impl<T> TrustCell<T> {
///
/// # Panics
///
/// This function will panic if there is a mutable reference to the data already in use.
/// This function will panic if there is a mutable reference to the data
/// already in use.
pub fn borrow(&self) -> Ref<T> {
self.check_flag_read().expect("Already borrowed mutably");

Expand All @@ -110,8 +113,8 @@ impl<T> TrustCell<T> {

/// Get an immutable reference to the inner data.
///
/// Absence of write accesses is checked at run-time. If access is not possible, an error is
/// returned.
/// Absence of write accesses is checked at run-time. If access is not
/// possible, an error is returned.
pub fn try_borrow(&self) -> Result<Ref<T>, InvalidBorrow> {
self.check_flag_read()?;

Expand All @@ -127,7 +130,8 @@ impl<T> TrustCell<T> {
///
/// # Panics
///
/// This function will panic if there are any references to the data already in use.
/// This function will panic if there are any references to the data already
/// in use.
pub fn borrow_mut(&self) -> RefMut<T> {
self.check_flag_write().expect("Already borrowed");

Expand All @@ -139,7 +143,8 @@ impl<T> TrustCell<T> {

/// Get a mutable reference to the inner data.
///
/// Exclusive access is checked at run-time. If access is not possible, an error is returned.
/// Exclusive access is checked at run-time. If access is not possible, an
/// error is returned.
pub fn try_borrow_mut(&self) -> Result<RefMut<T>, InvalidBorrow> {
self.check_flag_write()?;

Expand All @@ -157,10 +162,11 @@ impl<T> TrustCell<T> {
unsafe { &mut *self.inner.get() }
}

/// Make sure we are allowed to aquire a read lock, and increment the read count by 1
/// Make sure we are allowed to aquire a read lock, and increment the read
/// count by 1
fn check_flag_read(&self) -> Result<(), InvalidBorrow> {
// Check that no write reference is out, then try to increment the read count and return
// once successful.
// Check that no write reference is out, then try to increment the read count
// and return once successful.
loop {
let val = self.flag.load(Ordering::Acquire);

Expand All @@ -174,7 +180,8 @@ impl<T> TrustCell<T> {
}
}

/// Make sure we are allowed to aquire a write lock, and then set the write lock flag.
/// Make sure we are allowed to aquire a write lock, and then set the write
/// lock flag.
fn check_flag_write(&self) -> Result<(), InvalidBorrow> {
// Check we have 0 references out, and then set the ref count to usize::MAX to
// indicate a write lock.
Expand All @@ -185,11 +192,7 @@ impl<T> TrustCell<T> {
}
}

unsafe impl<T> Sync for TrustCell<T>
where
T: Sync,
{
}
unsafe impl<T> Sync for TrustCell<T> where T: Sync {}

impl<T> Default for TrustCell<T>
where
Expand Down
Loading

0 comments on commit 9b5b027

Please sign in to comment.