diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-06-17 17:10:42 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2022-06-28 03:21:12 +0800 |
| commit | 1f6fa90304e68e3a682a85c6a3a84d87f5fb6798 (patch) | |
| tree | 8e5b42e0123332530e8d3622a8ffd860fee3ce8c /runtime | |
| parent | c20ebf2a0ee9de73c72b80fd10fd09bed6f041b4 (diff) | |
| download | RoughlyEnoughItems-1f6fa90304e68e3a682a85c6a3a84d87f5fb6798.tar.gz RoughlyEnoughItems-1f6fa90304e68e3a682a85c6a3a84d87f5fb6798.tar.bz2 RoughlyEnoughItems-1f6fa90304e68e3a682a85c6a3a84d87f5fb6798.zip | |
Fix #864
Diffstat (limited to 'runtime')
6 files changed, 203 insertions, 24 deletions
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 f2f9ad795..a56ecd3aa 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 @@ -190,6 +190,18 @@ public class ConfigManagerImpl implements ConfigManager { } }); + // CompoundTag + builder.registerSerializer(CompoundTag.class, (value, marshaller) -> { + return marshaller.serialize(value.toString()); + }); + builder.registerDeserializer(String.class, CompoundTag.class, (value, marshaller) -> { + try { + return TagParser.parseTag(value); + } catch (CommandSyntaxException e) { + throw new DeserializationException(e); + } + }); + // EntryStackProvider builder.registerSerializer(EntryStackProvider.class, (stack, marshaller) -> { try { 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 0bfa01856..1ec1b4fb1 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 @@ -39,6 +39,7 @@ import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Mth; import net.minecraft.world.level.GameType; import org.jetbrains.annotations.ApiStatus; @@ -369,12 +370,16 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @Override public List<FavoriteEntry> getFavoriteEntries() { return basics.favorites; - } + } public List<FavoriteEntry> getHiddenFavoriteEntries() { return basics.hiddenFavorites; } + public List<CompoundTag> getDisplayHistory() { + return basics.displayHistory; + } + @Override public List<EntryStackProvider<?>> getFilteredStackProviders() { return advanced.filtering.filteredStacks; @@ -531,6 +536,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { public static class Basics { @ConfigEntry.Gui.Excluded public List<FavoriteEntry> favorites = new ArrayList<>(); @ConfigEntry.Gui.Excluded public List<FavoriteEntry> hiddenFavorites = new ArrayList<>(); + @ConfigEntry.Gui.Excluded public List<CompoundTag> displayHistory = new ArrayList<>(); @Comment("Declares whether cheating mode is on.") @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON) private CheatingMode cheating = CheatingMode.OFF; private boolean favoritesEnabled = true; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java index d77bd67d9..c2b9782b2 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java @@ -53,6 +53,7 @@ import me.shedaniel.rei.impl.client.config.ConfigManagerImpl; import me.shedaniel.rei.impl.client.config.ConfigObjectImpl; import me.shedaniel.rei.impl.client.favorites.FavoriteEntryTypeRegistryImpl; import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; +import me.shedaniel.rei.impl.client.gui.widget.favorites.history.DisplayHistoryManager; import me.shedaniel.rei.impl.client.gui.widget.favorites.history.DisplayHistoryWidget; import me.shedaniel.rei.impl.client.gui.widget.favorites.listeners.FavoritesRegionListener; import me.shedaniel.rei.impl.client.gui.widget.favorites.listeners.FavoritesSystemRegionListener; @@ -190,7 +191,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableCo boolean draggingDisplay = DraggingContext.getInstance().isDraggingComponent() && DraggingContext.getInstance().getDragged().get() instanceof Display; int topOffsetHeight = 0; - this.favoritesBounds = displayHistory.getEntries().isEmpty() && !draggingDisplay + this.favoritesBounds = DisplayHistoryManager.INSTANCE.getEntries(displayHistory).isEmpty() && !draggingDisplay ? fullBounds : RectangleUtils.excludeZones(this.fullBounds, Stream.of(displayHistory.createBounds(this.excludedBounds))); systemRegion.getBounds().setBounds(this.favoritesBounds.x, this.favoritesBounds.y + 1, this.favoritesBounds.width, Math.max(1, systemRegion.scrolling.getMaxScrollHeight())); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayEntry.java index 96eb61220..0bf8e2dc4 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayEntry.java @@ -43,26 +43,39 @@ import me.shedaniel.rei.impl.client.gui.widget.EntryWidget; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.UUID; public class DisplayEntry extends WidgetWithBounds { private final LazyResettable<List<Widget>> widgets = new LazyResettable<>(this::setupWidgets); private final DisplayHistoryWidget parent; private final Display display; private final Dimension size = new Dimension(1, 1); + private boolean hasInitialBounds; private final ValueAnimator<FloatingRectangle> bounds = ValueAnimator.ofFloatingRectangle(); private final Button plusButton; private double xOffset = 0; private boolean reachedStable = false; + private UUID uuid = UUID.randomUUID(); - public DisplayEntry(DisplayHistoryWidget parent, Display display, Rectangle initialBounds) { + public DisplayEntry(DisplayHistoryWidget parent, Display display, @Nullable Rectangle initialBounds) { this.display = display; this.parent = parent; - this.bounds.setAs(initialBounds.getFloatingBounds()); - this.plusButton = Widgets.createButton(new Rectangle(initialBounds.getMaxX() - 16, initialBounds.getMaxY() - 16, 10, 10), Component.literal("+")); + this.hasInitialBounds = initialBounds != null; + if (this.hasInitialBounds) { + this.bounds.setAs(initialBounds.getFloatingBounds()); + this.plusButton = Widgets.createButton(new Rectangle(initialBounds.getMaxX() - 16, initialBounds.getMaxY() - 16, 10, 10), Component.literal("+")); + } else { + this.plusButton = Widgets.createButton(new Rectangle(-1000, -1000, 10, 10), new TextComponent("+")); + } + } + + public UUID getUuid() { + return uuid; } public void markBoundsDirty() { @@ -85,10 +98,15 @@ public class DisplayEntry extends WidgetWithBounds { float x = parentBounds.getCenterX() - displayBounds.width / 2 * scale; float y = parentBounds.getCenterY() - displayBounds.height / 2 * scale; FloatingRectangle newBounds = new Rectangle(x, y, displayBounds.width * scale, displayBounds.height * scale).getFloatingBounds(); - if (this.size.width == 1 && this.size.height == 1) { - this.bounds.setTo(newBounds, 700); + if (hasInitialBounds) { + if (this.size.width == 1 && this.size.height == 1) { + this.bounds.setTo(newBounds, 700); + } else { + this.bounds.setAs(newBounds); + } } else { this.bounds.setAs(newBounds); + hasInitialBounds = true; } this.size.setSize(displayBounds.getSize()); return widgets; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryManager.java new file mode 100644 index 000000000..7f98c3122 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryManager.java @@ -0,0 +1,141 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 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.widget.favorites.history; + +import com.google.common.collect.Iterables; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.display.DisplaySerializerRegistry; +import me.shedaniel.rei.api.common.plugins.PluginManager; +import me.shedaniel.rei.impl.client.config.ConfigManagerImpl; +import me.shedaniel.rei.impl.common.InternalLogger; +import net.minecraft.Util; +import net.minecraft.nbt.CompoundTag; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class DisplayHistoryManager { + public static final DisplayHistoryManager INSTANCE = new DisplayHistoryManager(); + private Map<String, DisplayEntry> entries = new LinkedHashMap<>(); + private long lastCheckTime = -1; + + public Collection<DisplayEntry> getEntries(DisplayHistoryWidget parent) { + if ((lastCheckTime == -1 || Util.getMillis() - lastCheckTime > 4000) && !PluginManager.areAnyReloading()) { + updateEntries(parent); + lastCheckTime = Util.getMillis(); + } + + return Collections.unmodifiableCollection(entries.values()); + } + + private void updateEntries(DisplayHistoryWidget parent) { + List<CompoundTag> displayHistory = ConfigManagerImpl.getInstance().getConfig().getDisplayHistory(); + Map<String, DisplayEntry> copy = new LinkedHashMap<>(entries); + entries.clear(); + for (CompoundTag tag : displayHistory) { + String uuid = tag.getString("DisplayHistoryUUID"); + + DisplayEntry entry = copy.get(uuid); + if (entry != null) { + entries.put(entry.getUuid().toString(), entry); + } else if (tag.getBoolean("DisplayHistoryContains")) { + try { + CategoryIdentifier<?> categoryIdentifier = CategoryIdentifier.of(tag.getString("DisplayHistoryCategory")); + if (CategoryRegistry.getInstance().tryGet(categoryIdentifier).isPresent()) { + Display display = DisplaySerializerRegistry.getInstance().read(categoryIdentifier, tag.getCompound("DisplayHistoryData")); + DisplayEntry newEntry = new DisplayEntry(parent, display, null); + entries.put(newEntry.getUuid().toString(), newEntry); + } + } catch (Exception e) { + InternalLogger.getInstance().warn("Failed to read display history entry", e); + } + } + } + } + + public void removeEntry(DisplayEntry entry) { + this.entries.remove(entry.getUuid().toString()); + List<CompoundTag> displayHistory = ConfigManagerImpl.getInstance().getConfig().getDisplayHistory(); + displayHistory.removeIf(tag -> tag.getString("DisplayHistoryUUID").equals(entry.getUuid().toString())); + save(); + } + + public void addEntry(DisplayHistoryWidget parent, @Nullable Rectangle bounds, Display display) { + List<CompoundTag> displayHistory = ConfigManagerImpl.getInstance().getConfig().getDisplayHistory(); + Iterator<DisplayEntry> iterator = this.entries.values().iterator(); + while (iterator.hasNext()) { + DisplayEntry entry = iterator.next(); + if (entry.getDisplay() == display) { + displayHistory.removeIf(tag -> tag.getString("DisplayHistoryUUID").equals(entry.getUuid().toString())); + iterator.remove(); + } + } + DisplayEntry newEntry = new DisplayEntry(parent, display, bounds); + Map<String, DisplayEntry> copy = new LinkedHashMap<>(); + copy.put(newEntry.getUuid().toString(), newEntry); + copy.putAll(this.entries); + this.entries = copy; + while (entries.size() >= 10) { + DisplayEntry entry = Iterables.get(entries.values(), entries.size() - 1); + displayHistory.removeIf(tag -> tag.getString("DisplayHistoryUUID").equals(entry.getUuid().toString())); + this.entries.remove(entry.getUuid().toString()); + } + + CompoundTag compoundTag = new CompoundTag(); + compoundTag.putBoolean("DisplayHistoryContains", false); + compoundTag.putString("DisplayHistoryUUID", newEntry.getUuid().toString()); + compoundTag.putString("DisplayHistoryCategory", display.getCategoryIdentifier().toString()); + displayHistory.add(compoundTag); + + save(); + } + + private void save() { + List<CompoundTag> displayHistory = ConfigManagerImpl.getInstance().getConfig().getDisplayHistory(); + for (CompoundTag compoundTag : displayHistory) { + String uuid = compoundTag.getString("DisplayHistoryUUID"); + DisplayEntry entry = entries.get(uuid); + + if (entry != null) { + compoundTag.putBoolean("DisplayHistoryContains", false); + Display display = entry.getDisplay(); + boolean hasSerializer = DisplaySerializerRegistry.getInstance().hasSerializer(display.getCategoryIdentifier()); + + if (hasSerializer) { + try { + compoundTag.put("DisplayHistoryData", DisplaySerializerRegistry.getInstance().save(display, new CompoundTag())); + compoundTag.putBoolean("DisplayHistoryContains", true); + } catch (Exception e) { + InternalLogger.getInstance().warn("Failed to save display history entry", e); + } + } + } + } + + ConfigManagerImpl.getInstance().saveConfig(); + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryWidget.java index 307631c62..6c95663aa 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryWidget.java @@ -23,7 +23,6 @@ package me.shedaniel.rei.impl.client.gui.widget.favorites.history; -import com.google.common.collect.Iterables; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; import com.mojang.math.Matrix4f; @@ -53,6 +52,7 @@ import net.minecraft.util.Mth; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -62,7 +62,6 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC private final Rectangle bounds = new Rectangle(); private final NumberAnimator<Double> height; - private final List<DisplayEntry> entries = new ArrayList<>(); private final NumberAnimator<Double> scroll = ValueAnimator.ofDouble(); public DisplayHistoryWidget(FavoritesListWidget parent) { @@ -82,13 +81,10 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC return bounds; } - public List<DisplayEntry> getEntries() { - return entries; - } - @Override public void render(PoseStack poses, int mouseX, int mouseY, float delta) { Rectangle fullBounds = parent.excludedBounds; + List<DisplayEntry> entries = new ArrayList<>(DisplayHistoryManager.INSTANCE.getEntries(this)); if (updateBounds(fullBounds)) { for (DisplayEntry entry : entries) { entry.markBoundsDirty(); @@ -209,7 +205,7 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC this.scroll.update(delta); if (this.scroll.target() >= 0 && this.scroll.target() <= getMaxScrollDist()) { - if (entries.size() > 1) { + if (DisplayHistoryManager.INSTANCE.getEntries(this).size() > 1) { int before = (int) (Math.floor(this.scroll.target() / getBounds().getWidth()) * getBounds().getWidth()); int after = (int) (Math.ceil(this.scroll.target() / getBounds().getWidth()) * getBounds().getWidth()); if (before <= this.scroll.target() && after >= this.scroll.target()) { @@ -226,6 +222,7 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC } public int getContentHeight() { + Collection<DisplayEntry> entries = DisplayHistoryManager.INSTANCE.getEntries(this); if (entries.isEmpty()) return 0; return getBounds().getWidth() * entries.size(); } @@ -241,6 +238,8 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC @Override public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + Collection<DisplayEntry> entries = DisplayHistoryManager.INSTANCE.getEntries(this); + if (containsMouse(mouseX, mouseY)) { for (DisplayEntry entry : entries) { if (!entry.isStable()) { @@ -263,7 +262,7 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { - for (DisplayEntry entry : entries) { + for (DisplayEntry entry : DisplayHistoryManager.INSTANCE.getEntries(this)) { if (entry.mouseClicked(mouseX, mouseY, button)) { return true; } @@ -274,6 +273,8 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { + Collection<DisplayEntry> entries = DisplayHistoryManager.INSTANCE.getEntries(this); + for (DisplayEntry entry : entries) { if (entry.mouseReleased(mouseX, mouseY, button)) { return true; @@ -287,7 +288,7 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC double xOffset = -this.scroll.value(); for (DisplayEntry entry : entries) { if (entry.isStable() && entry.getBounds().contains(mouse.x + xOffset, mouse.y)) { - entries.remove(entry); + DisplayHistoryManager.INSTANCE.removeEntry(entry); scroll.setAs(scroll.target() - getBounds().getWidth()); scroll.setTo(scroll.target() + getBounds().getWidth(), 800); DisplayCompositeWidget.DisplayDraggableComponent component = new DisplayCompositeWidget.DisplayDraggableComponent(Widgets.concat(entry.getWidgets()), entry.getDisplay(), @@ -305,6 +306,8 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + Collection<DisplayEntry> entries = DisplayHistoryManager.INSTANCE.getEntries(this); + for (DisplayEntry entry : entries) { if (entry.keyPressed(keyCode, scanCode, modifiers)) { return true; @@ -318,7 +321,7 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC double xOffset = -this.scroll.value(); for (DisplayEntry entry : entries) { if (entry.isStable() && entry.getBounds().contains(mouse.x + xOffset, mouse.y)) { - entries.remove(entry); + DisplayHistoryManager.INSTANCE.removeEntry(entry); scroll.setAs(scroll.target() - getBounds().getWidth()); scroll.setTo(scroll.target() + getBounds().getWidth(), 800); DisplayCompositeWidget.DisplayDraggableComponent component = new DisplayCompositeWidget.DisplayDraggableComponent(Widgets.concat(entry.getWidgets()), entry.getDisplay(), @@ -347,14 +350,10 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC }) ? DraggedAcceptorResult.CONSUMED : DraggedAcceptorResult.PASS; } - public void addDisplay(Rectangle bounds, Display display) { - this.entries.removeIf(displayEntry -> displayEntry.getDisplay() == display); - this.entries.add(0, new DisplayEntry(this, display, bounds)); + public void addDisplay(@Nullable Rectangle bounds, Display display) { + DisplayHistoryManager.INSTANCE.addEntry(this, bounds, display); this.scroll.setAs(this.scroll.target() + getBounds().getWidth()); this.scroll.setTo(0, 800); - while (entries.size() >= 10) { - entries.remove(Iterables.get(entries, entries.size() - 1)); - } } @Override @@ -362,6 +361,8 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC public DraggableComponent<Display> getHovered(DraggingContext<Screen> context, double mouseX, double mouseY) { if (containsMouse(mouseX, mouseY)) { double xOffset = -this.scroll.value(); + Collection<DisplayEntry> entries = DisplayHistoryManager.INSTANCE.getEntries(this); + for (DisplayEntry entry : entries) { if (entry.isStable() && entry.getBounds().contains(mouseX + xOffset, mouseY)) { return new DisplayCompositeWidget.DisplayDraggableComponent(Widgets.concat(entry.getWidgets()), entry.getDisplay(), @@ -369,7 +370,7 @@ public class DisplayHistoryWidget extends WidgetWithBounds implements DraggableC new Rectangle(0, 0, entry.getSize().width, entry.getSize().height)) { @Override public void drag() { - entries.remove(entry); + DisplayHistoryManager.INSTANCE.removeEntry(entry); scroll.setAs(scroll.target() - getBounds().getWidth()); scroll.setTo(scroll.target() + getBounds().getWidth(), 800); } |
