aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/main/java/me/shedaniel/rei/impl/client
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2021-10-28 15:12:18 +0800
committershedaniel <daniel@shedaniel.me>2021-10-28 15:12:18 +0800
commit6b44b3e633e009d9d3fdedfa02b46db34dd5b1ae (patch)
treed00eaeabc27639a717593d0613c7a381fb341eb9 /runtime/src/main/java/me/shedaniel/rei/impl/client
parente3eebe08fac49d1924670565bc4e34b151ef395d (diff)
parentb68e07108e21e4f1f231dfccac6c095c22b9a695 (diff)
downloadRoughlyEnoughItems-6b44b3e633e009d9d3fdedfa02b46db34dd5b1ae.tar.gz
RoughlyEnoughItems-6b44b3e633e009d9d3fdedfa02b46db34dd5b1ae.tar.bz2
RoughlyEnoughItems-6b44b3e633e009d9d3fdedfa02b46db34dd5b1ae.zip
Merge remote-tracking branch 'origin/6.x-1.17' into 7.x-1.18
# Conflicts: # gradle.properties # settings.gradle
Diffstat (limited to 'runtime/src/main/java/me/shedaniel/rei/impl/client')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/ErrorDisplayer.java13
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java5
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/renderer/EntryRendererRegistryImpl.java66
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java9
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/PerformanceScreen.java193
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/EntryListEntry.java71
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/PerformanceEntry.java93
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/SubCategoryListEntry.java177
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java41
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java17
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java130
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/UncertainDisplayViewingScreen.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java23
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java9
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java23
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ExclusionZonesImpl.java36
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java11
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/util/CrashReportUtils.java7
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java14
25 files changed, 851 insertions, 103 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/ErrorDisplayer.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/ErrorDisplayer.java
index 12bf9da50..7fb13845a 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/ErrorDisplayer.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/ErrorDisplayer.java
@@ -29,7 +29,7 @@ import me.shedaniel.rei.impl.client.gui.screen.WarningAndErrorScreen;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
-import java.util.function.Consumer;
+import java.util.function.UnaryOperator;
public class ErrorDisplayer {
public void onInitializeClient() {
@@ -46,18 +46,15 @@ public class ErrorDisplayer {
}
});
warningAndErrorScreen.setParent(screen);
- try {
- if (minecraft.screen != null) minecraft.screen.removed();
- } catch (Throwable ignored) {
- }
- minecraft.screen = null;
- minecraft.setScreen(warningAndErrorScreen);
+ return warningAndErrorScreen;
}
+
+ return null;
});
}
@ExpectPlatform
- public static void registerGuiInit(Consumer<Screen> consumer) {
+ public static void registerGuiInit(UnaryOperator<Screen> consumer) {
throw new AssertionError();
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java
index 07a94a0b3..e80e5f572 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java
@@ -43,6 +43,7 @@ import me.shedaniel.rei.api.common.registry.ReloadStage;
import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl;
import me.shedaniel.rei.impl.client.gui.hints.HintProvider;
import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField;
+import me.shedaniel.rei.impl.client.search.argument.Argument;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
@@ -216,6 +217,7 @@ public class REIRuntimeImpl implements REIRuntime {
@Override
public void startReload() {
+ Argument.SEARCH_CACHE.clear();
getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay);
lastDisplayScreen.clear();
}
@@ -227,6 +229,7 @@ public class REIRuntimeImpl implements REIRuntime {
@Override
public void endReload(ReloadStage stage) {
+ Argument.SEARCH_CACHE.clear();
getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay);
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java
index f582734e2..e6eefa6b6 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java
@@ -63,6 +63,7 @@ import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule;
import me.shedaniel.rei.impl.client.entry.filtering.rules.ManualFilteringRule;
import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl;
import me.shedaniel.rei.impl.client.gui.credits.CreditsScreen;
+import me.shedaniel.rei.impl.client.gui.performance.entry.PerformanceEntry;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.ChatFormatting;
@@ -340,6 +341,7 @@ public class ConfigManagerImpl implements ConfigManager {
builder.setGlobalizedExpanded(false);
if (Minecraft.getInstance().getConnection() != null && Minecraft.getInstance().getConnection().getRecipeManager() != null) {
builder.getOrCreateCategory(new TranslatableComponent("config.roughlyenoughitems.advanced")).getEntries().add(0, new ReloadPluginsEntry(220));
+ builder.getOrCreateCategory(new TranslatableComponent("config.roughlyenoughitems.advanced")).getEntries().add(0, new PerformanceEntry(220));
}
return builder.setAfterInitConsumer(screen -> {
TextListEntry feedbackEntry = ConfigEntryBuilder.create().startTextDescription(
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
index 089819553..fba1fd4c2 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
@@ -493,7 +493,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
@ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
private EntryPanelOrderingConfig entryPanelOrdering = EntryPanelOrderingConfig.REGISTRY_ASCENDING;
@Comment("Declares the maximum amount of recipes displayed in a page if possible.") @ConfigEntry.BoundedDiscrete(min = 2, max = 99)
- private int maxRecipesPerPage = 15;
+ private int maxRecipesPerPage = 3;
@Comment("Declares whether entry rendering time should be debugged.") private boolean debugRenderTimeRequired = false;
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java
index a96680983..6452e883c 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java
@@ -48,7 +48,10 @@ import java.util.Optional;
@ApiStatus.Internal
public class ReloadPluginsEntry extends AbstractConfigListEntry<Unit> {
private int width;
- private AbstractWidget buttonWidget = new Button(0, 0, 0, 20, NarratorChatListener.NO_TITLE, button -> RoughlyEnoughItemsCoreClient.reloadPlugins(null, null)) {
+ private AbstractWidget buttonWidget = new Button(0, 0, 0, 20, NarratorChatListener.NO_TITLE, button -> {
+ RoughlyEnoughItemsCore.PERFORMANCE_LOGGER.clear();
+ RoughlyEnoughItemsCoreClient.reloadPlugins(null, null);
+ }) {
@Override
public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
if (PluginManager.areAnyReloading()) {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java
index 3bf154c6b..1d52db2d9 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java
@@ -46,7 +46,7 @@ public class FilteringContextImpl implements FilteringContext {
public final Map<FilteringContextType, Set<HashedEntryStackWrapper>> stacks;
private final Map<FilteringContextType, Collection<EntryStack<?>>> cachedStacks;
- public FilteringContextImpl(List<EntryStack<?>> allStacks) {
+ public FilteringContextImpl(Collection<EntryStack<?>> allStacks) {
this.stacks = Maps.newHashMap();
this.cachedStacks = Maps.newHashMap();
for (FilteringContextType type : FilteringContextType.values()) {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/renderer/EntryRendererRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/renderer/EntryRendererRegistryImpl.java
new file mode 100644
index 000000000..62b3235a2
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/renderer/EntryRendererRegistryImpl.java
@@ -0,0 +1,66 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.entry.renderer;
+
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
+import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer;
+import me.shedaniel.rei.api.client.entry.renderer.EntryRendererProvider;
+import me.shedaniel.rei.api.client.entry.renderer.EntryRendererRegistry;
+import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
+import me.shedaniel.rei.api.common.entry.EntryStack;
+import me.shedaniel.rei.api.common.entry.type.EntryType;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Objects;
+
+public class EntryRendererRegistryImpl implements EntryRendererRegistry {
+ private final Multimap<EntryType<?>, EntryRendererProvider<?>> providers = Multimaps.newListMultimap(new Reference2ObjectOpenHashMap<>(), ArrayList::new);
+
+ @Override
+ public <T> void register(EntryType<T> type, EntryRendererProvider<T> provider) {
+ this.providers.put(type, provider);
+ }
+
+ @Override
+ public <T> EntryRenderer<T> get(EntryStack<T> stack) {
+ EntryRenderer<T> renderer = stack.getDefinition().getRenderer();
+ for (EntryRendererProvider<T> provider : (Collection<EntryRendererProvider<T>>) (Collection<? extends EntryRendererProvider<?>>) providers.get(stack.getType())) {
+ renderer = Objects.requireNonNull(provider.provide(stack, renderer));
+ }
+ return renderer;
+ }
+
+ @Override
+ public void startReload() {
+ providers.clear();
+ }
+
+ @Override
+ public void acceptPlugin(REIClientPlugin plugin) {
+ plugin.registerEntryRenderers(this);
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java
index b8525b6dc..04901ba45 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java
@@ -58,7 +58,6 @@ import me.shedaniel.rei.api.common.plugins.PluginManager;
import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.api.common.util.EntryStacks;
import me.shedaniel.rei.api.common.util.ImmutableTextComponent;
-import me.shedaniel.rei.impl.ClientInternals;
import me.shedaniel.rei.impl.client.ClientHelperImpl;
import me.shedaniel.rei.impl.client.REIRuntimeImpl;
import me.shedaniel.rei.impl.client.gui.craftable.CraftableFilter;
@@ -70,29 +69,24 @@ import me.shedaniel.rei.impl.client.gui.widget.FavoritesListWidget;
import me.shedaniel.rei.impl.client.gui.widget.InternalWidgets;
import me.shedaniel.rei.impl.client.gui.widget.LateRenderable;
import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField;
-import me.shedaniel.rei.impl.client.search.argument.Argument;
import me.shedaniel.rei.impl.common.util.Weather;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.chat.NarratorChatListener;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
-import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.PlayerInfo;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
-import net.minecraft.locale.Language;
import net.minecraft.network.chat.Component;
-import net.minecraft.network.chat.Style;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.inventory.Slot;
-import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.Blocks;
@@ -102,8 +96,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
@ApiStatus.Internal
public class ScreenOverlayImpl extends ScreenOverlay {
@@ -225,7 +217,6 @@ public class ScreenOverlayImpl extends ScreenOverlay {
}
public void init() {
- Argument.SEARCH_CACHE.clear();
draggingStack.set(DraggableStackProvider.from(() -> ScreenRegistry.getInstance().getDraggableProviders()),
DraggableStackVisitor.from(() -> ScreenRegistry.getInstance().getDraggableVisitors()));
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
new file mode 100644
index 000000000..92bfb78be
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/PerformanceScreen.java
@@ -0,0 +1,193 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.vertex.PoseStack;
+import com.mojang.datafixers.util.Pair;
+import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget;
+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.impl.client.gui.performance.entry.EntryListEntry;
+import me.shedaniel.rei.impl.client.gui.performance.entry.SubCategoryListEntry;
+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.network.chat.TextComponent;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.util.FormattedCharSequence;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static java.util.concurrent.TimeUnit.*;
+
+@Environment(EnvType.CLIENT)
+public class PerformanceScreen extends Screen {
+ private Screen parent;
+
+ public PerformanceScreen(Screen parent) {
+ super(new TranslatableComponent("text.rei.performance"));
+ this.parent = parent;
+ }
+
+ private PerformanceEntryListWidget list;
+
+ /*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+ public static FormattedCharSequence formatTime(long time, boolean total) {
+ TimeUnit unit = chooseUnit(time);
+ double value = (double) time / NANOSECONDS.convert(1, unit);
+ return new TextComponent(String.format(Locale.ROOT, "%.4g", value) + " " + abbreviate(unit))
+ .withStyle(style -> style.withColor(TextColor.fromRgb(chooseColor(MILLISECONDS.convert(time, NANOSECONDS), total))))
+ .getVisualOrderText();
+ }
+
+ private static int chooseColor(long time, boolean total) {
+ if (time > (total ? 2500 : 1000)) {
+ return 0xff5555;
+ } else if (time > (total ? 700 : 300)) {
+ return 0xffa600;
+ } else if (time > (total ? 200 : 100)) {
+ return 0xfff017;
+ }
+ return 0x12ff22;
+ }
+
+ private static TimeUnit chooseUnit(long nanos) {
+ if (DAYS.convert(nanos, NANOSECONDS) > 0) {
+ return DAYS;
+ }
+ if (HOURS.convert(nanos, NANOSECONDS) > 0) {
+ return HOURS;
+ }
+ if (MINUTES.convert(nanos, NANOSECONDS) > 0) {
+ return MINUTES;
+ }
+ if (SECONDS.convert(nanos, NANOSECONDS) > 0) {
+ return SECONDS;
+ }
+ if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) {
+ return MILLISECONDS;
+ }
+ if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) {
+ return MICROSECONDS;
+ }
+ return NANOSECONDS;
+ }
+
+ private static String abbreviate(TimeUnit unit) {
+ switch (unit) {
+ case NANOSECONDS:
+ return "ns";
+ case MICROSECONDS:
+ return "\u03bcs"; // μs
+ case MILLISECONDS:
+ return "ms";
+ case SECONDS:
+ return "s";
+ case MINUTES:
+ return "min";
+ case HOURS:
+ return "h";
+ case DAYS:
+ return "d";
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @Override
+ public void init() {
+ {
+ Component backText = new TextComponent("↩ ").append(new TranslatableComponent("gui.back"));
+ addRenderableWidget(new Button(4, 4, Minecraft.getInstance().font.width(backText) + 10, 20, backText, button -> {
+ minecraft.setScreen(parent);
+ this.parent = null;
+ }));
+ }
+ list = new PerformanceEntryListWidget();
+ RoughlyEnoughItemsCore.PERFORMANCE_LOGGER.getStages().forEach((stage, inner) -> {
+ List<EntryListEntry> entries = new ArrayList<>();
+ inner.times().forEach((obj, time) -> {
+ entries.add(new EntryListEntry(new TextComponent(obj instanceof Pair ? ((Pair<REIPluginProvider<?>, REIPlugin<?>>) obj).getFirst().getPluginProviderName() : Objects.toString(obj)), time));
+ });
+ long separateTime = inner.times().values().stream().collect(Collectors.summarizingLong(value -> value)).getSum();
+ if ((inner.totalNano() - separateTime) > 1000000) {
+ entries.add(new EntryListEntry(new TextComponent("Miscellaneous Operations"), inner.totalNano() - separateTime));
+ }
+ entries.sort(Comparator.<EntryListEntry>comparingLong(value -> value.time).reversed());
+ list.addItem(new SubCategoryListEntry(new TextComponent(stage), (List<PerformanceScreen.PerformanceEntry>) (List<? extends PerformanceScreen.PerformanceEntry>) entries, inner.totalNano(), false));
+ });
+ addWidget(list);
+ }
+
+ @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 PerformanceEntry extends DynamicElementListWidget.ElementEntry<PerformanceEntry> {
+
+ }
+
+ private class PerformanceEntryListWidget extends DynamicElementListWidget<PerformanceEntry> {
+ public PerformanceEntryListWidget() {super(PerformanceScreen.this.minecraft, PerformanceScreen.this.width, PerformanceScreen.this.height, 30, PerformanceScreen.this.height, GuiComponent.BACKGROUND_LOCATION);}
+
+ @Override
+ public int getItemWidth() {
+ return width;
+ }
+
+ @Override
+ public int addItem(PerformanceEntry item) {
+ return super.addItem(item);
+ }
+
+ @Override
+ protected int getScrollbarPosition() {
+ return width - 6;
+ }
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/EntryListEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/EntryListEntry.java
new file mode 100644
index 000000000..5c2db0471
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/EntryListEntry.java
@@ -0,0 +1,71 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.entry;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.PoseStack;
+import me.shedaniel.rei.impl.client.gui.performance.PerformanceScreen;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.Minecraft;
+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.Collections;
+import java.util.List;
+
+@Environment(EnvType.CLIENT)
+public class EntryListEntry extends PerformanceScreen.PerformanceEntry {
+ private final Component name;
+ public final long time;
+
+ public EntryListEntry(Component name, long time) {
+ this.name = name;
+ this.time = time;
+ }
+
+ 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.name.getVisualOrderText(), (float) x, (float) (y + 6), -1);
+ FormattedCharSequence timeText = PerformanceScreen.formatTime(time, false);
+ Minecraft.getInstance().font.drawShadow(matrices, timeText, (float) x + entryWidth - 6 - 4 - Minecraft.getInstance().font.width(timeText), (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();
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/PerformanceEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/performance/entry/PerformanceEntry.java
new file mode 100644
index 000000000..99b84e