Skip to content

Commit

Permalink
Implemented a few KeyBindings
Browse files Browse the repository at this point in the history
  • Loading branch information
jortrr committed Sep 19, 2023
1 parent 73cf56b commit 3d4d222
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 41 deletions.
27 changes: 18 additions & 9 deletions src/controller/key_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl KeyAction {
}

///Run self.action
pub fn action(&self) {
pub fn run(&self) {
(self.action)();
}
}
Expand All @@ -28,20 +28,20 @@ impl fmt::Debug for KeyAction {
}

pub struct KeyBindings {
key_actions: Vec<KeyAction>,
key_bindings: Vec<KeyAction>,
}

impl KeyBindings {
pub fn new(key_actions: Vec<KeyAction>) -> KeyBindings {
KeyBindings { key_actions }
pub fn new(key_bindings: Vec<KeyAction>) -> KeyBindings {
KeyBindings { key_bindings }
}

///Adds a `KeyAction` to these `KeyBindings`, will remove any existing `KeyAction` `x` where `x.key` == `key_action.key`
pub fn add_key(&mut self, key_action: KeyAction) {
//Remove any KeyAction x where x.key == key_action.key
self.key_actions.retain(|x| x.key != key_action.key);
self.key_bindings.retain(|x| x.key != key_action.key);

self.key_actions.push(key_action);
self.key_bindings.push(key_action);
}

///Adds a `KeyAction` to these `KeyBindings`, will remove any existing `KeyAction` `x` where `x.key` == `key`
Expand All @@ -50,7 +50,7 @@ impl KeyBindings {
}

pub fn key_actions(&self) -> &Vec<KeyAction> {
&self.key_actions
&self.key_bindings
}

/// Prints all `KeyAction`s in these `KeyBindings` to stdout
Expand All @@ -59,7 +59,7 @@ impl KeyBindings {
}

pub fn print_key(&self, key: &Key) {
for key_action in &self.key_actions {
for key_action in &self.key_bindings {
if key_action.key == *key {
println!("{:?}", key_action);
return;
Expand All @@ -68,12 +68,21 @@ impl KeyBindings {
//KeyBindings does not contain a KeyAction x with x.key == key, unbound
println!("{:?}", key);
}

pub fn run(&self, key: &Key) {
for key_binding in &self.key_bindings {
if key_binding.key == *key {
key_binding.run();
break;
}
}
}
}

impl fmt::Debug for KeyBindings {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "KeyBindings {{")?;
for key_action in &self.key_actions {
for key_action in &self.key_bindings {
writeln!(f, " {:?},", key_action)?;
}
write!(f, "}}")
Expand Down
48 changes: 19 additions & 29 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,11 @@ impl Default for InteractionVariables {

// Handle any key events
fn handle_key_events(window: &Window, k: &KeyBindings, coloring_function: &mut ColoringFunction) {
let mut mandelbrot_model = MandelbrotModel::get_instance();
if let Some(key) = window.get_keys_pressed(minifb::KeyRepeat::No).first() {
print!("\nKey pressed: ");
k.print_key(key);
k.run(key);
let mut mandelbrot_model = MandelbrotModel::get_instance();
match key {
Key::Up => {
let rows = mandelbrot_model.vars.translation_amount;
Expand Down Expand Up @@ -169,16 +170,6 @@ fn handle_key_events(window: &Window, k: &KeyBindings, coloring_function: &mut C
mandelbrot_model.c.center(),
mandelbrot_model.c.get_scale()
),
Key::Key1 => mandelbrot_model.c.set_view(&VIEW_1),
Key::Key2 => mandelbrot_model.c.set_view(&VIEW_2),
Key::Key3 => mandelbrot_model.c.set_view(&VIEW_3),
Key::Key4 => mandelbrot_model.c.set_view(&VIEW_4),
Key::Key5 => mandelbrot_model.c.set_view(&VIEW_5),
Key::Key6 => mandelbrot_model.c.set_view(&VIEW_6),
Key::Key7 => mandelbrot_model.c.set_view(&VIEW_7),
Key::Key8 => mandelbrot_model.c.set_view(&VIEW_8),
Key::Key9 => mandelbrot_model.c.set_view(&VIEW_9),
Key::Key0 => mandelbrot_model.c.set_view(&VIEW_0),
Key::K => k.print(),
Key::S => {
let time_stamp = chrono::Utc::now().to_string();
Expand Down Expand Up @@ -261,23 +252,22 @@ fn was_clicked(current: bool, previous: bool) -> bool {
current && !previous
}

fn handle_left_mouse_clicked(x: f32, y: f32, c: &ComplexPlane) {
fn handle_left_mouse_clicked(mandelbrot_model: &MandelbrotModel, x: f32, y: f32) {
println!("\nMouseButton::Left -> Info at ({x}, {y})");
//let iterations = MandelbrotModel::get_instance().p.iterations_at_point(x as usize, y as usize, MandelbrotModel::get_instance().m.max_iterations); //TODO: fix this
let complex = MandelbrotModel::get_instance().c.complex_from_pixel_plane(x.into(), y.into());
let complex = mandelbrot_model.c.complex_from_pixel_plane(x.into(), y.into());
println!("Complex: {:?}", complex);
//println!("iterations: {}", iterations);
println!();
}

fn handle_right_mouse_clicked(x: f32, y: f32, coloring_function: ColoringFunction) {
let mut mandelbrot_model = MandelbrotModel::get_instance();
fn handle_right_mouse_clicked(mandelbrot_model: &mut MandelbrotModel, x: f32, y: f32, coloring_function: ColoringFunction) {
println!("\nMouseButton::Right -> Move to ({x}, {y})");
let new_center = mandelbrot_model.c.complex_from_pixel_plane(x.into(), y.into());
println!("mandelbrot_model.c.center: {:?}", mandelbrot_model.c.center());
println!("new_center: {:?}", new_center);

rendering::translate_to_center_and_render_efficiently(&mut mandelbrot_model, &new_center, coloring_function);
rendering::translate_to_center_and_render_efficiently(mandelbrot_model, &new_center, coloring_function);
mandelbrot_model.c.print();
println!();
}
Expand Down Expand Up @@ -310,19 +300,19 @@ impl MouseClickRecorder {
}

fn handle_mouse_events(window: &Window, coloring_function: ColoringFunction) {
let mandelbrot_model = MandelbrotModel::get_instance();
let mut mandelbrot_model = MandelbrotModel::get_instance();
static LEFT_MOUSE_RECORDER: MouseClickRecorder = MouseClickRecorder::new(MouseButton::Left); //Static variable with interior mutability to toggle mouse clicks; without such a variable, clicking the screen once would result in multiple actions

Check warning on line 304 in src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

adding items after statements is confusing, since items exist from the start of the scope

warning: adding items after statements is confusing, since items exist from the start of the scope --> src/lib.rs:304:5 | 304 | static LEFT_MOUSE_RECORDER: MouseClickRecorder = MouseClickRecorder::new(MouseButton::Left); //Static variable with interior mutabili... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements = note: `#[warn(clippy::items_after_statements)]` implied by `#[warn(clippy::pedantic)]`
static RIGHT_MOUSE_RECORDER: MouseClickRecorder = MouseClickRecorder::new(MouseButton::Right);

Check warning on line 305 in src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

adding items after statements is confusing, since items exist from the start of the scope

warning: adding items after statements is confusing, since items exist from the start of the scope --> src/lib.rs:305:5 | 305 | static RIGHT_MOUSE_RECORDER: MouseClickRecorder = MouseClickRecorder::new(MouseButton::Right); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements

if let Some((x, y)) = window.get_mouse_pos(MouseMode::Discard) {
//Left mouse actions
if LEFT_MOUSE_RECORDER.was_clicked(window) {
handle_left_mouse_clicked(x, y, &mandelbrot_model.c);
handle_left_mouse_clicked(&mandelbrot_model, x, y);
}

//Right mouse actions
if RIGHT_MOUSE_RECORDER.was_clicked(window) {
handle_right_mouse_clicked(x, y, coloring_function);
handle_right_mouse_clicked(&mut mandelbrot_model, x, y, coloring_function);
}
}
}
Expand Down Expand Up @@ -412,16 +402,16 @@ pub fn run() -> Result<(), Box<dyn Error>> {
"Prints the current Mandelbrot set view; the center and scale",
empty_closure,
);
key_bindings.add(Key::Key1, "Renders VIEW_1", empty_closure);
key_bindings.add(Key::Key2, "Renders VIEW_2", empty_closure);
key_bindings.add(Key::Key3, "Renders VIEW_3", empty_closure);
key_bindings.add(Key::Key4, "Renders VIEW_4", empty_closure);
key_bindings.add(Key::Key5, "Renders VIEW_5", empty_closure);
key_bindings.add(Key::Key6, "Renders VIEW_6", empty_closure);
key_bindings.add(Key::Key7, "Renders VIEW_7", empty_closure);
key_bindings.add(Key::Key8, "Renders VIEW_8", empty_closure);
key_bindings.add(Key::Key9, "Renders VIEW_9", empty_closure);
key_bindings.add(Key::Key0, "Renders VIEW_0", empty_closure);
key_bindings.add(Key::Key1, "Renders VIEW_1", || MandelbrotModel::get_instance().c.set_view(&VIEW_1));
key_bindings.add(Key::Key2, "Renders VIEW_2", || MandelbrotModel::get_instance().c.set_view(&VIEW_2));
key_bindings.add(Key::Key3, "Renders VIEW_3", || MandelbrotModel::get_instance().c.set_view(&VIEW_3));
key_bindings.add(Key::Key4, "Renders VIEW_4", || MandelbrotModel::get_instance().c.set_view(&VIEW_4));
key_bindings.add(Key::Key5, "Renders VIEW_5", || MandelbrotModel::get_instance().c.set_view(&VIEW_5));
key_bindings.add(Key::Key6, "Renders VIEW_6", || MandelbrotModel::get_instance().c.set_view(&VIEW_6));
key_bindings.add(Key::Key7, "Renders VIEW_7", || MandelbrotModel::get_instance().c.set_view(&VIEW_7));
key_bindings.add(Key::Key8, "Renders VIEW_8", || MandelbrotModel::get_instance().c.set_view(&VIEW_8));
key_bindings.add(Key::Key9, "Renders VIEW_9", || MandelbrotModel::get_instance().c.set_view(&VIEW_9));
key_bindings.add(Key::Key0, "Renders VIEW_0", || MandelbrotModel::get_instance().c.set_view(&VIEW_0));
key_bindings.add(Key::K, "Prints the keybindings", empty_closure);
key_bindings.add(
Key::S,
Expand Down
7 changes: 5 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use std::process;
use std::{env, process};

use mandelbrot::{self, MandelbrotModel};
use mandelbrot::{self};

fn main() {
//Turn on Rust backtrace
env::set_var("RUST_BACKTRACE", "1");

if let Err(err) = mandelbrot::run() {
eprintln!("Application error: {}", err);
process::exit(1);
Expand Down
6 changes: 5 additions & 1 deletion src/model/mandelbrot_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ impl MandelbrotModel {

/// Returns the singleton MandelbrotModel instance.

Check warning on line 40 in src/model/mandelbrot_model.rs

View workflow job for this annotation

GitHub Actions / clippy

item in documentation is missing backticks

warning: item in documentation is missing backticks --> src/model/mandelbrot_model.rs:40:31 | 40 | /// Returns the singleton MandelbrotModel instance. | ^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown = note: `#[warn(clippy::doc_markdown)]` implied by `#[warn(clippy::pedantic)]` help: try | 40 | /// Returns the singleton `MandelbrotModel` instance. | ~~~~~~~~~~~~~~~~~
pub fn get_instance() -> MutexGuard<'static, MandelbrotModel> {

Check warning on line 41 in src/model/mandelbrot_model.rs

View workflow job for this annotation

GitHub Actions / clippy

docs for function which may panic missing `# Panics` section

warning: docs for function which may panic missing `# Panics` section --> src/model/mandelbrot_model.rs:41:5 | 41 | pub fn get_instance() -> MutexGuard<'static, MandelbrotModel> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here --> src/model/mandelbrot_model.rs:46:9 | 46 | ... panic!("You have called the singleton twice! This should never happen. It means that within the same scope, MandelbrotModel::get_instance() was called more than once.... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc
MANDELBROT_MODEL_INSTANCE.lock().unwrap()
let lock = MANDELBROT_MODEL_INSTANCE.try_lock();

Check warning on line 42 in src/model/mandelbrot_model.rs

View workflow job for this annotation

GitHub Actions / clippy

temporary with significant `Drop` can be early dropped

warning: temporary with significant `Drop` can be early dropped --> src/model/mandelbrot_model.rs:42:13 | 41 | pub fn get_instance() -> MutexGuard<'static, MandelbrotModel> { | ___________________________________________________________________- 42 | | let lock = MANDELBROT_MODEL_INSTANCE.try_lock(); | | ^^^^ 43 | | if let Ok(instance) = lock { 44 | | return instance; 45 | | } 46 | | panic!("You have called the singleton twice! This should never happen. It means that within the same scope, MandelbrotModel::get_... 47 | | } | |_____- temporary `lock` is currently being dropped at the end of its contained scope | = note: this might lead to unnecessary resource contention = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#significant_drop_tightening note: the lint level is defined here --> src/lib.rs:4:5 | 4 | clippy::nursery, | ^^^^^^^^^^^^^^^ = note: `#[warn(clippy::significant_drop_tightening)]` implied by `#[warn(clippy::nursery)]` help: merge the temporary construction with its single usage | 42 ~ 43 + MANDELBROT_MODEL_INSTANCE.try_lock().; | help: remove separated single usage | 43 - if let Ok(instance) = lock { 44 - return instance; 45 - } 43 + |
if let Ok(instance) = lock {
return instance;
}
panic!("You have called the singleton twice! This should never happen. It means that within the same scope, MandelbrotModel::get_instance() was called more than once.");
}
}

0 comments on commit 3d4d222

Please sign in to comment.