Logic constant optimizations / Display admins on top
This commit is contained in:
@@ -17,6 +17,7 @@ import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.input.*;
|
||||
import mindustry.io.*;
|
||||
import mindustry.logic.*;
|
||||
import mindustry.maps.Map;
|
||||
import mindustry.maps.*;
|
||||
import mindustry.mod.*;
|
||||
@@ -68,7 +69,7 @@ public class Vars implements Loadable{
|
||||
/** list of built-in servers.*/
|
||||
public static final Seq<ServerGroup> defaultServers = Seq.with();
|
||||
/** 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 */
|
||||
public static final float mineTransferRange = 220f;
|
||||
/** max chat message length */
|
||||
@@ -195,6 +196,7 @@ public class Vars implements Loadable{
|
||||
public static BeControl becontrol;
|
||||
public static AsyncCore asyncCore;
|
||||
public static BaseRegistry bases;
|
||||
public static GlobalConstants constants;
|
||||
|
||||
public static Universe universe;
|
||||
public static World world;
|
||||
@@ -268,6 +270,7 @@ public class Vars implements Loadable{
|
||||
indexer = new BlockIndexer();
|
||||
pathfinder = new Pathfinder();
|
||||
bases = new BaseRegistry();
|
||||
constants = new GlobalConstants();
|
||||
|
||||
state = new GameState();
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ public class ContentLoader{
|
||||
/** Calls Content#init() on everything. Use only after all modules have been created.*/
|
||||
public void 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.*/
|
||||
|
||||
78
core/src/mindustry/logic/GlobalConstants.java
Normal file
78
core/src/mindustry/logic/GlobalConstants.java
Normal file
@@ -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.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.logic.LExecutor.*;
|
||||
import mindustry.logic.LStatements.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
/** "Compiles" a sequence of statements into instructions. */
|
||||
public class LAssembler{
|
||||
@@ -31,42 +28,6 @@ public class LAssembler{
|
||||
putConst("@unit", null);
|
||||
//reference to self
|
||||
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){
|
||||
@@ -185,6 +146,12 @@ public class LAssembler{
|
||||
/** @return a variable ID by name.
|
||||
* This may be a constant variable referring to a number or object. */
|
||||
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();
|
||||
|
||||
//string case
|
||||
|
||||
@@ -97,28 +97,33 @@ public class LExecutor{
|
||||
|
||||
//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){
|
||||
Object o = vars[index].objval;
|
||||
return vars[index].isobj && o instanceof Building building ? building : null;
|
||||
Object o = var(index).objval;
|
||||
return var(index).isobj && o instanceof Building building ? building : null;
|
||||
}
|
||||
|
||||
public @Nullable Object obj(int index){
|
||||
Object o = vars[index].objval;
|
||||
return vars[index].isobj ? o : null;
|
||||
Object o = var(index).objval;
|
||||
return var(index).isobj ? o : null;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -131,7 +136,7 @@ public class LExecutor{
|
||||
}
|
||||
|
||||
public void setnum(int index, double value){
|
||||
Var v = vars[index];
|
||||
Var v = var(index);
|
||||
if(v.constant) return;
|
||||
v.numval = Double.isNaN(value) || Double.isInfinite(value) ? 0 : value;
|
||||
v.objval = null;
|
||||
@@ -139,20 +144,21 @@ public class LExecutor{
|
||||
}
|
||||
|
||||
public void setobj(int index, Object value){
|
||||
Var v = vars[index];
|
||||
Var v = var(index);
|
||||
if(v.constant) return;
|
||||
v.objval = value;
|
||||
v.isobj = true;
|
||||
}
|
||||
|
||||
public void setconst(int index, Object value){
|
||||
Var v = vars[index];
|
||||
Var v = var(index);
|
||||
v.objval = value;
|
||||
v.isobj = true;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
/** A logic variable. */
|
||||
public static class Var{
|
||||
public final String name;
|
||||
|
||||
@@ -735,8 +741,8 @@ public class LExecutor{
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
Var v = exec.vars[to];
|
||||
Var f = exec.vars[from];
|
||||
Var v = exec.var(to);
|
||||
Var f = exec.var(from);
|
||||
|
||||
//TODO error out when the from-value is a constant
|
||||
if(!v.constant){
|
||||
@@ -769,8 +775,8 @@ public class LExecutor{
|
||||
if(op.unary){
|
||||
exec.setnum(dest, op.function1.get(exec.num(a)));
|
||||
}else{
|
||||
Var va = exec.vars[a];
|
||||
Var vb = exec.vars[b];
|
||||
Var va = exec.var(a);
|
||||
Var vb = exec.var(b);
|
||||
|
||||
if(op.objFunction2 != null && (va.isobj || vb.isobj)){
|
||||
//use object function if provided, and one of the variables is an object
|
||||
@@ -788,7 +794,7 @@ public class LExecutor{
|
||||
|
||||
@Override
|
||||
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;
|
||||
|
||||
//this should avoid any garbage allocation
|
||||
Var v = exec.vars[value];
|
||||
Var v = exec.var(value);
|
||||
if(v.isobj && value != 0){
|
||||
String strValue =
|
||||
v.objval == null ? "null" :
|
||||
@@ -940,8 +946,8 @@ public class LExecutor{
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
if(address != -1){
|
||||
Var va = exec.vars[value];
|
||||
Var vb = exec.vars[compare];
|
||||
Var va = exec.var(value);
|
||||
Var vb = exec.var(compare);
|
||||
boolean cmp;
|
||||
|
||||
if(op.objFunction != null && (va.isobj || vb.isobj)){
|
||||
@@ -952,7 +958,7 @@ public class LExecutor{
|
||||
}
|
||||
|
||||
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.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
@@ -21,6 +22,7 @@ public class PlayerListFragment extends Fragment{
|
||||
private Interval timer = new Interval();
|
||||
private TextField sField;
|
||||
private boolean found = false;
|
||||
private Seq<Player> players = new Seq<>();
|
||||
|
||||
@Override
|
||||
public void build(Group parent){
|
||||
@@ -78,8 +80,12 @@ public class PlayerListFragment extends Fragment{
|
||||
float h = 74f;
|
||||
found = false;
|
||||
|
||||
Groups.player.sort(Structs.comparing(Player::team));
|
||||
Groups.player.each(user -> {
|
||||
players.clear();
|
||||
Groups.player.copy(players);
|
||||
|
||||
players.sort(Structs.comps(Structs.comparing(Player::team), Structs.comparingBool(p -> !p.admin)));
|
||||
|
||||
for(var user : players){
|
||||
found = true;
|
||||
NetConnection connection = user.con;
|
||||
|
||||
@@ -159,7 +165,7 @@ public class PlayerListFragment extends Fragment{
|
||||
content.row();
|
||||
content.image().height(4f).color(state.rules.pvp ? user.team().color : Pal.gray).growX();
|
||||
content.row();
|
||||
});
|
||||
}
|
||||
|
||||
if(!found){
|
||||
content.add(Core.bundle.format("players.notfound")).padBottom(6).width(350f).maxHeight(h + 14);
|
||||
|
||||
Reference in New Issue
Block a user