From 090e0f35dc5d048d80103947e6a41b58790d17e4 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 7 Aug 2020 17:50:54 -0400 Subject: [PATCH] aa --- core/src/mindustry/logic/LAssembler.java | 99 +++++++++++++++++++++ core/src/mindustry/logic/LBuilder.java | 49 ----------- core/src/mindustry/logic/LCanvas.java | 102 ++++++++++++++++------ core/src/mindustry/logic/LExecutor.java | 25 ++++++ core/src/mindustry/logic/LStatement.java | 10 ++- core/src/mindustry/logic/LStatements.java | 39 ++++++--- gradle.properties | 2 +- 7 files changed, 234 insertions(+), 92 deletions(-) create mode 100644 core/src/mindustry/logic/LAssembler.java delete mode 100644 core/src/mindustry/logic/LBuilder.java diff --git a/core/src/mindustry/logic/LAssembler.java b/core/src/mindustry/logic/LAssembler.java new file mode 100644 index 0000000000..7fd12026d9 --- /dev/null +++ b/core/src/mindustry/logic/LAssembler.java @@ -0,0 +1,99 @@ +package mindustry.logic; + +import arc.struct.*; +import arc.util.ArcAnnotate.*; +import mindustry.io.*; +import mindustry.logic.LCanvas.*; +import mindustry.logic.LExecutor.*; + +/** "Compiles" a sequence of statements into instructions. */ +public class LAssembler{ + private transient int lastVar; + /** Maps names to variable IDs. */ + ObjectMap vars = new ObjectMap<>(); + /** All instructions to be executed. */ + LInstruction[] instructions; + /** Statement UI elements being processed. */ + @Nullable Seq elements; + + public LAssembler(){ + //add default constants + putConst("false", 0); + putConst("true", 1); + putConst("null", null); + } + + public static LAssembler assemble(Seq seq){ + LAssembler out = new LAssembler(); + + out.elements = seq; + out.instructions = seq.map(s -> s.st.build(out)).toArray(LInstruction.class); + + return out; + } + + //TODO this is awful and confusing + public static LAssembler fromJson(String json){ + LAssembler asm = new LAssembler(); + + LStatement[] statements = JsonIO.read(LStatement[].class, json); + for(LStatement s : statements){ + s.afterLoad(asm); + } + asm.instructions = Seq.with(statements).map(l -> l.build(asm)).toArray(LInstruction.class); + + return asm; + } + + public String toJson(){ + Seq states = elements.map(s -> s.st); + states.each(s -> s.beforeSave(this)); + return JsonIO.write(states.toArray(LStatement.class)); + } + + /** @return a variable ID by name. + * This may be a constant variable referring to a number or object. */ + public int var(String symbol){ + symbol = symbol.trim(); + try{ + double value = Double.parseDouble(symbol); + //this creates a hidden const variable with the specified value + String key = "___" + value; + return putConst(key, value).id; + }catch(NumberFormatException e){ + return putVar(symbol).id; + } + } + + /** Adds a constant value by name. */ + private BVar putConst(String name, Object value){ + BVar var = putVar(name); + var.constant = true; + var.value = value; + return var; + } + + /** Registers a variable name mapping. */ + private BVar putVar(String name){ + if(vars.containsKey(name)){ + return vars.get(name); + }else{ + BVar var = new BVar(lastVar++); + vars.put(name, var); + return var; + } + } + + /** A saved variable. */ + public static class BVar{ + public int id; + public boolean constant; + public Object value; + + public BVar(int id){ + this.id = id; + } + + BVar(){} + } +} diff --git a/core/src/mindustry/logic/LBuilder.java b/core/src/mindustry/logic/LBuilder.java deleted file mode 100644 index fa9ce105f4..0000000000 --- a/core/src/mindustry/logic/LBuilder.java +++ /dev/null @@ -1,49 +0,0 @@ -package mindustry.logic; - -import arc.struct.*; - -/** "Compiles" a sequence of statements into instructions. */ -public class LBuilder{ - private int lastVar; - /** Maps names to variable IDs. */ - private ObjectIntMap vars = new ObjectIntMap<>(); - /** Maps variable IDs to their constant value. */ - private IntMap constants = new IntMap<>(); - - public LBuilder(){ - //add default constant variables - putConst("false", 0); - putConst("true", 1); - } - - /** @return a variable ID by name. - * This may be a constant variable referring to a number or object. */ - public int var(String symbol){ - try{ - double value = Double.parseDouble(symbol); - //this creates a hidden const variable with the specified value - String key = "___" + value; - return putConst(key, value); - }catch(NumberFormatException e){ - return putVar(symbol); - } - } - - /** Adds a constant value by name. */ - private int putConst(String name, double value){ - int id = putVar(name); - constants.put(id, value); - return id; - } - - /** Registers a variable name mapping. */ - private int putVar(String name){ - if(vars.containsKey(name)){ - return vars.get(name); - }else{ - int id = lastVar++; - vars.put(name, id); - return id; - } - } -} diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index 57ba9624f4..ce1c4d73ba 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -13,13 +13,16 @@ import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; +import arc.util.ArcAnnotate.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.io.*; import mindustry.logic.LStatements.*; import mindustry.ui.*; public class LCanvas extends Table{ private static final Color backgroundCol = Pal.darkMetal.cpy().mul(0.1f), gridCol = Pal.darkMetal.cpy().mul(0.5f); + private static Seq postDraw = new Seq<>(); private Vec2 offset = new Vec2(); private DragLayout statements; @@ -32,11 +35,11 @@ public class LCanvas extends Table{ pane(statements).grow().get().setClip(false); - add(new LStatements.AssignStatement()); + add(new AssignStatement()); add(new FetchBuildStatement()); add(new JumpStatement()); add(new ToggleStatement()); - add(new LStatements.OpStatement()); + add(new OpStatement()); } private void drawGrid(){ @@ -66,9 +69,35 @@ public class LCanvas extends Table{ } void add(LStatement statement){ - StatementElem e = new StatementElem(statement); + statements.addChild(new StatementElem(statement)); + } - statements.addChild(e); + String save(){ + return LAssembler.assemble(statements.getChildren().as()).toJson(); + } + + void load(String json){ + statements.clearChildren(); + LStatement[] statements = JsonIO.read(LStatement[].class, json); + for(LStatement st : statements){ + add(st); + } + + LAssembler asm = new LAssembler(); + asm.elements = this.statements.getChildren().as(); + + for(LStatement st : statements){ + st.afterLoad(asm); + } + + this.statements.layout(); + } + + @Override + public void draw(){ + postDraw.clear(); + super.draw(); + postDraw.each(Runnable::run); } public class DragLayout extends WidgetGroup{ @@ -119,6 +148,7 @@ public class LCanvas extends Table{ seq.get(i).y -= shiftAmount; } } + } @Override @@ -246,20 +276,22 @@ public class LCanvas extends Table{ } public static class JumpButton extends ImageButton{ - StatementElem to; + @NonNull Prov to; boolean selecting; float mx, my; - public JumpButton(Color color, Cons setter){ + public JumpButton(Color color, @NonNull Prov getter, Cons setter){ super(Tex.logicNode, Styles.colori); + to = getter; + getStyle().imageUpColor = color; addListener(new InputListener(){ @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode code){ selecting = true; - setter.get(to = null); + setter.get(null); mx = x; my = y; return true; @@ -277,18 +309,17 @@ public class LCanvas extends Table{ StatementElem elem = hovered(); if(elem != null && !isDescendantOf(elem)){ - to = elem; + setter.get(elem); }else{ - to = null; + setter.get(null); } - setter.get(to); selecting = false; } }); update(() -> { - if(to != null && to.parent == null){ - setter.get(to = null); + if(to.get() != null && to.get().parent == null){ + setter.get(null); } }); } @@ -296,26 +327,39 @@ public class LCanvas extends Table{ @Override public void draw(){ super.draw(); - Element hover = to == null && selecting ? hovered() : to; - float tx = 0, ty = 0; - boolean draw = false; - if(hover != null){ - tx = hover.getX(Align.right) + hover.translation.x; - ty = hover.getY(Align.right) + hover.translation.y; - draw = true; - }else if(selecting){ - tx = x + mx; - ty = y + my; - draw = true; - } - if(draw){ - drawCurve(x + width/2f, y + height/2f, tx, ty, color); - float s = width; - Tex.logicNode.draw(tx + s*0.75f, ty - s/2f, -s, s); - } + postDraw.add(() -> { + Element hover = to.get() == null && selecting ? hovered() : to.get(); + float tx = 0, ty = 0; + boolean draw = false; + //capture coordinates for use in lambda + float rx = x, ry = y; + Element p = parent; + while(p != null){ + rx += p.x; + ry += p.y; + p = p.parent; + } + + if(hover != null){ + tx = hover.getX(Align.right) + hover.translation.x; + ty = hover.getY(Align.right) + hover.translation.y; + draw = true; + }else if(selecting){ + tx = rx + mx; + ty = ry + my; + draw = true; + } + + if(draw){ + drawCurve(rx + width/2f, ry + height/2f, tx, ty, color); + + float s = width; + Tex.logicNode.draw(tx + s*0.75f, ty - s/2f, -s, s); + } + }); } StatementElem hovered(){ diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index ea2f763fef..af9fc7352d 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -20,6 +20,29 @@ public class LExecutor{ } } + public void load(LAssembler builder){ + vars = new Var[builder.vars.size]; + instructions = builder.instructions; + counter = 0; + + builder.vars.each((name, var) -> { + Var v = new Var(); + vars[var.id] = v; + + if(var.constant){ + v.constant = true; + if(var.value instanceof Number){ + v.numval = ((Number)var.value).doubleValue(); + }else{ + v.isobj = true; + v.objval = var.value; + } + } + }); + } + + //region utility + @Nullable Building building(int index){ Object o = vars[index].objval; return o == null && o instanceof Building ? (Building)o : null; @@ -54,6 +77,8 @@ public class LExecutor{ v.isobj = true; } + //endregion + static class Var{ boolean isobj, constant; diff --git a/core/src/mindustry/logic/LStatement.java b/core/src/mindustry/logic/LStatement.java index a19e687211..c4295b473e 100644 --- a/core/src/mindustry/logic/LStatement.java +++ b/core/src/mindustry/logic/LStatement.java @@ -7,7 +7,15 @@ public abstract class LStatement{ public abstract void build(Table table); public abstract LCategory category(); - public abstract LExecutor.LInstruction build(LBuilder builder); + public abstract LExecutor.LInstruction build(LAssembler builder); + + public void afterLoad(LAssembler assembler){ + + } + + public void beforeSave(LAssembler assembler){ + + } public String name(){ return getClass().getSimpleName().replace("Statement", ""); diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index b260144a58..4d8f3507d2 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -30,7 +30,7 @@ public class LStatements{ } @Override - public LExecutor.LInstruction build(LBuilder builder){ + public LInstruction build(LAssembler builder){ //TODO internal consts need to start with ___ and not be assignable to return new LExecutor.AssignI(builder.var(from), builder.var(to)); } @@ -57,13 +57,13 @@ public class LStatements{ } @Override - public LExecutor.LInstruction build(LBuilder builder){ + public LExecutor.LInstruction build(LAssembler builder){ return new LExecutor.ToggleI(builder.var(target), builder.var(value)); } } public static class OpStatement extends LStatement{ - public mindustry.logic.BinaryOp op = mindustry.logic.BinaryOp.add; + public BinaryOp op = BinaryOp.add; public String a = "a", b = "b", dest = "result"; @Override @@ -79,7 +79,7 @@ public class LStatements{ TextButton[] button = {null}; button[0] = table.button(op.symbol, Styles.cleart, () -> { - op = mindustry.logic.BinaryOp.all[(op.ordinal() + 1) % BinaryOp.all.length]; + op = BinaryOp.all[(op.ordinal() + 1) % BinaryOp.all.length]; button[0].setText(op.symbol); }).size(50f, 30f).pad(4f).get(); @@ -88,7 +88,7 @@ public class LStatements{ } @Override - public LInstruction build(LBuilder builder){ + public LInstruction build(LAssembler builder){ return new BinaryOpI(op,builder.var(a), builder.var(b), builder.var(dest)); } @@ -105,7 +105,7 @@ public class LStatements{ } @Override - public LInstruction build(LBuilder builder){ + public LInstruction build(LAssembler builder){ return new EndI(); } @@ -116,8 +116,9 @@ public class LStatements{ } public static class JumpStatement extends LStatement{ - public StatementElem dest; - public String condition = " true"; + public transient StatementElem dest; + public int destIndex; + public String condition = "true"; @Override public void build(Table table){ @@ -125,12 +126,26 @@ public class LStatements{ table.field(condition, Styles.nodeField, str -> condition = str) .size(100f, 40f).pad(2f).color(table.color); table.add().growX(); - table.add(new JumpButton(Color.white, s -> dest = s)).size(30).right().padRight(-17); + table.add(new JumpButton(Color.white, () -> dest, s -> dest = s)).size(30).right().padRight(-17); + } + + //elements need separate conversion logic + @Override + public void afterLoad(LAssembler assembler){ + if(assembler.elements != null){ + dest = assembler.elements.get(destIndex); + } } @Override - public LInstruction build(LBuilder builder){ - return new JumpI(builder.var(condition), dest == null ? -1 : dest.parent.getChildren().indexOf(dest)); + public void beforeSave(LAssembler assembler){ + destIndex = dest == null ? -1 : dest.parent.getChildren().indexOf(dest); + } + + @Override + public LInstruction build(LAssembler builder){ + beforeSave(builder); + return new JumpI(builder.var(condition),destIndex); } @Override @@ -159,7 +174,7 @@ public class LStatements{ } @Override - public LExecutor.LInstruction build(LBuilder builder){ + public LInstruction build(LAssembler builder){ return new FetchBuildI(builder.var(dest), builder.var(x), builder.var(y)); } diff --git a/gradle.properties b/gradle.properties index e106e9552f..eb762dd4d6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=c18b1b1bff478e44baabebe1a944b2fb4bd37bad +archash=746b415d20da18753c6f477361979621d4e78ac2