aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/main
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2024-09-06 20:49:27 +0900
committershedaniel <daniel@shedaniel.me>2024-09-06 20:59:03 +0900
commit428d5359f0aff3b9922c7a80058f5214cf7f8340 (patch)
tree9a8cefc83f037b25ca463e756031afbe43592dbf /runtime/src/main
parenta31f7254d76add6c34f134713c131463602f8cef (diff)
downloadRoughlyEnoughItems-428d5359f0aff3b9922c7a80058f5214cf7f8340.tar.gz
RoughlyEnoughItems-428d5359f0aff3b9922c7a80058f5214cf7f8340.tar.bz2
RoughlyEnoughItems-428d5359f0aff3b9922c7a80058f5214cf7f8340.zip
New Display Registry Analysis in REI config, with options to sort the entries
Diffstat (limited to 'runtime/src/main')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/DisplayRegistryInfoScreen.java173
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/PerformanceScreen.java38
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/SubCategoryListEntry.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/ScreenWithMenu.java89
-rwxr-xr-xruntime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json6
7 files changed, 312 insertions, 5 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java
index 28b83e639..b206fd6e5 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java
@@ -116,7 +116,8 @@ public interface AllREIConfigGroups {
OptionGroup DEBUG_PERFORMANCE = make("debug.performance")
.add(PLUGINS_PERFORMANCE)
.add(SEARCH_PERFORMANCE)
- .add(ENTRY_LIST_PERFORMANCE);
+ .add(ENTRY_LIST_PERFORMANCE)
+ .add(DISPLAY_REGISTRY_ANALYSIS);
OptionGroup RESET_RELOAD = make("reset.reload")
.add(RELOAD_PLUGINS)
.add(RELOAD_SEARCH);
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java
index b9596c200..97119df2e 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java
@@ -36,6 +36,7 @@ import me.shedaniel.rei.impl.client.config.entries.ConfigureCategoriesScreen;
import me.shedaniel.rei.impl.client.config.entries.FilteringEntry;
import me.shedaniel.rei.impl.client.gui.config.REIConfigScreen;
import me.shedaniel.rei.impl.client.gui.config.options.configure.PanelBoundariesConfiguration;
+import me.shedaniel.rei.impl.client.gui.performance.DisplayRegistryInfoScreen;
import me.shedaniel.rei.impl.client.gui.performance.PerformanceScreen;
import me.shedaniel.rei.impl.client.gui.screen.ConfigReloadingScreen;
import me.shedaniel.rei.impl.client.gui.screen.collapsible.CollapsibleEntriesScreen;
@@ -245,6 +246,9 @@ public interface AllREIConfigOptions {
.enabledDisabled();
CompositeOption<Boolean> ENTRY_LIST_PERFORMANCE = make("debug.entry_list_performance", i -> i.advanced.layout.debugRenderTimeRequired, (i, v) -> i.advanced.layout.debugRenderTimeRequired = v)
.enabledDisabled();
+ CompositeOption<Object> DISPLAY_REGISTRY_ANALYSIS = make("debug.display_registry_analysis", i -> null, (i, v) -> new Object())
+ .details((access, option, onClose) -> Minecraft.getInstance().setScreen(new DisplayRegistryInfoScreen(onClose)))
+ .requiresLevel();
CompositeOption<Object> RELOAD_PLUGINS = make("reset.reload_plugins", i -> null, (i, v) -> new Object())
.reload((access, option, onClose) -> {
RoughlyEnoughItemsCoreClient.reloadPlugins(null, null);
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/DisplayRegistryInfoScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/DisplayRegistryInfoScreen.java
new file mode 100644
index 000000000..289a1c4fd
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/DisplayRegistryInfoScreen.java
@@ -0,0 +1,173 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.gui.performance;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.PoseStack;
+import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.registry.display.DisplayRegistry;
+import me.shedaniel.rei.api.common.category.CategoryIdentifier;
+import me.shedaniel.rei.api.common.display.Display;
+import me.shedaniel.rei.api.common.util.CollectionUtils;
+import me.shedaniel.rei.impl.client.gui.modules.Menu;
+import me.shedaniel.rei.impl.client.gui.modules.entries.ToggleMenuEntry;
+import me.shedaniel.rei.impl.client.gui.screen.ScreenWithMenu;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiComponent;
+import net.minecraft.client.gui.components.Button;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.narration.NarratableEntry;
+import net.minecraft.network.chat.Component;
+import net.minecraft.util.FormattedCharSequence;
+
+import java.util.*;
+import java.util.stream.Stream;
+
+@Environment(EnvType.CLIENT)
+public class DisplayRegistryInfoScreen extends ScreenWithMenu {
+ private Runnable onClose;
+
+ public DisplayRegistryInfoScreen(Runnable onClose) {
+ super(Component.translatable("text.rei.display_registry_analysis"));
+ this.onClose = onClose;
+ }
+
+ private ListWidget list;
+ private SortType sortType = SortType.ID;
+
+ @Override
+ public void init() {
+ {
+ Component backText = Component.literal("↩ ").append(Component.translatable("gui.back"));
+ addRenderableWidget(new Button(4, 4, Minecraft.getInstance().font.width(backText) + 10, 20, backText, button -> {
+ this.onClose.run();
+ this.onClose = null;
+ }));
+ }
+ {
+ Component text = Component.translatable("text.rei.sort");
+ Rectangle bounds = new Rectangle(this.width - 4 - Minecraft.getInstance().font.width(text) - 10, 4, Minecraft.getInstance().font.width(text) + 10, 20);
+ addRenderableWidget(new Button(bounds.x, bounds.y, bounds.width, bounds.height, text, button -> {
+ this.setMenu(new Menu(bounds, CollectionUtils.map(SortType.values(), type -> {
+ return ToggleMenuEntry.of(Component.translatable("text.rei.sort.by", type.name().toLowerCase(Locale.ROOT)), () -> false, o -> {
+ this.closeMenu();
+ this.sortType = type;
+ this.init(this.minecraft, this.width, this.height);
+ });
+ }), false));
+ }));
+ }
+ list = new ListWidget();
+ list.addItem(new EntryImpl(Component.literal("Total Displays"), DisplayRegistry.getInstance().displaySize()));
+ sort(DisplayRegistry.getInstance().getAll().entrySet().stream())
+ .forEach(entry -> {
+ list.addItem(new EntryImpl(entry.getKey(), entry.getValue().size()));
+ });
+ addWidget(list);
+ }
+
+ private Stream<Map.Entry<CategoryIdentifier<?>, List<Display>>> sort(Stream<Map.Entry<CategoryIdentifier<?>, List<Display>>> stream) {
+ return switch (sortType) {
+ case COUNT -> stream.sorted(Comparator.<Map.Entry<CategoryIdentifier<?>, List<Display>>>comparingInt(value -> value.getValue().size()).reversed());
+ case ID -> stream.sorted(Comparator.comparing(value -> value.getKey().toString()));
+ };
+ }
+
+ @Override
+ public void render(PoseStack poses, int mouseX, int mouseY, float delta) {
+ renderDirtBackground(0);
+ list.render(poses, mouseX, mouseY, delta);
+ this.font.drawShadow(poses, this.title.getVisualOrderText(), this.width / 2.0F - this.font.width(this.title) / 2.0F, 12.0F, -1);
+ super.render(poses, mouseX, mouseY, delta);
+ }
+
+ public static abstract class ListEntry extends DynamicElementListWidget.ElementEntry<ListEntry> {
+ }
+
+ private class ListWidget extends DynamicElementListWidget<ListEntry> {
+ public ListWidget() {
+ super(DisplayRegistryInfoScreen.this.minecraft, DisplayRegistryInfoScreen.this.width, DisplayRegistryInfoScreen.this.height, 30, DisplayRegistryInfoScreen.this.height, GuiComponent.BACKGROUND_LOCATION);
+ }
+
+ @Override
+ public int getItemWidth() {
+ return width;
+ }
+
+ @Override
+ public int addItem(ListEntry item) {
+ return super.addItem(item);
+ }
+
+ @Override
+ protected int getScrollbarPosition() {
+ return width - 6;
+ }
+ }
+
+ public static class EntryImpl extends ListEntry {
+ private final Component component;
+ public final int count;
+
+ public EntryImpl(CategoryIdentifier<?> identifier, int count) {
+ this(Component.literal(identifier.getIdentifier().toString()), count);
+ }
+
+ public EntryImpl(Component component, int count) {
+ this.component = component;
+ this.count = count;
+ }
+
+ @Override
+ public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
+ RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
+ Minecraft.getInstance().font.drawShadow(matrices, this.component.getVisualOrderText(), (float) x + 4, (float) (y + 6), -1);
+ FormattedCharSequence rightText = Component.translatable("text.rei.display_registry_analysis.displays", count).getVisualOrderText();
+ Minecraft.getInstance().font.drawShadow(matrices, rightText, (float) x + entryWidth - 6 - 8 - Minecraft.getInstance().font.width(rightText), (float) (y + 6), -1);
+ }
+
+ @Override
+ public int getItemHeight() {
+ return 24;
+ }
+
+ @Override
+ public List<? extends GuiEventListener> children() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<? extends NarratableEntry> narratables() {
+ return Collections.emptyList();
+ }
+ }
+
+ private enum SortType {
+ COUNT,
+ ID
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/PerformanceScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/PerformanceScreen.java
index 239489a71..29d170779 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/PerformanceScreen.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/PerformanceScreen.java
@@ -26,17 +26,21 @@ package me.shedaniel.rei.impl.client.gui.performance;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.datafixers.util.Pair;
import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget;
+import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.RoughlyEnoughItemsCore;
import me.shedaniel.rei.api.common.plugins.REIPlugin;
import me.shedaniel.rei.api.common.plugins.REIPluginProvider;
+import me.shedaniel.rei.api.common.util.CollectionUtils;
+import me.shedaniel.rei.impl.client.gui.modules.Menu;
+import me.shedaniel.rei.impl.client.gui.modules.entries.ToggleMenuEntry;
import me.shedaniel.rei.impl.client.gui.performance.entry.PerformanceEntryImpl;
import me.shedaniel.rei.impl.client.gui.performance.entry.SubCategoryListEntry;
+import me.shedaniel.rei.impl.client.gui.screen.ScreenWithMenu;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.Button;
-import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextColor;
import net.minecraft.util.FormattedCharSequence;
@@ -48,7 +52,7 @@ import java.util.stream.Collectors;
import static java.util.concurrent.TimeUnit.*;
@Environment(EnvType.CLIENT)
-public class PerformanceScreen extends Screen {
+public class PerformanceScreen extends ScreenWithMenu {
private Runnable onClose;
public PerformanceScreen(Runnable onClose) {
@@ -57,6 +61,7 @@ public class PerformanceScreen extends Screen {
}
private PerformanceEntryListWidget list;
+ private SortType sortType = SortType.ORDER;
/*
* Copyright (C) 2008 The Guava Authors
@@ -142,8 +147,22 @@ public class PerformanceScreen extends Screen {
this.onClose = null;
}));
}
+ {
+ Component text = Component.translatable("text.rei.sort");
+ Rectangle bounds = new Rectangle(this.width - 4 - Minecraft.getInstance().font.width(text) - 10, 4, Minecraft.getInstance().font.width(text) + 10, 20);
+ addRenderableWidget(new Button(bounds.x, bounds.y, bounds.width, bounds.height, text, button -> {
+ this.setMenu(new Menu(bounds, CollectionUtils.map(SortType.values(), type -> {
+ return ToggleMenuEntry.of(Component.translatable("text.rei.sort.by", type.name().toLowerCase(Locale.ROOT)), () -> false, o -> {
+ this.closeMenu();
+ this.sortType = type;
+ this.init(this.minecraft, this.width, this.height);
+ });
+ }), false));
+ }));
+ }
list = new PerformanceEntryListWidget();
long[] totalTime = {0};
+ List<SubCategoryListEntry> subCategories = new ArrayList<>();
RoughlyEnoughItemsCore.PERFORMANCE_LOGGER.getStages().forEach((stage, inner) -> {
List<PerformanceEntryImpl> entries = new ArrayList<>();
inner.times().forEach((obj, time) -> {
@@ -158,9 +177,15 @@ public class PerformanceScreen extends Screen {
entries.add(new PerformanceEntryImpl(Component.literal("Miscellaneous Operations"), inner.totalNano() - separateTime));
}
totalTime[0] += Math.max(inner.totalNano(), separateTime);
- entries.sort(Comparator.<PerformanceEntryImpl>comparingLong(value -> value.time).reversed());
- list.addItem(new SubCategoryListEntry(Component.literal(stage), (List<PerformanceScreen.PerformanceEntry>) (List<? extends PerformanceScreen.PerformanceEntry>) entries, Math.max(inner.totalNano(), separateTime), false));
+ if (this.sortType == SortType.DURATION) {
+ entries.sort(Comparator.<PerformanceEntryImpl>comparingLong(value -> value.time).reversed());
+ }
+ subCategories.add(new SubCategoryListEntry(Component.literal(stage), (List<PerformanceScreen.PerformanceEntry>) (List<? extends PerformanceScreen.PerformanceEntry>) entries, Math.max(inner.totalNano(), separateTime), false));
});
+ if (this.sortType == SortType.DURATION) {
+ subCategories.sort(Comparator.comparingLong(SubCategoryListEntry::getTotalTime).reversed());
+ }
+ subCategories.forEach(list::addItem);
list.children().add(0, new PerformanceEntryImpl(Component.literal("Total Load Time"), totalTime[0]));
addWidget(list);
}
@@ -212,4 +237,9 @@ public class PerformanceScreen extends Screen {
return width - 6;
}
}
+
+ private enum SortType {
+ ORDER,
+ DURATION
+ }
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/SubCategoryListEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/SubCategoryListEntry.java
index 368bd5a3a..9596fc51d 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/SubCategoryListEntry.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/SubCategoryListEntry.java
@@ -157,6 +157,10 @@ public class SubCategoryListEntry extends PerformanceScreen.PerformanceEntry imp
return Collections.emptyList();
}
+ public long getTotalTime() {
+ return totalTime;
+ }
+
public class CategoryLabelWidget implements GuiEventListener {
private final Rectangle rectangle = new Rectangle();
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/ScreenWithMenu.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/ScreenWithMenu.java
new file mode 100644
index 000000000..ab8df5df8
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/ScreenWithMenu.java
@@ -0,0 +1,89 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.gui.screen;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import me.shedaniel.rei.impl.client.gui.modules.Menu;
+import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.network.chat.Component;
+import org.jetbrains.annotations.Nullable;
+
+public class ScreenWithMenu extends Screen {
+ @Nullable
+ private Menu menu;
+
+ protected ScreenWithMenu(Component component) {
+ super(component);
+ }
+
+ @Override
+ public void render(PoseStack poses, int mouseX, int mouseY, float delta) {
+ super.render(poses, mouseX, mouseY, delta);
+ if (this.menu != null) {
+ poses.pushPose();
+ poses.translate(0, 0, 400);
+ this.menu.render(poses, mouseX, mouseY, delta);
+ poses.popPose();
+ }
+ }
+
+ protected void setMenu(@Nullable Menu menu) {
+ this.menu = menu;
+ }
+
+ protected void closeMenu() {
+ this.menu = null;
+ }
+
+ @Override
+ public boolean mouseClicked(double mouseX, double mouseY, int button) {
+ if (this.menu != null) {
+ if (!this.menu.mouseClicked(mouseX, mouseY, button))
+ this.menu = null;
+ return true;
+ }
+ return super.mouseClicked(mouseX, mouseY, button);
+ }
+
+ @Override
+ public boolean mouseReleased(double mouseX, double mouseY, int button) {
+ if (this.menu != null && this.menu.mouseReleased(mouseX, mouseY, button))
+ return true;
+ return super.mouseReleased(mouseX, mouseY, button);
+ }
+
+ @Override
+ public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
+ if (this.menu != null && this.menu.mouseScrolled(mouseX, mouseY, amount))
+ return true;
+ return super.mouseScrolled(mouseX, mouseY, amount);
+ }
+
+ @Override
+ public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
+ if (this.menu != null && this.menu.mouseDragged(mouseX, mouseY, button, deltaX, deltaY))
+ return true;
+ return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
+ }
+}
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 0146868cf..5568968b6 100755
--- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json
+++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json
@@ -79,6 +79,10 @@
"text.rei.tag_accept": "Tag: #%s",
"text.rei.missing": "Missing following:",
"text.rei.performance": "Performance Analysis",
+ "text.rei.display_registry_analysis": "Display Registry Analysis",
+ "text.rei.display_registry_analysis.displays": "%d display(s)",
+ "text.rei.sort": "Sort",
+ "text.rei.sort.by": "Sort by %s",
"text.rei.addons": "REI Addons",
"text.rei.shapeless": "Shapeless",
"text.rei.crafting.firework.gunpowder.amount": "The amount of gunpowder affects the flight duration of the firework.",
@@ -451,6 +455,8 @@
"config.rei.options.debug.search_performance.desc": "Verbose console print out for analysing search performance.",
"config.rei.options.debug.entry_list_performance": "Entry List Performance",
"config.rei.options.debug.entry_list_performance.desc": "Display the time used to render entries on the entry list.",
+ "config.rei.options.debug.display_registry_analysis": "Display Registry Analysis",
+ "config.rei.options.debug.display_registry_analysis.desc": "Break-down in registration of displays in each category.",
"config.rei.options.groups.reset.reload": "Reload",
"config.rei.options.reset.reload_plugins": "Reload Plugins",
"config.rei.options.reset.reload_plugins.desc": "Resets the current loaded data and reload all data and plugins.",