Guest User

Untitled

a guest
Nov 12th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 KB | None | 0 0
  1. //! Data structure for handling (dense) 2D grids
  2. use std::cmp;
  3.  
  4. /// 2D grid
  5. #[derive(Debug, Clone)]
  6. pub struct Grid2D<T> {
  7. width: usize,
  8. height: usize,
  9. grid: Vec<T>,
  10. }
  11.  
  12. /// Immutable iterator over a Grid2D
  13. #[derive(Debug)]
  14. pub struct GridIter<'a, T> {
  15. owner: &'a Grid2D<T>,
  16. x: i32,
  17. y: i32,
  18. ofs: usize,
  19. /// distance between end of one span and beginning of another
  20. stride: usize,
  21. x1: i32,
  22. x2: i32,
  23. y2: i32,
  24. }
  25.  
  26. /// Mutable iterator over a Grid2D
  27. #[derive(Debug)]
  28. pub struct MutGridIter<'a, T> {
  29. owner: &'a mut Grid2D<T>,
  30. x: i32,
  31. y: i32,
  32. ofs: usize,
  33. /// distance between end of one span and beginning of another
  34. stride: usize,
  35. x1: i32,
  36. x2: i32,
  37. y2: i32,
  38. }
  39.  
  40. impl<T: Clone> Grid2D<T> {
  41. /// New empty grid
  42. pub fn new() -> Grid2D<T> {
  43. Grid2D {
  44. width: 0,
  45. height: 0,
  46. grid: Vec::new(),
  47. }
  48. }
  49.  
  50. /// New sized grid, filled in with value
  51. pub fn new_sized(width: usize, height: usize, val: &T) -> Grid2D<T> {
  52. Grid2D {
  53. width,
  54. height,
  55. grid: vec![val.clone(); width * height],
  56. }
  57. }
  58.  
  59. /// Coordinates to offset in array
  60. fn to_offset(&self, x: i32, y: i32) -> Option<usize> {
  61. // This makes use of the fact that negative values casted to usize
  62. // will be larger than the width/height.
  63. if (x as usize) < self.width && (y as usize) < self.height {
  64. Some((y as usize) * self.width + (x as usize))
  65. } else {
  66. None
  67. }
  68. }
  69.  
  70. /// 2D map lookup
  71. pub fn get(&self, x: i32, y: i32) -> Option<&T> {
  72. self.to_offset(x, y).map(|ofs| &self.grid[ofs])
  73. }
  74.  
  75. /// 2D map lookup (mutable)
  76. #[allow(dead_code)]
  77. pub fn get_mut(&mut self, x: i32, y: i32) -> Option<&mut T> {
  78. // Cannot use the following:
  79. // self.to_offset(x, y).map(|ofs| &mut self.grid[ofs])
  80. // error[E0373]: closure may outlive the current function, but it borrows `self`, which is
  81. // owned by the current function
  82. if let Some(ofs) = self.to_offset(x, y) {
  83. Some(&mut self.grid[ofs])
  84. } else {
  85. None
  86. }
  87. }
  88.  
  89. /// 2D map put
  90. pub fn set(&mut self, x: i32, y: i32, tile_in: T) -> bool {
  91. if let Some(ofs) = self.to_offset(x, y) {
  92. self.grid[ofs] = tile_in;
  93. true
  94. } else {
  95. false
  96. }
  97. }
  98.  
  99. /// Return width of grid
  100. pub fn width(&self) -> usize {
  101. self.width
  102. }
  103.  
  104. /// Return height of grid
  105. pub fn height(&self) -> usize {
  106. self.height
  107. }
  108.  
  109. /// Clip a rectangle against grid boundaries
  110. fn clip_rect(&self, x1: i32, y1: i32, x2: i32, y2: i32) -> (i32, i32, i32, i32) {
  111. let x1 = cmp::min(cmp::max(x1, 0), self.width as i32);
  112. let x2 = cmp::min(cmp::max(x2, 0), self.width as i32);
  113. let y1 = cmp::min(cmp::max(y1, 0), self.height as i32);
  114. let y2 = cmp::min(cmp::max(y2, 0), self.height as i32);
  115. (x1, y1, x2, y2)
  116. }
  117.  
  118. /// Iterate over a rectangle
  119. pub fn iter_region(&self, x1: i32, y1: i32, x2: i32, y2: i32) -> GridIter<T> {
  120. let (x1, y1, x2, y2) = self.clip_rect(x1, y1, x2, y2);
  121. let ofs = self.to_offset(x1, y1).unwrap_or(0);
  122. let stride = self.width - cmp::max(x2 - x1, 0) as usize;
  123. GridIter {
  124. owner: self,
  125. x: x1,
  126. y: y1,
  127. ofs: ofs,
  128. stride,
  129. x1,
  130. x2,
  131. y2,
  132. }
  133. }
  134.  
  135. /// Iterate over a rectangle (mutable)
  136. #[allow(dead_code)]
  137. pub fn iter_region_mut(&mut self, x1: i32, y1: i32, x2: i32, y2: i32) -> MutGridIter<T> {
  138. let (x1, y1, x2, y2) = self.clip_rect(x1, y1, x2, y2);
  139. let ofs = self.to_offset(x1, y1).unwrap_or(0);
  140. let stride = self.width - cmp::max(x2 - x1, 0) as usize;
  141. MutGridIter {
  142. owner: self,
  143. x: x1,
  144. y: y1,
  145. ofs,
  146. stride,
  147. x1,
  148. x2,
  149. y2,
  150. }
  151. }
  152.  
  153. /// Iterate over entire grid
  154. #[allow(dead_code)]
  155. pub fn iter(&mut self) -> GridIter<T> {
  156. let (x2, y2) = (self.width as i32, self.height as i32);
  157. GridIter {
  158. owner: self,
  159. x: 0,
  160. y: 0,
  161. ofs: 0,
  162. stride: 0,
  163. x1: 0,
  164. x2,
  165. y2,
  166. }
  167. }
  168.  
  169. /// Iterate over entire grid (mutable)
  170. pub fn iter_mut(&mut self) -> MutGridIter<T> {
  171. let (x2, y2) = (self.width as i32, self.height as i32);
  172. MutGridIter {
  173. owner: self,
  174. x: 0,
  175. y: 0,
  176. ofs: 0,
  177. stride: 0,
  178. x1: 0,
  179. x2,
  180. y2,
  181. }
  182. }
  183.  
  184. // TODO: consuming iterator iter_into() ? would be useful for operations that create
  185. // a new structure and throw away the old one.
  186. }
  187.  
  188. impl<'a, T> Iterator for GridIter<'a, T> {
  189. type Item = ((i32, i32), &'a T);
  190.  
  191. fn next(&mut self) -> Option<Self::Item> {
  192. if self.y < self.y2 && self.x < self.x2 {
  193. // This assumes no out-of-bounds access as the original rectangle
  194. // was clipped against the owner extents.
  195. let ret = Some(((self.x, self.y), &self.owner.grid[self.ofs]));
  196.  
  197. // Advance
  198. self.x += 1;
  199. self.ofs += 1;
  200. if self.x >= self.x2 {
  201. self.x = self.x1;
  202. self.y += 1;
  203. self.ofs += self.stride;
  204. }
  205.  
  206. ret
  207. } else {
  208. // out of range
  209. None
  210. }
  211. }
  212. }
  213.  
  214. impl<'a, T> Iterator for MutGridIter<'a, T> {
  215. type Item = ((i32, i32), &'a mut T);
  216.  
  217. fn next(&mut self) -> Option<Self::Item> {
  218. if self.y < self.y2 && self.x < self.x2 {
  219. // This assumes no out-of-bounds access as the original rectangle
  220. // was clipped against the owner extents.
  221. // TODO cannot get rid of the unsafe here?
  222. // error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in
  223. // function call due to conflicting requirements
  224. let ret = Some(((self.x, self.y), unsafe {
  225. &mut *(&mut self.owner.grid[self.ofs] as *mut T)
  226. }));
  227.  
  228. // Advance
  229. self.x += 1;
  230. self.ofs += 1;
  231. if self.x >= self.x2 {
  232. self.x = self.x1;
  233. self.y += 1;
  234. self.ofs += self.stride;
  235. }
  236.  
  237. ret
  238. } else {
  239. // out of range
  240. None
  241. }
  242. }
  243. }
  244.  
  245. #[cfg(test)]
  246. mod tests {
  247. use super::*;
  248.  
  249. #[test]
  250. fn test_new() {
  251. let x = Grid2D::<i32>::new();
  252. assert_eq!(x.get(-1, -1), None);
  253. assert_eq!(x.get(0, 0), None);
  254. assert_eq!(x.get(1, 1), None);
  255. }
  256.  
  257. #[test]
  258. fn test() {
  259. let mut x = Grid2D::new_sized(3, 3, &0);
  260. x.set(1, 1, 21);
  261. *(x.get_mut(2, 2).unwrap()) = 23;
  262. *(x.get_mut(2, 1).unwrap()) = 26;
  263. assert_eq!(x.get(0, 0), Some(&0));
  264. assert_eq!(x.get(0, 1), Some(&0));
  265. assert_eq!(x.get(0, 2), Some(&0));
  266. assert_eq!(x.get(1, 1), Some(&21));
  267. assert_eq!(x.get(2, 1), Some(&26));
  268. assert_eq!(x.get(2, 2), Some(&23));
  269. }
  270.  
  271. #[test]
  272. fn test_iter_region() {
  273. let mut x = Grid2D::new_sized(3, 3, &0);
  274. x.set(1, 1, 21);
  275. x.set(2, 1, 23);
  276. let mut i = x.iter_region(-1, -1, 4, 4);
  277. assert_eq!(i.next(), Some(((0, 0), &0)));
  278. assert_eq!(i.next(), Some(((1, 0), &0)));
  279. assert_eq!(i.next(), Some(((2, 0), &0)));
  280. assert_eq!(i.next(), Some(((0, 1), &0)));
  281. assert_eq!(i.next(), Some(((1, 1), &21)));
  282. assert_eq!(i.next(), Some(((2, 1), &23)));
  283. assert_eq!(i.next(), Some(((0, 2), &0)));
  284. assert_eq!(i.next(), Some(((1, 2), &0)));
  285. assert_eq!(i.next(), Some(((2, 2), &0)));
  286. assert_eq!(i.next(), None);
  287.  
  288. let mut i = x.iter_region(1, 1, 4, 4);
  289. assert_eq!(i.next(), Some(((1, 1), &21)));
  290. assert_eq!(i.next(), Some(((2, 1), &23)));
  291. assert_eq!(i.next(), Some(((1, 2), &0)));
  292. assert_eq!(i.next(), Some(((2, 2), &0)));
  293. assert_eq!(i.next(), None);
  294.  
  295. let mut i = x.iter_region(-1, -1, 2, 2);
  296. assert_eq!(i.next(), Some(((0, 0), &0)));
  297. assert_eq!(i.next(), Some(((1, 0), &0)));
  298. assert_eq!(i.next(), Some(((0, 1), &0)));
  299. assert_eq!(i.next(), Some(((1, 1), &21)));
  300.  
  301. let mut i = x.iter_region(1, 1, 1, 1);
  302. assert_eq!(i.next(), None);
  303.  
  304. let mut i = x.iter_region(1, 1, -1, -1);
  305. assert_eq!(i.next(), None);
  306. }
  307.  
  308. #[test]
  309. fn test_iter_region_mut() {
  310. let mut x = Grid2D::new_sized(3, 3, &0);
  311. x.set(1, 1, 21);
  312. {
  313. let mut i = x.iter_region_mut(-1, -1, 4, 4);
  314. assert_eq!(i.next(), Some(((0, 0), &mut 0)));
  315. assert_eq!(i.next(), Some(((1, 0), &mut 0)));
  316. assert_eq!(i.next(), Some(((2, 0), &mut 0)));
  317. assert_eq!(i.next(), Some(((0, 1), &mut 0)));
  318. assert_eq!(i.next(), Some(((1, 1), &mut 21)));
  319. assert_eq!(i.next(), Some(((2, 1), &mut 0)));
  320. assert_eq!(i.next(), Some(((0, 2), &mut 0)));
  321. assert_eq!(i.next(), Some(((1, 2), &mut 0)));
  322. assert_eq!(i.next(), Some(((2, 2), &mut 0)));
  323. assert_eq!(i.next(), None);
  324. }
  325. {
  326. let mut i = x.iter_region_mut(1, 1, 4, 4);
  327. assert_eq!(i.next(), Some(((1, 1), &mut 21)));
  328. assert_eq!(i.next(), Some(((2, 1), &mut 0)));
  329. assert_eq!(i.next(), Some(((1, 2), &mut 0)));
  330. assert_eq!(i.next(), Some(((2, 2), &mut 0)));
  331. assert_eq!(i.next(), None);
  332. }
  333. {
  334. let mut i = x.iter_region_mut(-1, -1, 2, 2);
  335. assert_eq!(i.next(), Some(((0, 0), &mut 0)));
  336. assert_eq!(i.next(), Some(((1, 0), &mut 0)));
  337. assert_eq!(i.next(), Some(((0, 1), &mut 0)));
  338. assert_eq!(i.next(), Some(((1, 1), &mut 21)));
  339. }
  340. {
  341. let mut i = x.iter_region_mut(1, 1, 1, 1);
  342. assert_eq!(i.next(), None);
  343. }
  344. {
  345. let mut i = x.iter_region_mut(1, 1, -1, -1);
  346. assert_eq!(i.next(), None);
  347. }
  348. {
  349. for (_, cell) in x.iter_region_mut(0, 0, 2, 2) {
  350. *cell = 111;
  351. }
  352. for (_, cell) in x.iter_region(0, 0, 2, 2) {
  353. assert_eq!(*cell, 111);
  354. }
  355. }
  356. }
  357. }
Add Comment
Please, Sign In to add comment