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;
import arc.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
@@ -98,6 +99,10 @@ public class LExecutor{
//region utility
private static boolean invalid(double d){
return Double.isNaN(d) || Double.isInfinite(d);
}
public Var var(int index){
//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];
@@ -120,12 +125,12 @@ public class LExecutor{
public double num(int 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){
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){
@@ -139,10 +144,15 @@ public class LExecutor{
public void setnum(int index, double value){
Var v = var(index);
if(v.constant) return;
v.numval = Double.isNaN(value) || Double.isInfinite(value) ? 0 : value;
if(invalid(value)){
v.objval = null;
v.isobj = true;
}else{
v.numval = value;
v.objval = null;
v.isobj = false;
}
}
public void setobj(int index, Object value){
Var v = var(index);
@@ -622,21 +632,21 @@ public class LExecutor{
//note that remote units/buildings can be sensed as well
if(target instanceof Senseable se){
if(sense instanceof Content){
exec.setnum(to, se.sense(((Content)sense)));
}else if(sense instanceof LAccess){
Object objOut = se.senseObject((LAccess)sense);
if(sense instanceof Content co){
exec.setnum(to, se.sense(co));
}else if(sense instanceof LAccess la){
Object objOut = se.senseObject(la);
if(objOut == Senseable.noSensed){
//numeric output
exec.setnum(to, se.sense((LAccess)sense));
exec.setnum(to, se.sense(la));
}else{
//object output
exec.setobj(to, objOut);
}
}
}else{
exec.setnum(to, 0);
exec.setobj(to, null);
}
}
}
@@ -752,7 +762,7 @@ public class LExecutor{
v.objval = f.objval;
v.isobj = true;
}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;
}
}
@@ -774,7 +784,10 @@ public class LExecutor{
@Override
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)));
}else{
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
}

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")
public static class EndStatement extends LStatement{
@Override

View File

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