isNull op / Return null for null block sense/NaNs

This commit is contained in:
Anuken
2021-02-08 12:48:39 -05:00
parent 49fe47f1f8
commit 1802aab683
3 changed files with 81 additions and 13 deletions

View File

@@ -1,5 +1,6 @@
package mindustry.logic; package mindustry.logic;
import arc.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
@@ -98,6 +99,10 @@ public class LExecutor{
//region utility //region utility
private static boolean invalid(double d){
return Double.isNaN(d) || Double.isInfinite(d);
}
public Var var(int index){ public Var var(int index){
//global constants have variable IDs < 0, and they are fetched from the global constants object after being negated //global constants have variable IDs < 0, and they are fetched from the global constants object after being negated
return index < 0 ? constants.get(-index) : vars[index]; return index < 0 ? constants.get(-index) : vars[index];
@@ -120,12 +125,12 @@ public class LExecutor{
public double num(int index){ public double num(int index){
Var v = var(index); Var v = var(index);
return v.isobj ? v.objval != null ? 1 : 0 : Double.isNaN(v.numval) || Double.isInfinite(v.numval) ? 0 : v.numval; return v.isobj ? v.objval != null ? 1 : 0 : invalid(v.numval) ? 0 : v.numval;
} }
public float numf(int index){ public float numf(int index){
Var v = var(index); Var v = var(index);
return v.isobj ? v.objval != null ? 1 : 0 : Double.isNaN(v.numval) || Double.isInfinite(v.numval) ? 0 : (float)v.numval; return v.isobj ? v.objval != null ? 1 : 0 : invalid(v.numval) ? 0 : (float)v.numval;
} }
public int numi(int index){ public int numi(int index){
@@ -139,9 +144,14 @@ public class LExecutor{
public void setnum(int index, double value){ public void setnum(int index, double value){
Var v = var(index); Var v = var(index);
if(v.constant) return; if(v.constant) return;
v.numval = Double.isNaN(value) || Double.isInfinite(value) ? 0 : value; if(invalid(value)){
v.objval = null; v.objval = null;
v.isobj = false; v.isobj = true;
}else{
v.numval = value;
v.objval = null;
v.isobj = false;
}
} }
public void setobj(int index, Object value){ public void setobj(int index, Object value){
@@ -622,21 +632,21 @@ public class LExecutor{
//note that remote units/buildings can be sensed as well //note that remote units/buildings can be sensed as well
if(target instanceof Senseable se){ if(target instanceof Senseable se){
if(sense instanceof Content){ if(sense instanceof Content co){
exec.setnum(to, se.sense(((Content)sense))); exec.setnum(to, se.sense(co));
}else if(sense instanceof LAccess){ }else if(sense instanceof LAccess la){
Object objOut = se.senseObject((LAccess)sense); Object objOut = se.senseObject(la);
if(objOut == Senseable.noSensed){ if(objOut == Senseable.noSensed){
//numeric output //numeric output
exec.setnum(to, se.sense((LAccess)sense)); exec.setnum(to, se.sense(la));
}else{ }else{
//object output //object output
exec.setobj(to, objOut); exec.setobj(to, objOut);
} }
} }
}else{ }else{
exec.setnum(to, 0); exec.setobj(to, null);
} }
} }
} }
@@ -752,7 +762,7 @@ public class LExecutor{
v.objval = f.objval; v.objval = f.objval;
v.isobj = true; v.isobj = true;
}else{ }else{
v.numval = Double.isNaN(f.numval) || Double.isInfinite(f.numval) ? 0 : f.numval; v.numval = invalid(f.numval) ? 0 : f.numval;
v.isobj = false; v.isobj = false;
} }
} }
@@ -774,7 +784,10 @@ public class LExecutor{
@Override @Override
public void run(LExecutor exec){ public void run(LExecutor exec){
if(op.unary){ if(op == LogicOp.isNull){
var v = exec.var(a);
exec.setnum(dest, v.isobj && v.objval == null ? 1 : 0);
}else if(op.unary){
exec.setnum(dest, op.function1.get(exec.num(a))); exec.setnum(dest, op.function1.get(exec.num(a)));
}else{ }else{
Var va = exec.var(a); Var va = exec.var(a);
@@ -965,5 +978,37 @@ public class LExecutor{
} }
} }
public static class WaitI implements LInstruction{
public int value;
public float curTime;
public double wait;
public long frameId;
public WaitI(int value){
this.value = value;
}
public WaitI(){
}
@Override
public void run(LExecutor exec){
if(curTime >= exec.num(value)){
curTime = 0f;
}else{
//skip back to self.
exec.var(varCounter).numval --;
}
if(Core.graphics.getFrameId() != frameId){
curTime += Time.delta / 60f;
frameId = Core.graphics.getFrameId();
}
}
}
//endregion //endregion
} }

View File

@@ -637,6 +637,28 @@ public class LStatements{
} }
} }
//TODO untested
//@RegisterStatement("wait")
public static class WaitStatement extends LStatement{
public String value = "0.5";
@Override
public void build(Table table){
field(table, value, str -> value = str);
table.add(" sec");
}
@Override
public Color color(){
return Pal.logicOperations;
}
@Override
public LInstruction build(LAssembler builder){
return new WaitI(builder.var(value));
}
}
@RegisterStatement("end") @RegisterStatement("end")
public static class EndStatement extends LStatement{ public static class EndStatement extends LStatement{
@Override @Override

View File

@@ -27,6 +27,7 @@ public enum LogicOp{
xor("xor", (a, b) -> (long)a ^ (long)b), xor("xor", (a, b) -> (long)a ^ (long)b),
not("flip", a -> ~(long)(a)), not("flip", a -> ~(long)(a)),
isNull("isNull", v -> v == 0 ? 1 : 0), //this lambda is not actually used
max("max", Math::max), max("max", Math::max),
min("min", Math::min), min("min", Math::min),
atan2("atan2", (x, y) -> Mathf.atan2((float)x, (float)y) * Mathf.radDeg), atan2("atan2", (x, y) -> Mathf.atan2((float)x, (float)y) * Mathf.radDeg),