diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-12-03 22:17:27 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2022-12-12 21:01:07 +0800 |
| commit | 47ae69cd83f36aa5acf4bfedf9bbccc0eec34b67 (patch) | |
| tree | b111b75620e263fa5a027241b03ebbe122f90669 | |
| parent | 2caa595aa94d46ddaefc5ecdb79f7ec834f7eae8 (diff) | |
| download | RoughlyEnoughItems-47ae69cd83f36aa5acf4bfedf9bbccc0eec34b67.tar.gz RoughlyEnoughItems-47ae69cd83f36aa5acf4bfedf9bbccc0eec34b67.tar.bz2 RoughlyEnoughItems-47ae69cd83f36aa5acf4bfedf9bbccc0eec34b67.zip | |
Add init progress to IME
7 files changed, 145 insertions, 25 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/search/method/CharacterUnpackingInputMethod.java b/api/src/main/java/me/shedaniel/rei/api/client/search/method/CharacterUnpackingInputMethod.java index f14e1b334..f7f1779f8 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/search/method/CharacterUnpackingInputMethod.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/search/method/CharacterUnpackingInputMethod.java @@ -45,9 +45,8 @@ public interface CharacterUnpackingInputMethod extends InputMethod<IntList> { default String suggestInputString(String str) { return str.codePoints().mapToObj(c -> { List<ExpendedChar> chars = expendSourceChar(c); - String result; - if (chars.isEmpty()) return result = ((char) c) + ""; - result = chars.get(0).phonemes().stream() + if (chars.isEmpty()) return ((char) c) + ""; + String result = chars.get(0).phonemes().stream() .flatMap(integers -> integers.intStream().mapToObj(value -> ((char) value) + "")) .collect(Collectors.joining()); if (result.codePointCount(0, result.length()) == 1 && result.codePointAt(0) == c) { diff --git a/api/src/main/java/me/shedaniel/rei/api/client/search/method/InputMethod.java b/api/src/main/java/me/shedaniel/rei/api/client/search/method/InputMethod.java index 90e6ba092..fc81acd33 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/search/method/InputMethod.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/search/method/InputMethod.java @@ -34,35 +34,132 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +/** + * An input method to match a search filter to another source input. + * + * @param <T> the type of expansion from the search filter + * @see me.shedaniel.rei.impl.client.search.method.DefaultInputMethod + */ @ApiStatus.Experimental public interface InputMethod<T> { + /** + * Returns the active input method. + * + * @return the active input method + */ static InputMethod<?> active() { return InputMethodRegistry.getInstance().getOrDefault(ConfigObject.getInstance().getInputMethodId()); } + /** + * Returns the list of all Minecraft supported locales. + * + * @return the list of all Minecraft supported locales + */ static List<Locale> getAllLocales() { return CollectionUtils.map(Minecraft.getInstance().getLanguageManager().getLanguages(), info -> new Locale(info.getCode(), Component.literal(info.getName()))); } + /** + * Returns the list of locales that are supported by this input method. + * You should use {@link #getAllLocales()} to get the list of all Minecraft supported locales. + * + * @return the list of locales that are supported by this input method + */ List<Locale> getMatchingLocales(); + /** + * Returns all the possible expansions from the search filter. + * + * @param filter the search filter + * @return all the possible expansions from the search filter + */ Iterable<T> expendFilter(String filter); + /** + * Returns whether the search filter matches the input. + * + * @param str the input + * @param substr the expanded search filter + * @return whether the search filter matches the input + */ boolean contains(String str, T substr); + /** + * Returns a suggested expansion from the search filter. + * + * @param str the input + * @return a suggested expansion from the search filter, or {@code null} if no suggestion is available + */ @Nullable default String suggestInputString(String str) { return null; } + /** + * Prepares the input method for activation. + * + * @param executor the executor to run the preparation on + * @return a future that completes when the preparation is done + */ CompletableFuture<Void> prepare(Executor executor); + /** + * Prepares the input method for activation. + * + * @param executor the executor to run the preparation on + * @param progressCallback the callback to call when the progress is updated + * @return a future that completes when the preparation is done + */ + default CompletableFuture<Void> prepare(Executor executor, ProgressCallback progressCallback) { + progressCallback.onProgress(0.0); + return prepare(executor).whenComplete((aVoid, throwable) -> progressCallback.onProgress(1.0)); + } + + /** + * Disposes the input method. + * + * @param executor the executor to run the disposal on + * @return a future that completes when the disposal is done + */ CompletableFuture<Void> dispose(Executor executor); + /** + * Disposes the input method. + * + * @param executor the executor to run the disposal on + * @param progressCallback the callback to call when the progress is updated + * @return a future that completes when the disposal is done + */ + default CompletableFuture<Void> dispose(Executor executor, ProgressCallback progressCallback) { + progressCallback.onProgress(0.0); + return dispose(executor).whenComplete((aVoid, throwable) -> progressCallback.onProgress(1.0)); + } + + /** + * Returns the name of this input method. + * + * @return the name of this input method + */ Component getName(); + /** + * Returns the description of this input method. + * + * @return the description of this input method + */ Component getDescription(); record Locale(String code, Component name) {} + + @FunctionalInterface + interface ProgressCallback { + /** + * Called when the progress of the preparation is updated. + * + * @param progress the progress of the preparation, between 0.0 and 1.0 + */ + void onProgress(double progress); + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/ConfigReloadingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/ConfigReloadingScreen.java index eeb1a1852..082ac44ec 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/ConfigReloadingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/ConfigReloadingScreen.java @@ -28,14 +28,17 @@ import net.minecraft.Util; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; import java.util.function.BooleanSupplier; +import java.util.function.Supplier; @ApiStatus.Internal public class ConfigReloadingScreen extends Screen { private final Component title; private final BooleanSupplier predicate; - private Runnable parent; + private Supplier<@Nullable Component> subtitle = () -> null; + private final Runnable parent; public ConfigReloadingScreen(Component title, BooleanSupplier predicate, Runnable parent) { super(Component.empty()); @@ -44,6 +47,10 @@ public class ConfigReloadingScreen extends Screen { this.parent = parent; } + public void setSubtitle(Supplier<@Nullable Component> subtitle) { + this.subtitle = subtitle; + } + @Override public boolean shouldCloseOnEsc() { return false; @@ -56,21 +63,17 @@ public class ConfigReloadingScreen extends Screen { parent.run(); return; } - drawCenteredString(matrices, this.font, title, this.width / 2, this.height / 2 - 50, 16777215); - String text; - switch ((int) (Util.getMillis() / 300L % 4L)) { - case 0: - default: - text = "O o o"; - break; - case 1: - case 3: - text = "o O o"; - break; - case 2: - text = "o o O"; + drawCenteredString(matrices, this.font, title, this.width / 2, this.height / 2 - 50, 0xffffff); + String text = switch ((int) (Util.getMillis() / 300L % 4L)) { + case 1, 3 -> "o O o"; + case 2 -> "o o O"; + default -> "O o o"; + }; + drawCenteredString(matrices, this.font, text, this.width / 2, this.height / 2 - 50 + 9, 0x808080); + Component subtitle = this.subtitle.get(); + if (subtitle != null) { + drawCenteredString(matrices, this.font, subtitle, this.width / 2, this.height / 2 - 50 + 9 + 9, 0x808080); } - drawCenteredString(matrices, this.font, text, this.width / 2, this.height / 2 - 41, 8421504); super.render(matrices, mouseX, mouseY, delta); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CraftableFilterButtonWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CraftableFilterButtonWidget.java index 94bf01921..d0d611890 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CraftableFilterButtonWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CraftableFilterButtonWidget.java @@ -49,6 +49,7 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Blocks; @@ -130,7 +131,8 @@ public class CraftableFilterButtonWidget { ConfigManagerImpl.getInstance().getConfig().setInputMethodId(new ResourceLocation("rei:default")); }).join(); - CompletableFuture<Void> future = pair.getValue().prepare(service).whenComplete((unused, throwable) -> { + double[] progress = {0}; + CompletableFuture<Void> future = pair.getValue().prepare(service, p -> progress[0] = Mth.clamp(p, 0, 1)).whenComplete((unused, throwable) -> { if (throwable != null) { InternalLogger.getInstance().error("Failed to prepare input method", throwable); ConfigManagerImpl.getInstance().getConfig().setInputMethodId(new ResourceLocation("rei:default")); @@ -139,10 +141,12 @@ public class CraftableFilterButtonWidget { } }); Screen screen = Minecraft.getInstance().screen; - Minecraft.getInstance().setScreen(new ConfigReloadingScreen(Component.translatable("text.rei.input.methods.initializing"), + ConfigReloadingScreen reloadingScreen = new ConfigReloadingScreen(Component.translatable("text.rei.input.methods.initializing"), () -> !future.isDone(), () -> { Minecraft.getInstance().setScreen(screen); - })); + }); + reloadingScreen.setSubtitle(() -> new TranslatableComponent("text.rei.input.methods.reload.progress", String.format("%.2f", progress[0] * 100))); + Minecraft.getInstance().setScreen(reloadingScreen); future.whenComplete((unused, throwable) -> { service.shutdown(); }); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanInputMethod.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanInputMethod.java index 1402c54ba..91619f644 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanInputMethod.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanInputMethod.java @@ -50,9 +50,15 @@ public abstract class UniHanInputMethod implements InputMethod<IntList> { @Override public CompletableFuture<Void> prepare(Executor executor) { + return this.prepare(executor, p -> {}); + } + + @Override + public CompletableFuture<Void> prepare(Executor executor, ProgressCallback progressCallback) { return dispose(executor) - .thenRunAsync(manager::download, executor) - .thenRunAsync(this::load, executor); + .thenRunAsync(() -> manager.download(p -> progressCallback.onProgress(p * 0.99)), executor) + .thenRunAsync(this::load, executor) + .whenComplete((aVoid, throwable) -> progressCallback.onProgress(1.0)); } public void load() { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanManager.java index bf36fc130..f2f9a5b74 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanManager.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanManager.java @@ -23,6 +23,7 @@ package me.shedaniel.rei.impl.client.search.method.unihan; +import me.shedaniel.rei.api.client.search.method.InputMethod; import me.shedaniel.rei.impl.common.InternalLogger; import org.apache.commons.io.IOUtils; import org.apache.commons.io.LineIterator; @@ -50,10 +51,18 @@ public class UniHanManager { return Files.exists(unihanPath); } - public void download() { + public void download(InputMethod.ProgressCallback progressCallback) { + try { + download("https://www.shedaniel.moe/uoAqECzbQo5s.zip", progressCallback); + } catch (Exception e) { + download("https://www.unicode.org/Public/UCD/latest/ucd/Unihan.zip", progressCallback); + } + } + + public void download(String URL, InputMethod.ProgressCallback progressCallback) { if (downloaded()) return; try { - URL url = new URL("https://www.unicode.org/Public/UCD/latest/ucd/Unihan.zip"); + URL url = new URL("https://shedaniel.moe/uoAqECzbQo5s.zip"); Files.deleteIfExists(unihanPath); Path parent = unihanPath.getParent(); if (parent != null) Files.createDirectories(parent); @@ -74,6 +83,7 @@ public class UniHanManager { lastPercent = percent; InternalLogger.getInstance().debug("Downloading UniHan Progress: %d%%".formatted(percent)); } + progressCallback.onProgress(progress); bufferedStream.write(data, 0, x); } bufferedStream.close(); diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json index c487cfae8..796f5bf9e 100755 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json @@ -78,6 +78,7 @@ "text.rei.addons": "REI Addons", "text.rei.shapeless": "Shapeless", "text.rei.input.methods": "Input Methods", + "text.rei.input.methods.reload.progress": "Progress: %s%%", "text.rei.input.methods.default": "Default", "text.rei.input.methods.default.description": "The default input method. This does not transform the search term.", "text.rei.input.methods.jyutping": "Jyutping (Cantonese)", |
