wip: different heights for jump arrows
Note that this is very incomplete, for two different reasons: - it's O(n^2) or potentially worse - it makes the GC work hard (it invokes `new` in `LCanvas.DragLayout.layout()`) For the second reason this does not clearly fit the criteria of CONTRIBUTING.md, but I have yet to figure out ways to work around this (or make the algorithm more efficient).
This commit is contained in:
@@ -21,8 +21,10 @@ import mindustry.ui.*;
|
||||
|
||||
public class LCanvas extends Table{
|
||||
public static final int maxJumpsDrawn = 100;
|
||||
private static final int invalidJump = Integer.MAX_VALUE; // terrible hack
|
||||
//ew static variables
|
||||
static LCanvas canvas;
|
||||
private static boolean dynamicJumpHeights = false;
|
||||
|
||||
public DragLayout statements;
|
||||
public ScrollPane pane;
|
||||
@@ -108,6 +110,8 @@ public class LCanvas extends Table{
|
||||
statements = new DragLayout();
|
||||
jumps = statements.jumps;
|
||||
|
||||
dynamicJumpHeights = Core.settings.getBool("dynamicjumpheights", false);
|
||||
|
||||
pane = pane(t -> {
|
||||
t.center();
|
||||
t.add(statements).pad(2f).center().width(targetWidth);
|
||||
@@ -196,6 +200,7 @@ public class LCanvas extends Table{
|
||||
int insertPosition = 0;
|
||||
boolean invalidated;
|
||||
public Group jumps = new WidgetGroup();
|
||||
private Seq<JumpCurve> processedJumps = new Seq<JumpCurve>();
|
||||
|
||||
{
|
||||
setTransform(true);
|
||||
@@ -251,13 +256,73 @@ public class LCanvas extends Table{
|
||||
}
|
||||
}
|
||||
|
||||
if(parent != null) parent.invalidateHierarchy();
|
||||
if(dynamicJumpHeights) setJumpHeights();
|
||||
|
||||
if(parent != null) parent.invalidateHierarchy();//don't invalid self
|
||||
|
||||
if(parent != null && parent instanceof Table){
|
||||
setCullingArea(parent.getCullingArea());
|
||||
}
|
||||
}
|
||||
|
||||
private void setJumpHeights(){
|
||||
SnapshotSeq<Element> jumpsChildren = jumps.getChildren();
|
||||
processedJumps.clear();
|
||||
jumpsChildren.each(e -> {
|
||||
if(e instanceof JumpCurve e2){
|
||||
e2.prepareHeight();
|
||||
if(e2.jumpUIBegin != invalidJump){
|
||||
processedJumps.add(e2);
|
||||
}
|
||||
}
|
||||
});
|
||||
processedJumps.sort((a,b) -> a.jumpUIBegin - b.jumpUIBegin);
|
||||
|
||||
Seq<JumpCurve> occupiers = new Seq<JumpCurve>();
|
||||
Bits occupied = new Bits();
|
||||
for(int i = 0; i < processedJumps.size; i++){
|
||||
JumpCurve cur = processedJumps.get(i);
|
||||
occupiers.retainAll(e -> {
|
||||
if(e.jumpUIEnd > cur.jumpUIBegin) return true;
|
||||
occupied.clear(e.predHeight);
|
||||
return false;
|
||||
});
|
||||
int h = getJumpHeight(i, occupiers, occupied);
|
||||
occupiers.add(cur);
|
||||
occupied.set(h);
|
||||
}
|
||||
}
|
||||
|
||||
private int getJumpHeight(int index, Seq<JumpCurve> occupiers, Bits occupied){
|
||||
JumpCurve jmp = processedJumps.get(index);
|
||||
if(jmp.markedDone) return jmp.predHeight;
|
||||
|
||||
// TODO: optimize for LESS cloning
|
||||
Seq<JumpCurve> tmpOccupiers = new Seq<JumpCurve>(occupiers);
|
||||
Bits tmpOccupied = new Bits();
|
||||
tmpOccupied.set(occupied);
|
||||
|
||||
int max = -1;
|
||||
for(int i = index + 1; i < processedJumps.size; i++){
|
||||
JumpCurve cur = processedJumps.get(i);
|
||||
if(cur.jumpUIEnd > jmp.jumpUIEnd) continue;
|
||||
tmpOccupiers.retainAll(e -> {
|
||||
if(e.jumpUIEnd > cur.jumpUIBegin) return true;
|
||||
tmpOccupied.clear(e.predHeight);
|
||||
return false;
|
||||
});
|
||||
int h = getJumpHeight(i, tmpOccupiers, tmpOccupied);
|
||||
tmpOccupiers.add(cur);
|
||||
tmpOccupied.set(h);
|
||||
max = Math.max(max, h);
|
||||
}
|
||||
|
||||
jmp.predHeight = occupied.nextClearBit(max + 1);
|
||||
jmp.markedDone = true;
|
||||
|
||||
return jmp.predHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPrefWidth(){
|
||||
return prefWidth;
|
||||
@@ -452,12 +517,14 @@ public class LCanvas extends Table{
|
||||
ClickListener listener;
|
||||
|
||||
public JumpCurve curve;
|
||||
public StatementElem elem;
|
||||
|
||||
public JumpButton(Prov<StatementElem> getter, Cons<StatementElem> setter){
|
||||
public JumpButton(Prov<StatementElem> getter, Cons<StatementElem> setter, StatementElem elem){
|
||||
super(Tex.logicNode, new ImageButtonStyle(){{
|
||||
imageUpColor = Color.white;
|
||||
}});
|
||||
|
||||
this.elem = elem;
|
||||
to = getter;
|
||||
addListener(listener = new ClickListener());
|
||||
|
||||
@@ -518,6 +585,11 @@ public class LCanvas extends Table{
|
||||
public static class JumpCurve extends Element{
|
||||
public JumpButton button;
|
||||
|
||||
// for jump prediction; see DragLayout
|
||||
public int predHeight = 0;
|
||||
public boolean markedDone = false;
|
||||
public int jumpUIBegin = 0, jumpUIEnd = 0;
|
||||
|
||||
public JumpCurve(JumpButton button){
|
||||
this.button = button;
|
||||
}
|
||||
@@ -575,7 +647,7 @@ public class LCanvas extends Table{
|
||||
Lines.stroke(4f, button.color);
|
||||
Draw.alpha(parentAlpha);
|
||||
|
||||
float dist = 100f;
|
||||
float dist = 100f + 100f * (float) predHeight;
|
||||
|
||||
//square jumps
|
||||
if(false){
|
||||
@@ -599,5 +671,20 @@ public class LCanvas extends Table{
|
||||
x2, y2,
|
||||
Math.max(18, (int)(Mathf.dst(x, y, x2, y2) / 6)));
|
||||
}
|
||||
|
||||
public void prepareHeight(){
|
||||
if(this.button.to.get() == null){
|
||||
this.markedDone = true;
|
||||
this.predHeight = 0;
|
||||
this.jumpUIBegin = this.jumpUIEnd = invalidJump;
|
||||
} else {
|
||||
this.markedDone = false;
|
||||
int i = this.button.elem.index;
|
||||
int j = this.button.to.get().index;
|
||||
this.jumpUIBegin = Math.min(i,j);
|
||||
this.jumpUIEnd = Math.max(i,j);
|
||||
// height will be recalculated later
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -870,7 +870,7 @@ public class LStatements{
|
||||
table.table(this::rebuild);
|
||||
|
||||
table.add().growX();
|
||||
table.add(new JumpButton(() -> dest, s -> dest = s)).size(30).right().padLeft(-8);
|
||||
table.add(new JumpButton(() -> dest, s -> dest = s, this.elem)).size(30).right().padLeft(-8);
|
||||
|
||||
String name = name();
|
||||
|
||||
|
||||
@@ -502,6 +502,8 @@ public class SettingsMenuDialog extends BaseDialog{
|
||||
if(!mobile){
|
||||
Core.settings.put("swapdiagonal", false);
|
||||
}
|
||||
|
||||
graphics.checkPref("dynamicjumpheights", true);
|
||||
}
|
||||
|
||||
public void exportData(Fi file) throws IOException{
|
||||
|
||||
Reference in New Issue
Block a user