add formula evaluation for watch overrides

This commit is contained in:
Vivian Lim 2021-08-05 00:13:19 -07:00
parent 8a46b7f3de
commit 4d1be53a30
6 changed files with 60 additions and 10 deletions

19
Cargo.lock generated
View File

@ -703,6 +703,7 @@ dependencies = [
"glutin",
"hex",
"libloading 0.5.2",
"meval",
"mini_gl_fb",
"structopt",
"winit",
@ -1132,6 +1133,16 @@ dependencies = [
"autocfg",
]
[[package]]
name = "meval"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f79496a5651c8d57cd033c5add8ca7ee4e3d5f7587a4777484640d9cb60392d9"
dependencies = [
"fnv",
"nom 1.2.4",
]
[[package]]
name = "mini_gl_fb"
version = "0.9.0"
@ -1269,6 +1280,12 @@ dependencies = [
"libc",
]
[[package]]
name = "nom"
version = "1.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
[[package]]
name = "nom"
version = "6.2.1"
@ -2425,7 +2442,7 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a9a231574ae78801646617cefd13bfe94be907c0e4fa979cfd8b770aa3c5d08"
dependencies = [
"nom",
"nom 6.2.1",
]
[[package]]

View File

@ -25,4 +25,5 @@ winit = "0.25"
gilrs = "0.8.1"
find_folder="0.3.0"
hex = "0.4.3"
hex = "0.4.3"
meval = "0.2.0"

View File

@ -7,6 +7,7 @@ extern crate conrod_core;
extern crate failure;
extern crate glutin;
extern crate hex;
extern crate meval;
use mini_gl_fb::glutin::event_loop::EventLoop;

View File

@ -3,6 +3,7 @@ use std::{cell::RefCell, collections::HashSet, io::{Read, Write}, pin::Pin, rc::
use conrod_core::{Borderable, Colorable, Dimensions, Labelable, Positionable, Sizeable, Widget, position::Place, widget, widget_ids};
use glium::Surface;
use glutin::{dpi::LogicalSize, event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}, event_loop::EventLoop, window::WindowId};
use meval::Context;
use mini_gl_fb::{config, get_fancy};
use crate::{MyEmulator, memory::search::MemorySearch, ui::memory_watch::remove_temporary_watches};
@ -125,6 +126,9 @@ impl TrackedWindow for DebugWindow {
let mut ui = self.ui.set_widgets();
let mut meval_context = meval::Context::new();
meval_context.var("t", emu.frame as f64);
widget::Canvas::new()
.color(conrod_core::color::DARK_PURPLE)
.set(self.ids.canvas, &mut ui);
@ -241,7 +245,7 @@ impl TrackedWindow for DebugWindow {
// Refresh watches
for watch in &mut self.watches{
watch.refresh(memory);
watch.refresh(memory, &meval_context);
}
widget::BorderedRectangle::new([500.0, 230.0])

View File

@ -1,5 +1,7 @@
use std::{collections::HashSet, fmt::Display};
use meval::{Context, Expr};
pub struct MemoryWatch {
pub start: usize,
@ -24,7 +26,7 @@ impl MemoryWatch {
}
}
pub fn refresh(&mut self, data: &mut [u8]) {
pub fn refresh(&mut self, data: &mut [u8], meval_context: &Context) {
if self.start + self.length > data.len() {
self.last_seen_value = None;
self.status = WatchStatus::OutOfBounds;
@ -36,14 +38,39 @@ impl MemoryWatch {
}
if let Some(user_input) = &self.user_input {
match hex::decode(user_input) {
Ok(user_input_bytes) => {
if user_input_bytes.len() == self.length {
data[self.start..self.start + self.length].copy_from_slice(user_input_bytes.as_slice());
self.status = WatchStatus::Ok;
if user_input.starts_with("=") && self.length == 1{ // only support one byte for expressions for now
// evaluate formula
match &user_input[1..].parse::<Expr>() {
Ok(expr) => {
match expr.eval_with_context(meval_context){
Ok(result) => {
// truncate to a byte.
let truncated_result = result.min(255.0).max(0.0).round();
let byte_result = truncated_result as u8;
data[self.start] = byte_result;
}
Err(e) => {
println!("Failed to evaluate expression '{}', {}", user_input, e);
}
}
}
Err(e) => {
println!("Failed to parse expression '{}', {}", user_input, e);
}
}
Err(_) => {self.status = WatchStatus::InputDecodeFailed;}
}
else { // it's data
match hex::decode(user_input) {
Ok(user_input_bytes) => {
if user_input_bytes.len() == self.length {
data[self.start..self.start + self.length].copy_from_slice(user_input_bytes.as_slice());
self.status = WatchStatus::Ok;
}
}
Err(_) => {self.status = WatchStatus::InputDecodeFailed;}
}
}
}

0
src/ui/widget_macros.rs Normal file
View File