mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'lemu/src/executor/mod.rs')
-rw-r--r--lemu/src/executor/mod.rs41
1 files changed, 24 insertions, 17 deletions
diff --git a/lemu/src/executor/mod.rs b/lemu/src/executor/mod.rs
index 94b9c57..fb33c91 100644
--- a/lemu/src/executor/mod.rs
+++ b/lemu/src/executor/mod.rs
@@ -1,10 +1,13 @@
mod builder;
-use crate::debug::{info::DebugInfo, printable::Printable};
+use crate::{
+ debug::{info::DebugInfo, printable::Printable},
+ instructions::draw::Drawn,
+};
use super::{
code::{Code, PInstr},
- instructions::{DrawInstr, DrawInstruction, Flow, Instr, LInstruction},
+ instructions::{DrawInstr, Flow, Frozen, Instr, LInstruction},
lexer::Token,
memory::{LAddress, LRegistry, LVar},
};
@@ -132,13 +135,12 @@ pub enum UPInstr<'s> {
}
pub struct Drawing {
- pub displays: Box<[fimg::Image<Vec<u8>, 4>]>,
- /// points to `Executor.program`
- pub buffer: VecDeque<*const DrawInstr>,
+ pub displays: Box<[(fimg::Image<Vec<u8>, 4>, DisplayState)]>,
+ pub buffer: VecDeque<Drawn>,
}
impl Drawing {
- fn buffer(&mut self, i: &DrawInstr) {
+ fn buffer(&mut self, i: Drawn) {
self.buffer.push_back(i);
}
}
@@ -155,8 +157,11 @@ pub struct ExecutorContext<'strings, W: Write> {
pub iterations: usize,
}
+/// State of a display.
pub struct DisplayState {
+ /// Color to draw
pub color: (u8, u8, u8, u8),
+ /// Stroke to draw
pub stroke: f64,
}
@@ -176,15 +181,17 @@ impl Default for DisplayState {
}
impl<'s, W: Write> ExecutorContext<'s, W> {
+ pub fn buffer(&mut self, instr: &DrawInstr) {
+ if let Some(i) = instr.freeze(&self.memory) {
+ self.display.buffer(i)
+ }
+ }
+
pub fn flush(&mut self, to: Display) {
- let mut state = DisplayState::default();
- // SAFETY: safe as long as the instruction isnt held too long
- while let Some(d) = unsafe { self.display.buffer.pop_front().map(|v| &*v) } {
- d.draw(
- &mut self.memory,
- &mut self.display.displays[to.0].as_mut(),
- &mut state,
- );
+ let (ref mut img, ref mut state) = &mut self.display.displays[to.0];
+ while let Some(d) = self.display.buffer.pop_front() {
+ use crate::instructions::draw::Apply;
+ d.apply(img.as_mut(), state);
}
}
@@ -217,7 +224,7 @@ pub struct Output<W: Write> {
/// Everything created by a `print` instruction.
pub output: Option<W>,
/// Logic displays that were drawn with `draw` instructions.
- pub displays: Box<[Image<Vec<u8>, 4>]>,
+ pub displays: Box<[(Image<Vec<u8>, 4>, DisplayState)]>,
/// Memory banks, written to with the `write`/`read` instructions
pub cells: Box<[[f64; CELL_SIZE]]>,
/// Memory cells, written to with the `write`/`read` instructions
@@ -227,7 +234,7 @@ pub struct Output<W: Write> {
impl<'s, W: Write> Executor<'s, W> {
/// Consume this executor, returning all output.
pub fn output(mut self) -> Output<W> {
- for display in &mut *self.inner.display.displays {
+ for (display, _) in &mut *self.inner.display.displays {
// TODO make the instructions draw flipped-ly
display.flip_v();
}
@@ -256,7 +263,7 @@ impl<'s, W: Write> Executor<'s, W> {
i.run(&mut self.inner)
}
PInstr::Draw(i) => {
- self.inner.display.buffer(i);
+ self.inner.buffer(i);
Flow::Continue
}
_ => Flow::Continue,