From c1094980a6621e9c18d8986e8fd816635216270c Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Sat, 7 Dec 2024 16:19:59 +0100 Subject: [PATCH] increase max speed and step counter digits, show microseconds per step, massive simulation optimisation for large worlds (5-100x faster) --- src/editor.rs | 24 ++++++++++++++++-------- src/marble_engine.rs | 17 +++++++++++------ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/editor.rs b/src/editor.rs index 37c114d..4c88ec5 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -28,6 +28,8 @@ const FOOTER_HEIGHT: i32 = 95; const SIDEBAR_WIDTH: i32 = 200 + 32 * 2 + 5 * 4; const MAX_ZOOM_IN: i32 = 3; const BOARD_MARGIN: isize = 3; +const MAX_SPEED_POWER: u8 = 16; +const SPEED_DIGITS: u8 = 5; #[derive(Debug)] pub struct Editor { @@ -58,6 +60,7 @@ pub struct Editor { blueprints: Vec, selected_blueprint: usize, blueprint_scroll: usize, + step_time: u128, } #[derive(Debug, PartialEq)] @@ -133,6 +136,7 @@ impl Editor { blueprints: get_blueprints(), selected_blueprint: usize::MAX, blueprint_scroll: 0, + step_time: 0, } } @@ -174,7 +178,10 @@ impl Editor { } fn step(&mut self) { + let start_time = std::time::Instant::now(); self.machine.step(); + self.step_time = start_time.elapsed().as_micros(); + if self.complete_popup == Popup::Visible { self.complete_popup = Popup::Dismissed; } @@ -572,20 +579,21 @@ impl Editor { } draw_scaled_texture(d, textures.get("step"), 332, 4, 2.); - d.draw_text("spd", 368, 6, 10, Color::WHITE); - draw_usize(d, textures, 1 << self.sim_speed, 388, 4, 3, 1); - slider(d, &mut self.sim_speed, 0, 9, 368, 24, 48, 12); + draw_usize(d, textures, 1 << self.sim_speed, 368, 4, SPEED_DIGITS, 1); + slider(d, &mut self.sim_speed, 0, MAX_SPEED_POWER, 368, 24, 48, 12); - draw_usize(d, textures, self.machine.step_count(), 420, 4, 5, 2); + draw_usize(d, textures, self.machine.step_count(), 420, 4, 9, 2); - d.draw_text("input:", 523, 8, 10, Color::WHITE); - if simple_button(d, 520, 20, 35, 15) { + draw_usize(d, textures, self.step_time as usize, 540, 42, 9, 1); + + d.draw_text("input:", 603, 8, 10, Color::WHITE); + if simple_button(d, 600, 20, 35, 15) { self.input_as_text = !self.input_as_text } let input_mode_text = if self.input_as_text { "text" } else { "bytes" }; - d.draw_text(input_mode_text, 523, 23, 10, Color::WHITE); + d.draw_text(input_mode_text, 603, 23, 10, Color::WHITE); - let input_x = 560; + let input_x = 638; let width = d.get_screen_width(); if self.input_as_text { let mut input_text = String::new(); diff --git a/src/marble_engine.rs b/src/marble_engine.rs index 1ce2c58..6b521b9 100644 --- a/src/marble_engine.rs +++ b/src/marble_engine.rs @@ -1,3 +1,5 @@ +use std::hint::unreachable_unchecked; + use raylib::prelude::*; pub mod board; @@ -13,6 +15,7 @@ use crate::{draw_usize_small, Textures}; pub struct Machine { board: Board, marbles: Vec, + powered: Vec, input: Vec, input_index: usize, @@ -25,6 +28,7 @@ impl Machine { Self { board: Board::new_empty(width, width), marbles: Vec::new(), + powered: Vec::new(), input, input_index: 0, output: Vec::new(), @@ -97,13 +101,13 @@ impl Machine { pub fn step(&mut self) { self.steps += 1; // reset wires - for y in 0..self.board.height() { - for x in 0..self.board.width() { - if let Some(Tile::Powerable(_, state)) = self.board.get_mut((x, y).into()) { - *state = false; - } - } + for &p in &self.powered { + let Some(Tile::Powerable(_, state)) = self.board.get_mut(p) else { + unsafe { unreachable_unchecked() } + }; + *state = false; } + self.powered.clear(); if self.marbles.is_empty() { return; @@ -302,6 +306,7 @@ impl Machine { } let was_powered = *state; *state = true; + self.powered.push(pos); match tile { PTile::Wire(wiretype) => { if was_powered {