Created
August 6, 2017 11:53
-
-
Save anonymous/e126f2ea51b5728d5ec1e2130d59d8bd to your computer and use it in GitHub Desktop.
Rust code shared from the playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::borrow::Cow; | |
use std::fmt::Debug; | |
use specs::Entity; | |
use Tile; | |
use TileRef; | |
use TileRefMut; | |
use TileMap; | |
use NeighboursIter; | |
use NeighboursIterMut; | |
pub trait ObjectCollection: Debug + Clone {} | |
impl<'a, T: ToOwned + ?Sized + Clone + Debug + 'a> ObjectCollection for T {} | |
pub struct ObjectsAroundIter<'a, C, T> | |
where T: Tile + 'a, | |
C: ObjectCollection + 'a | |
{ | |
object_lists: &'a [Cow<'a, C>], | |
neighbours_iter: NeighboursIter<'a, T>, | |
} | |
impl<'a, C, T> ObjectsAroundIter<'a, C, T> | |
where T: Tile, | |
C: ObjectCollection | |
{ | |
pub fn new(tiles: &'a [T], object_lists: &'a [Cow<'a, C>], width: usize, height: usize, center_x: usize, center_y: usize, radius: u8) -> ObjectsAroundIter<'a, C, T> { | |
let neighbours_iter = NeighboursIter::from_tiles(tiles, width, height, center_x, center_y, radius); | |
ObjectsAroundIter { object_lists, neighbours_iter } | |
} | |
} | |
impl<'a, C, T> Iterator for ObjectsAroundIter<'a, C, T> | |
where T: Tile, | |
C: ObjectCollection | |
{ | |
type Item = (TileRef<'a, T>, &'a Cow<'a, C>); | |
fn next(&mut self) -> Option<Self::Item> { | |
self.neighbours_iter.next().map(|tile_ref| { | |
let object_list = self.object_lists.get(tile_ref.index).unwrap(); | |
(tile_ref, object_list) | |
}) | |
} | |
} | |
pub struct ObjectsAroundIterMut<'a, C, T> | |
where T: Tile + 'a, | |
C: ObjectCollection + 'a | |
{ | |
object_lists: &'a mut [Cow<'a, C>], | |
neighbours_iter: NeighboursIterMut<'a, T>, | |
last_index: usize, | |
} | |
impl<'a, C, T> ObjectsAroundIterMut<'a, C, T> | |
where T: Tile, | |
C: ObjectCollection | |
{ | |
pub fn new(tiles: &'a mut [T], object_lists: &'a mut [Cow<'a, C>], width: usize, height: usize, center_x: usize, center_y: usize, radius: u8) -> ObjectsAroundIterMut<'a, C, T> { | |
let neighbours_iter = NeighboursIterMut::from_tiles(tiles, width, height, center_x, center_y, radius); | |
ObjectsAroundIterMut { object_lists, neighbours_iter, last_index: 0 } | |
} | |
} | |
impl<'a, C, T> Iterator for ObjectsAroundIterMut<'a, C, T> | |
where T: Tile, | |
C: ObjectCollection | |
{ | |
type Item = (TileRefMut<'a, T>, &'a mut C); | |
fn next(&mut self) -> Option<Self::Item> { | |
use std::mem; | |
self.neighbours_iter.next().map(|tile_ref| { | |
let object_lists = mem::replace(&mut self.object_lists, &mut []); | |
let (head, rest) = object_lists.split_at_mut(tile_ref.index - self.last_index + 1); | |
self.object_lists = rest; | |
self.last_index = tile_ref.index + 1; | |
(tile_ref, head.last_mut().unwrap().to_mut()) | |
}) | |
} | |
} | |
#[cfg(test)] | |
mod test { | |
use std::cell::Cell; | |
use super::*; | |
use tilemap::TileMap; | |
use tilemap::Tile; | |
#[derive(Debug, PartialEq, Eq)] | |
struct MyObjectList { | |
statics: Vec<usize>, | |
max_clones: usize, | |
num_clones: Cell<usize>, | |
} | |
impl MyObjectList { | |
pub fn new(max_clones: usize) -> Self { | |
MyObjectList { statics: vec![], num_clones: Cell::new(0), max_clones } | |
} | |
pub fn add_object(&mut self, item: usize) { | |
println!("Adding object to list"); | |
self.statics.push(item); | |
} | |
} | |
impl Clone for MyObjectList { | |
fn clone(&self) -> Self { | |
println!("Tring to clone"); | |
let clones = self.num_clones.get(); | |
if clones >= self.max_clones { | |
panic!("Shouldn't be cloned!"); | |
} | |
self.num_clones.set(clones + 1); | |
println!("Cloning objects_list"); | |
Self { statics: self.statics.clone(), num_clones: self.num_clones.clone(), max_clones: self.max_clones } | |
} | |
} | |
impl<'a> From<&'a MyObjectList> for Cow<'a, MyObjectList> { | |
fn from(s: &'a MyObjectList) -> Self { | |
Cow::Borrowed(s) | |
} | |
} | |
#[derive(Clone)] | |
struct EmptyTile; | |
impl Tile for EmptyTile { | |
fn new() -> EmptyTile { | |
EmptyTile | |
} | |
} | |
#[test] | |
fn objects_around_mut() { | |
let object_list = MyObjectList::new(3); | |
let mut map = TileMap::<MyObjectList, EmptyTile>::new(5, 5, Cow::from(&object_list)); | |
for (tile_ref, obj_list) in map.objects_around_mut(0, 0, 1) { | |
obj_list.add_object(tile_ref.x); | |
obj_list.add_object(tile_ref.y); | |
} | |
for (tile_ref, obj_list) in map.objects_around(0, 0, 1) { | |
assert_eq!((*obj_list).statics, vec![tile_ref.x, tile_ref.y]); | |
} | |
} | |
#[test] | |
fn objects_around() { | |
let object_list = MyObjectList::new(0); | |
let mut map = TileMap::<MyObjectList, EmptyTile>::new(5, 5, Cow::from(&object_list)); | |
for (tile_ref, obj_list) in map.objects_around(2, 2, 2) { | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment