mirror of
https://github.com/Dark98/SliceBeam.git
synced 2026-07-02 16:49:02 +00:00
Optimize boot time
This commit is contained in:
@@ -90,6 +90,7 @@ dependencies {
|
||||
implementation project(":eventbus")
|
||||
implementation project(":eventbus_api")
|
||||
annotationProcessor project(":eventbus_processor")
|
||||
implementation 'com.github.instacart:truetime-android:3.5'
|
||||
|
||||
implementation 'com.github.mrudultora:Colorpicker:1.2.0'
|
||||
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
||||
|
||||
@@ -6,6 +6,8 @@ import android.content.Intent;
|
||||
import android.util.Log;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import com.instacart.library.truetime.TrueTime;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -15,15 +17,30 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import ru.ytkab0bp.eventbus.EventBus;
|
||||
import ru.ytkab0bp.slicebeam.boot.AppBoot;
|
||||
import ru.ytkab0bp.slicebeam.boot.BeamServerDataTask;
|
||||
import ru.ytkab0bp.slicebeam.boot.CheckUpdateJsonTask;
|
||||
import ru.ytkab0bp.slicebeam.boot.ClearModelCacheTask;
|
||||
import ru.ytkab0bp.slicebeam.boot.CloudInitTask;
|
||||
import ru.ytkab0bp.slicebeam.boot.EventBusTask;
|
||||
import ru.ytkab0bp.slicebeam.boot.LoadSlic3rConfigTask;
|
||||
import ru.ytkab0bp.slicebeam.boot.PrefsTask;
|
||||
import ru.ytkab0bp.slicebeam.boot.PrintConfigWarmupTask;
|
||||
import ru.ytkab0bp.slicebeam.boot.TrueTimeTask;
|
||||
import ru.ytkab0bp.slicebeam.boot.VibrationUtilsTask;
|
||||
import ru.ytkab0bp.slicebeam.cloud.CloudController;
|
||||
import ru.ytkab0bp.slicebeam.config.ConfigObject;
|
||||
import ru.ytkab0bp.slicebeam.slic3r.ConfigOptionDef;
|
||||
import ru.ytkab0bp.slicebeam.slic3r.PrintConfigDef;
|
||||
import ru.ytkab0bp.slicebeam.slic3r.Slic3rConfigWrapper;
|
||||
import ru.ytkab0bp.slicebeam.utils.IOUtils;
|
||||
import ru.ytkab0bp.slicebeam.utils.Prefs;
|
||||
import ru.ytkab0bp.slicebeam.utils.VibrationUtils;
|
||||
import ru.ytkab0bp.slicebeam.utils.ViewUtils;
|
||||
|
||||
public class SliceBeam extends Application {
|
||||
public static SliceBeam INSTANCE;
|
||||
@@ -38,36 +55,18 @@ public class SliceBeam extends Application {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
INSTANCE = this;
|
||||
EventBus.registerImpl(this);
|
||||
Prefs.init(this);
|
||||
VibrationUtils.init(this);
|
||||
tryCheckInfo();
|
||||
PrintConfigDef.getInstance();
|
||||
try {
|
||||
getAssets().open("update.json").close();
|
||||
hasUpdateInfo = true;
|
||||
} catch (IOException e) {
|
||||
hasUpdateInfo = false;
|
||||
}
|
||||
|
||||
File cache = SliceBeam.getModelCacheDir();
|
||||
if (cache.exists()) {
|
||||
for (File f : cache.listFiles()) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
|
||||
File cfgFile = getConfigFile();
|
||||
getCurrentConfigFile().delete();
|
||||
if (cfgFile.exists()) {
|
||||
try {
|
||||
CONFIG = new Slic3rConfigWrapper(cfgFile);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG);
|
||||
|
||||
AppBoot.run(Arrays.asList(
|
||||
new EventBusTask(),
|
||||
new PrefsTask(),
|
||||
new VibrationUtilsTask(),
|
||||
new TrueTimeTask(),
|
||||
new BeamServerDataTask(),
|
||||
new PrintConfigWarmupTask(),
|
||||
new CheckUpdateJsonTask(),
|
||||
new ClearModelCacheTask(),
|
||||
new LoadSlic3rConfigTask(),
|
||||
new CloudInitTask()
|
||||
));
|
||||
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
@@ -81,17 +80,6 @@ public class SliceBeam extends Application {
|
||||
});
|
||||
}
|
||||
|
||||
private static void tryCheckInfo() {
|
||||
try {
|
||||
SERVER_DATA = new BeamServerData(new JSONObject(Prefs.getBeamServerData()));
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (System.currentTimeMillis() - Prefs.getLastCheckedInfo() >= 86400000L) {
|
||||
BeamServerData.load();
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveConfig() {
|
||||
SliceBeam.CONFIG_UID++;
|
||||
File f = getConfigFile();
|
||||
@@ -122,6 +110,7 @@ public class SliceBeam extends Application {
|
||||
if (SliceBeam.CONFIG.findPrint(SliceBeam.CONFIG.presets.get("print")) != null) {
|
||||
singleObject.values.putAll(SliceBeam.CONFIG.findPrint(SliceBeam.CONFIG.presets.get("print")).values);
|
||||
}
|
||||
// TODO: MMU. Detect by printerConfig#getExtruderCount()
|
||||
if (SliceBeam.CONFIG.findFilament(SliceBeam.CONFIG.presets.get("filament")) != null) {
|
||||
singleObject.values.putAll(SliceBeam.CONFIG.findFilament(SliceBeam.CONFIG.presets.get("filament")).values);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AppBoot {
|
||||
static ExecutorService executor = Executors.newCachedThreadPool();
|
||||
static List<BootTask> tasks;
|
||||
static List<Runnable> pendingMain = new ArrayList<>();
|
||||
static List<BootTask> pendingTasks = new ArrayList<>();
|
||||
static SparseBooleanArray completed = new SparseBooleanArray();
|
||||
static CountDownLatch latch;
|
||||
|
||||
public static void run(List<BootTask> tasks) {
|
||||
long start = System.currentTimeMillis();
|
||||
AppBoot.tasks = tasks;
|
||||
AppBoot.latch = new CountDownLatch(tasks.size());
|
||||
|
||||
for (int i = 0, s = tasks.size(); i < s; i++) {
|
||||
BootTask task = tasks.get(i);
|
||||
task.index = i;
|
||||
tryRunTask(task, true, false);
|
||||
}
|
||||
try {
|
||||
while (!latch.await(50, TimeUnit.MILLISECONDS)) {
|
||||
if (!pendingMain.isEmpty()) {
|
||||
List<Runnable> clone = new ArrayList<>(pendingMain);
|
||||
for (Runnable r : clone) {
|
||||
r.run();
|
||||
}
|
||||
pendingMain.removeAll(clone);
|
||||
}
|
||||
}
|
||||
Log.d("boot", "Boot in " + (System.currentTimeMillis() - start) + "ms");
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void tryRunTask(BootTask task, boolean fromMain, boolean isContinue) {
|
||||
if (checkDependencies(task.dependencies)) {
|
||||
if (task.workerThread) {
|
||||
executor.submit(() -> {
|
||||
task.run.run();
|
||||
completed.put(task.index, true);
|
||||
latch.countDown();
|
||||
|
||||
if (!isContinue) {
|
||||
continueTasks(fromMain);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Runnable r = () -> {
|
||||
task.run.run();
|
||||
completed.put(task.index, true);
|
||||
latch.countDown();
|
||||
|
||||
if (!isContinue) {
|
||||
continueTasks(fromMain);
|
||||
}
|
||||
};
|
||||
if (fromMain) {
|
||||
r.run();
|
||||
} else {
|
||||
pendingMain.add(r);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pendingTasks.add(task);
|
||||
}
|
||||
}
|
||||
|
||||
private static void continueTasks(boolean fromMain) {
|
||||
for (Iterator<BootTask> it = pendingTasks.iterator(); it.hasNext();) {
|
||||
BootTask task = it.next();
|
||||
if (checkDependencies(task.dependencies)) {
|
||||
tryRunTask(task, fromMain, true);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkDependencies(List<Class<?>> clzs) {
|
||||
if (clzs.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0, s = tasks.size(); i < s; i++) {
|
||||
if (clzs.contains(tasks.get(i).getClass())) {
|
||||
if (!completed.get(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import ru.ytkab0bp.slicebeam.BeamServerData;
|
||||
import ru.ytkab0bp.slicebeam.SliceBeam;
|
||||
import ru.ytkab0bp.slicebeam.utils.Prefs;
|
||||
|
||||
public class BeamServerDataTask extends BootTask {
|
||||
public BeamServerDataTask() {
|
||||
super(() -> {
|
||||
try {
|
||||
SliceBeam.SERVER_DATA = new BeamServerData(new JSONObject(Prefs.getBeamServerData()));
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (System.currentTimeMillis() - Prefs.getLastCheckedInfo() >= 86400000L) {
|
||||
BeamServerData.load();
|
||||
}
|
||||
});
|
||||
onWorker();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class BootTask {
|
||||
public final List<Class<?>> dependencies;
|
||||
public final Runnable run;
|
||||
public boolean workerThread;
|
||||
public int priority;
|
||||
|
||||
/* package */ int index;
|
||||
|
||||
public BootTask(Runnable run) {
|
||||
this.dependencies = Collections.emptyList();
|
||||
this.run = run;
|
||||
}
|
||||
|
||||
public BootTask(List<Class<?>> dependencies, Runnable run) {
|
||||
this.dependencies = dependencies;
|
||||
this.run = run;
|
||||
}
|
||||
|
||||
public BootTask onWorker() {
|
||||
return onWorker(-20);
|
||||
}
|
||||
|
||||
public BootTask onWorker(int priority) {
|
||||
this.workerThread = true;
|
||||
this.priority = priority;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ru.ytkab0bp.slicebeam.SliceBeam;
|
||||
|
||||
public class CheckUpdateJsonTask extends BootTask {
|
||||
public CheckUpdateJsonTask() {
|
||||
super(() -> {
|
||||
try {
|
||||
SliceBeam.INSTANCE.getAssets().open("update.json").close();
|
||||
SliceBeam.hasUpdateInfo = true;
|
||||
} catch (IOException e) {
|
||||
SliceBeam.hasUpdateInfo = false;
|
||||
}
|
||||
});
|
||||
onWorker();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import ru.ytkab0bp.slicebeam.SliceBeam;
|
||||
|
||||
public class ClearModelCacheTask extends BootTask {
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public ClearModelCacheTask() {
|
||||
super(()->{
|
||||
File cache = SliceBeam.getModelCacheDir();
|
||||
if (cache.exists()) {
|
||||
for (File f : cache.listFiles()) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
});
|
||||
onWorker();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import ru.ytkab0bp.slicebeam.cloud.CloudController;
|
||||
|
||||
public class CloudInitTask extends BootTask {
|
||||
public CloudInitTask() {
|
||||
super(Arrays.asList(PrefsTask.class, TrueTimeTask.class, LoadSlic3rConfigTask.class), CloudController::init);
|
||||
onWorker();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import ru.ytkab0bp.eventbus.EventBus;
|
||||
import ru.ytkab0bp.slicebeam.BuildConfig;
|
||||
|
||||
public class EventBusTask extends BootTask {
|
||||
|
||||
public EventBusTask() {
|
||||
super(() -> EventBus.registerImpl(BuildConfig.APPLICATION_ID));
|
||||
onWorker();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import ru.ytkab0bp.slicebeam.SliceBeam;
|
||||
import ru.ytkab0bp.slicebeam.slic3r.Slic3rConfigWrapper;
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public class LoadSlic3rConfigTask extends BootTask {
|
||||
public LoadSlic3rConfigTask() {
|
||||
super(() -> {
|
||||
File cfgFile = SliceBeam.getConfigFile();
|
||||
SliceBeam.getCurrentConfigFile().delete();
|
||||
if (cfgFile.exists()) {
|
||||
try {
|
||||
SliceBeam.CONFIG = new Slic3rConfigWrapper(cfgFile);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
onWorker();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import ru.ytkab0bp.slicebeam.SliceBeam;
|
||||
import ru.ytkab0bp.slicebeam.utils.Prefs;
|
||||
|
||||
public class PrefsTask extends BootTask {
|
||||
public PrefsTask() {
|
||||
super(()->Prefs.init(SliceBeam.INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import ru.ytkab0bp.slicebeam.slic3r.PrintConfigDef;
|
||||
|
||||
public class PrintConfigWarmupTask extends BootTask {
|
||||
public PrintConfigWarmupTask() {
|
||||
super(PrintConfigDef::getInstance);
|
||||
onWorker();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import com.instacart.library.truetime.TrueTime;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TrueTimeTask extends BootTask {
|
||||
/** @noinspection BusyWait*/
|
||||
public TrueTimeTask() {
|
||||
super(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
TrueTime.build().withNtpHost("0.ru.pool.ntp.org").initialize();
|
||||
break;
|
||||
} catch (IOException ignore) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
});
|
||||
onWorker();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package ru.ytkab0bp.slicebeam.boot;
|
||||
|
||||
import ru.ytkab0bp.slicebeam.SliceBeam;
|
||||
import ru.ytkab0bp.slicebeam.utils.VibrationUtils;
|
||||
|
||||
public class VibrationUtilsTask extends BootTask {
|
||||
|
||||
public VibrationUtilsTask() {
|
||||
super(() -> VibrationUtils.init(SliceBeam.INSTANCE));
|
||||
onWorker();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user