memory allocation & fix some potential bug

This commit is contained in:
Tungstend 2023-01-09 18:52:56 +08:00
parent 26cacf88b5
commit 787d35ecee
11 changed files with 214 additions and 56 deletions

View File

@ -308,13 +308,13 @@ public final class TaskListPane extends FCLAdapter {
FCLTextView title = parent.findViewById(R.id.name);
state = parent.findViewById(R.id.state);
bar.progressProperty().bind(task.progressProperty());
bar.percentProgressProperty().bind(task.progressProperty());
title.setText(task.getName());
state.stringProperty().bind(task.messageProperty());
}
public void unbind() {
bar.progressProperty().unbind();
bar.percentProgressProperty().unbind();
state.stringProperty().unbind();
}

View File

@ -5,12 +5,15 @@ import android.view.View;
import android.widget.ArrayAdapter;
import com.tungsten.fcl.R;
import com.tungsten.fcl.game.FCLGameRepository;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.setting.VersionSetting;
import com.tungsten.fcl.util.AndroidUtils;
import com.tungsten.fcl.util.FXUtils;
import com.tungsten.fcl.util.WeakListenerHolder;
import com.tungsten.fclauncher.FCLConfig;
import com.tungsten.fclcore.fakefx.beans.InvalidationListener;
import com.tungsten.fclcore.fakefx.beans.binding.Bindings;
import com.tungsten.fclcore.fakefx.beans.property.BooleanProperty;
import com.tungsten.fclcore.fakefx.beans.property.IntegerProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleBooleanProperty;
@ -21,6 +24,8 @@ import com.tungsten.fclcore.game.JavaVersion;
import com.tungsten.fclcore.game.ProcessPriority;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.util.Lang;
import com.tungsten.fclcore.util.platform.MemoryUtils;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.view.FCLCheckBox;
import com.tungsten.fcllibrary.component.view.FCLEditText;
@ -60,8 +65,6 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
private FCLSeekBar allocateSeekbar;
private FCLProgressBar memoryBar;
private FCLSwitch isolateWorkingDirSwitch;
private FCLSwitch beGestureSwitch;
private FCLSwitch noGameCheckSwitch;
@ -75,15 +78,11 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
private FCLImageButton deleteIconButton;
private FCLImageButton controllerButton;
private FCLTextView memoryText;
private FCLTextView memoryInfoText;
private FCLTextView memoryAllocateText;
private final InvalidationListener specificSettingsListener;
private final StringProperty selectedVersion = new SimpleStringProperty();
private final BooleanProperty enableSpecificSettings = new SimpleBooleanProperty(false);
private final IntegerProperty maxMemory = new SimpleIntegerProperty();
//private final ObjectProperty<OperatingSystem.PhysicalMemoryStatus> memoryStatus = new SimpleObjectProperty<>(OperatingSystem.PhysicalMemoryStatus.INVALID);
private final IntegerProperty usedMemory = new SimpleIntegerProperty(0);
private final BooleanProperty modpack = new SimpleBooleanProperty();
public VersionSettingPage(Context context, int id, FCLUILayout parent, int resId, boolean globalSetting) {
@ -111,8 +110,6 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
allocateSeekbar = findViewById(R.id.edit_memory);
memoryBar = findViewById(R.id.memory_bar);
FCLSwitch specialSettingSwitch = findViewById(R.id.enable_per_instance_setting);
specialSettingSwitch.addCheckedChangeListener();
isolateWorkingDirSwitch = findViewById(R.id.edit_game_dir);
@ -176,9 +173,46 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
deleteIconButton.setOnClickListener(this);
controllerButton.setOnClickListener(this);
memoryText = findViewById(R.id.memory_text);
memoryInfoText = findViewById(R.id.memory_info_text);
memoryAllocateText = findViewById(R.id.memory_allocate_text);
FCLProgressBar memoryBar = findViewById(R.id.memory_bar);
FCLTextView memoryStateText = findViewById(R.id.memory_state);
FCLTextView memoryText = findViewById(R.id.memory_text);
FCLTextView memoryInfoText = findViewById(R.id.memory_info_text);
FCLTextView memoryAllocateText = findViewById(R.id.memory_allocate_text);
memoryStateText.stringProperty().bind(Bindings.createStringBinding(() -> {
if (chkAutoAllocate.isChecked()) {
return getContext().getString(R.string.settings_memory_lower_bound);
} else {
return getContext().getString(R.string.settings_memory);
}
}, chkAutoAllocate.checkProperty()));
allocateSeekbar.setMax(MemoryUtils.getTotalDeviceMemory(getContext()));
memoryBar.setMax(MemoryUtils.getTotalDeviceMemory(getContext()));
allocateSeekbar.addProgressListener();
allocateSeekbar.progressProperty().bindBidirectional(maxMemory);
memoryText.stringProperty().bind(Bindings.createStringBinding(() -> allocateSeekbar.progressProperty().intValue() + " MB", allocateSeekbar.progressProperty()));
memoryBar.firstProgressProperty().bind(usedMemory);
memoryBar.secondProgressProperty().bind(Bindings.createIntegerBinding(() -> {
int allocate = (int) (FCLGameRepository.getAllocatedMemory(maxMemory.intValue() * 1024L * 1024L, MemoryUtils.getFreeDeviceMemory(getContext()) * 1024L * 1024L, chkAutoAllocate.isChecked()) / 1024. / 1024);
return usedMemory.intValue() + (chkAutoAllocate.isChecked() ? allocate : maxMemory.intValue());
}, usedMemory, maxMemory, chkAutoAllocate.checkProperty()));
memoryInfoText.stringProperty().bind(Bindings.createStringBinding(() -> AndroidUtils.getLocalizedText(getContext(), "settings_memory_used_per_total", MemoryUtils.getUsedDeviceMemory(getContext()) / 1024., MemoryUtils.getTotalDeviceMemory(getContext()) / 1024.), usedMemory));
memoryAllocateText.stringProperty().bind(Bindings.createStringBinding(() -> {
long maxMemory = Lang.parseInt(this.maxMemory.get(), 0) * 1024L * 1024L;
return AndroidUtils.getLocalizedText(getContext(), maxMemory / 1024. / 1024. > MemoryUtils.getFreeDeviceMemory(getContext())
? (chkAutoAllocate.isChecked() ? "settings_memory_allocate_auto_exceeded" : "settings_memory_allocate_manual_exceeded")
: (chkAutoAllocate.isChecked() ? "settings_memory_allocate_auto" : "settings_memory_allocate_manual"),
maxMemory / 1024. / 1024. / 1024.,
FCLGameRepository.getAllocatedMemory(maxMemory, MemoryUtils.getFreeDeviceMemory(getContext()) * 1024L * 1024L, chkAutoAllocate.isChecked()) / 1024. / 1024. / 1024.,
MemoryUtils.getFreeDeviceMemory(getContext()) / 1024.);
}, usedMemory, maxMemory, chkAutoAllocate.checkProperty()));
settingTypeLayout.setVisibility(globalSetting ? View.GONE : View.VISIBLE);
@ -208,6 +242,12 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
return null;
}
@Override
public void onResume() {
super.onResume();
usedMemory.set(MemoryUtils.getUsedDeviceMemory(getContext()));
}
@Override
public void loadVersion(Profile profile, String versionId) {
this.profile = profile;
@ -222,12 +262,12 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
VersionSetting versionSetting = profile.getVersionSetting(versionId);
modpack.set(versionId != null && profile.getRepository().isModpack(versionId));
usedMemory.set(MemoryUtils.getUsedDeviceMemory(getContext()));
// unbind data fields
if (lastVersionSetting != null) {
FXUtils.unbind(txtWidth, lastVersionSetting.widthProperty());
FXUtils.unbind(txtHeight, lastVersionSetting.heightProperty());
maxMemory.unbindBidirectional(lastVersionSetting.maxMemoryProperty());
FXUtils.unbind(txtJVMArgs, lastVersionSetting.javaArgsProperty());
FXUtils.unbind(txtGameArgs, lastVersionSetting.minecraftArgsProperty());
FXUtils.unbind(txtMetaspace, lastVersionSetting.permSizeProperty());
@ -241,6 +281,7 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
FXUtils.unbindSelection(javaSpinner, lastVersionSetting.javaProperty());
FXUtils.unbindSelection(processPrioritySpinner, lastVersionSetting.processPriorityProperty());
FXUtils.unbindSelection(rendererSpinner, lastVersionSetting.rendererProperty());
maxMemory.unbindBidirectional(lastVersionSetting.maxMemoryProperty());
lastVersionSetting.usesGlobalProperty().removeListener(specificSettingsListener);
}
@ -248,8 +289,6 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
// bind new data fields
FXUtils.bindInt(txtWidth, versionSetting.widthProperty());
FXUtils.bindInt(txtHeight, versionSetting.heightProperty());
maxMemory.bindBidirectional(versionSetting.maxMemoryProperty());
FXUtils.bindString(txtJVMArgs, versionSetting.javaArgsProperty());
FXUtils.bindString(txtGameArgs, versionSetting.minecraftArgsProperty());
FXUtils.bindString(txtMetaspace, versionSetting.permSizeProperty());
@ -263,6 +302,7 @@ public class VersionSettingPage extends FCLCommonPage implements ManageUI.Versio
FXUtils.bindSelection(javaSpinner, versionSetting.javaProperty());
FXUtils.bindSelection(processPrioritySpinner, versionSetting.processPriorityProperty());
FXUtils.bindSelection(rendererSpinner, versionSetting.rendererProperty());
maxMemory.bindBidirectional(versionSetting.maxMemoryProperty());
versionSetting.usesGlobalProperty().addListener(specificSettingsListener);
if (versionId != null)

View File

@ -6,6 +6,8 @@ import android.content.Context;
import com.google.android.material.tabs.TabLayout;
import com.tungsten.fcl.R;
import com.tungsten.fcl.setting.Profiles;
import com.tungsten.fcl.ui.manage.VersionSettingPage;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fcllibrary.component.ui.FCLBasePage;
import com.tungsten.fcllibrary.component.ui.FCLMultiPageUI;
@ -36,6 +38,12 @@ public class SettingUI extends FCLMultiPageUI implements TabLayout.OnTabSelected
container.post(this::initPages);
}
@Override
public void onStart() {
super.onStart();
((VersionSettingPage) pageManager.getPageById(SettingPageManager.PAGE_ID_SETTING_GAME)).loadVersion(Profiles.getSelectedProfile(), null);
}
@Override
public void onBackPressed() {
if (pageManager != null && pageManager.canReturn()) {
@ -99,6 +107,7 @@ public class SettingUI extends FCLMultiPageUI implements TabLayout.OnTabSelected
break;
default:
pageManager.switchPage(SettingPageManager.PAGE_ID_SETTING_GAME);
((VersionSettingPage) pageManager.getPageById(SettingPageManager.PAGE_ID_SETTING_GAME)).loadVersion(Profiles.getSelectedProfile(), null);
break;
}
}

