add formula evaluation for watch overrides
This commit is contained in:
parent
8a46b7f3de
commit
4d1be53a30
|
@ -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]]
|
||||
|
|
|
@ -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"
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue