Logic Refactor (#9940)
* Replace logic variable indexes * Fix `draw print`'s align * Update core/src/mindustry/logic/LExecutor.java Co-authored-by: Anuken <arnukren@gmail.com> * Remove duplicated variables * Update core/src/mindustry/world/blocks/logic/LogicBlock.java --------- Co-authored-by: Anuken <arnukren@gmail.com>
This commit is contained in:
@@ -1038,14 +1038,19 @@ public class TypeIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface Boxed<T> {
|
||||||
|
T unbox();
|
||||||
|
}
|
||||||
|
|
||||||
/** Represents a building that has not been resolved yet. */
|
/** Represents a building that has not been resolved yet. */
|
||||||
public static class BuildingBox{
|
public static class BuildingBox implements Boxed<Building>{
|
||||||
public int pos;
|
public int pos;
|
||||||
|
|
||||||
public BuildingBox(int pos){
|
public BuildingBox(int pos){
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Building unbox(){
|
public Building unbox(){
|
||||||
return world.build(pos);
|
return world.build(pos);
|
||||||
}
|
}
|
||||||
@@ -1059,13 +1064,14 @@ public class TypeIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Represents a unit that has not been resolved yet. TODO unimplemented / unused*/
|
/** Represents a unit that has not been resolved yet. TODO unimplemented / unused*/
|
||||||
public static class UnitBox{
|
public static class UnitBox implements Boxed<Unit>{
|
||||||
public int id;
|
public int id;
|
||||||
|
|
||||||
public UnitBox(int id){
|
public UnitBox(int id){
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Unit unbox(){
|
public Unit unbox(){
|
||||||
return Groups.unit.getByID(id);
|
return Groups.unit.getByID(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import mindustry.*;
|
|||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.logic.LExecutor.*;
|
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.legacy.*;
|
import mindustry.world.blocks.legacy.*;
|
||||||
@@ -27,12 +26,11 @@ public class GlobalVars{
|
|||||||
public static final Rand rand = new Rand();
|
public static final Rand rand = new Rand();
|
||||||
|
|
||||||
//non-constants that depend on state
|
//non-constants that depend on state
|
||||||
private static int varTime, varTick, varSecond, varMinute, varWave, varWaveTime, varMapW, varMapH, varServer, varClient, varClientLocale, varClientUnit, varClientName, varClientTeam, varClientMobile;
|
private static LVar varTime, varTick, varSecond, varMinute, varWave, varWaveTime, varMapW, varMapH, varServer, varClient, varClientLocale, varClientUnit, varClientName, varClientTeam, varClientMobile;
|
||||||
|
|
||||||
private ObjectIntMap<String> namesToIds = new ObjectIntMap<>();
|
private ObjectMap<String, LVar> vars = new ObjectMap<>();
|
||||||
private Seq<Var> vars = new Seq<>(Var.class);
|
|
||||||
private Seq<VarEntry> varEntries = new Seq<>();
|
private Seq<VarEntry> varEntries = new Seq<>();
|
||||||
private IntSet privilegedIds = new IntSet();
|
private ObjectSet<String> privilegedNames = new ObjectSet<>();
|
||||||
private UnlockableContent[][] logicIdToContent;
|
private UnlockableContent[][] logicIdToContent;
|
||||||
private int[][] contentIdToLogicId;
|
private int[][] contentIdToLogicId;
|
||||||
|
|
||||||
@@ -172,31 +170,31 @@ public class GlobalVars{
|
|||||||
public void update(){
|
public void update(){
|
||||||
//set up time; note that @time is now only updated once every invocation and directly based off of @tick.
|
//set up time; note that @time is now only updated once every invocation and directly based off of @tick.
|
||||||
//having time be based off of user system time was a very bad idea.
|
//having time be based off of user system time was a very bad idea.
|
||||||
vars.items[varTime].numval = state.tick / 60.0 * 1000.0;
|
varTime.numval = state.tick / 60.0 * 1000.0;
|
||||||
vars.items[varTick].numval = state.tick;
|
varTick.numval = state.tick;
|
||||||
|
|
||||||
//shorthands for seconds/minutes spent in save
|
//shorthands for seconds/minutes spent in save
|
||||||
vars.items[varSecond].numval = state.tick / 60f;
|
varSecond.numval = state.tick / 60f;
|
||||||
vars.items[varMinute].numval = state.tick / 60f / 60f;
|
varMinute.numval = state.tick / 60f / 60f;
|
||||||
|
|
||||||
//wave state
|
//wave state
|
||||||
vars.items[varWave].numval = state.wave;
|
varWave.numval = state.wave;
|
||||||
vars.items[varWaveTime].numval = state.wavetime / 60f;
|
varWaveTime.numval = state.wavetime / 60f;
|
||||||
|
|
||||||
vars.items[varMapW].numval = world.width();
|
varMapW.numval = world.width();
|
||||||
vars.items[varMapH].numval = world.height();
|
varMapH.numval = world.height();
|
||||||
|
|
||||||
//network
|
//network
|
||||||
vars.items[varServer].numval = (net.server() || !net.active()) ? 1 : 0;
|
varServer.numval = (net.server() || !net.active()) ? 1 : 0;
|
||||||
vars.items[varClient].numval = net.client() ? 1 : 0;
|
varClient.numval = net.client() ? 1 : 0;
|
||||||
|
|
||||||
//client
|
//client
|
||||||
if(!net.server() && player != null){
|
if(!net.server() && player != null){
|
||||||
vars.items[varClientLocale].objval = player.locale();
|
varClientLocale.objval = player.locale();
|
||||||
vars.items[varClientUnit].objval = player.unit();
|
varClientUnit.objval = player.unit();
|
||||||
vars.items[varClientName].objval = player.name();
|
varClientName.objval = player.name();
|
||||||
vars.items[varClientTeam].numval = player.team().id;
|
varClientTeam.numval = player.team().id;
|
||||||
vars.items[varClientMobile].numval = mobile ? 1 : 0;
|
varClientMobile.numval = mobile ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,84 +215,81 @@ public class GlobalVars{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a constant ID > 0 if there is a constant with this name, otherwise -1.
|
* @return a constant variable if there is a constant with this name, otherwise null.
|
||||||
* Attempt to get privileged variable id from non-privileged logic executor returns null constant id.
|
* Attempt to get privileged variable from non-privileged logic executor returns null constant.
|
||||||
*/
|
*/
|
||||||
public int get(String name){
|
public LVar get(String name){
|
||||||
return namesToIds.get(name, -1);
|
return vars.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a constant variable by ID. ID is not bound checked and must be positive.
|
* @return a constant variable by name
|
||||||
* Attempt to get privileged variable from non-privileged logic executor returns null constant
|
* Attempt to get privileged variable from non-privileged logic executor returns null constant.
|
||||||
*/
|
*/
|
||||||
public Var get(int id, boolean privileged){
|
public LVar get(String name, boolean privileged){
|
||||||
if(!privileged && privilegedIds.contains(id)) return vars.get(namesToIds.get("null"));
|
if(!privileged && privilegedNames.contains(name)) return vars.get("null");
|
||||||
return vars.items[id];
|
return vars.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets a global variable by an ID returned from put(). */
|
/** Sets a global variable by name. */
|
||||||
public void set(int id, double value){
|
public void set(String name, double value){
|
||||||
get(id, true).numval = value;
|
get(name, true).numval = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a constant value by name. */
|
/** Adds a constant value by name. */
|
||||||
public int put(String name, Object value, boolean privileged){
|
public LVar put(String name, Object value, boolean privileged){
|
||||||
return put(name, value, privileged, true);
|
return put(name, value, privileged, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a constant value by name. */
|
/** Adds a constant value by name. */
|
||||||
public int put(String name, Object value, boolean privileged, boolean hidden){
|
public LVar put(String name, Object value, boolean privileged, boolean hidden){
|
||||||
int existingIdx = namesToIds.get(name, -1);
|
LVar existingVar = vars.get(name);
|
||||||
if(existingIdx != -1){ //don't overwrite existing vars (see #6910)
|
if(existingVar != null){ //don't overwrite existing vars (see #6910)
|
||||||
Log.debug("Failed to add global logic variable '@', as it already exists.", name);
|
Log.debug("Failed to add global logic variable '@', as it already exists.", name);
|
||||||
return existingIdx;
|
return existingVar;
|
||||||
}
|
}
|
||||||
|
|
||||||
Var var = new Var(name);
|
LVar var = new LVar(name);
|
||||||
var.constant = true;
|
var.constant = true;
|
||||||
if(value instanceof Number num){
|
if(value instanceof Number num){
|
||||||
|
var.isobj = false;
|
||||||
var.numval = num.doubleValue();
|
var.numval = num.doubleValue();
|
||||||
}else{
|
}else{
|
||||||
var.isobj = true;
|
var.isobj = true;
|
||||||
var.objval = value;
|
var.objval = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = vars.size;
|
vars.put(name, var);
|
||||||
namesToIds.put(name, index);
|
if(privileged) privilegedNames.add(name);
|
||||||
if(privileged) privilegedIds.add(index);
|
|
||||||
vars.add(var);
|
|
||||||
|
|
||||||
if(!hidden){
|
if(!hidden){
|
||||||
varEntries.add(new VarEntry(index, name, "", "", privileged));
|
varEntries.add(new VarEntry(name, "", "", privileged));
|
||||||
}
|
}
|
||||||
return index;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int put(String name, Object value){
|
public LVar put(String name, Object value){
|
||||||
return put(name, value, false);
|
return put(name, value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int putEntry(String name, Object value){
|
public LVar putEntry(String name, Object value){
|
||||||
return put(name, value, false, false);
|
return put(name, value, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int putEntry(String name, Object value, boolean privileged){
|
public LVar putEntry(String name, Object value, boolean privileged){
|
||||||
return put(name, value, privileged, false);
|
return put(name, value, privileged, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putEntryOnly(String name){
|
public void putEntryOnly(String name){
|
||||||
varEntries.add(new VarEntry(0, name, "", "", false));
|
varEntries.add(new VarEntry(name, "", "", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An entry that describes a variable for documentation purposes. This is *only* used inside UI for global variables. */
|
/** An entry that describes a variable for documentation purposes. This is *only* used inside UI for global variables. */
|
||||||
public static class VarEntry{
|
public static class VarEntry{
|
||||||
public int id;
|
|
||||||
public String name, description, icon;
|
public String name, description, icon;
|
||||||
public boolean privileged;
|
public boolean privileged;
|
||||||
|
|
||||||
public VarEntry(int id, String name, String description, String icon, boolean privileged){
|
public VarEntry(String name, String description, String icon, boolean privileged){
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import arc.graphics.*;
|
|||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.ui.dialogs.*;
|
import mindustry.ui.dialogs.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class GlobalVarsDialog extends BaseDialog{
|
public class GlobalVarsDialog extends BaseDialog{
|
||||||
|
|
||||||
public GlobalVarsDialog(){
|
public GlobalVarsDialog(){
|
||||||
@@ -28,8 +29,7 @@ public class GlobalVarsDialog extends BaseDialog{
|
|||||||
cont.pane(t -> {
|
cont.pane(t -> {
|
||||||
t.margin(10f).marginRight(16f);
|
t.margin(10f).marginRight(16f);
|
||||||
t.defaults().fillX().fillY();
|
t.defaults().fillX().fillY();
|
||||||
for(var entry : Vars.logicVars.getEntries()){
|
for(var entry : logicVars.getEntries()){
|
||||||
|
|
||||||
if(entry.name.startsWith("section")){
|
if(entry.name.startsWith("section")){
|
||||||
Color color = Pal.accent;
|
Color color = Pal.accent;
|
||||||
t.add("@lglobal." + entry.name).fillX().center().labelAlign(Align.center).colspan(4).color(color).padTop(4f).padBottom(2f).row();
|
t.add("@lglobal." + entry.name).fillX().center().labelAlign(Align.center).colspan(4).color(color).padTop(4f).padBottom(2f).row();
|
||||||
|
|||||||
@@ -14,16 +14,15 @@ public class LAssembler{
|
|||||||
|
|
||||||
private static final int invalidNum = Integer.MIN_VALUE;
|
private static final int invalidNum = Integer.MIN_VALUE;
|
||||||
|
|
||||||
private int lastVar;
|
|
||||||
private boolean privileged;
|
private boolean privileged;
|
||||||
/** Maps names to variable IDs. */
|
/** Maps names to variable. */
|
||||||
public ObjectMap<String, BVar> vars = new ObjectMap<>();
|
public OrderedMap<String, LVar> vars = new OrderedMap<>();
|
||||||
/** All instructions to be executed. */
|
/** All instructions to be executed. */
|
||||||
public LInstruction[] instructions;
|
public LInstruction[] instructions;
|
||||||
|
|
||||||
public LAssembler(){
|
public LAssembler(){
|
||||||
//instruction counter
|
//instruction counter
|
||||||
putVar("@counter").value = 0;
|
putVar("@counter");
|
||||||
//currently controlled unit
|
//currently controlled unit
|
||||||
putConst("@unit", null);
|
putConst("@unit", null);
|
||||||
//reference to self
|
//reference to self
|
||||||
@@ -57,20 +56,17 @@ public class LAssembler{
|
|||||||
return new LParser(text, privileged).parse();
|
return new LParser(text, privileged).parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return a variable ID by name.
|
/** @return a variable by name.
|
||||||
* This may be a constant variable referring to a number or object. */
|
* This may be a constant variable referring to a number or object. */
|
||||||
public int var(String symbol){
|
public LVar var(String symbol){
|
||||||
int constId = Vars.logicVars.get(symbol);
|
LVar constVar = Vars.logicVars.get(symbol);
|
||||||
if(constId > 0){
|
if(constVar != null) return constVar;
|
||||||
//global constants are *negated* and stored separately
|
|
||||||
return -constId;
|
|
||||||
}
|
|
||||||
|
|
||||||
symbol = symbol.trim();
|
symbol = symbol.trim();
|
||||||
|
|
||||||
//string case
|
//string case
|
||||||
if(!symbol.isEmpty() && symbol.charAt(0) == '\"' && symbol.charAt(symbol.length() - 1) == '\"'){
|
if(!symbol.isEmpty() && symbol.charAt(0) == '\"' && symbol.charAt(symbol.length() - 1) == '\"'){
|
||||||
return putConst("___" + symbol, symbol.substring(1, symbol.length() - 1).replace("\\n", "\n")).id;
|
return putConst("___" + symbol, symbol.substring(1, symbol.length() - 1).replace("\\n", "\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove spaces for non-strings
|
//remove spaces for non-strings
|
||||||
@@ -79,10 +75,10 @@ public class LAssembler{
|
|||||||
double value = parseDouble(symbol);
|
double value = parseDouble(symbol);
|
||||||
|
|
||||||
if(value == invalidNum){
|
if(value == invalidNum){
|
||||||
return putVar(symbol).id;
|
return putVar(symbol);
|
||||||
}else{
|
}else{
|
||||||
//this creates a hidden const variable with the specified value
|
//this creates a hidden const variable with the specified value
|
||||||
return putConst("___" + value, value).id;
|
return putConst("___" + value, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,48 +102,34 @@ public class LAssembler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a constant value by name. */
|
/** Adds a constant value by name. */
|
||||||
public BVar putConst(String name, Object value){
|
public LVar putConst(String name, Object value){
|
||||||
BVar var = putVar(name);
|
LVar var = putVar(name);
|
||||||
|
if(value instanceof Number number){
|
||||||
|
var.isobj = false;
|
||||||
|
var.numval = number.doubleValue();
|
||||||
|
var.objval = null;
|
||||||
|
}else{
|
||||||
|
var.isobj = true;
|
||||||
|
var.objval = value;
|
||||||
|
}
|
||||||
var.constant = true;
|
var.constant = true;
|
||||||
var.value = value;
|
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Registers a variable name mapping. */
|
/** Registers a variable name mapping. */
|
||||||
public BVar putVar(String name){
|
public LVar putVar(String name){
|
||||||
if(vars.containsKey(name)){
|
if(vars.containsKey(name)){
|
||||||
return vars.get(name);
|
return vars.get(name);
|
||||||
}else{
|
}else{
|
||||||
BVar var = new BVar(lastVar++);
|
LVar var = new LVar(name);
|
||||||
vars.put(name, var);
|
vars.put(name, var);
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public BVar getVar(String name){
|
public LVar getVar(String name){
|
||||||
return vars.get(name);
|
return vars.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A variable "builder". */
|
|
||||||
public static class BVar{
|
|
||||||
public int id;
|
|
||||||
public boolean constant;
|
|
||||||
public Object value;
|
|
||||||
|
|
||||||
public BVar(int id){
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
BVar(){}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(){
|
|
||||||
return "BVar{" +
|
|
||||||
"id=" + id +
|
|
||||||
", constant=" + constant +
|
|
||||||
", value=" + value +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -281,8 +281,8 @@ public class LStatements{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LInstruction build(LAssembler builder){
|
public LInstruction build(LAssembler builder){
|
||||||
return new DrawI((byte)type.ordinal(), 0, builder.var(x), builder.var(y),
|
return new DrawI((byte)type.ordinal(), builder.var(x), builder.var(y),
|
||||||
type == GraphicsType.print ? nameToAlign.get(p1, Align.bottomLeft) : builder.var(p1), builder.var(p2), builder.var(p3), builder.var(p4));
|
type == GraphicsType.print ? new LVar(p1, nameToAlign.get(p1, Align.bottomLeft), true) : builder.var(p1), builder.var(p2), builder.var(p3), builder.var(p4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1045,7 +1045,7 @@ public class LStatements{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LInstruction build(LAssembler builder){
|
public LInstruction build(LAssembler builder){
|
||||||
return new RadarI(target1, target2, target3, sort, LExecutor.varUnit, builder.var(sortOrder), builder.var(output));
|
return new RadarI(target1, target2, target3, sort, builder.var("@unit"), builder.var(sortOrder), builder.var(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
108
core/src/mindustry/logic/LVar.java
Normal file
108
core/src/mindustry/logic/LVar.java
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package mindustry.logic;
|
||||||
|
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.game.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
|
||||||
|
public class LVar{
|
||||||
|
public final String name;
|
||||||
|
public int id;
|
||||||
|
|
||||||
|
public boolean isobj, constant;
|
||||||
|
|
||||||
|
public Object objval;
|
||||||
|
public double numval;
|
||||||
|
|
||||||
|
//ms timestamp for when this was last synced; used in the sync instruction
|
||||||
|
public long syncTime;
|
||||||
|
|
||||||
|
public LVar(String name){
|
||||||
|
this(name, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LVar(String name, int id){
|
||||||
|
this(name, id, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LVar(String name, int id, boolean constant){
|
||||||
|
this.name = name;
|
||||||
|
this.id = id;
|
||||||
|
this.constant = constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Building building(){
|
||||||
|
return isobj && objval instanceof Building building ? building : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Object obj(){
|
||||||
|
return isobj ? objval : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Team team(){
|
||||||
|
if(isobj){
|
||||||
|
return objval instanceof Team t ? t : null;
|
||||||
|
}else{
|
||||||
|
int t = (int)numval;
|
||||||
|
if(t < 0 || t >= Team.all.length) return null;
|
||||||
|
return Team.all[t];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean bool(){
|
||||||
|
return isobj ? objval != null : Math.abs(numval) >= 0.00001;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double num(){
|
||||||
|
return isobj ? objval != null ? 1 : 0 : invalid(numval) ? 0 : numval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get num value from variable, convert null to NaN to handle it differently in some instructions */
|
||||||
|
public double numOrNan(){
|
||||||
|
return isobj ? objval != null ? 1 : Double.NaN : invalid(numval) ? 0 : numval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float numf(){
|
||||||
|
return isobj ? objval != null ? 1 : 0 : invalid(numval) ? 0 : (float)numval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get float value from variable, convert null to NaN to handle it differently in some instructions */
|
||||||
|
public float numfOrNan(){
|
||||||
|
return isobj ? objval != null ? 1 : Float.NaN : invalid(numval) ? 0 : (float)numval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int numi(){
|
||||||
|
return (int)num();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setbool(boolean value){
|
||||||
|
setnum(value ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setnum(double value){
|
||||||
|
if(constant) return;
|
||||||
|
if(invalid(value)){
|
||||||
|
objval = null;
|
||||||
|
isobj = true;
|
||||||
|
}else{
|
||||||
|
numval = value;
|
||||||
|
objval = null;
|
||||||
|
isobj = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setobj(Object value){
|
||||||
|
if(constant) return;
|
||||||
|
objval = value;
|
||||||
|
isobj = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setconst(Object value){
|
||||||
|
objval = value;
|
||||||
|
isobj = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean invalid(double d){
|
||||||
|
return Double.isNaN(d) || Double.isInfinite(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -53,7 +53,7 @@ public class LogicDialog extends BaseDialog{
|
|||||||
add(buttons).growX().name("canvas");
|
add(buttons).growX().name("canvas");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Color typeColor(Var s, Color color){
|
public static Color typeColor(LVar s, Color color){
|
||||||
return color.set(
|
return color.set(
|
||||||
!s.isobj ? Pal.place :
|
!s.isobj ? Pal.place :
|
||||||
s.objval == null ? Color.darkGray :
|
s.objval == null ? Color.darkGray :
|
||||||
@@ -67,7 +67,7 @@ public class LogicDialog extends BaseDialog{
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String typeName(Var s){
|
public static String typeName(LVar s){
|
||||||
return
|
return
|
||||||
!s.isobj ? "number" :
|
!s.isobj ? "number" :
|
||||||
s.objval == null ? "null" :
|
s.objval == null ? "null" :
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ import mindustry.graphics.*;
|
|||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
import mindustry.io.TypeIO.*;
|
import mindustry.io.TypeIO.*;
|
||||||
import mindustry.logic.*;
|
import mindustry.logic.*;
|
||||||
import mindustry.logic.LAssembler.*;
|
|
||||||
import mindustry.logic.LExecutor.*;
|
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.ConstructBlock.*;
|
import mindustry.world.blocks.ConstructBlock.*;
|
||||||
@@ -381,12 +379,14 @@ public class LogicBlock extends Block{
|
|||||||
|
|
||||||
if(keep){
|
if(keep){
|
||||||
//store any older variables
|
//store any older variables
|
||||||
for(Var var : executor.vars){
|
for(LVar var : executor.vars){
|
||||||
boolean unit = var.name.equals("@unit");
|
boolean unit = var.name.equals("@unit");
|
||||||
if(!var.constant || unit){
|
if(!var.constant || unit){
|
||||||
BVar dest = asm.getVar(var.name);
|
LVar dest = asm.getVar(var.name);
|
||||||
if(dest != null && (!dest.constant || unit)){
|
if(dest != null && (!dest.constant || unit)){
|
||||||
dest.value = var.isobj ? var.objval : var.numval;
|
dest.isobj = var.isobj;
|
||||||
|
dest.objval = var.objval;
|
||||||
|
dest.numval = var.numval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,7 +397,7 @@ public class LogicBlock extends Block{
|
|||||||
assemble.get(asm);
|
assemble.get(asm);
|
||||||
}
|
}
|
||||||
|
|
||||||
asm.getVar("@this").value = this;
|
asm.getVar("@this").setconst(this);
|
||||||
asm.putConst("@thisx", World.conv(x));
|
asm.putConst("@thisx", World.conv(x));
|
||||||
asm.putConst("@thisy", World.conv(y));
|
asm.putConst("@thisy", World.conv(y));
|
||||||
|
|
||||||
@@ -682,17 +682,17 @@ public class LogicBlock extends Block{
|
|||||||
write.b(compressed);
|
write.b(compressed);
|
||||||
|
|
||||||
//write only the non-constant variables
|
//write only the non-constant variables
|
||||||
int count = Structs.count(executor.vars, v -> (!v.constant || v == executor.vars[LExecutor.varUnit]) && !(v.isobj && v.objval == null));
|
int count = Structs.count(executor.vars, v -> (!v.constant || v == executor.unit) && !(v.isobj && v.objval == null));
|
||||||
|
|
||||||
write.i(count);
|
write.i(count);
|
||||||
for(int i = 0; i < executor.vars.length; i++){
|
for(int i = 0; i < executor.vars.length; i++){
|
||||||
Var v = executor.vars[i];
|
LVar v = executor.vars[i];
|
||||||
|
|
||||||
//null is the default variable value, so waste no time serializing that
|
//null is the default variable value, so waste no time serializing that
|
||||||
if(v.isobj && v.objval == null) continue;
|
if(v.isobj && v.objval == null) continue;
|
||||||
|
|
||||||
//skip constants
|
//skip constants
|
||||||
if(v.constant && i != LExecutor.varUnit) continue;
|
if(v.constant && v != executor.unit) continue;
|
||||||
|
|
||||||
//write the name and the object value
|
//write the name and the object value
|
||||||
write.str(v.name);
|
write.str(v.name);
|
||||||
@@ -751,13 +751,9 @@ public class LogicBlock extends Block{
|
|||||||
loadBlock = () -> updateCode(code, false, asm -> {
|
loadBlock = () -> updateCode(code, false, asm -> {
|
||||||
//load up the variables that were stored
|
//load up the variables that were stored
|
||||||
for(int i = 0; i < varcount; i++){
|
for(int i = 0; i < varcount; i++){
|
||||||
BVar dest = asm.getVar(names[i]);
|
LVar var = asm.getVar(names[i]);
|
||||||
|
if(var.objval instanceof Boxed<?> boxed){
|
||||||
if(dest != null && (!dest.constant || dest.id == LExecutor.varUnit)){
|
var.objval = boxed.unbox();
|
||||||
dest.value =
|
|
||||||
values[i] instanceof BuildingBox box ? box.unbox() :
|
|
||||||
values[i] instanceof UnitBox box ? box.unbox() :
|
|
||||||
values[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user