Reduce ControlButton instantiation memory usage

This commit is contained in:
SerpentSpirale 2021-09-06 19:21:52 +02:00 committed by SerpentSpirale
parent 7ec533a997
commit 66f65f04d2

View File

@ -1,6 +1,10 @@
package net.kdt.pojavlaunch.customcontrols; package net.kdt.pojavlaunch.customcontrols;
import android.util.*; import android.util.*;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
import net.kdt.pojavlaunch.*; import net.kdt.pojavlaunch.*;
import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.prefs.LauncherPreferences;
@ -29,6 +33,13 @@ public class ControlData {
// Internal usage only // Internal usage only
public boolean isHideable; public boolean isHideable;
private static WeakReference<ExpressionBuilder> builder;
private static WeakReference<Field> expression;
static {
bypassExpressionBuilder();
}
/** /**
* Both fields below are dynamic position data, auto updates * Both fields below are dynamic position data, auto updates
* X and Y position, unlike the original one which uses fixed * X and Y position, unlike the original one which uses fixed
@ -188,20 +199,9 @@ public class ControlData {
} }
private static float calculate(String math) { private static float calculate(String math) {
return (float) new ExpressionBuilder(math) setExpression(math);
.function(new Function("dp", 1) { if(builder.get() == null) bypassExpressionBuilder();
@Override return (float) builder.get().build().evaluate();
public double apply(double... args) {
return Tools.pxToDp((float) args[0]);
}
})
.function(new Function("px", 1) {
@Override
public double apply(double... args) {
return Tools.dpToPx((float) args[0]);
}
})
.build().evaluate();
} }
private static int[] inflateKeycodeArray(int[] keycodes){ private static int[] inflateKeycodeArray(int[] keycodes){
@ -236,4 +236,43 @@ public class ControlData {
public void setHeight(float heightInPx){ public void setHeight(float heightInPx){
height = Tools.pxToDp(heightInPx); height = Tools.pxToDp(heightInPx);
} }
/**
* Create a weak reference to a builder and its expression field.
* Although VERY bad practice it isn't slower due to saved GC time.
* The normal way requires us to create ONE builder and TWO functions for EACH button.
*/
private static void bypassExpressionBuilder(){
ExpressionBuilder expressionBuilder = new ExpressionBuilder("1 + 1")
.function(new Function("dp", 1) {
@Override
public double apply(double... args) {
return Tools.pxToDp((float) args[0]);
}
})
.function(new Function("px", 1) {
@Override
public double apply(double... args) {
return Tools.dpToPx((float) args[0]);
}
});
builder = new WeakReference<>(expressionBuilder);
try {
expression = new WeakReference<>(builder.get().getClass().getDeclaredField("expression"));
expression.get().setAccessible(true);
expression.get().set(expression.get(), expression.get().getModifiers() & ~Modifier.FINAL);
}catch (Exception ignored){}
}
/**
* wrapper for the WeakReference to the expressionField.
* @param stringExpression the expression to set.
*/
private static void setExpression(String stringExpression){
try {
expression.get().set(builder.get(), (String) stringExpression);
}catch (IllegalAccessException e){}
}
} }