store grid as flat vec for faster access
This commit is contained in:
parent
73a1c62f52
commit
e6437ae9cf
2 changed files with 32 additions and 92 deletions
|
@ -350,8 +350,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
fn save_blueprint(&mut self, selection: (Pos, Pos)) {
|
||||
let mut board = self.get_selected_as_board(selection);
|
||||
board.trim_size(0);
|
||||
let board = self.get_selected_as_board(selection);
|
||||
let id = get_free_id(&self.blueprints, Blueprint::id);
|
||||
let mut blueprint = Blueprint::new(&board, id);
|
||||
if !self.new_blueprint_name.is_empty() {
|
||||
|
@ -1086,7 +1085,6 @@ impl Editor {
|
|||
Tool::Mirror => self.set_tile(pos, Tile::Mirror(self.tool_mirror)),
|
||||
Tool::Digits(_pos) => {
|
||||
self.active_tool = Tool::Digits(Some(pos));
|
||||
|
||||
let tile = self.source_board.get_or_blank(pos);
|
||||
if !matches!(tile, Tile::Open(OpenTile::Digit(_), _)) {
|
||||
self.set_tile(pos, Tile::Open(OpenTile::Digit(0), Claim::Free));
|
||||
|
|
|
@ -8,7 +8,7 @@ use raylib::prelude::*;
|
|||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Board {
|
||||
rows: Vec<Vec<Tile>>,
|
||||
tiles: Vec<Tile>,
|
||||
width: usize,
|
||||
height: usize,
|
||||
}
|
||||
|
@ -26,7 +26,9 @@ impl Board {
|
|||
let mut rows = Vec::new();
|
||||
|
||||
let mut width = 0;
|
||||
let mut height = 0;
|
||||
for line in source.lines() {
|
||||
height += 1;
|
||||
width = width.max(line.len());
|
||||
let mut tiles = Vec::new();
|
||||
for char in line.chars() {
|
||||
|
@ -37,14 +39,20 @@ impl Board {
|
|||
for line in &mut rows {
|
||||
line.resize(width, Tile::BLANK);
|
||||
}
|
||||
let tiles = rows.into_iter().flatten().collect();
|
||||
|
||||
Board::new(rows)
|
||||
Self {
|
||||
tiles,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
let mut out = String::new();
|
||||
for row in &self.rows {
|
||||
for tile in row {
|
||||
for y in 0..self.height {
|
||||
for x in 0..self.width {
|
||||
let tile = self.get((x, y).into()).unwrap();
|
||||
out.push(tile.to_char());
|
||||
}
|
||||
out.push('\n');
|
||||
|
@ -53,9 +61,9 @@ impl Board {
|
|||
}
|
||||
|
||||
pub fn new_empty(width: usize, height: usize) -> Self {
|
||||
let rows = vec![vec![Tile::BLANK; width]; height];
|
||||
let tiles = vec![Tile::BLANK; width * height];
|
||||
Self {
|
||||
rows,
|
||||
tiles,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
|
@ -63,28 +71,17 @@ impl Board {
|
|||
|
||||
pub fn new_single(tile: Tile) -> Self {
|
||||
Self {
|
||||
rows: vec![vec![tile]],
|
||||
tiles: vec![tile],
|
||||
width: 1,
|
||||
height: 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(rows: Vec<Vec<Tile>>) -> Self {
|
||||
Self {
|
||||
width: rows[0].len(),
|
||||
height: rows.len(),
|
||||
rows,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn count_tiles(&self) -> usize {
|
||||
let mut sum = 0;
|
||||
for row in &self.rows {
|
||||
for tile in row {
|
||||
match tile {
|
||||
Tile::Open(OpenTile::Blank, _) | Tile::Block => (),
|
||||
_ => sum += 1,
|
||||
}
|
||||
for tile in &self.tiles {
|
||||
if !matches!(tile, Tile::Open(OpenTile::Blank, _) | Tile::Block) {
|
||||
sum += 1
|
||||
}
|
||||
}
|
||||
sum
|
||||
|
@ -94,9 +91,13 @@ impl Board {
|
|||
p.x >= 0 && p.y >= 0 && p.x < self.width as PosInt && p.y < self.height as PosInt
|
||||
}
|
||||
|
||||
fn get_unchecked(&self, p: Pos) -> Tile {
|
||||
self.tiles[p.y as usize * self.width + p.x as usize]
|
||||
}
|
||||
|
||||
pub fn get(&self, p: Pos) -> Option<Tile> {
|
||||
if self.in_bounds(p) {
|
||||
Some(self.rows[p.y as usize][p.x as usize])
|
||||
Some(self.get_unchecked(p))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -104,7 +105,7 @@ impl Board {
|
|||
|
||||
pub fn get_or_blank(&self, p: Pos) -> Tile {
|
||||
if self.in_bounds(p) {
|
||||
self.rows[p.y as usize][p.x as usize]
|
||||
self.get_unchecked(p)
|
||||
} else {
|
||||
Tile::BLANK
|
||||
}
|
||||
|
@ -112,7 +113,7 @@ impl Board {
|
|||
|
||||
pub fn get_mut(&mut self, p: Pos) -> Option<&mut Tile> {
|
||||
if self.in_bounds(p) {
|
||||
Some(&mut self.rows[p.y as usize][p.x as usize])
|
||||
Some(&mut self.tiles[p.y as usize * self.width + p.x as usize])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ impl Board {
|
|||
|
||||
pub fn set(&mut self, p: Pos, tile: Tile) {
|
||||
if self.in_bounds(p) {
|
||||
self.rows[p.y as usize][p.x as usize] = tile;
|
||||
self.tiles[p.y as usize * self.width + p.x as usize] = tile;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,73 +149,14 @@ impl Board {
|
|||
out
|
||||
}
|
||||
|
||||
pub fn trim_size(&mut self, margin: usize) -> (usize, usize) {
|
||||
let (offset_x, offset_y);
|
||||
// top
|
||||
{
|
||||
let mut n = 0;
|
||||
while n < self.height && self.rows[n].iter().all(|t| t.is_blank()) {
|
||||
n += 1;
|
||||
}
|
||||
let trim_top = n.saturating_sub(margin);
|
||||
for _ in 0..trim_top {
|
||||
self.rows.remove(0);
|
||||
}
|
||||
offset_y = trim_top;
|
||||
self.height -= trim_top;
|
||||
}
|
||||
// bottom
|
||||
{
|
||||
let mut n = 0;
|
||||
while n < self.height && self.rows[self.height - n - 1].iter().all(|t| t.is_blank()) {
|
||||
n += 1;
|
||||
}
|
||||
let trim_bottom = n.saturating_sub(margin);
|
||||
for _ in 0..trim_bottom {
|
||||
self.rows.pop();
|
||||
}
|
||||
self.height -= trim_bottom;
|
||||
}
|
||||
// left
|
||||
{
|
||||
let mut n = 0;
|
||||
while n < self.width && self.rows.iter().all(|row| row[n].is_blank()) {
|
||||
n += 1;
|
||||
}
|
||||
let trim_left = n.saturating_sub(margin);
|
||||
for row in &mut self.rows {
|
||||
for _ in 0..trim_left {
|
||||
row.remove(0);
|
||||
}
|
||||
}
|
||||
offset_x = trim_left;
|
||||
self.width -= trim_left;
|
||||
}
|
||||
// right
|
||||
{
|
||||
let mut n = 0;
|
||||
while n < self.width && self.rows.iter().all(|r| r[self.width - n - 1].is_blank()) {
|
||||
n += 1;
|
||||
}
|
||||
let trim_right = n.saturating_sub(margin);
|
||||
for row in &mut self.rows {
|
||||
for _ in 0..trim_right {
|
||||
row.pop();
|
||||
}
|
||||
}
|
||||
self.width -= trim_right;
|
||||
}
|
||||
(offset_x, offset_y)
|
||||
}
|
||||
|
||||
pub fn grow(&mut self, deltas: &ResizeDeltas) {
|
||||
let new_width = self.width + deltas.x_neg + deltas.x_pos;
|
||||
let new_height = self.height + deltas.y_neg + deltas.y_pos;
|
||||
let mut new_board = Board::new_empty(new_width, new_height);
|
||||
for x in 0..self.width {
|
||||
for y in 0..self.height {
|
||||
let tile = self.rows[y][x];
|
||||
new_board.rows[y + deltas.y_neg][x + deltas.x_neg] = tile;
|
||||
let tile = self.get_unchecked((x, y).into());
|
||||
new_board.set((x + deltas.x_neg, y + deltas.y_neg).into(), tile);
|
||||
}
|
||||
}
|
||||
*self = new_board;
|
||||
|
@ -226,8 +168,8 @@ impl Board {
|
|||
let mut new_board = Board::new_empty(new_width, new_height);
|
||||
for x in 0..new_width {
|
||||
for y in 0..new_height {
|
||||
let tile = self.rows[y + deltas.y_neg][x + deltas.x_neg];
|
||||
new_board.rows[y][x] = tile;
|
||||
let tile = self.get_unchecked((x + deltas.x_neg, y + deltas.y_neg).into());
|
||||
new_board.set((x, y).into(), tile);
|
||||
}
|
||||
}
|
||||
*self = new_board;
|
||||
|
@ -245,7 +187,7 @@ impl Board {
|
|||
let mut out = Vec::new();
|
||||
for y in 0..self.height {
|
||||
for x in 0..self.width {
|
||||
if let Tile::Marble { value: _, dir: _ } = self.rows[y][x] {
|
||||
if let Tile::Marble { value: _, dir: _ } = self.get_unchecked((x, y).into()) {
|
||||
out.push((x, y).into());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue