pub mod data; pub mod icon; pub mod icon_renderer; pub mod mappable; pub mod polygon_room; pub mod rect_room; pub mod wall; pub use data::MapData; pub use icon::*; pub use mappable::Mappable; pub use polygon_room::*; pub use rect_room::*; pub use wall::*; use crate::transform::Transform; use icon_renderer::IconRenderer; use raylib::drawing::RaylibDrawHandle; use raylib::{RaylibHandle, RaylibThread}; use std::rc::Rc; pub struct Map { rect_rooms: Vec, polygon_rooms: Vec, walls: Vec, icons: Vec, icon_renderer: Rc, } impl Map { pub fn new(rl: &mut RaylibHandle, rlt: &RaylibThread) -> Self { Self { rect_rooms: Vec::new(), polygon_rooms: Vec::new(), walls: Vec::new(), icons: Vec::new(), icon_renderer: Rc::new(IconRenderer::new(rl, rlt)), } } pub fn push_rect_room(&mut self, room_data: RectRoomData) { self.rect_rooms.push(RectRoom::from_data(room_data)); } pub fn push_polygon_room(&mut self, room_data: PolygonRoomData) { self.polygon_rooms.push(PolygonRoom::from_data(room_data)); } pub fn push_wall(&mut self, wall_data: WallData) { /* Check for intersections with any wall that was arleady created so the wall ends can be * rendered properly. */ let mut start_intersects = false; let mut end_intersects = false; for wall in &self.walls { if wall.data().contains_collinear(wall_data.start) { start_intersects = true; } if wall.data().contains_collinear(wall_data.end) { end_intersects = true; } // Currently, additional intersections can be ignored, since it is just a yes-no-question if start_intersects && end_intersects { break; } } self.walls .push(Wall::from_data(wall_data, start_intersects, end_intersects)); } pub fn push_icon(&mut self, icon: Icon) { self.icons.push(icon); } pub fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { for element in self.elements() { element.draw(rld, transform); } } pub fn icon_renderer(&self) -> Rc { self.icon_renderer.clone() } /// Retain all map elements that fulfill the given predicate. pub fn retain(&mut self, mut f: F) where F: FnMut(&dyn Mappable) -> bool, { // Call retain on all vectors containing the maps actual types. self.rect_rooms.retain(|r| f(r as &dyn Mappable)); self.polygon_rooms.retain(|p| f(p as &dyn Mappable)); self.walls.retain(|w| f(w as &dyn Mappable)); self.icons.retain(|i| f(i as &dyn Mappable)); } /// Iterator over all elements as objects when an operation needs to go over all elements of the /// map. pub fn elements(&self) -> impl Iterator { self.rect_rooms .iter() .map(|r| r as &dyn Mappable) .chain(self.polygon_rooms.iter().map(|p| p as &dyn Mappable)) .chain(self.walls.iter().map(|w| w as &dyn Mappable)) .chain(self.icons.iter().map(|i| i as &dyn Mappable)) } pub fn elements_mut(&mut self) -> impl Iterator { self.rect_rooms .iter_mut() .map(|r| r as &mut dyn Mappable) .chain( self.polygon_rooms .iter_mut() .map(|p| p as &mut dyn Mappable), ) .chain(self.walls.iter_mut().map(|w| w as &mut dyn Mappable)) .chain(self.icons.iter_mut().map(|i| i as &mut dyn Mappable)) } }