merge undo/redo logic for areas and single tiles

This commit is contained in:
Crispy 2024-12-16 22:24:27 +01:00
parent 6970b18e22
commit ba1f404250
3 changed files with 14 additions and 49 deletions

View file

@ -4,7 +4,6 @@
logic mostly like https://git.crispypin.cc/CrispyPin/marble logic mostly like https://git.crispypin.cc/CrispyPin/marble
## todo ## todo
- undo/redo
- more levels - more levels
- make direct power (comparator -> machine) work, (needs storing power direction in machine tiles) - make direct power (comparator -> machine) work, (needs storing power direction in machine tiles)
- cut selections, copy to system clipboard - cut selections, copy to system clipboard

View file

@ -76,7 +76,6 @@ pub struct Editor {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Action { enum Action {
SetTile(ResizeDeltas, Pos, Tile, Tile),
SetArea(ResizeDeltas, Pos, Board, Board), SetArea(ResizeDeltas, Pos, Board, Board),
} }
@ -181,13 +180,8 @@ impl Editor {
fn do_action(&mut self, action: Action) { fn do_action(&mut self, action: Action) {
match action { match action {
Action::SetTile(deltas, pos, _old, new) => {
self.shift_view(deltas.x_neg as f32, deltas.y_neg as f32);
self.source_board.grow(&deltas);
self.source_board.set(pos, new);
}
Action::SetArea(deltas, pos, _old, new) => { Action::SetArea(deltas, pos, _old, new) => {
self.shift_view(deltas.x_neg as f32, deltas.y_neg as f32); self.shift_world(deltas.x_neg as f32, deltas.y_neg as f32);
self.source_board.grow(&deltas); self.source_board.grow(&deltas);
self.source_board.paste_board(pos, &new); self.source_board.paste_board(pos, &new);
} }
@ -199,22 +193,17 @@ impl Editor {
return; return;
} }
self.undo_index -= 1; self.undo_index -= 1;
let action = self.undo_history[self.undo_index].clone(); let action = &self.undo_history[self.undo_index];
match action { match action {
Action::SetTile(deltas, pos, old, _new) => {
self.source_board.set(pos, old);
self.source_board.shrink(&deltas);
self.shift_view(-(deltas.x_neg as f32), -(deltas.y_neg as f32));
}
Action::SetArea(deltas, pos, old, _new) => { Action::SetArea(deltas, pos, old, _new) => {
self.source_board.paste_board(pos, &old); self.source_board.paste_board(*pos, &old);
self.source_board.shrink(&deltas); self.source_board.shrink(&deltas);
self.shift_view(-(deltas.x_neg as f32), -(deltas.y_neg as f32)); self.shift_world(-(deltas.x_neg as f32), -(deltas.y_neg as f32));
} }
} }
} }
fn shift_view(&mut self, x: f32, y: f32) { fn shift_world(&mut self, x: f32, y: f32) {
match &mut self.active_tool { match &mut self.active_tool {
Tool::SelectArea(Selection { Tool::SelectArea(Selection {
area: Some((a, b)), area: Some((a, b)),
@ -410,38 +399,7 @@ impl Editor {
} }
fn set_tile(&mut self, pos: Pos, tile: Tile) { fn set_tile(&mut self, pos: Pos, tile: Tile) {
let old_tile = self.source_board.get_or_blank(pos); self.set_area(pos, Board::new_single(tile));
if old_tile == tile {
return;
}
let width = self.source_board.width() as PosInt;
let height = self.source_board.height() as PosInt;
let resize = ResizeDeltas {
x_pos: if (pos.x + BOARD_MARGIN + 1) > width {
pos.x + BOARD_MARGIN + 1 - width
} else {
0
} as usize,
x_neg: if pos.x < BOARD_MARGIN {
BOARD_MARGIN - pos.x
} else {
0
} as usize,
y_pos: if (pos.y + BOARD_MARGIN + 1) > height {
pos.y + BOARD_MARGIN + 1 - height
} else {
0
} as usize,
y_neg: if pos.y < BOARD_MARGIN {
BOARD_MARGIN - pos.y
} else {
0
} as usize,
};
let mut pos = pos;
pos.x += resize.x_neg as PosInt;
pos.y += resize.y_neg as PosInt;
self.push_action(Action::SetTile(resize, pos, old_tile, tile));
} }
pub fn update(&mut self, rl: &RaylibHandle) { pub fn update(&mut self, rl: &RaylibHandle) {

View file

@ -61,6 +61,14 @@ impl Board {
} }
} }
pub fn new_single(tile: Tile) -> Self {
Self {
rows: vec![vec![tile]],
width: 1,
height: 1,
}
}
pub fn new(rows: Vec<Vec<Tile>>) -> Self { pub fn new(rows: Vec<Vec<Tile>>) -> Self {
Self { Self {
width: rows[0].len(), width: rows[0].len(),