From 4efa61d47ca739cf655971a510fb779f88951bdd Mon Sep 17 00:00:00 2001 From: Dragon-Seeker Date: Fri, 5 Jul 2024 19:39:54 -0500 Subject: [PATCH 1/3] Reimplement the ability to wrap ItemGroups and adjust RegistryAccess to fix #252 --- .../owo/itemgroup/json/WrapperGroup.java | 11 ++- .../owo/mixin/SimpleRegistryMixin.java | 34 --------- .../owo/mixin/registry/ReferenceAccessor.java | 15 ++++ .../SimpleRegistryAccessor.java | 7 +- .../mixin/registry/SimpleRegistryMixin.java | 74 +++++++++++++++++++ .../wispforest/owo/util/RegistryAccess.java | 13 +--- .../pond/OwoSimpleRegistryExtensions.java | 12 +++ src/main/resources/owo.mixins.json | 5 +- .../tags/{items => item}/tab_2_content.json | 0 9 files changed, 116 insertions(+), 55 deletions(-) delete mode 100644 src/main/java/io/wispforest/owo/mixin/SimpleRegistryMixin.java create mode 100644 src/main/java/io/wispforest/owo/mixin/registry/ReferenceAccessor.java rename src/main/java/io/wispforest/owo/mixin/{ui => registry}/SimpleRegistryAccessor.java (68%) create mode 100644 src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryMixin.java create mode 100644 src/main/java/io/wispforest/owo/util/pond/OwoSimpleRegistryExtensions.java rename src/testmod/resources/data/uwu/tags/{items => item}/tab_2_content.json (100%) diff --git a/src/main/java/io/wispforest/owo/itemgroup/json/WrapperGroup.java b/src/main/java/io/wispforest/owo/itemgroup/json/WrapperGroup.java index c6ada99b..f9ad0aa3 100644 --- a/src/main/java/io/wispforest/owo/itemgroup/json/WrapperGroup.java +++ b/src/main/java/io/wispforest/owo/itemgroup/json/WrapperGroup.java @@ -1,17 +1,17 @@ package io.wispforest.owo.itemgroup.json; -import com.mojang.serialization.Lifecycle; import io.wispforest.owo.itemgroup.Icon; import io.wispforest.owo.itemgroup.OwoItemGroup; import io.wispforest.owo.itemgroup.gui.ItemGroupButton; import io.wispforest.owo.itemgroup.gui.ItemGroupTab; import io.wispforest.owo.mixin.itemgroup.ItemGroupAccessor; -import io.wispforest.owo.mixin.ui.SimpleRegistryAccessor; +import io.wispforest.owo.mixin.registry.SimpleRegistryAccessor; +import io.wispforest.owo.util.pond.OwoSimpleRegistryExtensions; import net.minecraft.item.ItemGroup; import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.SimpleRegistry; +import net.minecraft.registry.entry.RegistryEntryInfo; import net.minecraft.util.Identifier; import org.jetbrains.annotations.ApiStatus; @@ -34,9 +34,8 @@ public WrapperGroup(ItemGroup parent, Identifier parentId, List ta int parentRawId = Registries.ITEM_GROUP.getRawId(parent); - // TODO: set doesn't exist anymore. figure out what to do. -// ((SimpleRegistryAccessor) Registries.ITEM_GROUP).owo$getValueToEntry().remove(parent); -// ((SimpleRegistry) Registries.ITEM_GROUP).set(parentRawId, RegistryKey.of(RegistryKeys.ITEM_GROUP, parentId), this, Lifecycle.stable()); + ((SimpleRegistryAccessor) Registries.ITEM_GROUP).owo$getValueToEntry().remove(parent); + ((OwoSimpleRegistryExtensions) Registries.ITEM_GROUP).owo$set(parentRawId, RegistryKey.of(RegistryKeys.ITEM_GROUP, parentId), this, RegistryEntryInfo.DEFAULT); ((ItemGroupAccessor) this).owo$setDisplayName(parent.getDisplayName()); ((ItemGroupAccessor) this).owo$setColumn(parent.getColumn()); diff --git a/src/main/java/io/wispforest/owo/mixin/SimpleRegistryMixin.java b/src/main/java/io/wispforest/owo/mixin/SimpleRegistryMixin.java deleted file mode 100644 index 997c5be3..00000000 --- a/src/main/java/io/wispforest/owo/mixin/SimpleRegistryMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.wispforest.owo.mixin; - -import io.wispforest.owo.util.RegistryAccess; -import net.minecraft.registry.SimpleRegistry; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.Map; - -@Mixin(SimpleRegistry.class) -public class SimpleRegistryMixin implements RegistryAccess.AccessibleRegistry { - - @Shadow - @Final - private Map> idToEntry; - - @Shadow - @Final - private Map> valueToEntry; - - @Override - public @Nullable RegistryEntry getEntry(Identifier id) { - return this.idToEntry.get(id); - } - - @Override - public @Nullable RegistryEntry getEntry(T value) { - return this.valueToEntry.get(value); - } -} diff --git a/src/main/java/io/wispforest/owo/mixin/registry/ReferenceAccessor.java b/src/main/java/io/wispforest/owo/mixin/registry/ReferenceAccessor.java new file mode 100644 index 00000000..09354e4d --- /dev/null +++ b/src/main/java/io/wispforest/owo/mixin/registry/ReferenceAccessor.java @@ -0,0 +1,15 @@ +package io.wispforest.owo.mixin.registry; + +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(RegistryEntry.Reference.class) +public interface ReferenceAccessor { + @Invoker("setRegistryKey") + void owo$setRegistryKey(RegistryKey registryKey); + + @Invoker("setValue") + void owo$setValue(T value); +} diff --git a/src/main/java/io/wispforest/owo/mixin/ui/SimpleRegistryAccessor.java b/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryAccessor.java similarity index 68% rename from src/main/java/io/wispforest/owo/mixin/ui/SimpleRegistryAccessor.java rename to src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryAccessor.java index a51860a5..b1219351 100644 --- a/src/main/java/io/wispforest/owo/mixin/ui/SimpleRegistryAccessor.java +++ b/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryAccessor.java @@ -1,8 +1,8 @@ -package io.wispforest.owo.mixin.ui; +package io.wispforest.owo.mixin.registry; -import com.mojang.serialization.Lifecycle; import net.minecraft.registry.SimpleRegistry; import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; @@ -10,8 +10,9 @@ @Mixin(SimpleRegistry.class) public interface SimpleRegistryAccessor { - @Accessor("valueToEntry") Map> owo$getValueToEntry(); + @Accessor("idToEntry") + Map> owo$getIdToEntry(); } diff --git a/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryMixin.java b/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryMixin.java new file mode 100644 index 00000000..93adc7ac --- /dev/null +++ b/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryMixin.java @@ -0,0 +1,74 @@ +package io.wispforest.owo.mixin.registry; + +import com.mojang.serialization.Lifecycle; +import io.wispforest.owo.util.OwoFreezer; +import io.wispforest.owo.util.pond.OwoSimpleRegistryExtensions; +import it.unimi.dsi.fastutil.objects.ObjectList; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; +import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback; +import net.minecraft.registry.MutableRegistry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.SimpleRegistry; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryInfo; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +@Mixin(SimpleRegistry.class) +public abstract class SimpleRegistryMixin implements MutableRegistry, OwoSimpleRegistryExtensions { + + @Shadow private Map> intrusiveValueToEntry; + @Shadow @Final private Map, RegistryEntry.Reference> keyToEntry; + @Shadow @Final private Map> idToEntry; + @Shadow @Final private Map> valueToEntry; + @Shadow @Final private ObjectList> rawIdToEntry; + @Shadow @Final private Reference2IntMap entryToRawId; + @Shadow @Final private Map, RegistryEntryInfo> keyToEntryInfo; + @Shadow private Lifecycle lifecycle; + + //-- + + /** + * Copy of the {@link SimpleRegistry#add} function but uses {@link List#set} instead of {@link List#add} for {@link SimpleRegistry#rawIdToEntry} + */ + public RegistryEntry.Reference owo$set(int id, RegistryKey arg, T object, RegistryEntryInfo arg2) { + OwoFreezer.checkRegister("Registry Set Calls"); //this.assertNotFrozen(arg); + + Objects.requireNonNull(arg); + Objects.requireNonNull(object); + + RegistryEntry.Reference reference; + + if (this.intrusiveValueToEntry != null) { + reference = this.intrusiveValueToEntry.remove(object); + + if (reference == null) { + throw new AssertionError("Missing intrusive holder for " + arg + ":" + object); + } + + ((ReferenceAccessor) reference).owo$setRegistryKey(arg); + } else { + reference = this.keyToEntry.computeIfAbsent(arg, k -> RegistryEntry.Reference.standAlone(this.getEntryOwner(), k)); + ((ReferenceAccessor) reference).owo$setValue((T)object); + } + + this.keyToEntry.put(arg, reference); + this.idToEntry.put(arg.getValue(), reference); + this.valueToEntry.put(object, reference); + this.rawIdToEntry.set(id, reference); + this.entryToRawId.put(object, id); + this.keyToEntryInfo.put(arg, arg2); + this.lifecycle = this.lifecycle.add(arg2.lifecycle()); + + // TODO: SHOULD WE BE REFIREING THE EVENT? + RegistryEntryAddedCallback.event(this).invoker().onEntryAdded(id, arg.getValue(), (T)object); + + return reference; + } +} diff --git a/src/main/java/io/wispforest/owo/util/RegistryAccess.java b/src/main/java/io/wispforest/owo/util/RegistryAccess.java index a090e109..04c229b5 100644 --- a/src/main/java/io/wispforest/owo/util/RegistryAccess.java +++ b/src/main/java/io/wispforest/owo/util/RegistryAccess.java @@ -1,7 +1,7 @@ package io.wispforest.owo.util; +import io.wispforest.owo.mixin.registry.SimpleRegistryAccessor; import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; import net.minecraft.util.Identifier; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.SimpleRegistry; @@ -23,7 +23,7 @@ private RegistryAccess() {} @SuppressWarnings("unchecked") public static RegistryEntry getEntry(Registry registry, Identifier id) { checkSimple(registry); - return ((AccessibleRegistry) registry).getEntry(id); + return ((SimpleRegistryAccessor) registry).owo$getIdToEntry().get(id); } /** @@ -38,7 +38,7 @@ public static RegistryEntry getEntry(Registry registry, Identifier id) @SuppressWarnings("unchecked") public static RegistryEntry getEntry(Registry registry, T value) { checkSimple(registry); - return ((AccessibleRegistry) registry).getEntry(value); + return ((SimpleRegistryAccessor) registry).owo$getValueToEntry().get(value); } private static void checkSimple(Registry registry) { @@ -46,11 +46,4 @@ private static void checkSimple(Registry registry) { throw new IllegalArgumentException("[RegistryAccess] Tried to operate on Registry of class '" + registry.getClass() + "', but only 'SimpleRegistry' and descendants are supported"); } - - public interface AccessibleRegistry { - @Nullable RegistryEntry getEntry(Identifier id); - - @Nullable RegistryEntry getEntry(T value); - } - } diff --git a/src/main/java/io/wispforest/owo/util/pond/OwoSimpleRegistryExtensions.java b/src/main/java/io/wispforest/owo/util/pond/OwoSimpleRegistryExtensions.java new file mode 100644 index 00000000..2b7cc077 --- /dev/null +++ b/src/main/java/io/wispforest/owo/util/pond/OwoSimpleRegistryExtensions.java @@ -0,0 +1,12 @@ +package io.wispforest.owo.util.pond; + +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryInfo; +import org.jetbrains.annotations.ApiStatus; + +public interface OwoSimpleRegistryExtensions { + + @ApiStatus.Internal + RegistryEntry.Reference owo$set(int id, RegistryKey arg, T object, RegistryEntryInfo arg2); +} diff --git a/src/main/resources/owo.mixins.json b/src/main/resources/owo.mixins.json index 4f60f67d..ec8f45f2 100644 --- a/src/main/resources/owo.mixins.json +++ b/src/main/resources/owo.mixins.json @@ -20,7 +20,6 @@ "ServerPlayerEntityMixin", "ServerPlayerInteractionManagerMixin", "SetComponentsLootFunctionAccessor", - "SimpleRegistryMixin", "TagGroupLoaderMixin", "itemgroup.ItemGroupAccessor", "itemgroup.ItemMixin", @@ -30,13 +29,15 @@ "offline.WorldSaveHandlerMixin", "recipe_remainders.CraftingResultSlotMixin", "recipe_remainders.RecipeManagerMixin", + "registry.SimpleRegistryAccessor", + "registry.SimpleRegistryMixin", + "registry.ReferenceAccessor", "text.LanguageMixin", "text.TextCodecsMixin", "text.TranslatableTextContentMixin", "text.stapi.SystemDelegatedLanguageFixin", "tweaks.EulaReaderMixin", "tweaks.LevelInfoMixin", - "ui.SimpleRegistryAccessor", "ui.SlotAccessor", "ui.SlotMixin", "ui.access.BlockEntityAccessor" diff --git a/src/testmod/resources/data/uwu/tags/items/tab_2_content.json b/src/testmod/resources/data/uwu/tags/item/tab_2_content.json similarity index 100% rename from src/testmod/resources/data/uwu/tags/items/tab_2_content.json rename to src/testmod/resources/data/uwu/tags/item/tab_2_content.json From af7f7c58752736234603a86cc7bdf03aeef38e95 Mon Sep 17 00:00:00 2001 From: Dragon-Seeker Date: Wed, 10 Jul 2024 19:41:36 -0500 Subject: [PATCH 2/3] Remove SimpleRegistryAccessor and adjust Registry Access for removal/deprecation --- .../owo/itemgroup/json/WrapperGroup.java | 2 -- .../registry/SimpleRegistryAccessor.java | 18 ----------- .../mixin/registry/SimpleRegistryMixin.java | 2 ++ .../wispforest/owo/util/RegistryAccess.java | 31 +++---------------- src/main/resources/owo.mixins.json | 1 - 5 files changed, 7 insertions(+), 47 deletions(-) delete mode 100644 src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryAccessor.java diff --git a/src/main/java/io/wispforest/owo/itemgroup/json/WrapperGroup.java b/src/main/java/io/wispforest/owo/itemgroup/json/WrapperGroup.java index f9ad0aa3..bb501cda 100644 --- a/src/main/java/io/wispforest/owo/itemgroup/json/WrapperGroup.java +++ b/src/main/java/io/wispforest/owo/itemgroup/json/WrapperGroup.java @@ -5,7 +5,6 @@ import io.wispforest.owo.itemgroup.gui.ItemGroupButton; import io.wispforest.owo.itemgroup.gui.ItemGroupTab; import io.wispforest.owo.mixin.itemgroup.ItemGroupAccessor; -import io.wispforest.owo.mixin.registry.SimpleRegistryAccessor; import io.wispforest.owo.util.pond.OwoSimpleRegistryExtensions; import net.minecraft.item.ItemGroup; import net.minecraft.registry.Registries; @@ -34,7 +33,6 @@ public WrapperGroup(ItemGroup parent, Identifier parentId, List ta int parentRawId = Registries.ITEM_GROUP.getRawId(parent); - ((SimpleRegistryAccessor) Registries.ITEM_GROUP).owo$getValueToEntry().remove(parent); ((OwoSimpleRegistryExtensions) Registries.ITEM_GROUP).owo$set(parentRawId, RegistryKey.of(RegistryKeys.ITEM_GROUP, parentId), this, RegistryEntryInfo.DEFAULT); ((ItemGroupAccessor) this).owo$setDisplayName(parent.getDisplayName()); diff --git a/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryAccessor.java b/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryAccessor.java deleted file mode 100644 index b1219351..00000000 --- a/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryAccessor.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.wispforest.owo.mixin.registry; - -import net.minecraft.registry.SimpleRegistry; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.Map; - -@Mixin(SimpleRegistry.class) -public interface SimpleRegistryAccessor { - @Accessor("valueToEntry") - Map> owo$getValueToEntry(); - - @Accessor("idToEntry") - Map> owo$getIdToEntry(); -} diff --git a/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryMixin.java b/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryMixin.java index 93adc7ac..8a875c6f 100644 --- a/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryMixin.java +++ b/src/main/java/io/wispforest/owo/mixin/registry/SimpleRegistryMixin.java @@ -38,6 +38,8 @@ public abstract class SimpleRegistryMixin implements MutableRegistry, OwoS * Copy of the {@link SimpleRegistry#add} function but uses {@link List#set} instead of {@link List#add} for {@link SimpleRegistry#rawIdToEntry} */ public RegistryEntry.Reference owo$set(int id, RegistryKey arg, T object, RegistryEntryInfo arg2) { + this.valueToEntry.remove(object); + OwoFreezer.checkRegister("Registry Set Calls"); //this.assertNotFrozen(arg); Objects.requireNonNull(arg); diff --git a/src/main/java/io/wispforest/owo/util/RegistryAccess.java b/src/main/java/io/wispforest/owo/util/RegistryAccess.java index 04c229b5..a9dee950 100644 --- a/src/main/java/io/wispforest/owo/util/RegistryAccess.java +++ b/src/main/java/io/wispforest/owo/util/RegistryAccess.java @@ -1,49 +1,28 @@ package io.wispforest.owo.util; -import io.wispforest.owo.mixin.registry.SimpleRegistryAccessor; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.SimpleRegistry; import org.jetbrains.annotations.Nullable; +@Deprecated public final class RegistryAccess { private RegistryAccess() {} /** - * Gets a {@link RegistryEntry} from its id - * - * @param registry The registry to operate on. Must be a {@link SimpleRegistry} at some point in the hierarchy - * @param id The id to use - * @param The type of the registry and returned entry - * @return The entry, or {@code null} if it's not present + * @deprecated Use {@link Registry#getEntry(Identifier)} */ @Nullable - @SuppressWarnings("unchecked") public static RegistryEntry getEntry(Registry registry, Identifier id) { - checkSimple(registry); - return ((SimpleRegistryAccessor) registry).owo$getIdToEntry().get(id); + return registry.getEntry(id).orElse(null); } /** - * Gets a {@link RegistryEntry} from its value - * - * @param registry The registry to operate on. Must be a {@link SimpleRegistry} at some point in the hierarchy - * @param value The value to use - * @param The type of the registry and returned entry - * @return The entry, or {@code null} if it's not present + * @deprecated Use {@link Registry#getEntry(T)} */ @Nullable - @SuppressWarnings("unchecked") public static RegistryEntry getEntry(Registry registry, T value) { - checkSimple(registry); - return ((SimpleRegistryAccessor) registry).owo$getValueToEntry().get(value); - } - - private static void checkSimple(Registry registry) { - if (registry instanceof SimpleRegistry) return; - throw new IllegalArgumentException("[RegistryAccess] Tried to operate on Registry of class '" - + registry.getClass() + "', but only 'SimpleRegistry' and descendants are supported"); + return registry.getEntry(value); } } diff --git a/src/main/resources/owo.mixins.json b/src/main/resources/owo.mixins.json index ec8f45f2..70ec27c0 100644 --- a/src/main/resources/owo.mixins.json +++ b/src/main/resources/owo.mixins.json @@ -29,7 +29,6 @@ "offline.WorldSaveHandlerMixin", "recipe_remainders.CraftingResultSlotMixin", "recipe_remainders.RecipeManagerMixin", - "registry.SimpleRegistryAccessor", "registry.SimpleRegistryMixin", "registry.ReferenceAccessor", "text.LanguageMixin", From 3f562f6aa0a6918ffc60b468069fdf4791e42a01 Mon Sep 17 00:00:00 2001 From: Dragon-Seeker Date: Sun, 21 Jul 2024 14:40:40 -0500 Subject: [PATCH 3/3] Adjust annotation to be marked for removal --- src/main/java/io/wispforest/owo/util/RegistryAccess.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/wispforest/owo/util/RegistryAccess.java b/src/main/java/io/wispforest/owo/util/RegistryAccess.java index a9dee950..ef11309c 100644 --- a/src/main/java/io/wispforest/owo/util/RegistryAccess.java +++ b/src/main/java/io/wispforest/owo/util/RegistryAccess.java @@ -3,9 +3,10 @@ import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; import net.minecraft.registry.entry.RegistryEntry; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -@Deprecated +@Deprecated(forRemoval = true) public final class RegistryAccess { private RegistryAccess() {}