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)) {
|
fn save_blueprint(&mut self, selection: (Pos, Pos)) {
|
||||||
let mut board = self.get_selected_as_board(selection);
|
let board = self.get_selected_as_board(selection);
|
||||||
board.trim_size(0);
|
|
||||||
let id = get_free_id(&self.blueprints, Blueprint::id);
|
let id = get_free_id(&self.blueprints, Blueprint::id);
|
||||||
let mut blueprint = Blueprint::new(&board, id);
|
let mut blueprint = Blueprint::new(&board, id);
|
||||||
if !self.new_blueprint_name.is_empty() {
|
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::Mirror => self.set_tile(pos, Tile::Mirror(self.tool_mirror)),
|
||||||
Tool::Digits(_pos) => {
|
Tool::Digits(_pos) => {
|
||||||
self.active_tool = Tool::Digits(Some(pos));
|
self.active_tool = Tool::Digits(Some(pos));
|
||||||
|
|
||||||
let tile = self.source_board.get_or_blank(pos);
|
let tile = self.source_board.get_or_blank(pos);
|
||||||
if !matches!(tile, Tile::Open(OpenTile::Digit(_), _)) {
|
if !matches!(tile, Tile::Open(OpenTile::Digit(_), _)) {
|
||||||
self.set_tile(pos, Tile::Open(OpenTile::Digit(0), Claim::Free));
|
self.set_tile(pos, Tile::Open(OpenTile::Digit(0), Claim::Free));
|
||||||
|
|
|
@ -8,7 +8,7 @@ use raylib::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Board {
|
pub struct Board {
|
||||||
rows: Vec<Vec<Tile>>,
|
tiles: Vec<Tile>,
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,9 @@ impl Board {
|
||||||
let mut rows = Vec::new();
|
let mut rows = Vec::new();
|
||||||
|
|
||||||
let mut width = 0;
|
let mut width = 0;
|
||||||
|
let mut height = 0;
|
||||||
for line in source.lines() {
|
for line in source.lines() {
|
||||||
|
height += 1;
|
||||||
width = width.max(line.len());
|
width = width.max(line.len());
|
||||||
let mut tiles = Vec::new();
|
let mut tiles = Vec::new();
|
||||||
for char in line.chars() {
|
for char in line.chars() {
|
||||||
|
@ -37,14 +39,20 @@ impl Board {
|
||||||
for line in &mut rows {
|
for line in &mut rows {
|
||||||
line.resize(width, Tile::BLANK);
|
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 {
|
pub fn to_string(&self) -> String {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
for row in &self.rows {
|
for y in 0..self.height {
|
||||||
for tile in row {
|
for x in 0..self.width {
|
||||||
|
let tile = self.get((x, y).into()).unwrap();
|
||||||
out.push(tile.to_char());
|
out.push(tile.to_char());
|
||||||
}
|
}
|
||||||
out.push('\n');
|
out.push('\n');
|
||||||
|
@ -53,9 +61,9 @@ impl Board {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_empty(width: usize, height: usize) -> Self {
|
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 {
|
Self {
|
||||||
rows,
|
tiles,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
}
|
}
|
||||||
|
@ -63,28 +71,17 @@ impl Board {
|
||||||
|
|
||||||
pub fn new_single(tile: Tile) -> Self {
|
pub fn new_single(tile: Tile) -> Self {
|
||||||
Self {
|
Self {
|
||||||
rows: vec![vec![tile]],
|
tiles: vec![tile],
|
||||||
width: 1,
|
width: 1,
|
||||||
height: 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 {
|
pub fn count_tiles(&self) -> usize {
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
for row in &self.rows {
|
for tile in &self.tiles {
|
||||||
for tile in row {
|
if !matches!(tile, Tile::Open(OpenTile::Blank, _) | Tile::Block) {
|
||||||
match tile {
|
sum += 1
|
||||||
Tile::Open(OpenTile::Blank, _) | Tile::Block => (),
|
|
||||||
_ => sum += 1,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sum
|
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
|
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> {
|
pub fn get(&self, p: Pos) -> Option<Tile> {
|
||||||
if self.in_bounds(p) {
|
if self.in_bounds(p) {
|
||||||
Some(self.rows[p.y as usize][p.x as usize])
|
Some(self.get_unchecked(p))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -104,7 +105,7 @@ impl Board {
|
||||||
|
|
||||||
pub fn get_or_blank(&self, p: Pos) -> Tile {
|
pub fn get_or_blank(&self, p: Pos) -> Tile {
|
||||||
if self.in_bounds(p) {
|
if self.in_bounds(p) {
|
||||||
self.rows[p.y as usize][p.x as usize]
|
self.get_unchecked(p)
|
||||||
} else {
|
} else {
|
||||||
Tile::BLANK
|
Tile::BLANK
|
||||||
}
|
}
|
||||||
|
@ -112,7 +113,7 @@ impl Board {
|
||||||
|
|
||||||
pub fn get_mut(&mut self, p: Pos) -> Option<&mut Tile> {
|
pub fn get_mut(&mut self, p: Pos) -> Option<&mut Tile> {
|
||||||
if self.in_bounds(p) {
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -120,7 +121,7 @@ impl Board {
|
||||||
|
|
||||||
pub fn set(&mut self, p: Pos, tile: Tile) {
|
pub fn set(&mut self, p: Pos, tile: Tile) {
|
||||||
if self.in_bounds(p) {
|
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
|
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) {
|
pub fn grow(&mut self, deltas: &ResizeDeltas) {
|
||||||
let new_width = self.width + deltas.x_neg + deltas.x_pos;
|
let new_width = self.width + deltas.x_neg + deltas.x_pos;
|
||||||
let new_height = self.height + deltas.y_neg + deltas.y_pos;
|
let new_height = self.height + deltas.y_neg + deltas.y_pos;
|
||||||
let mut new_board = Board::new_empty(new_width, new_height);
|
let mut new_board = Board::new_empty(new_width, new_height);
|
||||||
for x in 0..self.width {
|
for x in 0..self.width {
|
||||||
for y in 0..self.height {
|
for y in 0..self.height {
|
||||||
let tile = self.rows[y][x];
|
let tile = self.get_unchecked((x, y).into());
|
||||||
new_board.rows[y + deltas.y_neg][x + deltas.x_neg] = tile;
|
new_board.set((x + deltas.x_neg, y + deltas.y_neg).into(), tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*self = new_board;
|
*self = new_board;
|
||||||
|
@ -226,8 +168,8 @@ impl Board {
|
||||||
let mut new_board = Board::new_empty(new_width, new_height);
|
let mut new_board = Board::new_empty(new_width, new_height);
|
||||||
for x in 0..new_width {
|
for x in 0..new_width {
|
||||||
for y in 0..new_height {
|
for y in 0..new_height {
|
||||||
let tile = self.rows[y + deltas.y_neg][x + deltas.x_neg];
|
let tile = self.get_unchecked((x + deltas.x_neg, y + deltas.y_neg).into());
|
||||||
new_board.rows[y][x] = tile;
|
new_board.set((x, y).into(), tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*self = new_board;
|
*self = new_board;
|
||||||
|
@ -245,7 +187,7 @@ impl Board {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
for y in 0..self.height {
|
for y in 0..self.height {
|
||||||
for x in 0..self.width {
|
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());
|
out.push((x, y).into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue