Logic constant optimizations / Display admins on top
This commit is contained in:
@@ -17,6 +17,7 @@ import mindustry.game.*;
|
|||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.input.*;
|
import mindustry.input.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
|
import mindustry.logic.*;
|
||||||
import mindustry.maps.Map;
|
import mindustry.maps.Map;
|
||||||
import mindustry.maps.*;
|
import mindustry.maps.*;
|
||||||
import mindustry.mod.*;
|
import mindustry.mod.*;
|
||||||
@@ -68,7 +69,7 @@ public class Vars implements Loadable{
|
|||||||
/** list of built-in servers.*/
|
/** list of built-in servers.*/
|
||||||
public static final Seq<ServerGroup> defaultServers = Seq.with();
|
public static final Seq<ServerGroup> defaultServers = Seq.with();
|
||||||
/** maximum size of any block, do not change unless you know what you're doing */
|
/** maximum size of any block, do not change unless you know what you're doing */
|
||||||
public static final int maxBlockSize = 14;
|
public static final int maxBlockSize = 16;
|
||||||
/** maximum distance between mine and core that supports automatic transferring */
|
/** maximum distance between mine and core that supports automatic transferring */
|
||||||
public static final float mineTransferRange = 220f;
|
public static final float mineTransferRange = 220f;
|
||||||
/** max chat message length */
|
/** max chat message length */
|
||||||
@@ -195,6 +196,7 @@ public class Vars implements Loadable{
|
|||||||
public static BeControl becontrol;
|
public static BeControl becontrol;
|
||||||
public static AsyncCore asyncCore;
|
public static AsyncCore asyncCore;
|
||||||
public static BaseRegistry bases;
|
public static BaseRegistry bases;
|
||||||
|
public static GlobalConstants constants;
|
||||||
|
|
||||||
public static Universe universe;
|
public static Universe universe;
|
||||||
public static World world;
|
public static World world;
|
||||||
@@ -268,6 +270,7 @@ public class Vars implements Loadable{
|
|||||||
indexer = new BlockIndexer();
|
indexer = new BlockIndexer();
|
||||||
pathfinder = new Pathfinder();
|
pathfinder = new Pathfinder();
|
||||||
bases = new BaseRegistry();
|
bases = new BaseRegistry();
|
||||||
|
constants = new GlobalConstants();
|
||||||
|
|
||||||
state = new GameState();
|
state = new GameState();
|
||||||
|
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ public class ContentLoader{
|
|||||||
/** Calls Content#init() on everything. Use only after all modules have been created.*/
|
/** Calls Content#init() on everything. Use only after all modules have been created.*/
|
||||||
public void init(){
|
public void init(){
|
||||||
initialize(Content::init);
|
initialize(Content::init);
|
||||||
|
if(constants != null) constants.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Calls Content#load() on everything. Use only after all modules have been created on the client.*/
|
/** Calls Content#load() on everything. Use only after all modules have been created on the client.*/
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package mindustry.logic;
|
||||||
|
|
||||||
|
import arc.struct.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.logic.LExecutor.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
/** Stores global constants for logic processors. */
|
||||||
|
public class GlobalConstants{
|
||||||
|
private ObjectIntMap<String> namesToIds = new ObjectIntMap<>();
|
||||||
|
private Seq<Var> vars = new Seq<>(Var.class);
|
||||||
|
|
||||||
|
public void init(){
|
||||||
|
put("the end", null);
|
||||||
|
//add default constants
|
||||||
|
put("false", 0);
|
||||||
|
put("true", 1);
|
||||||
|
put("null", null);
|
||||||
|
|
||||||
|
//store base content
|
||||||
|
|
||||||
|
for(Item item : Vars.content.items()){
|
||||||
|
put("@" + item.name, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Liquid liquid : Vars.content.liquids()){
|
||||||
|
put("@" + liquid.name, liquid);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Block block : Vars.content.blocks()){
|
||||||
|
if(block.synthetic()){
|
||||||
|
put("@" + block.name, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//used as a special value for any environmental solid block
|
||||||
|
put("@solid", Blocks.stoneWall);
|
||||||
|
put("@air", Blocks.air);
|
||||||
|
|
||||||
|
for(UnitType type : Vars.content.units()){
|
||||||
|
put("@" + type.name, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
//store sensor constants
|
||||||
|
for(LAccess sensor : LAccess.all){
|
||||||
|
put("@" + sensor.name(), sensor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a constant ID > 0 if there is a constant with this name, otherwise -1. */
|
||||||
|
public int get(String name){
|
||||||
|
return namesToIds.get(name, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a constant variable by ID. ID is not bound checked and must be positive. */
|
||||||
|
public Var get(int id){
|
||||||
|
return vars.items[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds a constant value by name. */
|
||||||
|
public Var put(String name, Object value){
|
||||||
|
Var var = new Var(name);
|
||||||
|
var.constant = true;
|
||||||
|
if(value instanceof Number num){
|
||||||
|
var.numval = num.doubleValue();
|
||||||
|
}else{
|
||||||
|
var.isobj = true;
|
||||||
|
var.objval = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = vars.size;
|
||||||
|
namesToIds.put(name, index);
|
||||||
|
vars.add(var);
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,12 +4,9 @@ import arc.func.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.content.*;
|
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.logic.LExecutor.*;
|
import mindustry.logic.LExecutor.*;
|
||||||
import mindustry.logic.LStatements.*;
|
import mindustry.logic.LStatements.*;
|
||||||
import mindustry.type.*;
|
|
||||||
import mindustry.world.*;
|
|
||||||
|
|
||||||
/** "Compiles" a sequence of statements into instructions. */
|
/** "Compiles" a sequence of statements into instructions. */
|
||||||
public class LAssembler{
|
public class LAssembler{
|
||||||
@@ -31,42 +28,6 @@ public class LAssembler{
|
|||||||
putConst("@unit", null);
|
putConst("@unit", null);
|
||||||
//reference to self
|
//reference to self
|
||||||
putConst("@this", null);
|
putConst("@this", null);
|
||||||
|
|
||||||
//add default constants
|
|
||||||
putConst("false", 0);
|
|
||||||
putConst("true", 1);
|
|
||||||
putConst("null", null);
|
|
||||||
|
|
||||||
//store base content (TODO hacky?)
|
|
||||||
|
|
||||||
for(Item item : Vars.content.items()){
|
|
||||||
putConst("@" + item.name, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Liquid liquid : Vars.content.liquids()){
|
|
||||||
putConst("@" + liquid.name, liquid);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Block block : Vars.content.blocks()){
|
|
||||||
if(block.synthetic()){
|
|
||||||
putConst("@" + block.name, block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//used as a special value for any environmental solid block
|
|
||||||
putConst("@solid", Blocks.stoneWall);
|
|
||||||
|
|
||||||
putConst("@air", Blocks.air);
|
|
||||||
|
|
||||||
for(UnitType type : Vars.content.units()){
|
|
||||||
putConst("@" + type.name, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
//store sensor constants
|
|
||||||
|
|
||||||
for(LAccess sensor : LAccess.all){
|
|
||||||
putConst("@" + sensor.name(), sensor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LAssembler assemble(String data, int maxInstructions){
|
public static LAssembler assemble(String data, int maxInstructions){
|
||||||
@@ -185,6 +146,12 @@ public class LAssembler{
|
|||||||
/** @return a variable ID by name.
|
/** @return a variable ID 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 int var(String symbol){
|
||||||
|
int constId = Vars.constants.get(symbol);
|
||||||
|
if(constId > 0){
|
||||||
|
//global constants are *negated* and stored separately
|
||||||
|
return -constId;
|
||||||
|
}
|
||||||
|
|
||||||
symbol = symbol.trim();
|
symbol = symbol.trim();
|
||||||
|
|
||||||
//string case
|
//string case
|
||||||
|
|||||||
@@ -97,28 +97,33 @@ public class LExecutor{
|
|||||||
|
|
||||||
//region utility
|
//region utility
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable Building building(int index){
|
public @Nullable Building building(int index){
|
||||||
Object o = vars[index].objval;
|
Object o = var(index).objval;
|
||||||
return vars[index].isobj && o instanceof Building building ? building : null;
|
return var(index).isobj && o instanceof Building building ? building : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Object obj(int index){
|
public @Nullable Object obj(int index){
|
||||||
Object o = vars[index].objval;
|
Object o = var(index).objval;
|
||||||
return vars[index].isobj ? o : null;
|
return var(index).isobj ? o : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean bool(int index){
|
public boolean bool(int index){
|
||||||
Var v = vars[index];
|
Var v = var(index);
|
||||||
return v.isobj ? v.objval != null : Math.abs(v.numval) >= 0.00001;
|
return v.isobj ? v.objval != null : Math.abs(v.numval) >= 0.00001;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double num(int index){
|
public double num(int index){
|
||||||
Var v = vars[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 : Double.isNaN(v.numval) || Double.isInfinite(v.numval) ? 0 : v.numval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float numf(int index){
|
public float numf(int index){
|
||||||
Var v = vars[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 : Double.isNaN(v.numval) || Double.isInfinite(v.numval) ? 0 : (float)v.numval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +136,7 @@ public class LExecutor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setnum(int index, double value){
|
public void setnum(int index, double value){
|
||||||
Var v = vars[index];
|
Var v = var(index);
|
||||||
if(v.constant) return;
|
if(v.constant) return;
|
||||||
v.numval = Double.isNaN(value) || Double.isInfinite(value) ? 0 : value;
|
v.numval = Double.isNaN(value) || Double.isInfinite(value) ? 0 : value;
|
||||||
v.objval = null;
|
v.objval = null;
|
||||||
@@ -139,20 +144,21 @@ public class LExecutor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setobj(int index, Object value){
|
public void setobj(int index, Object value){
|
||||||
Var v = vars[index];
|
Var v = var(index);
|
||||||
if(v.constant) return;
|
if(v.constant) return;
|
||||||
v.objval = value;
|
v.objval = value;
|
||||||
v.isobj = true;
|
v.isobj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setconst(int index, Object value){
|
public void setconst(int index, Object value){
|
||||||
Var v = vars[index];
|
Var v = var(index);
|
||||||
v.objval = value;
|
v.objval = value;
|
||||||
v.isobj = true;
|
v.isobj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
/** A logic variable. */
|
||||||
public static class Var{
|
public static class Var{
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
@@ -735,8 +741,8 @@ public class LExecutor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(LExecutor exec){
|
public void run(LExecutor exec){
|
||||||
Var v = exec.vars[to];
|
Var v = exec.var(to);
|
||||||
Var f = exec.vars[from];
|
Var f = exec.var(from);
|
||||||
|
|
||||||
//TODO error out when the from-value is a constant
|
//TODO error out when the from-value is a constant
|
||||||
if(!v.constant){
|
if(!v.constant){
|
||||||
@@ -769,8 +775,8 @@ public class LExecutor{
|
|||||||
if(op.unary){
|
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.vars[a];
|
Var va = exec.var(a);
|
||||||
Var vb = exec.vars[b];
|
Var vb = exec.var(b);
|
||||||
|
|
||||||
if(op.objFunction2 != null && (va.isobj || vb.isobj)){
|
if(op.objFunction2 != null && (va.isobj || vb.isobj)){
|
||||||
//use object function if provided, and one of the variables is an object
|
//use object function if provided, and one of the variables is an object
|
||||||
@@ -788,7 +794,7 @@ public class LExecutor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(LExecutor exec){
|
public void run(LExecutor exec){
|
||||||
exec.vars[varCounter].numval = exec.instructions.length;
|
exec.var(varCounter).numval = exec.instructions.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -876,7 +882,7 @@ public class LExecutor{
|
|||||||
if(exec.textBuffer.length() >= maxTextBuffer) return;
|
if(exec.textBuffer.length() >= maxTextBuffer) return;
|
||||||
|
|
||||||
//this should avoid any garbage allocation
|
//this should avoid any garbage allocation
|
||||||
Var v = exec.vars[value];
|
Var v = exec.var(value);
|
||||||
if(v.isobj && value != 0){
|
if(v.isobj && value != 0){
|
||||||
String strValue =
|
String strValue =
|
||||||
v.objval == null ? "null" :
|
v.objval == null ? "null" :
|
||||||
@@ -940,8 +946,8 @@ public class LExecutor{
|
|||||||
@Override
|
@Override
|
||||||
public void run(LExecutor exec){
|
public void run(LExecutor exec){
|
||||||
if(address != -1){
|
if(address != -1){
|
||||||
Var va = exec.vars[value];
|
Var va = exec.var(value);
|
||||||
Var vb = exec.vars[compare];
|
Var vb = exec.var(compare);
|
||||||
boolean cmp;
|
boolean cmp;
|
||||||
|
|
||||||
if(op.objFunction != null && (va.isobj || vb.isobj)){
|
if(op.objFunction != null && (va.isobj || vb.isobj)){
|
||||||
@@ -952,7 +958,7 @@ public class LExecutor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(cmp){
|
if(cmp){
|
||||||
exec.vars[varCounter].numval = address;
|
exec.var(varCounter).numval = address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import arc.scene.*;
|
|||||||
import arc.scene.event.*;
|
import arc.scene.event.*;
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
@@ -21,6 +22,7 @@ public class PlayerListFragment extends Fragment{
|
|||||||
private Interval timer = new Interval();
|
private Interval timer = new Interval();
|
||||||
private TextField sField;
|
private TextField sField;
|
||||||
private boolean found = false;
|
private boolean found = false;
|
||||||
|
private Seq<Player> players = new Seq<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build(Group parent){
|
public void build(Group parent){
|
||||||
@@ -78,8 +80,12 @@ public class PlayerListFragment extends Fragment{
|
|||||||
float h = 74f;
|
float h = 74f;
|
||||||
found = false;
|
found = false;
|
||||||
|
|
||||||
Groups.player.sort(Structs.comparing(Player::team));
|
players.clear();
|
||||||
Groups.player.each(user -> {
|
Groups.player.copy(players);
|
||||||
|
|
||||||
|
players.sort(Structs.comps(Structs.comparing(Player::team), Structs.comparingBool(p -> !p.admin)));
|
||||||
|
|
||||||
|
for(var user : players){
|
||||||
found = true;
|
found = true;
|
||||||
NetConnection connection = user.con;
|
NetConnection connection = user.con;
|
||||||
|
|
||||||
@@ -159,7 +165,7 @@ public class PlayerListFragment extends Fragment{
|
|||||||
content.row();
|
content.row();
|
||||||
content.image().height(4f).color(state.rules.pvp ? user.team().color : Pal.gray).growX();
|
content.image().height(4f).color(state.rules.pvp ? user.team().color : Pal.gray).growX();
|
||||||
content.row();
|
content.row();
|
||||||
});
|
}
|
||||||
|
|
||||||
if(!found){
|
if(!found){
|
||||||
content.add(Core.bundle.format("players.notfound")).padBottom(6).width(350f).maxHeight(h + 14);
|
content.add(Core.bundle.format("players.notfound")).padBottom(6).width(350f).maxHeight(h + 14);
|
||||||
|
|||||||
Reference in New Issue
Block a user