View File

@ -113,7 +113,6 @@ public final class FXUtils {
T value = property.getValue();
editText.setText(converter == null ? (String) value : converter.toString(value));
}
editText.fromUserOrSystem = false;
}
}

View File

@ -267,33 +267,24 @@
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>
<androidx.appcompat.widget.LinearLayoutCompat
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:layout_width="match_parent"
android:id="@+id/memory_info_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:singleLine="true"
app:auto_text_tint="true"
android:text="@string/settings_memory_used_per_total"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/memory_info_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"
android:layout_gravity="center"
android:text="@string/settings_memory_used_per_total"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/memory_allocate_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"
android:layout_gravity="center"
android:text="@string/settings_memory_allocate_auto"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:id="@+id/memory_allocate_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
app:auto_text_tint="true"
android:text="@string/settings_memory_allocate_auto"/>
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@ -3,6 +3,8 @@ package com.tungsten.fclcore.util.platform;
import android.app.ActivityManager;
import android.content.Context;
import com.tungsten.fclauncher.utils.Architecture;
public class MemoryUtils {
public static int getTotalDeviceMemory(Context context) {
@ -12,6 +14,13 @@ public class MemoryUtils {
return (int) (memInfo.totalMem / 1048576L);
}
public static int getUsedDeviceMemory(Context context) {
ActivityManager actManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
actManager.getMemoryInfo(memInfo);
return (int) ((memInfo.totalMem - memInfo.availMem) / 1048576L);
}
public static int getFreeDeviceMemory(Context context) {
ActivityManager actManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
@ -21,14 +30,14 @@ public class MemoryUtils {
public static int findBestRAMAllocation(Context context) {
int totalDeviceMemory = getTotalDeviceMemory(context);
if (totalDeviceMemory < 1024) {
if (totalDeviceMemory <= 1024) {
return 512;
} else if (totalDeviceMemory < 2048) {
return 1024;
} else if (totalDeviceMemory < 4096) {
return 2048;
} else if (totalDeviceMemory <= 6144) {
return Architecture.is32BitsDevice() ? 768 : 1024;
} else if (totalDeviceMemory <= 12288) {
return Architecture.is32BitsDevice() ? 768 : 2048;
} else {
return 4096;
return Architecture.is32BitsDevice() ? 768 : 4096;
}
}

View File

@ -64,6 +64,7 @@ public class FCLCheckBox extends AppCompatCheckBox {
setOnCheckedChangeListener((compoundButton, b) -> {
fromUserOrSystem = true;
checkProperty().set(b);
fromUserOrSystem = false;
});
}
@ -146,7 +147,6 @@ public class FCLCheckBox extends AppCompatCheckBox {
boolean isCheck = get();
setChecked(isCheck);
}
fromUserOrSystem = false;
});
}

View File

@ -115,6 +115,7 @@ public class FCLEditText extends AppCompatEditText {
public void afterTextChanged(Editable editable) {
fromUserOrSystem = true;
stringProperty().set(getText().toString());
fromUserOrSystem = false;
}
});
}

