diff options
| author | shedaniel <daniel@shedaniel.me> | 2024-09-17 22:15:52 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2024-09-17 22:15:52 +0800 |
| commit | 3251f01cacfaf6dcdfd35ee3eaa5e5bee9d372b7 (patch) | |
| tree | 3b4876ab4de85a4a702300d9bbbb812d94f888e4 /runtime/src/main/java/me/shedaniel/rei/impl/client | |
| parent | dcac5f4891046507047c5951c164fb1c1f08da74 (diff) | |
| parent | 15a46dc3a91cf3f8fdb7a1ddf382ce05bfcf742e (diff) | |
| download | RoughlyEnoughItems-3251f01cacfaf6dcdfd35ee3eaa5e5bee9d372b7.tar.gz RoughlyEnoughItems-3251f01cacfaf6dcdfd35ee3eaa5e5bee9d372b7.tar.bz2 RoughlyEnoughItems-3251f01cacfaf6dcdfd35ee3eaa5e5bee9d372b7.zip | |
Merge remote-tracking branch 'origin/15.x-1.20.5' into 16.x-1.21
# Conflicts:
# runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
Diffstat (limited to 'runtime/src/main/java/me/shedaniel/rei/impl/client')
12 files changed, 427 insertions, 41 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 30340bfba..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 @@ -24,7 +24,6 @@ package me.shedaniel.rei.impl.client.gui.config.options; import me.shedaniel.clothconfig2.api.ModifierKeyCode; -import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.RoughlyEnoughItemsCoreClient; import me.shedaniel.rei.api.client.config.entry.EntryStackProvider; import me.shedaniel.rei.api.client.gui.config.*; @@ -37,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; @@ -246,9 +246,11 @@ 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) -> { - RoughlyEnoughItemsCore.PERFORMANCE_LOGGER.clear(); RoughlyEnoughItemsCoreClient.reloadPlugins(null, null); while (!PluginManager.areAnyReloading()) { try { 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..168644367 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/DisplayRegistryInfoScreen.java @@ -0,0 +1,174 @@ +/* + * 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 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 me.shedaniel.rei.impl.client.gui.widget.UpdatedListWidget; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +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.function.Supplier; +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; + }, Supplier::get) { + }); + } + { + 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)); + }, Supplier::get) { + }); + } + 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(GuiGraphics graphics, int mouseX, int mouseY, float delta) { + super.render(graphics, mouseX, mouseY, delta); + list.render(graphics, mouseX, mouseY, delta); + graphics.drawString(this.font, this.title.getVisualOrderText(), (int) (this.width / 2.0F - this.font.width(this.title) / 2.0F), 12, -1); + } + + public static abstract class ListEntry extends UpdatedListWidget.ElementEntry<ListEntry> { + } + + private class ListWidget extends UpdatedListWidget<ListEntry> { + public ListWidget() { + super(DisplayRegistryInfoScreen.this.minecraft, DisplayRegistryInfoScreen.this.width, DisplayRegistryInfoScreen.this.height, 30, DisplayRegistryInfoScreen.this.height); + } + + @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(GuiGraphics graphics, 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); + graphics.drawString(Minecraft.getInstance().font, this.component.getVisualOrderText(), x + 4, y + 6, -1); + FormattedCharSequence rightText = Component.translatable("text.rei.display_registry_analysis.displays", count).getVisualOrderText(); + graphics.drawString(Minecraft.getInstance().font, rightText, x + entryWidth - 6 - 8 - Minecraft.getInstance().font.width(rightText), 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 625a56238..13e3a1c19 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 @@ -24,11 +24,16 @@ package me.shedaniel.rei.impl.client.gui.performance; import com.mojang.datafixers.util.Pair; +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 me.shedaniel.rei.impl.client.gui.widget.UpdatedListWidget; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -48,7 +53,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 +62,7 @@ public class PerformanceScreen extends Screen { } private PerformanceEntryListWidget list; + private SortType sortType = SortType.ORDER; /* * Copyright (C) 2008 The Guava Authors @@ -142,8 +148,22 @@ public class PerformanceScreen extends Screen { this.onClose = null; }, Supplier::get) {}); } + { + 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)); + }, Supplier::get) {}); + } 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 +178,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); } @@ -211,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 21c3f5120..dbc04f896 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 @@ -156,6 +156,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..bfd3379e9 --- /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 me.shedaniel.rei.impl.client.gui.modules.Menu; +import net.minecraft.client.gui.GuiGraphics; +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(GuiGraphics graphics, int mouseX, int mouseY, float delta) { + super.render(graphics, mouseX, mouseY, delta); + if (this.menu != null) { + graphics.pose().pushPose(); + graphics.pose().translate(0, 0, 400); + this.menu.render(graphics, mouseX, mouseY, delta); + graphics.pose().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 amountX, double amountY) { + if (this.menu != null && this.menu.mouseScrolled(mouseX, mouseY, amountX, amountY)) + return true; + return super.mouseScrolled(mouseX, mouseY, amountX, amountY); + } + + @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/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java index 559276f7f..ac6c63cea 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java @@ -85,6 +85,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.function.Consumer; import java.util.function.Supplier; import java.util.function.UnaryOperator; import java.util.stream.Collectors; @@ -272,6 +273,12 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { return this; } + @Override + public Slot withEntriesListener(Consumer<Slot> listener) { + this.getCyclingEntries().addListener($ -> listener.accept(this)); + return this; + } + public Slot entries(CyclingList<EntryStack<?>> stacks) { this.getCyclingEntries().setBacking(stacks); if (removeTagMatch) tagMatch = null; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCache.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCache.java index b65aba97c..9c725efc4 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCache.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCache.java @@ -34,6 +34,10 @@ import java.util.List; import java.util.Set; public interface DisplayCache { + int cachedSize(); + + int notCachedSize(); + boolean doesCache(); boolean isCached(Display display); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCacheImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCacheImpl.java index 80a73f82e..4c995c9b0 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCacheImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCacheImpl.java @@ -54,6 +54,16 @@ public class DisplayCacheImpl implements DisplayCache { } @Override + public int cachedSize() { + return this.displaysCached.size(); + } + + @Override + public int notCachedSize() { + return this.displaysNotCached.size(); + } + + @Override public boolean doesCache() { return this.cache; } @@ -66,7 +76,7 @@ public class DisplayCacheImpl implements DisplayCache { @Override public void add(Display display) { if (this.cache) { - if (!preprocessed) { + if (!this.preprocessed) { this.displaysNotCached.add(display); } else { this.process(display); @@ -80,7 +90,7 @@ public class DisplayCacheImpl implements DisplayCache { @Override public boolean remove(Display display) { if (this.cache) { - if (!preprocessed) { + if (!this.preprocessed) { return this.displaysNotCached.remove(display); } else { boolean removed = this.displaysCached.remove(display); @@ -106,7 +116,7 @@ public class DisplayCacheImpl implements DisplayCache { @Override public void endReload() { if (this.cache) { - if (preprocessed) { + if (this.preprocessed) { InternalLogger.getInstance().error("DisplayCache#endReload called after preprocessed!"); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java index 9d03a4450..313817395 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java @@ -23,7 +23,9 @@ package me.shedaniel.rei.impl.client.registry.display; -import com.google.common.base.Preconditions; +import com.google.common.base.Stopwatch; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; import dev.architectury.event.EventResult; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; @@ -36,6 +38,7 @@ import me.shedaniel.rei.api.client.registry.display.visibility.DisplayVisibility import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.api.common.plugins.PluginManager; +import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.impl.common.InternalLogger; import me.shedaniel.rei.impl.common.registry.RecipeManagerContextImpl; import net.minecraft.world.item.crafting.Recipe; @@ -56,10 +59,6 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi private long lastAddWarning = -1; private DisplaysHolder displaysHolder = new DisplaysHolderImpl(false); - public DisplayRegistryImpl() { - super(RecipeManagerContextImpl.supplier()); - } - @Override public void acceptPlugin(REIClientPlugin plugin) { plugin.registerDisplays(this); @@ -123,7 +122,11 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi @Override public boolean isDisplayVisible(Display display) { DisplayCategory<Display> category = (DisplayCategory<Display>) CategoryRegistry.getInstance().get(display.getCategoryIdentifier()).getCategory(); - Preconditions.checkNotNull(category, "Failed to resolve category: " + display.getCategoryIdentifier()); + return isDisplayVisible(category, display); + } + + public boolean isDisplayVisible(DisplayCategory<?> category, Display display) { + if (category == null) throw new NullPointerException("Failed to resolve category: " + display.getCategoryIdentifier()); for (DisplayVisibilityPredicate predicate : visibilityPredicates) { try { EventResult result = predicate.handleDisplay(category, display); @@ -188,13 +191,8 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi @Override public void endReload() { - if (!fillers.isEmpty()) { - List<RecipeHolder<?>> allSortedRecipes = getAllSortedRecipes(); - for (int i = allSortedRecipes.size() - 1; i >= 0; i--) { - RecipeHolder<?> recipe = allSortedRecipes.get(i); - addWithReason(recipe, DisplayAdditionReason.RECIPE_MANAGER); - } - } + InternalLogger.getInstance().debug("Found preliminary %d displays", displaySize()); + fillSortedRecipes(); for (CategoryIdentifier<?> identifier : getAll().keySet()) { if (CategoryRegistry.getInstance().tryGet(identifier).isEmpty()) { @@ -202,21 +200,59 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi } } - List<Display> failedDisplays = new ArrayList<>(); + removeFailedDisplays(); + this.displaysHolder.endReload(); + InternalLogger.getInstance().debug("%d displays registration have completed", displaySize()); + } + + private void fillSortedRecipes() { + Stopwatch stopwatch = Stopwatch.createStarted(); + int lastSize = displaySize(); + if (!fillers.isEmpty()) { + List<RecipeHolder<?>> allSortedRecipes = getAllSortedRecipes(); + for (int i = allSortedRecipes.size() - 1; i >= 0; i--) { + RecipeHolder<?> recipe = allSortedRecipes.get(i); + try { + addWithReason(recipe, DisplayAdditionReason.RECIPE_MANAGER); + } catch (Throwable e) { + InternalLogger.getInstance().error("Failed to fill display for recipe: %s [%s]", recipe.value(), recipe.id(), e); + } + } + } + InternalLogger.getInstance().debug("Filled %d displays from recipe manager in %s", displaySize() - lastSize, stopwatch.stop()); + } + + private void removeFailedDisplays() { + Multimap<CategoryIdentifier<?>, Display> failedDisplays = Multimaps.newListMultimap(new HashMap<>(), ArrayList::new); for (List<Display> displays : getAll().values()) { for (Display display : displays) { if (!DisplayValidator.validate(display)) { - failedDisplays.add(display); + failedDisplays.put(display.getCategoryIdentifier(), display); } } } - for (Display display : failedDisplays) { - this.displaysHolder.remove(display); - } - - this.displaysHolder.endReload(); - InternalLogger.getInstance().debug("Registered %d displays", displaySize()); + InternalLogger.getInstance().debug("Removing %d failed displays" + (!failedDisplays.isEmpty() ? ":" : ""), failedDisplays.size()); + failedDisplays.asMap().entrySet().stream() + .sorted(Comparator.comparing(entry -> entry.getKey().toString())) + .forEach(entry -> { + InternalLogger.getInstance().debug("- %s: %d failed display" + (entry.getValue().size() == 1 ? "" : "s"), entry.getKey(), entry.getValue().size()); + for (Display display : entry.getValue()) { + this.displaysHolder.remove(display); + } + }); + } + + @Override + public void postStage(ReloadStage stage) { + if (stage != ReloadStage.END) return; + Internal |
