mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'lemu/src/instructions/draw.rs')
-rw-r--r--lemu/src/instructions/draw.rs247
1 files changed, 139 insertions, 108 deletions
diff --git a/lemu/src/instructions/draw.rs b/lemu/src/instructions/draw.rs
index fc93d8f..04b168c 100644
--- a/lemu/src/instructions/draw.rs
+++ b/lemu/src/instructions/draw.rs
@@ -12,8 +12,8 @@ pub const INSTRS: &[&str] = &[
];
#[enum_dispatch]
-pub trait DrawInstruction<'v>: Disp {
- fn draw(
+pub trait DrawInstruction: Disp {
+ fn draw<'v>(
&self,
mem: &mut LRegistry<'v>,
image: &mut Image<&mut [u8], 4>,
@@ -21,21 +21,21 @@ pub trait DrawInstruction<'v>: Disp {
);
}
-#[derive(Debug)]
+#[derive(Debug, Copy, Clone)]
#[enum_dispatch(DrawInstruction)]
-pub enum DrawInstr<'v> {
- Line(Line<'v>),
- RectBordered(RectBordered<'v>),
- RectFilled(RectFilled<'v>),
- Triangle(Triangle<'v>),
- Clear(Clear<'v>),
- SetColor(SetColor<'v>),
- SetStroke(SetStroke<'v>),
- Poly(Poly<'v>),
- LinePoly(LinePoly<'v>),
-}
-
-impl Disp for DrawInstr<'_> {
+pub enum DrawInstr {
+ Line(Line),
+ RectBordered(RectBordered),
+ RectFilled(RectFilled),
+ Triangle(Triangle),
+ Clear(Clear),
+ SetColor(SetColor),
+ SetStroke(SetStroke),
+ Poly(Poly),
+ LinePoly(LinePoly),
+}
+
+impl Disp for DrawInstr {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Line(i) => write!(f, "{i}"),
@@ -51,18 +51,24 @@ impl Disp for DrawInstr<'_> {
}
}
-#[derive(Debug)]
-pub struct Clear<'v> {
- pub r: LAddress<'v>,
- pub g: LAddress<'v>,
- pub b: LAddress<'v>,
+#[derive(Debug, Copy, Clone)]
+
+pub struct Clear {
+ pub r: LAddress,
+ pub g: LAddress,
+ pub b: LAddress,
}
-impl<'v> DrawInstruction<'v> for Clear<'v> {
- fn draw(&self, mem: &mut LRegistry<'v>, image: &mut Image<&mut [u8], 4>, _: &mut DisplayState) {
+impl DrawInstruction for Clear {
+ fn draw<'v>(
+ &self,
+ mem: &mut LRegistry<'v>,
+ image: &mut Image<&mut [u8], 4>,
+ _: &mut DisplayState,
+ ) {
macro_rules! u8 {
($v:ident) => {
- match mem.get(&self.$v) {
+ match mem.get(self.$v) {
LVar::Num(n) => n.round() as u8,
_ => return,
}
@@ -75,24 +81,30 @@ impl<'v> DrawInstruction<'v> for Clear<'v> {
}
}
-impl Disp for Clear<'_> {
+impl Disp for Clear {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "draw clear {} {} {}", self.r, self.g, self.b)
}
}
-#[derive(Debug)]
-pub struct SetColor<'v> {
- pub r: LAddress<'v>,
- pub g: LAddress<'v>,
- pub b: LAddress<'v>,
- pub a: LAddress<'v>,
-}
-impl<'v> DrawInstruction<'v> for SetColor<'v> {
- fn draw(&self, mem: &mut LRegistry<'v>, _: &mut Image<&mut [u8], 4>, state: &mut DisplayState) {
+#[derive(Debug, Copy, Clone)]
+
+pub struct SetColor {
+ pub r: LAddress,
+ pub g: LAddress,
+ pub b: LAddress,
+ pub a: LAddress,
+}
+impl DrawInstruction for SetColor {
+ fn draw<'v>(
+ &self,
+ mem: &mut LRegistry<'v>,
+ _: &mut Image<&mut [u8], 4>,
+ state: &mut DisplayState,
+ ) {
macro_rules! u8 {
($v:ident) => {
- match mem.get(&self.$v) {
+ match mem.get(self.$v) {
LVar::Num(n) => n.round() as u8,
_ => return,
}
@@ -102,36 +114,42 @@ impl<'v> DrawInstruction<'v> for SetColor<'v> {
}
}
-impl Disp for SetColor<'_> {
+impl Disp for SetColor {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "draw color {} {} {} {}", self.r, self.g, self.b, self.a)
}
}
-#[derive(Debug)]
-pub struct SetStroke<'v> {
- pub size: LAddress<'v>,
+#[derive(Debug, Copy, Clone)]
+
+pub struct SetStroke {
+ pub size: LAddress,
}
-impl<'v> DrawInstruction<'v> for SetStroke<'v> {
- fn draw(&self, mem: &mut LRegistry<'v>, _: &mut Image<&mut [u8], 4>, state: &mut DisplayState) {
- if let &LVar::Num(n) = mem.get(&self.size) {
+impl DrawInstruction for SetStroke {
+ fn draw<'v>(
+ &self,
+ mem: &mut LRegistry<'v>,
+ _: &mut Image<&mut [u8], 4>,
+ state: &mut DisplayState,
+ ) {
+ if let &LVar::Num(n) = mem.get(self.size) {
state.stroke = n;
}
}
}
-impl Disp for SetStroke<'_> {
+impl Disp for SetStroke {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "draw stroke {}", self.size)
}
}
-pub type Point<'v> = (LAddress<'v>, LAddress<'v>);
+pub type Point = (LAddress, LAddress);
#[rustfmt::skip]
macro_rules! point {
($mem:ident@$point:expr) => {{
- let &LVar::Num(a) = $mem.get(&$point.0) else { return; };
- let &LVar::Num(b) = $mem.get(&$point.1) else { return; };
+ let &LVar::Num(a) = $mem.get($point.0) else { return };
+ let &LVar::Num(b) = $mem.get($point.1) else { return };
(a,b)
}}
}
@@ -142,14 +160,15 @@ macro_rules! map {
($fn(a), $fn(b))
}};
}
-#[derive(Debug)]
-pub struct Line<'v> {
- pub point_a: Point<'v>,
- pub point_b: Point<'v>,
+#[derive(Debug, Copy, Clone)]
+
+pub struct Line {
+ pub point_a: Point,
+ pub point_b: Point,
}
-impl<'v> DrawInstruction<'v> for Line<'v> {
- fn draw(
+impl DrawInstruction for Line {
+ fn draw<'v>(
&self,
mem: &mut LRegistry<'v>,
image: &mut Image<&mut [u8], 4>,
@@ -161,7 +180,7 @@ impl<'v> DrawInstruction<'v> for Line<'v> {
}
}
-impl Disp for Line<'_> {
+impl Disp for Line {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
@@ -171,28 +190,29 @@ impl Disp for Line<'_> {
}
}
-#[derive(Debug)]
-pub struct RectFilled<'v> {
- pub position: Point<'v>,
- pub width: LAddress<'v>,
- pub height: LAddress<'v>,
+#[derive(Debug, Copy, Clone)]
+
+pub struct RectFilled {
+ pub position: Point,
+ pub width: LAddress,
+ pub height: LAddress,
}
-impl<'v> DrawInstruction<'v> for RectFilled<'v> {
- fn draw(
+impl DrawInstruction for RectFilled {
+ fn draw<'v>(
&self,
mem: &mut LRegistry<'v>,
image: &mut Image<&mut [u8], 4>,
state: &mut DisplayState,
) {
let pos = map!(point!([email protected]), |n| n as u32);
- let width = get_num!(mem.get(&self.width)) as u32;
- let height = get_num!(mem.get(&self.height)) as u32;
+ let width = get_num!(mem.get(self.width)) as u32;
+ let height = get_num!(mem.get(self.height)) as u32;
image.filled_box(pos, width, height, state.col());
}
}
-impl Disp for RectFilled<'_> {
+impl Disp for RectFilled {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
@@ -202,14 +222,15 @@ impl Disp for RectFilled<'_> {
}
}
-#[derive(Debug)]
-pub struct RectBordered<'v> {
- pub position: Point<'v>,
- pub width: LAddress<'v>,
- pub height: LAddress<'v>,
+#[derive(Debug, Copy, Clone)]
+
+pub struct RectBordered {
+ pub position: Point,
+ pub width: LAddress,
+ pub height: LAddress,
}
-impl Disp for RectBordered<'_> {
+impl Disp for RectBordered {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
@@ -219,26 +240,32 @@ impl Disp for RectBordered<'_> {
}
}
-impl<'v> DrawInstruction<'v> for RectBordered<'v> {
- fn draw(
+impl DrawInstruction for RectBordered {
+ fn draw<'v>(
&self,
mem: &mut LRegistry<'v>,
image: &mut Image<&mut [u8], 4>,
state: &mut DisplayState,
) {
let pos = map!(point!([email protected]), |n| n as u32);
- let width = get_num!(mem.get(&self.width)) as u32;
- let height = get_num!(mem.get(&self.height)) as u32;
+ let width = get_num!(mem.get(self.width)) as u32;
+ let height = get_num!(mem.get(self.height)) as u32;
image.stroked_box(pos, width, height, state.stroke.round() as u32, state.col());
}
}
-#[derive(Debug)]
-pub struct Triangle<'v> {
- pub points: (Point<'v>, Point<'v>, Point<'v>),
+#[derive(Debug, Copy, Clone)]
+
+pub struct Triangle {
+ pub points: (Point, Point, Point),
}
-impl<'v> DrawInstruction<'v> for Triangle<'v> {
- fn draw(&self, mem: &mut LRegistry<'v>, i: &mut Image<&mut [u8], 4>, state: &mut DisplayState) {
+impl DrawInstruction for Triangle {
+ fn draw<'v>(
+ &self,
+ mem: &mut LRegistry<'v>,
+ i: &mut Image<&mut [u8], 4>,
+ state: &mut DisplayState,
+ ) {
let to32 = |n| n as f32;
let (a, b, c) = (
map!(point!([email protected]), to32),
@@ -248,7 +275,7 @@ impl<'v> DrawInstruction<'v> for Triangle<'v> {
i.tri(a, b, c, state.col());
}
}
-impl Disp for Triangle<'_> {
+impl Disp for Triangle {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
@@ -263,41 +290,42 @@ impl Disp for Triangle<'_> {
}
}
-#[derive(Debug)]
-pub struct Poly<'v> {
- pub(crate) pos: Point<'v>,
- pub(crate) sides: LAddress<'v>,
- pub(crate) radius: LAddress<'v>,
- pub(crate) rot: LAddress<'v>,
+#[derive(Debug, Copy, Clone)]
+
+pub struct Poly {
+ pub(crate) pos: Point,
+ pub(crate) sides: LAddress,
+ pub(crate) radius: LAddress,
+ pub(crate) rot: LAddress,
}
-impl<'v> DrawInstruction<'v> for Poly<'v> {
- fn draw(
+impl DrawInstruction for Poly {
+ fn draw<'v>(
&self,
mem: &mut LRegistry<'v>,
image: &mut Image<&mut [u8], 4>,
state: &mut DisplayState,
) {
- let sides = get_num!(mem.get(&self.sides)).round() as usize;
+ let sides = get_num!(mem.get(self.sides)).round() as usize;
if sides < 90 {
image.poly(
map!(point!([email protected]), |n| n as f32),
sides,
- get_num!(mem.get(&self.radius)) as f32,
- get_num!(mem.get(&self.rot)) as f32,
+ get_num!(mem.get(self.radius)) as f32,
+ get_num!(mem.get(self.rot)) as f32,
state.col(),
);
} else {
image.circle(
map!(point!([email protected]), |n: f64| n.round() as i32),
- get_num!(mem.get(&self.radius)).round() as i32,
+ get_num!(mem.get(self.radius)).round() as i32,
state.col(),
);
}
}
}
-impl Disp for Poly<'_> {
+impl Disp for Poly {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
@@ -307,42 +335,43 @@ impl Disp for Poly<'_> {
}
}
-#[derive(Debug)]
-pub struct LinePoly<'v> {
- pub(crate) pos: Point<'v>,
- pub(crate) sides: LAddress<'v>,
- pub(crate) radius: LAddress<'v>,
- pub(crate) rot: LAddress<'v>,
+#[derive(Debug, Copy, Clone)]
+
+pub struct LinePoly {
+ pub(crate) pos: Point,
+ pub(crate) sides: LAddress,
+ pub(crate) radius: LAddress,
+ pub(crate) rot: LAddress,
}
-impl<'v> DrawInstruction<'v> for LinePoly<'v> {
- fn draw(
+impl DrawInstruction for LinePoly {
+ fn draw<'v>(
&self,
mem: &mut LRegistry<'v>,
image: &mut Image<&mut [u8], 4>,
state: &mut DisplayState,
) {
- let sides = get_num!(mem.get(&self.sides)).round() as usize;
+ let sides = get_num!(mem.get(self.sides)).round() as usize;
if sides < 90 {
image.border_poly(
map!(point!([email protected]), |n| n as f32),
sides,
- get_num!(mem.get(&self.radius)) as f32,
- get_num!(mem.get(&self.rot)) as f32,
+ get_num!(mem.get(self.radius)) as f32,
+ get_num!(mem.get(self.rot)) as f32,
state.stroke as f32,
state.col(),
);
} else {
image.border_circle(
map!(point!([email protected]), |n: f64| n.round() as i32),
- get_num!(mem.get(&self.radius)).round() as i32,
+ get_num!(mem.get(self.radius)).round() as i32,
state.col(),
);
}
}
}
-impl Disp for LinePoly<'_> {
+impl Disp for LinePoly {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
@@ -352,11 +381,12 @@ impl Disp for LinePoly<'_> {
}
}
-#[derive(Debug, Default)]
+#[derive(Debug, Copy, Clone, Default)]
+
pub struct Flush {
pub(crate) display: Display,
}
-impl LInstruction<'_> for Flush {
+impl LInstruction for Flush {
fn run<W: std::io::Write>(&self, exec: &mut ExecutorContext<'_, W>) -> Flow {
exec.flush(self.display);
Flow::Continue
@@ -365,6 +395,7 @@ impl LInstruction<'_> for Flush {
impl Disp for Flush {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- write!(f, "drawflush {}", self.display)
+ let d = self.display;
+ write!(f, "drawflush {d}")
}
}