View File

@ -17,6 +17,8 @@ import com.tungsten.fcllibrary.component.theme.ThemeEngine;
public class FCLProgressBar extends ProgressBar {
private DoubleProperty progress;
private IntegerProperty firstProgressProperty;
private IntegerProperty secondProgressProperty;
private BooleanProperty visibilityProperty;
private BooleanProperty disableProperty;
@ -34,6 +36,7 @@ public class FCLProgressBar extends ProgressBar {
ThemeEngine.getInstance().getTheme().getDkColor()
};
setProgressTintList(new ColorStateList(state, color));
setSecondaryProgressTintList(new ColorStateList(state, color));
setIndeterminateTintList(new ColorStateList(state, color));
}
@ -68,11 +71,7 @@ public class FCLProgressBar extends ProgressBar {
theme.bind(ThemeEngine.getInstance().getTheme().colorProperty());
}
public final void setProgressValue(double progress) {
progressProperty().set(progress);
}
public final DoubleProperty progressProperty() {
public final DoubleProperty percentProgressProperty() {
if (progress == null) {
progress = new DoublePropertyBase() {
@ -92,7 +91,7 @@ public class FCLProgressBar extends ProgressBar {
}
public String getName() {
return "progress";
return "percentProgress";
}
};
}
@ -100,6 +99,58 @@ public class FCLProgressBar extends ProgressBar {
return progress;
}
public final IntegerProperty firstProgressProperty() {
if (firstProgressProperty == null) {
firstProgressProperty = new IntegerPropertyBase() {
public void invalidated() {
Schedulers.androidUIThread().execute(() -> {
int progress = get();
if (progress >= 0) {
setProgress(Math.min(progress, getMax()));
}
});
}
public Object getBean() {
return this;
}
public String getName() {
return "firstProgress";
}
};
}
return firstProgressProperty;
}
public final IntegerProperty secondProgressProperty() {
if (secondProgressProperty == null) {
secondProgressProperty = new IntegerPropertyBase() {
public void invalidated() {
Schedulers.androidUIThread().execute(() -> {
int progress = get();
if (progress >= 0) {
setSecondaryProgress(Math.min(progress, getMax()));
}
});
}
public Object getBean() {
return this;
}
public String getName() {
return "secondProgress";
}
};
}
return secondProgressProperty;
}
public final void setVisibilityValue(boolean visibility) {
visibilityProperty().set(visibility);
}

View File

@ -3,6 +3,7 @@ package com.tungsten.fcllibrary.component.view;
import android.content.Context;
import android.content.res.ColorStateList;
import android.util.AttributeSet;
import android.widget.SeekBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -17,8 +18,10 @@ import com.tungsten.fcllibrary.component.theme.ThemeEngine;
public class FCLSeekBar extends AppCompatSeekBar {
private boolean fromUserOrSystem = false;
private BooleanProperty visibilityProperty;
private BooleanProperty disableProperty;
private IntegerProperty progressProperty;
private final IntegerProperty theme = new IntegerPropertyBase() {
@ -48,6 +51,27 @@ public class FCLSeekBar extends AppCompatSeekBar {
}
};
public void addProgressListener() {
setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
fromUserOrSystem = true;
progressProperty().set(i);
fromUserOrSystem = false;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public FCLSeekBar(@NonNull Context context) {
super(context);
theme.bind(ThemeEngine.getInstance().getTheme().colorProperty());
@ -127,4 +151,38 @@ public class FCLSeekBar extends AppCompatSeekBar {
return disableProperty;
}
public final void setProgressValue(int progressValue) {
progressProperty().set(progressValue);
}
public final int getProgressValue() {
return progressProperty == null ? -1 : progressProperty().get();
}
public final IntegerProperty progressProperty() {
if (progressProperty == null) {
progressProperty = new IntegerPropertyBase() {
public void invalidated() {
Schedulers.androidUIThread().execute(() -> {
if (!fromUserOrSystem) {
int progress = get();
setProgress(progress);
}
});
}
public Object getBean() {
return this;
}
public String getName() {
return "progress";
}
};
}
return progressProperty;
}
}

View File

@ -29,6 +29,7 @@ public class FCLSpinner<T> extends AppCompatSpinner {
if (dataList != null && dataList.size() > i) {
fromUserOrSystem = true;
selectedItemProperty().set(dataList.get(i));
fromUserOrSystem = false;
}
}
@ -85,7 +86,6 @@ public class FCLSpinner<T> extends AppCompatSpinner {
T data = get();
setSelection(dataList.indexOf(data));
}
fromUserOrSystem = false;
});
}