Skip to content

Commit

Permalink
Merge #620
Browse files Browse the repository at this point in the history
620: impl Clone for JoinIter r=azriel91 a=lcnr

Closes #593 

## Checklist

* [x] I've added tests for all code changes and additions (where applicable)
* [x] I've added a demonstration of the new feature to one or more examples
* [x] I've updated the book to reflect my changes
* [x] Usage of new public items is shown in the API docs

## API changes

implement `Clone` for `JoinIter` where possible.
Updates hibitset version as this requires access to `BitIter::clone` and `BitIterAnd::clone`.
This is not a breaking change


Co-authored-by: Bastian Kauschke <[email protected]>
  • Loading branch information
bors[bot] and lcnr authored Feb 17, 2020
2 parents 69a4a98 + 32e099b commit 33ee8fe
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 2 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Unreleased

* Implement `Clone` for some `JoinIter`. ([#620])
* Bump `hibitset` to `0.6.3`. ([#620])

[#620]: https://github.com/slide-rs/specs/pull/620

# 0.16.0

* Update `syn`, `quote` and `proc-macro2` to `1.0`. ([#648])
Expand All @@ -17,7 +24,7 @@

# 0.15.1

* Benchmark uses `nalgebra` instead of `cgmath`. ([#619]).
* Benchmark uses `nalgebra` instead of `cgmath`. ([#619])
* Bumped `shrev` from `1.0` to `1.1`. ([#619]).
* Update hashbrown to 0.6.0, criterion to 0.3 ([#627], [#632])
* Remove `mopa` in favour of `std::any::Any` ([#631])
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ travis-ci = { repository = "slide-rs/specs" }
[dependencies]
crossbeam-queue = "0.2.1"
hashbrown = "0.7.0"
hibitset = { version = "0.6.2", default-features = false }
hibitset = { version = "0.6.3", default-features = false }
log = "0.4.8"
shred = { version = "0.10.2", default-features = false }
shrev = "1.1.1"
Expand Down
73 changes: 73 additions & 0 deletions src/join/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,79 @@ impl<J: Join> std::iter::Iterator for JoinIter<J> {
}
}

/// Clones the `JoinIter`.
///
/// # Examples
///
/// ```
/// # use specs::prelude::*;
/// # #[derive(Debug)]
/// # struct Position; impl Component for Position { type Storage = VecStorage<Self>; }
/// # #[derive(Debug)]
/// # struct Collider; impl Component for Collider { type Storage = VecStorage<Self>; }
/// let mut world = World::new();
///
/// world.register::<Position>();
/// world.register::<Collider>();
///
/// // add some entities to our world
/// for _ in 0..10 {
/// let entity = world
/// .create_entity()
/// .with(Position)
/// .with(Collider)
/// .build();
/// }
///
/// // check for collisions between entities
/// let positions = world.read_storage::<Position>();
/// let colliders = world.read_storage::<Collider>();
///
/// let mut join_iter = (&positions, &colliders).join();
/// while let Some(a) = join_iter.next() {
/// for b in join_iter.clone() {
/// # let check_collision = |a, b| true;
/// if check_collision(a, b) {
/// // do stuff
/// }
/// }
/// }
/// ```
///
/// It is *not* possible to clone a `JoinIter` which allows for
/// mutation of its content, as this would lead to shared mutable
/// access.
///
/// ```compile_fail
/// # use specs::prelude::*;
/// # #[derive(Debug)]
/// # struct Position; impl Component for Position { type Storage = VecStorage<Self>; }
/// # let mut world = World::new();
/// # world.register::<Position>();
/// # let entity = world.create_entity().with(Position).build();
/// // .. previous example
///
/// let mut positions = world.write_storage::<Position>();
///
/// let mut join_iter = (&mut positions).join();
/// // this must not compile, as the following line would cause
/// // undefined behavior!
/// let mut cloned_iter = join_iter.clone();
/// let (mut alias_one, mut alias_two) = (join_iter.next(), cloned_iter.next());
/// ```
impl<J: Join> Clone for JoinIter<J>
where
J::Mask: Clone,
J::Value: Clone,
{
fn clone(&self) -> Self {
Self {
keys: self.keys.clone(),
values: self.values.clone(),
}
}
}

macro_rules! define_open {
// use variables to indicate the arity of the tuple
($($from:ident),*) => {
Expand Down

0 comments on commit 33ee8fe

Please sign in to comment.