From 48c9e056a8c2a07926f3215b922b0524976416b8 Mon Sep 17 00:00:00 2001 From: cputnam-a11y Date: Wed, 4 Jun 2025 22:24:58 -0500 Subject: [PATCH 1/8] Initial Commit: CustomRegistryEntryLists for every occasion --- .../registry/CustomRegistryEntryList.java | 75 +++++++ .../registry/DependentRegistryEntryList.java | 91 +++++++++ .../registry/sync/FabricRegistryInit.java | 5 + .../CustomRegistryEntryListImpl.java | 132 ++++++++++++ .../defaults/DefaultRegistryEntryLists.java | 35 ++++ .../IntersectionRegistryEntryList.java | 114 +++++++++++ .../defaults/InverseRegistryEntryList.java | 191 ++++++++++++++++++ .../defaults/MultiPartRegistryEntryList.java | 134 ++++++++++++ .../defaults/UnionRegistryEntryList.java | 98 +++++++++ .../defaults/UniversalRegistryEntryList.java | 146 +++++++++++++ .../registryentrylists/util/ChannelUtil.java | 57 ++++++ ...egistryWrapperFromRegistryEntryLookup.java | 76 +++++++ .../util/RegistryWrapperUtils.java | 115 +++++++++++ .../registryentrylists/util/TagKeyCache.java | 35 ++++ .../PacketCodecs$25Mixin.java | 112 ++++++++++ .../RegistryEntryListCodecMixin.java | 90 +++++++++ .../RegistryEntryListMixin.java | 27 +++ .../RegistryEntryListNamedMixin.java | 38 ++++ .../RegistryKeyAccessor.java | 32 +++ .../sync/registryentrylists/TagKeyMixin.java | 52 +++++ .../fabric-registry-sync-v0.mixins.json | 10 +- .../src/main/resources/fabric.mod.json | 3 +- .../sync/CustomRegistryEntryListsTest.java | 105 ++++++++++ .../src/testmod/resources/fabric.mod.json | 1 + 24 files changed, 1771 insertions(+), 3 deletions(-) create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DependentRegistryEntryList.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListImpl.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultRegistryEntryLists.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/MultiPartRegistryEntryList.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/ChannelUtil.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperFromRegistryEntryLookup.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperUtils.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/TagKeyCache.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListNamedMixin.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryKeyAccessor.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java create mode 100644 fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java new file mode 100644 index 0000000000..3303a3e168 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.api.event.registry; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListImpl; + +public interface CustomRegistryEntryList extends RegistryEntryList { + CustomRegistryEntryListSerializer getSerializer(); + + static void registerSerializer(@NotNull CustomRegistryEntryListSerializer serializer) { + CustomRegistryEntryListImpl.registerSerializer(serializer); + } + + static @Nullable CustomRegistryEntryListSerializer getSerializer(Identifier id) { + return CustomRegistryEntryListImpl.getSerializer(id); + } + + @SafeVarargs + static RegistryEntryList union(RegistryEntryList... parts) { + return CustomRegistryEntryListImpl.union(parts); + } + + @SafeVarargs + static RegistryEntryList intersection(RegistryEntryList... parts) { + return CustomRegistryEntryListImpl.intersection(parts); + } + + static RegistryEntryList inverse(RegistryEntryLookup lookup, RegistryEntryList opposite) { + return CustomRegistryEntryListImpl.inverse(lookup, opposite); + } + + static RegistryEntryList universal(RegistryEntryLookup lookup) { + return CustomRegistryEntryListImpl.universal(lookup); + } + + static RegistryEntryList subtraction(RegistryEntryLookup lookup, RegistryEntryList initial, RegistryEntryList subtracted) { + return CustomRegistryEntryListImpl.subtraction(lookup, initial, subtracted); + } + + interface CustomRegistryEntryListSerializer { + Identifier getIdentifier(); + + MapCodec> createCodec(RegistryKey> registryKey, Codec> entryCodec, boolean forceList); + + PacketCodec> createPacketCodec(RegistryKey> registryKey); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DependentRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DependentRegistryEntryList.java new file mode 100644 index 0000000000..dab9fd4098 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DependentRegistryEntryList.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.api.event.registry; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import com.google.common.collect.MapMaker; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.MustBeInvokedByOverriders; + +import net.minecraft.registry.entry.RegistryEntryList; + +// Injected to RegistryEntryList +@ApiStatus.NonExtendable +public interface DependentRegistryEntryList { + // creating a cycle in the graph will lead to stack overflow, do with this knowledge what you will + Map, List>> DEPENDENCIES = new MapMaker() + .weakKeys() + .weakValues() + .makeMap(); + + default List> getDependencies() { + return Collections.unmodifiableList(castToT(DEPENDENCIES.get(this.asSelf()))); + } + + /** + * Unregisters a dependency. + * Does nothing is the dependency is not registered. + * + * @param dependency the dependency to unregister + */ + default void unregisterDependency(RegistryEntryList dependency) { + List> dependencies = castToT(DEPENDENCIES.get(this.asSelf())); + + if (dependencies != null) { + dependencies.remove(dependency); + } + } + + default void registerDependency(RegistryEntryList dependency) { + DEPENDENCIES.computeIfAbsent( + this.asSelf(), + k -> new ArrayList<>() + ) + .add(dependency); + } + + /** + * Invalidate dependents is called by this list when it is invalidated. + */ + private void invalidateDependents() { + DEPENDENCIES.getOrDefault(this.asSelf(), List.of()) + .forEach(DependentRegistryEntryList::invalidate); + } + + /** + * Invalidate is called by any list that this depends on when the parent list is invalidated. + */ + @MustBeInvokedByOverriders + default void invalidate() { + this.invalidateDependents(); + } + + // this interface should only be implemented on RegistryEntryList, so the case **should** be safe... + private RegistryEntryList asSelf() { + return (RegistryEntryList) this; + } + + // why can't java just have field generics or something? + @SuppressWarnings("unchecked") + private static List> castToT(List> entryList) { + return (List>) (Object) entryList; + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java index 0a5fede7e3..6652267076 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java @@ -25,6 +25,8 @@ import net.fabricmc.fabric.api.networking.v1.ServerConfigurationConnectionEvents; import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking; import net.fabricmc.fabric.impl.registry.sync.packet.DirectRegistryPacketHandler; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListImpl; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.ChannelUtil; public class FabricRegistryInit implements ModInitializer { @Override @@ -211,5 +213,8 @@ public void onInitialize() { // Synced via PacketCodecs.registryValue RegistryAttributeHolder.get(Registries.RECIPE_BOOK_CATEGORY) .addAttribute(RegistryAttribute.SYNCED); + + ChannelUtil.init(); + CustomRegistryEntryListImpl.init(); } } diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListImpl.java new file mode 100644 index 0000000000..c00d8a716f --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListImpl.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.DefaultRegistryEntryLists; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.IntersectionRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.InverseRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.UnionRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.UniversalRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.RegistryWrapperUtils; + +public final class CustomRegistryEntryListImpl { + private CustomRegistryEntryListImpl() { + throw new UnsupportedOperationException(); + } + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomRegistryEntryListImpl.class); + + private static final Map SERIALIZERS = new HashMap<>(); + + public static final Codec SERIALIZER_CODEC = Identifier.CODEC.flatXmap( + id -> Optional.ofNullable(SERIALIZERS.get(id)) + .map(DataResult::success) + .orElseGet( + () -> DataResult.error( + () -> "Unknown CustomRegistryEntryListSerializer: " + id + ) + ), + serializer -> Optional.of(serializer.getIdentifier()) + .filter(SERIALIZERS::containsKey) + .map(DataResult::success) + .orElseGet( + () -> DataResult.error( + () -> "Unknown CustomRegistryEntryListSerializer: " + serializer + ) + ) + ); + + public static boolean isSerializedCustomRegistryEntryList(DynamicOps ops, T entryList) { + return ops.getMap(entryList) + .map(it -> it.get("fabric:type")) + .map(Objects::nonNull) + .result() + .orElse(false); + } + + public static void registerSerializer(CustomRegistryEntryList.CustomRegistryEntryListSerializer serializer) { + CustomRegistryEntryList.CustomRegistryEntryListSerializer previous = SERIALIZERS.put(serializer.getIdentifier(), serializer); + + if (previous != null) { + LOGGER.warn("Overwriting CustomRegistryEntryListSerializer {} with {}", previous, serializer); + } + } + + public static CustomRegistryEntryList.CustomRegistryEntryListSerializer getSerializer(Identifier id) { + return SERIALIZERS.get(id); + } + + public static RegistryEntryList union(RegistryEntryList[] parts) { + return new UnionRegistryEntryList<>(List.of(validateNotNull(parts))); + } + + public static RegistryEntryList intersection(RegistryEntryList[] parts) { + return new IntersectionRegistryEntryList<>(List.of(validateNotNull(parts))); + } + + public static RegistryEntryList inverse(RegistryEntryLookup lookup, RegistryEntryList opposite) { + Objects.requireNonNull(lookup, "lookup"); + Objects.requireNonNull(opposite, "opposite"); + return new InverseRegistryEntryList<>(RegistryWrapperUtils.castOrCreateFromEntryLookup(lookup), opposite); + } + + public static RegistryEntryList universal(RegistryEntryLookup lookup) { + Objects.requireNonNull(lookup, "lookup"); + return new UniversalRegistryEntryList<>(RegistryWrapperUtils.castOrCreateFromEntryLookup(lookup)); + } + + public static RegistryEntryList subtraction(RegistryEntryLookup lookup, RegistryEntryList initial, RegistryEntryList subtracted) { + Objects.requireNonNull(lookup, "lookup"); + Objects.requireNonNull(initial, "initial"); + Objects.requireNonNull(subtracted, "subtracted"); + return new IntersectionRegistryEntryList<>(List.of(initial, inverse(lookup, subtracted))); + } + + private static RegistryEntryList[] validateNotNull(RegistryEntryList[] lists) { + Objects.requireNonNull(lists, "list array"); + + for (RegistryEntryList list : lists) { + Objects.requireNonNull(list, "list"); + } + + return lists; + } + + public static void init() { + } + + static { + DefaultRegistryEntryLists.registerDefaults(); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultRegistryEntryLists.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultRegistryEntryLists.java new file mode 100644 index 0000000000..a8df84d2db --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultRegistryEntryLists.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; + +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListImpl; + +public class DefaultRegistryEntryLists { + private static boolean initialized = false; + + public static void registerDefaults() { + if (initialized) { + return; + } + + initialized = true; + CustomRegistryEntryListImpl.registerSerializer(UnionRegistryEntryList.SERIALIZER); + CustomRegistryEntryListImpl.registerSerializer(IntersectionRegistryEntryList.SERIALIZER); + CustomRegistryEntryListImpl.registerSerializer(InverseRegistryEntryList.SERIALIZER); + CustomRegistryEntryListImpl.registerSerializer(UniversalRegistryEntryList.SERIALIZER); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java new file mode 100644 index 0000000000..fe217b3d01 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import org.jetbrains.annotations.NotNull; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.entry.RegistryEntryListCodec; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; + +public class IntersectionRegistryEntryList extends MultiPartRegistryEntryList { + public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); + + public IntersectionRegistryEntryList(List> parts) { + super(parts); + } + + @Override + protected Set> createCache() { + if (this.getParts().isEmpty()) { + return Set.of(); + } + + if (this.getParts().size() == 1) { + return this.getParts() + .getFirst() + .stream() + .collect(Collectors.toUnmodifiableSet()); + } + + List> remaining = this.getParts().subList(1, getParts().size()); + + return getParts() + .getFirst() + .stream() + .filter(it -> remaining.stream().allMatch( + registryEntryList -> registryEntryList.contains(it) + )) + .collect(Collectors.toUnmodifiableSet()); + } + + @Override + public CustomRegistryEntryListSerializer getSerializer() { + return SERIALIZER; + } + + @Override + public String toString() { + return "Intersection{" + this.getParts() + "}"; + } + + private record Serializer() implements CustomRegistryEntryListSerializer { + private static final Identifier ID = Identifier.of("fabric", "and"); + + @Override + public Identifier getIdentifier() { + return ID; + } + + @Override + public MapCodec> createCodec(RegistryKey> registryKey, Codec> entryCodec, boolean forceList) { + return RegistryEntryListCodec.create(registryKey, entryCodec, forceList) + .listOf() + .xmap( + IntersectionRegistryEntryList::new, + MultiPartRegistryEntryList::getParts + ) + .fieldOf("values"); + } + + @Override + public PacketCodec> createPacketCodec(RegistryKey> registryKey) { + return PacketCodecs.registryEntryList(registryKey) + .collect(PacketCodecs.toList()) + .xmap( + IntersectionRegistryEntryList::new, + MultiPartRegistryEntryList::getParts + ); + } + + @Override + public @NotNull String toString() { + return "CustomRegistryEntryListSerializer{\"" + ID + "\"}"; + } + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java new file mode 100644 index 0000000000..2c3b8f2b86 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; + +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.block.Blocks; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.Items; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.entry.RegistryEntryListCodec; +import net.minecraft.registry.entry.RegistryEntryOwner; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; +import net.minecraft.util.math.random.Random; + +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.RegistryWrapperUtils; + +public class InverseRegistryEntryList implements CustomRegistryEntryList { + public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); + + private final RegistryWrapper wrapper; + private final RegistryEntryList opposite; + @Nullable + private List> cache = null; + + public InverseRegistryEntryList(RegistryWrapper wrapper, RegistryEntryList opposite) { + this.wrapper = wrapper; + this.opposite = opposite; + this.opposite.registerDependency(this); + } + + public RegistryEntryList getOpposite() { + return opposite; + } + + public RegistryWrapper getWrapper() { + return wrapper; + } + + @Override + public Stream> stream() { + return getList().stream(); + } + + @Override + public int size() { + return getList().size(); + } + + @Override + public boolean isBound() { + return opposite.isBound(); + } + + @Override + public Either, List>> getStorage() { + return Either.right(this.getList()); + } + + @Override + public Optional> getRandom(Random random) { + return Util.getRandomOrEmpty(getList(), random); + } + + @Override + public RegistryEntry get(int index) { + return getList().get(index); + } + + @Override + public boolean contains(RegistryEntry entry) { + return !this.opposite.contains(entry); + } + + @Override + public boolean ownerEquals(RegistryEntryOwner owner) { + return this.opposite.ownerEquals(owner); + } + + @Override + public Optional> getTagKey() { + return Optional.empty(); + } + + @Override + public @NotNull Iterator> iterator() { + return getList().iterator(); + } + + private List> getList() { + if (this.cache == null) { + this.cache = this.wrapper + .streamEntries() + .filter( + it -> !(it.value().equals(Items.AIR) || it.value() == Blocks.AIR || it.value() == Fluids.EMPTY) + ) + .filter(Predicate.not(this.opposite::contains)) + .collect(Collectors.toUnmodifiableList()); + } + + return this.cache; + } + + @Override + public CustomRegistryEntryListSerializer getSerializer() { + return SERIALIZER; + } + + @Override + public void invalidate() { + this.cache = null; + CustomRegistryEntryList.super.invalidate(); + } + + @Override + public String toString() { + return "Inverse{" + this.getOpposite().toString() + "}"; + } + + private record Serializer() implements CustomRegistryEntryListSerializer { + private static final Identifier ID = Identifier.of("fabric", "not"); + + @Override + public Identifier getIdentifier() { + return ID; + } + + @Override + public MapCodec> createCodec(RegistryKey> registryKey, Codec> registryEntryCodec, boolean forceList) { + return RecordCodecBuilder.>mapCodec( + instance -> instance.apply2( + InverseRegistryEntryList::new, + RegistryWrapperUtils.createMapCodec(registryKey).forGetter(InverseRegistryEntryList::getWrapper), + RegistryEntryListCodec.create(registryKey, registryEntryCodec, forceList).fieldOf("value").forGetter(InverseRegistryEntryList::getOpposite) + ) + ); + } + + @Override + public PacketCodec> createPacketCodec(RegistryKey> registryKey) { + return PacketCodec., RegistryWrapper, RegistryEntryList>tuple( + RegistryWrapperUtils.createPacketCodec(registryKey), + InverseRegistryEntryList::getWrapper, + PacketCodecs.registryEntryList(registryKey), + InverseRegistryEntryList::getOpposite, + InverseRegistryEntryList::new + ); + } + + @Override + public @NotNull String toString() { + return "CustomRegistryEntryListSerializer{\"" + ID + "\"}"; + } + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/MultiPartRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/MultiPartRegistryEntryList.java new file mode 100644 index 0000000000..e8a0f327a0 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/MultiPartRegistryEntryList.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; + +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +import com.google.common.collect.ImmutableList; +import com.mojang.datafixers.util.Either; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.entry.RegistryEntryOwner; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Util; +import net.minecraft.util.math.random.Random; + +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; + +public abstract class MultiPartRegistryEntryList implements CustomRegistryEntryList { + private final ImmutableList> parts; + @Nullable + private Set> cachedSet = null; + @Nullable + private List> cachedList = null; + + public MultiPartRegistryEntryList(List> parts) { + this.parts = ImmutableList.copyOf(parts); + + for (RegistryEntryList part : parts) { + part.registerDependency(this); + } + } + + public ImmutableList> getParts() { + return this.parts; + } + + protected abstract Set> createCache(); + + private Set> getCachedSet() { + if (this.cachedSet == null) { + this.cachedSet = this.createCache(); + } + + return this.cachedSet; + } + + private List> getCachedList() { + if (this.cachedList == null) { + this.cachedList = List.copyOf(this.getCachedSet()); + } + + return this.cachedList; + } + + @Override + public void invalidate() { + this.cachedSet = null; + this.cachedList = null; + CustomRegistryEntryList.super.invalidate(); + } + + @Override + public Stream> stream() { + return this.getCachedList().stream(); + } + + @Override + public int size() { + return this.getCachedList().size(); + } + + @Override + public boolean isBound() { + return this.parts.stream().allMatch(RegistryEntryList::isBound); + } + + @Override + public Either, List>> getStorage() { + return Either.right(this.getCachedList()); + } + + @Override + public Optional> getRandom(Random random) { + return Util.getRandomOrEmpty(getCachedList(), random); + } + + @Override + public RegistryEntry get(int index) { + return this.getCachedList().get(index); + } + + @Override + public boolean contains(RegistryEntry entry) { + return this.getCachedSet().contains(entry); + } + + @Override + public boolean ownerEquals(RegistryEntryOwner owner) { + return this.parts.stream() + .allMatch(it -> it.ownerEquals(owner)); + } + + @Override + public Optional> getTagKey() { + return Optional.empty(); + } + + @Override + @NotNull + public Iterator> iterator() { + return this.getCachedList().iterator(); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java new file mode 100644 index 0000000000..6e21248f4a --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import org.jetbrains.annotations.NotNull; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.entry.RegistryEntryListCodec; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; + +public class UnionRegistryEntryList extends MultiPartRegistryEntryList { + public static final CustomRegistryEntryList.CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); + + public UnionRegistryEntryList(List> parts) { + super(parts); + } + + @Override + protected Set> createCache() { + return this.getParts() + .stream() + .flatMap(RegistryEntryList::stream) + .collect(Collectors.toUnmodifiableSet()); + } + + @Override + public CustomRegistryEntryListSerializer getSerializer() { + return SERIALIZER; + } + + @Override + public String toString() { + return "Union{" + this.getParts() + "}"; + } + + private record Serializer() implements CustomRegistryEntryListSerializer { + private static final Identifier ID = Identifier.of("fabric", "or"); + + @Override + public Identifier getIdentifier() { + return ID; + } + + @Override + public MapCodec> createCodec(RegistryKey> registryKey, Codec> entryCodec, boolean forceList) { + return RegistryEntryListCodec.create(registryKey, entryCodec, forceList) + .listOf() + .xmap( + UnionRegistryEntryList::new, + MultiPartRegistryEntryList::getParts + ) + .fieldOf("values"); + } + + @Override + public PacketCodec> createPacketCodec(RegistryKey> registryKey) { + return PacketCodecs.registryEntryList(registryKey) + .collect(PacketCodecs.toList()) + .xmap( + UnionRegistryEntryList::new, + MultiPartRegistryEntryList::getParts + ); + } + + @Override + public @NotNull String toString() { + return "CustomRegistryEntryListSerializer{\"" + ID + "\"}"; + } + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java new file mode 100644 index 0000000000..5b599464d7 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; + +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; + +import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import org.jetbrains.annotations.NotNull; + +import net.minecraft.block.Blocks; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.Items; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryOwner; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; +import net.minecraft.util.math.random.Random; + +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.RegistryWrapperUtils; + +public record UniversalRegistryEntryList(RegistryWrapper source) implements CustomRegistryEntryList { + public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); + + @Override + public Stream> stream() { + return source.streamEntries() + .filter( + it -> !(it.value().equals(Items.AIR) || it.value() == Blocks.AIR || it.value() == Fluids.EMPTY) + ) + .map(Function.identity()); + } + + @Override + public int size() { + return Math.toIntExact(source.streamEntries().count()); + } + + @Override + public boolean isBound() { + return true; + } + + @Override + public Either, List>> getStorage() { + return Either.right(stream().toList()); + } + + @Override + public Optional> getRandom(Random random) { + return Util.getRandomOrEmpty(stream().toList(), random); + } + + @Override + public RegistryEntry get(int index) { + return stream().toList().get(index); + } + + @Override + public boolean contains(RegistryEntry entry) { + return entry.getKey() + .flatMap(source::getOptional) + .isPresent(); + } + + @Override + public boolean ownerEquals(RegistryEntryOwner owner) { + return true; + } + + @Override + public Optional> getTagKey() { + return Optional.empty(); + } + + @Override + public @NotNull Iterator> iterator() { + return stream().iterator(); + } + + @Override + public CustomRegistryEntryListSerializer getSerializer() { + return SERIALIZER; + } + + @Override + public @NotNull String toString() { + return "Universal{" + source.toString() + "}"; + } + + private record Serializer() implements CustomRegistryEntryListSerializer { + private static final Identifier ID = Identifier.of("fabric", "all"); + + @Override + public Identifier getIdentifier() { + return ID; + } + + @Override + public MapCodec> createCodec(RegistryKey> registryKey, Codec> registryEntryCodec, boolean forceList) { + return RegistryWrapperUtils.createMapCodec(registryKey).xmap( + UniversalRegistryEntryList::new, + UniversalRegistryEntryList::source + ); + } + + @Override + public PacketCodec> createPacketCodec(RegistryKey> registryKey) { + return RegistryWrapperUtils.createPacketCodec(registryKey).xmap( + UniversalRegistryEntryList::new, + UniversalRegistryEntryList::source + ); + } + + @Override + public @NotNull String toString() { + return "CustomRegistryEntryListSerializer{\"" + ID + "\"}"; + } + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/ChannelUtil.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/ChannelUtil.java new file mode 100644 index 0000000000..f427f7f266 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/ChannelUtil.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.util; + +import java.util.Set; + +import io.netty.buffer.ByteBuf; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; +import net.fabricmc.fabric.impl.networking.FabricRegistryByteBuf; + +public class ChannelUtil { + private static final PacketCodec CODEC = PacketCodec.unit(null); + + private static final CustomPayload.Id ID = new CustomPayload.Id<>( + Identifier.of("fabric", "is_installed") + ); + + public static void init() { + PayloadTypeRegistry.configurationC2S().register(ID, CODEC); + PayloadTypeRegistry.configurationS2C().register(ID, CODEC); + } + + @SuppressWarnings({"BooleanMethodIsAlwaysInverted"}) + public static boolean isInstalled(RegistryByteBuf buf) { + if (!(buf instanceof FabricRegistryByteBuf fabricRegistryByteBuf)) { + return false; + } + + Set channels = fabricRegistryByteBuf.fabric_getSendableConfigurationChannels(); + + if (channels == null) { + return false; + } + + return channels.contains(ID.id()); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperFromRegistryEntryLookup.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperFromRegistryEntryLookup.java new file mode 100644 index 0000000000..9f0e05b363 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperFromRegistryEntryLookup.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.util; + +import java.util.Optional; +import java.util.stream.Stream; + +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.tag.TagKey; + +import net.fabricmc.fabric.mixin.registry.sync.registryentrylists.RegistryKeyAccessor; + +@SuppressWarnings("unchecked") +record RegistryWrapperFromRegistryEntryLookup(RegistryEntryLookup entryLookup) implements RegistryWrapper { + /** + * @see RegistryWrapperUtils#castOrCreateFromEntryLookup(RegistryEntryLookup) + * @param entryLookup the entry lookup backing this wrapper + */ + RegistryWrapperFromRegistryEntryLookup { + if (entryLookup instanceof RegistryWrapper) { + throw new IllegalArgumentException("use RegistryWrapperFromRegistryEntryLookup#tryFromEntryLookup instead"); + } + } + + @Override + public Stream> streamEntries() { + return RegistryKeyAccessor + .getInstances() + .values() + .stream() + .flatMap( + key -> entryLookup + .getOptional((RegistryKey) key) + .stream() + ); + } + + @Override + public Stream> getTags() { + return TagKeyCache + .stream() + .flatMap( + key -> entryLookup + .getOptional((TagKey) key) + .stream() + ); + } + + @Override + public Optional> getOptional(RegistryKey key) { + return entryLookup.getOptional(key); + } + + @Override + public Optional> getOptional(TagKey tag) { + return entryLookup.getOptional(tag); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperUtils.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperUtils.java new file mode 100644 index 0000000000..80c7b718cd --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperUtils.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.util; + +import java.util.stream.Stream; + +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.MapLike; +import com.mojang.serialization.RecordBuilder; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryOps; +import net.minecraft.registry.RegistryWrapper; + +public class RegistryWrapperUtils { + /** + * gets a {@link RegistryWrapper} from a {@link RegistryEntryLookup}. + * first checks if the entryLookup is a registryWrapper, then, if not, constructs a more expensive wrapper the bridges the loss of information + * + * @param the type of elements in the registry + * @param registryEntryLookup the entryLookup to wrap + * @return the entryLookup cast to a registryWrapper, or, if it isn't one, an expensive mimicry + */ + public static RegistryWrapper castOrCreateFromEntryLookup(RegistryEntryLookup registryEntryLookup) { + if (registryEntryLookup instanceof RegistryWrapper registryWrapper) { + return registryWrapper; + } + + return new RegistryWrapperFromRegistryEntryLookup<>(registryEntryLookup); + } + + public static MapCodec> createMapCodec(RegistryKey> registryKey) { + return new MapCodec<>() { + @Override + public Stream keys(DynamicOps ops) { + return Stream.empty(); + } + + @Override + public DataResult> decode(DynamicOps ops, MapLike input) { + if (!(ops instanceof RegistryOps registryOps)) { + return DataResult.error(() -> "RegistryWrapperCodec requires RegistryOps"); + } + + return registryOps.getEntryLookup(registryKey) + .map(RegistryWrapperUtils::castOrCreateFromEntryLookup) + .map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> "Registry Not Found")); + } + + @Override + public RecordBuilder encode(RegistryWrapper input, DynamicOps ops, RecordBuilder prefix) { + return prefix; + } + }; + } + + public static Codec> createCodec(RegistryKey> registryKey) { + return new Codec<>() { + @Override + public DataResult, T>> decode(DynamicOps ops, T input) { + if (!(ops instanceof RegistryOps registryOps)) { + return DataResult.error(() -> "Can't access registry"); + } + + return registryOps.getEntryLookup(registryKey) + .map(RegistryWrapperUtils::castOrCreateFromEntryLookup) + .map(it -> new Pair<>(it, input)) + .map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> "Registry Not Found")); + } + + @Override + public DataResult encode(RegistryWrapper input, DynamicOps ops, T prefix) { + return DataResult.success(prefix); + } + }; + } + + public static PacketCodec> createPacketCodec(RegistryKey> registryKey) { + return new PacketCodec<>() { + @Override + public RegistryWrapper decode(RegistryByteBuf buf) { + return buf.getRegistryManager().getOrThrow(registryKey); + } + + @Override + public void encode(RegistryByteBuf buf, RegistryWrapper value) { + // No need to encode, as the registry is already present in the buffer + } + }; + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/TagKeyCache.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/TagKeyCache.java new file mode 100644 index 0000000000..8d73b62d49 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/TagKeyCache.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.util; + +import java.util.Set; +import java.util.stream.Stream; + +import net.minecraft.registry.tag.TagKey; + +public class TagKeyCache { + // a weak immutable set containing all the TagKey instances in the game + private static Set> CACHE; + + public static void acceptCache(Set> cache) { + CACHE = cache; + } + + static Stream> stream() { + return CACHE.stream(); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java new file mode 100644 index 0000000000..dd62f602ff --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; + +import java.util.HashMap; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Cancellable; +import io.netty.buffer.ByteBuf; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.encoding.VarInts; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.ChannelUtil; + +@SuppressWarnings("unchecked") +@Mixin(targets = "net.minecraft.network.codec.PacketCodecs$25") +class PacketCodecs$25Mixin { + @Unique + private static final String COMMENT_IN_MIXIN_EXPORT = "-45 is ours. if anyone else uses it, they deserve the consequences"; + @Unique + private static final int FABRIC_CUSTOM_REGISTRY_LIST_ID = -45; + + @Shadow + @Final + RegistryKey> field_54511; + + @Unique + HashMap>> cache = new HashMap<>(); + + private PacketCodecs$25Mixin() { + } + + @Inject( + method = "encode(Lnet/minecraft/network/RegistryByteBuf;Lnet/minecraft/registry/entry/RegistryEntryList;)V", + at = @At("HEAD"), + cancellable = true + ) + private void encodeCustomRegistryEntryList(RegistryByteBuf registryByteBuf, RegistryEntryList registryEntryList, CallbackInfo ci) { + if (!ChannelUtil.isInstalled(registryByteBuf) || !(registryEntryList instanceof CustomRegistryEntryList customRegistryEntryList)) { + return; + } + + VarInts.write(registryByteBuf, FABRIC_CUSTOM_REGISTRY_LIST_ID); + Identifier.PACKET_CODEC.encode(registryByteBuf, customRegistryEntryList.getSerializer().getIdentifier()); + PacketCodec> packetCodec = cache.computeIfAbsent( + customRegistryEntryList.getSerializer(), + serializer1 -> (PacketCodec>) serializer1.createPacketCodec(field_54511) + ); + packetCodec.encode(registryByteBuf, (CustomRegistryEntryList) customRegistryEntryList); + ci.cancel(); + } + + @WrapOperation( + method = "decode(Lnet/minecraft/network/RegistryByteBuf;)Lnet/minecraft/registry/entry/RegistryEntryList;", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/encoding/VarInts;read(Lio/netty/buffer/ByteBuf;)I" + ) + ) + private int decodeCustomRegistryEntryList(ByteBuf buf, Operation original, RegistryByteBuf registryByteBuf, @Cancellable CallbackInfoReturnable> cir) { + int id = original.call(buf); + + if (!ChannelUtil.isInstalled(registryByteBuf) || id != FABRIC_CUSTOM_REGISTRY_LIST_ID || cir.isCancelled()) { + return id; + } + + Identifier identifier = Identifier.PACKET_CODEC.decode(buf); + CustomRegistryEntryList.CustomRegistryEntryListSerializer serializer = CustomRegistryEntryList.getSerializer(identifier); + + if (serializer == null) { + throw new IllegalStateException("Unknown CustomRegistryEntryListSerializer: " + identifier); + } + + PacketCodec> packetCodec = cache.computeIfAbsent( + serializer, + serializer1 -> (PacketCodec>) serializer1.createPacketCodec(field_54511) + ); + + cir.setReturnValue(packetCodec.decode(registryByteBuf)); + return id; + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java new file mode 100644 index 0000000000..272ac7d41b --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; + +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.entry.RegistryEntryListCodec; + +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListImpl; + +@SuppressWarnings("unchecked") +@Mixin(RegistryEntryListCodec.class) +class RegistryEntryListCodecMixin { + @Unique + private Codec> fabric$codec; + + @Inject( + method = "", + at = @At("TAIL") + ) + private void bindFabricCodec(RegistryKey> registry, Codec> entryCodec, boolean alwaysSerializeAsList, CallbackInfo ci) { + fabric$codec = CustomRegistryEntryListImpl.SERIALIZER_CODEC.dispatch( + "fabric:type", + CustomRegistryEntryList::getSerializer, + serializer -> serializer.createCodec(registry, entryCodec, alwaysSerializeAsList) + ); + } + + @Inject( + method = "encode(Lnet/minecraft/registry/entry/RegistryEntryList;Lcom/mojang/serialization/DynamicOps;Ljava/lang/Object;)Lcom/mojang/serialization/DataResult;", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/registry/entry/RegistryEntryListCodec;entryListStorageCodec:Lcom/mojang/serialization/Codec;" + ), + cancellable = true + ) + private void encodeCustomWithCustomCodec(RegistryEntryList registryEntryList, DynamicOps dynamicOps, T prefix, CallbackInfoReturnable> cir) { + if (registryEntryList instanceof CustomRegistryEntryList customRegistryEntryList) { + cir.setReturnValue(fabric$codec.encode(customRegistryEntryList, dynamicOps, prefix)); + } + } + + @Inject( + method = "decode", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/registry/entry/RegistryEntryListCodec;entryListStorageCodec:Lcom/mojang/serialization/Codec;" + ), + cancellable = true + ) + private void decodeCustomWithCustomCodec(DynamicOps ops, T input, CallbackInfoReturnable, T>>> cir) { + if (CustomRegistryEntryListImpl.isSerializedCustomRegistryEntryList(ops, input)) { + cir.setReturnValue( + fabric$codec.decode(ops, input).map( + pair -> pair.mapFirst( + list -> (RegistryEntryList) list + ) + ) + ); + } + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java new file mode 100644 index 0000000000..a07312a350 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; + +import org.spongepowered.asm.mixin.Mixin; + +import net.minecraft.registry.entry.RegistryEntryList; + +import net.fabricmc.fabric.api.event.registry.DependentRegistryEntryList; + +@Mixin(RegistryEntryList.class) +interface RegistryEntryListMixin extends DependentRegistryEntryList { +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListNamedMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListNamedMixin.java new file mode 100644 index 0000000000..60cd2e87ca --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListNamedMixin.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; + +import java.util.List; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; + +@Mixin(RegistryEntryList.Named.class) +public abstract class RegistryEntryListNamedMixin implements RegistryEntryListMixin { + @Inject( + method = "setEntries", + at = @At("TAIL") + ) + private void invalidateDependents(List> entries, CallbackInfo ci) { + this.invalidate(); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryKeyAccessor.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryKeyAccessor.java new file mode 100644 index 0000000000..c92578d1b6 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryKeyAccessor.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; + +import java.util.concurrent.ConcurrentMap; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.registry.RegistryKey; + +@Mixin(RegistryKey.class) +public interface RegistryKeyAccessor { + @Accessor("INSTANCES") + static ConcurrentMap> getInstances() { + throw new AssertionError("Mixin failed to apply"); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java new file mode 100644 index 0000000000..16dcdbd910 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; + +import java.util.Collections; +import java.util.Set; +import java.util.WeakHashMap; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.registry.tag.TagKey; + +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.TagKeyCache; + +@Mixin(TagKey.class) +class TagKeyMixin { + @Unique + private static final Set> CACHE = Collections.newSetFromMap(new WeakHashMap<>()); + + private TagKeyMixin() { + } + + @Inject( + method = "", + at = @At("TAIL") + ) + private void storeKey(CallbackInfo ci) { + CACHE.add((TagKey) (Object) this); + } + + static { + TagKeyCache.acceptCache(Collections.unmodifiableSet(CACHE)); + } +} diff --git a/fabric-registry-sync-v0/src/main/resources/fabric-registry-sync-v0.mixins.json b/fabric-registry-sync-v0/src/main/resources/fabric-registry-sync-v0.mixins.json index c51948bd22..3e536c5c60 100644 --- a/fabric-registry-sync-v0/src/main/resources/fabric-registry-sync-v0.mixins.json +++ b/fabric-registry-sync-v0/src/main/resources/fabric-registry-sync-v0.mixins.json @@ -5,7 +5,6 @@ "mixins": [ "BlocksMixin", "BootstrapMixin", - "SerializedChunkMixin", "DebugChunkGeneratorAccessor", "ExperimentalRegistriesValidatorMixin", "IdListMixin", @@ -17,8 +16,15 @@ "RegistryMixin", "SaveLoadingMixin", "SerializableRegistriesMixin", + "SerializedChunkMixin", "SimpleRegistryAccessor", - "SimpleRegistryMixin" + "SimpleRegistryMixin", + "registryentrylists.RegistryEntryListNamedMixin", + "registryentrylists.PacketCodecs$25Mixin", + "registryentrylists.RegistryEntryListCodecMixin", + "registryentrylists.RegistryEntryListMixin", + "registryentrylists.RegistryKeyAccessor", + "registryentrylists.TagKeyMixin" ], "injectors": { "defaultRequire": 1 diff --git a/fabric-registry-sync-v0/src/main/resources/fabric.mod.json b/fabric-registry-sync-v0/src/main/resources/fabric.mod.json index dc0cb9bb8b..ad0bf8a7e7 100644 --- a/fabric-registry-sync-v0/src/main/resources/fabric.mod.json +++ b/fabric-registry-sync-v0/src/main/resources/fabric.mod.json @@ -40,7 +40,8 @@ "custom": { "fabric-api:module-lifecycle": "stable", "loom:injected_interfaces": { - "net/minecraft/class_2378": ["net/fabricmc/fabric/api/event/registry/FabricRegistry"] + "net/minecraft/class_2378": ["net/fabricmc/fabric/api/event/registry/FabricRegistry"], + "net/minecraft/class_6885": ["net/fabricmc/fabric/api/event/registry/DependentRegistryEntryList"] } } } diff --git a/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java b/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java new file mode 100644 index 0000000000..48ec224aaa --- /dev/null +++ b/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.test.registry.sync; + +import com.mojang.logging.LogUtils; +import org.slf4j.Logger; + +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.tag.BlockTags; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents; +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; + +public class CustomRegistryEntryListsTest implements ModInitializer { + private static final Logger LOGGER = LogUtils.getLogger(); + + @Override + public void onInitialize() { + CommonLifecycleEvents.TAGS_LOADED.register((registries, client) -> { + LOGGER.info("Starting custom registry list tests..."); + + if (client) { + return; + } + + RegistryEntryList anvils = registries.getOrThrow(RegistryKeys.BLOCK).getOrThrow(BlockTags.ANVIL); + RegistryEntryList corals = registries.getOrThrow(RegistryKeys.BLOCK).getOrThrow(BlockTags.CORAL_BLOCKS); + RegistryEntry anvil = registries.getOrThrow(RegistryKeys.BLOCK).getEntry(Blocks.ANVIL); + RegistryEntry chippedAnvil = registries.getOrThrow(RegistryKeys.BLOCK).getEntry(Blocks.CHIPPED_ANVIL); + RegistryEntry coral = registries.getOrThrow(RegistryKeys.BLOCK).getEntry(Blocks.BRAIN_CORAL_BLOCK); + RegistryEntry log = registries.getOrThrow(RegistryKeys.BLOCK).getEntry(Blocks.OAK_LOG); + + RegistryEntryList union = CustomRegistryEntryList.union( + anvils, + corals + ); + + warnIfFalse(union.contains(anvil), "CustomRegistryEntryList.union doesn't contain anvil"); + warnIfFalse(union.contains(coral), "CustomRegistryEntryList.union doesn't contain brain coral"); + + RegistryEntryList intersection = CustomRegistryEntryList.intersection( + anvils, + corals + ); + + warnIfFalse(!intersection.contains(anvil), "CustomRegistryEntryList.intersection contains anvil"); + warnIfFalse(!intersection.contains(coral), "CustomRegistryEntryList.intersection contains brain coral"); + + RegistryEntryList inverse = CustomRegistryEntryList.inverse( + registries.getOrThrow(RegistryKeys.BLOCK), + union + ); + + warnIfFalse(!inverse.contains(anvil), "CustomRegistryEntryList.inverse contains anvil"); + warnIfFalse(!inverse.contains(coral), "CustomRegistryEntryList.inverse contains brain coral"); + warnIfFalse(inverse.contains(log), "CustomRegistryEntryList.inverse doesn't contain oak log"); + + RegistryEntryList universal = CustomRegistryEntryList.universal( + registries.getOrThrow(RegistryKeys.BLOCK) + ); + + warnIfFalse(universal.contains(anvil), "CustomRegistryEntryList.universal doesn't contain anvil"); + warnIfFalse(universal.contains(coral), "CustomRegistryEntryList.universal doesn't contain brain coral"); + warnIfFalse(universal.contains(log), "CustomRegistryEntryList.universal doesn't contain oak log"); + + RegistryEntryList subtraction = CustomRegistryEntryList.subtraction( + registries.getOrThrow(RegistryKeys.BLOCK), + universal, + RegistryEntryList.of(registries.getOrThrow(RegistryKeys.BLOCK).getEntry(Blocks.ANVIL)) + ); + + warnIfFalse(!subtraction.contains(anvil), "CustomRegistryEntryList.subtraction contains anvil"); + warnIfFalse(subtraction.contains(chippedAnvil), "CustomRegistryEntryList.subtraction doesn't contain chipped anvil"); + + // a future pr test serialization logic here. + + LOGGER.info("Finished custom registry list tests..."); + }); + } + + private static void warnIfFalse(boolean condition, String message) { + if (!condition) { + LOGGER.warn(message); + } + } +} diff --git a/fabric-registry-sync-v0/src/testmod/resources/fabric.mod.json b/fabric-registry-sync-v0/src/testmod/resources/fabric.mod.json index 0ed2f135fe..912221160a 100644 --- a/fabric-registry-sync-v0/src/testmod/resources/fabric.mod.json +++ b/fabric-registry-sync-v0/src/testmod/resources/fabric.mod.json @@ -15,6 +15,7 @@ "main": [ "net.fabricmc.fabric.test.registry.sync.CustomDynamicRegistryTest", "net.fabricmc.fabric.test.registry.sync.RegistrySyncTest", + "net.fabricmc.fabric.test.registry.sync.CustomRegistryEntryListsTest", "net.fabricmc.fabric.test.registry.sync.RegistryAliasTest" ], "client": [ From cf40a6fcc65ee842d255e23a3f54e54f55c140a8 Mon Sep 17 00:00:00 2001 From: cputnam-a11y Date: Wed, 4 Jun 2025 23:01:25 -0500 Subject: [PATCH 2/8] Comments from Discord per pepper --- .../registry/CustomRegistryEntryList.java | 51 ------- .../CustomRegistryEntryListSerializer.java | 19 +++ ...omRegistryEntryListSerializerRegistry.java | 18 +++ .../DefaultCustomRegistryEntryLists.java | 30 ++++ .../registry/sync/FabricRegistryInit.java | 5 +- .../CustomRegistryEntryListImpl.java | 132 ------------------ ...gistryEntryListSerializerRegistryImpl.java | 62 ++++++++ .../DefaultCustomRegistryEntryListsImpl.java | 78 +++++++++++ .../defaults/DefaultRegistryEntryLists.java | 35 ----- .../IntersectionRegistryEntryList.java | 1 + .../defaults/InverseRegistryEntryList.java | 1 + .../defaults/UnionRegistryEntryList.java | 3 +- .../defaults/UniversalRegistryEntryList.java | 1 + .../PacketCodecs$25Mixin.java | 7 +- .../RegistryEntryListCodecMixin.java | 6 +- .../sync/CustomRegistryEntryListsTest.java | 12 +- 16 files changed, 229 insertions(+), 232 deletions(-) create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializer.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializerRegistry.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DefaultCustomRegistryEntryLists.java delete mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListImpl.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListSerializerRegistryImpl.java create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultCustomRegistryEntryListsImpl.java delete mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultRegistryEntryLists.java diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java index 3303a3e168..a9427dedd7 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java @@ -16,60 +16,9 @@ package net.fabricmc.fabric.api.event.registry; -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryEntryLookup; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.entry.RegistryEntryList; -import net.minecraft.util.Identifier; - -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListImpl; public interface CustomRegistryEntryList extends RegistryEntryList { CustomRegistryEntryListSerializer getSerializer(); - static void registerSerializer(@NotNull CustomRegistryEntryListSerializer serializer) { - CustomRegistryEntryListImpl.registerSerializer(serializer); - } - - static @Nullable CustomRegistryEntryListSerializer getSerializer(Identifier id) { - return CustomRegistryEntryListImpl.getSerializer(id); - } - - @SafeVarargs - static RegistryEntryList union(RegistryEntryList... parts) { - return CustomRegistryEntryListImpl.union(parts); - } - - @SafeVarargs - static RegistryEntryList intersection(RegistryEntryList... parts) { - return CustomRegistryEntryListImpl.intersection(parts); - } - - static RegistryEntryList inverse(RegistryEntryLookup lookup, RegistryEntryList opposite) { - return CustomRegistryEntryListImpl.inverse(lookup, opposite); - } - - static RegistryEntryList universal(RegistryEntryLookup lookup) { - return CustomRegistryEntryListImpl.universal(lookup); - } - - static RegistryEntryList subtraction(RegistryEntryLookup lookup, RegistryEntryList initial, RegistryEntryList subtracted) { - return CustomRegistryEntryListImpl.subtraction(lookup, initial, subtracted); - } - - interface CustomRegistryEntryListSerializer { - Identifier getIdentifier(); - - MapCodec> createCodec(RegistryKey> registryKey, Codec> entryCodec, boolean forceList); - - PacketCodec> createPacketCodec(RegistryKey> registryKey); - } } diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializer.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializer.java new file mode 100644 index 0000000000..0ecde69e2e --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializer.java @@ -0,0 +1,19 @@ +package net.fabricmc.fabric.api.event.registry; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.Identifier; + +public interface CustomRegistryEntryListSerializer { + Identifier getIdentifier(); + + MapCodec> createCodec(RegistryKey> registryKey, Codec> entryCodec, boolean forceList); + + PacketCodec> createPacketCodec(RegistryKey> registryKey); +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializerRegistry.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializerRegistry.java new file mode 100644 index 0000000000..573a8cd6b3 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializerRegistry.java @@ -0,0 +1,18 @@ +package net.fabricmc.fabric.api.event.registry; + +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListSerializerRegistryImpl; + +import net.minecraft.util.Identifier; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface CustomRegistryEntryListSerializerRegistry { + static void registerSerializer(@NotNull CustomRegistryEntryListSerializer serializer) { + CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(serializer); + } + + static @Nullable CustomRegistryEntryListSerializer getSerializer(Identifier id) { + return CustomRegistryEntryListSerializerRegistryImpl.getSerializer(id); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DefaultCustomRegistryEntryLists.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DefaultCustomRegistryEntryLists.java new file mode 100644 index 0000000000..de0ae00095 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DefaultCustomRegistryEntryLists.java @@ -0,0 +1,30 @@ +package net.fabricmc.fabric.api.event.registry; + +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.DefaultCustomRegistryEntryListsImpl; + +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.entry.RegistryEntryList; + +public class DefaultCustomRegistryEntryLists { + @SafeVarargs + public static RegistryEntryList union(RegistryEntryList... parts) { + return DefaultCustomRegistryEntryListsImpl.union(parts); + } + + @SafeVarargs + public static RegistryEntryList intersection(RegistryEntryList... parts) { + return DefaultCustomRegistryEntryListsImpl.intersection(parts); + } + + public static RegistryEntryList inverse(RegistryEntryLookup lookup, RegistryEntryList opposite) { + return DefaultCustomRegistryEntryListsImpl.inverse(lookup, opposite); + } + + public static RegistryEntryList universal(RegistryEntryLookup lookup) { + return DefaultCustomRegistryEntryListsImpl.universal(lookup); + } + + public static RegistryEntryList subtraction(RegistryEntryLookup lookup, RegistryEntryList initial, RegistryEntryList subtracted) { + return DefaultCustomRegistryEntryListsImpl.subtraction(lookup, initial, subtracted); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java index 6652267076..5b5384db54 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java @@ -16,6 +16,8 @@ package net.fabricmc.fabric.impl.registry.sync; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.DefaultCustomRegistryEntryListsImpl; + import net.minecraft.registry.Registries; import net.fabricmc.api.ModInitializer; @@ -25,7 +27,6 @@ import net.fabricmc.fabric.api.networking.v1.ServerConfigurationConnectionEvents; import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking; import net.fabricmc.fabric.impl.registry.sync.packet.DirectRegistryPacketHandler; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListImpl; import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.ChannelUtil; public class FabricRegistryInit implements ModInitializer { @@ -215,6 +216,6 @@ public void onInitialize() { .addAttribute(RegistryAttribute.SYNCED); ChannelUtil.init(); - CustomRegistryEntryListImpl.init(); + DefaultCustomRegistryEntryListsImpl.register(); } } diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListImpl.java deleted file mode 100644 index c00d8a716f..0000000000 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListImpl.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * 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. - */ - -package net.fabricmc.fabric.impl.registry.sync.registryentrylists; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.DynamicOps; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import net.minecraft.registry.RegistryEntryLookup; -import net.minecraft.registry.entry.RegistryEntryList; -import net.minecraft.util.Identifier; - -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.DefaultRegistryEntryLists; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.IntersectionRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.InverseRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.UnionRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.UniversalRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.RegistryWrapperUtils; - -public final class CustomRegistryEntryListImpl { - private CustomRegistryEntryListImpl() { - throw new UnsupportedOperationException(); - } - - private static final Logger LOGGER = LoggerFactory.getLogger(CustomRegistryEntryListImpl.class); - - private static final Map SERIALIZERS = new HashMap<>(); - - public static final Codec SERIALIZER_CODEC = Identifier.CODEC.flatXmap( - id -> Optional.ofNullable(SERIALIZERS.get(id)) - .map(DataResult::success) - .orElseGet( - () -> DataResult.error( - () -> "Unknown CustomRegistryEntryListSerializer: " + id - ) - ), - serializer -> Optional.of(serializer.getIdentifier()) - .filter(SERIALIZERS::containsKey) - .map(DataResult::success) - .orElseGet( - () -> DataResult.error( - () -> "Unknown CustomRegistryEntryListSerializer: " + serializer - ) - ) - ); - - public static boolean isSerializedCustomRegistryEntryList(DynamicOps ops, T entryList) { - return ops.getMap(entryList) - .map(it -> it.get("fabric:type")) - .map(Objects::nonNull) - .result() - .orElse(false); - } - - public static void registerSerializer(CustomRegistryEntryList.CustomRegistryEntryListSerializer serializer) { - CustomRegistryEntryList.CustomRegistryEntryListSerializer previous = SERIALIZERS.put(serializer.getIdentifier(), serializer); - - if (previous != null) { - LOGGER.warn("Overwriting CustomRegistryEntryListSerializer {} with {}", previous, serializer); - } - } - - public static CustomRegistryEntryList.CustomRegistryEntryListSerializer getSerializer(Identifier id) { - return SERIALIZERS.get(id); - } - - public static RegistryEntryList union(RegistryEntryList[] parts) { - return new UnionRegistryEntryList<>(List.of(validateNotNull(parts))); - } - - public static RegistryEntryList intersection(RegistryEntryList[] parts) { - return new IntersectionRegistryEntryList<>(List.of(validateNotNull(parts))); - } - - public static RegistryEntryList inverse(RegistryEntryLookup lookup, RegistryEntryList opposite) { - Objects.requireNonNull(lookup, "lookup"); - Objects.requireNonNull(opposite, "opposite"); - return new InverseRegistryEntryList<>(RegistryWrapperUtils.castOrCreateFromEntryLookup(lookup), opposite); - } - - public static RegistryEntryList universal(RegistryEntryLookup lookup) { - Objects.requireNonNull(lookup, "lookup"); - return new UniversalRegistryEntryList<>(RegistryWrapperUtils.castOrCreateFromEntryLookup(lookup)); - } - - public static RegistryEntryList subtraction(RegistryEntryLookup lookup, RegistryEntryList initial, RegistryEntryList subtracted) { - Objects.requireNonNull(lookup, "lookup"); - Objects.requireNonNull(initial, "initial"); - Objects.requireNonNull(subtracted, "subtracted"); - return new IntersectionRegistryEntryList<>(List.of(initial, inverse(lookup, subtracted))); - } - - private static RegistryEntryList[] validateNotNull(RegistryEntryList[] lists) { - Objects.requireNonNull(lists, "list array"); - - for (RegistryEntryList list : lists) { - Objects.requireNonNull(list, "list"); - } - - return lists; - } - - public static void init() { - } - - static { - DefaultRegistryEntryLists.registerDefaults(); - } -} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListSerializerRegistryImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListSerializerRegistryImpl.java new file mode 100644 index 0000000000..a34e503e11 --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListSerializerRegistryImpl.java @@ -0,0 +1,62 @@ +package net.fabricmc.fabric.impl.registry.sync.registryentrylists; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; + +public class CustomRegistryEntryListSerializerRegistryImpl { + private CustomRegistryEntryListSerializerRegistryImpl() { + throw new UnsupportedOperationException(); + } + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomRegistryEntryListSerializerRegistryImpl.class); + private static final Map SERIALIZERS = new HashMap<>(); + public static final Codec SERIALIZER_CODEC = Identifier.CODEC.flatXmap( + id -> Optional.ofNullable(SERIALIZERS.get(id)) + .map(DataResult::success) + .orElseGet( + () -> DataResult.error( + () -> "Unknown CustomRegistryEntryListSerializer: " + id + ) + ), + serializer -> Optional.of(serializer.getIdentifier()) + .filter(SERIALIZERS::containsKey) + .map(DataResult::success) + .orElseGet( + () -> DataResult.error( + () -> "Unknown CustomRegistryEntryListSerializer: " + serializer + ) + ) + ); + + public static boolean isSerializedCustomRegistryEntryList(DynamicOps ops, T entryList) { + return ops.getMap(entryList) + .map(it -> it.get("fabric:type")) + .map(Objects::nonNull) + .result() + .orElse(false); + } + + public static void registerSerializer(CustomRegistryEntryListSerializer serializer) { + CustomRegistryEntryListSerializer previous = SERIALIZERS.put(serializer.getIdentifier(), serializer); + + if (previous != null) { + LOGGER.warn("Overwriting CustomRegistryEntryListSerializer {} with {}", previous, serializer); + } + } + + public static CustomRegistryEntryListSerializer getSerializer(Identifier id) { + return SERIALIZERS.get(id); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultCustomRegistryEntryListsImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultCustomRegistryEntryListsImpl.java new file mode 100644 index 0000000000..3e2c8f300e --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultCustomRegistryEntryListsImpl.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; + +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.RegistryWrapperUtils; + +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.entry.RegistryEntryList; + +import java.util.List; +import java.util.Objects; + +public class DefaultCustomRegistryEntryListsImpl { + private static boolean initialized = false; + + public static void register() { + if (initialized) { + return; + } + + initialized = true; + CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(UnionRegistryEntryList.SERIALIZER); + CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(IntersectionRegistryEntryList.SERIALIZER); + CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(InverseRegistryEntryList.SERIALIZER); + CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(UniversalRegistryEntryList.SERIALIZER); + } + + public static RegistryEntryList union(RegistryEntryList[] parts) { + return new UnionRegistryEntryList<>(List.of(validateNotNull(parts))); + } + + public static RegistryEntryList intersection(RegistryEntryList[] parts) { + return new IntersectionRegistryEntryList<>(List.of(validateNotNull(parts))); + } + + public static RegistryEntryList inverse(RegistryEntryLookup lookup, RegistryEntryList opposite) { + Objects.requireNonNull(lookup, "lookup"); + Objects.requireNonNull(opposite, "opposite"); + return new InverseRegistryEntryList<>(RegistryWrapperUtils.castOrCreateFromEntryLookup(lookup), opposite); + } + + public static RegistryEntryList universal(RegistryEntryLookup lookup) { + Objects.requireNonNull(lookup, "lookup"); + return new UniversalRegistryEntryList<>(RegistryWrapperUtils.castOrCreateFromEntryLookup(lookup)); + } + + public static RegistryEntryList subtraction(RegistryEntryLookup lookup, RegistryEntryList initial, RegistryEntryList subtracted) { + Objects.requireNonNull(lookup, "lookup"); + Objects.requireNonNull(initial, "initial"); + Objects.requireNonNull(subtracted, "subtracted"); + return new IntersectionRegistryEntryList<>(List.of(initial, inverse(lookup, subtracted))); + } + + private static RegistryEntryList[] validateNotNull(RegistryEntryList[] lists) { + Objects.requireNonNull(lists, "list array"); + + for (RegistryEntryList list : lists) { + Objects.requireNonNull(list, "list"); + } + + return lists; + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultRegistryEntryLists.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultRegistryEntryLists.java deleted file mode 100644 index a8df84d2db..0000000000 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultRegistryEntryLists.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * 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. - */ - -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; - -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListImpl; - -public class DefaultRegistryEntryLists { - private static boolean initialized = false; - - public static void registerDefaults() { - if (initialized) { - return; - } - - initialized = true; - CustomRegistryEntryListImpl.registerSerializer(UnionRegistryEntryList.SERIALIZER); - CustomRegistryEntryListImpl.registerSerializer(IntersectionRegistryEntryList.SERIALIZER); - CustomRegistryEntryListImpl.registerSerializer(InverseRegistryEntryList.SERIALIZER); - CustomRegistryEntryListImpl.registerSerializer(UniversalRegistryEntryList.SERIALIZER); - } -} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java index fe217b3d01..3694909349 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java @@ -22,6 +22,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; import org.jetbrains.annotations.NotNull; import net.minecraft.network.RegistryByteBuf; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java index 2c3b8f2b86..b979b80528 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java @@ -27,6 +27,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java index 6e21248f4a..e7b1969b4c 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java @@ -22,6 +22,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; import org.jetbrains.annotations.NotNull; import net.minecraft.network.RegistryByteBuf; @@ -37,7 +38,7 @@ import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; public class UnionRegistryEntryList extends MultiPartRegistryEntryList { - public static final CustomRegistryEntryList.CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); + public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); public UnionRegistryEntryList(List> parts) { super(parts); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java index 5b599464d7..4a4e17bd7a 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java @@ -25,6 +25,7 @@ import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; import org.jetbrains.annotations.NotNull; import net.minecraft.block.Blocks; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java index dd62f602ff..1992496065 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java @@ -22,6 +22,9 @@ import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Cancellable; import io.netty.buffer.ByteBuf; +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; +import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializerRegistry; + import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -55,7 +58,7 @@ class PacketCodecs$25Mixin { RegistryKey> field_54511; @Unique - HashMap>> cache = new HashMap<>(); + HashMap>> cache = new HashMap<>(); private PacketCodecs$25Mixin() { } @@ -95,7 +98,7 @@ private int decodeCustomRegistryEntryList(ByteBuf buf, Operation origin } Identifier identifier = Identifier.PACKET_CODEC.decode(buf); - CustomRegistryEntryList.CustomRegistryEntryListSerializer serializer = CustomRegistryEntryList.getSerializer(identifier); + CustomRegistryEntryListSerializer serializer = CustomRegistryEntryListSerializerRegistry.getSerializer(identifier); if (serializer == null) { throw new IllegalStateException("Unknown CustomRegistryEntryListSerializer: " + identifier); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java index 272ac7d41b..83d57aed65 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java @@ -20,6 +20,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; +import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListSerializerRegistryImpl; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -34,7 +35,6 @@ import net.minecraft.registry.entry.RegistryEntryListCodec; import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListImpl; @SuppressWarnings("unchecked") @Mixin(RegistryEntryListCodec.class) @@ -47,7 +47,7 @@ class RegistryEntryListCodecMixin { at = @At("TAIL") ) private void bindFabricCodec(RegistryKey> registry, Codec> entryCodec, boolean alwaysSerializeAsList, CallbackInfo ci) { - fabric$codec = CustomRegistryEntryListImpl.SERIALIZER_CODEC.dispatch( + fabric$codec = CustomRegistryEntryListSerializerRegistryImpl.SERIALIZER_CODEC.dispatch( "fabric:type", CustomRegistryEntryList::getSerializer, serializer -> serializer.createCodec(registry, entryCodec, alwaysSerializeAsList) @@ -77,7 +77,7 @@ private void encodeCustomWithCustomCodec(RegistryEntryList registryEnt cancellable = true ) private void decodeCustomWithCustomCodec(DynamicOps ops, T input, CallbackInfoReturnable, T>>> cir) { - if (CustomRegistryEntryListImpl.isSerializedCustomRegistryEntryList(ops, input)) { + if (CustomRegistryEntryListSerializerRegistryImpl.isSerializedCustomRegistryEntryList(ops, input)) { cir.setReturnValue( fabric$codec.decode(ops, input).map( pair -> pair.mapFirst( diff --git a/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java b/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java index 48ec224aaa..1ef3099907 100644 --- a/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java +++ b/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java @@ -17,6 +17,7 @@ package net.fabricmc.fabric.test.registry.sync; import com.mojang.logging.LogUtils; +import net.fabricmc.fabric.api.event.registry.DefaultCustomRegistryEntryLists; import org.slf4j.Logger; import net.minecraft.block.Block; @@ -28,7 +29,6 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; public class CustomRegistryEntryListsTest implements ModInitializer { private static final Logger LOGGER = LogUtils.getLogger(); @@ -49,7 +49,7 @@ public void onInitialize() { RegistryEntry coral = registries.getOrThrow(RegistryKeys.BLOCK).getEntry(Blocks.BRAIN_CORAL_BLOCK); RegistryEntry log = registries.getOrThrow(RegistryKeys.BLOCK).getEntry(Blocks.OAK_LOG); - RegistryEntryList union = CustomRegistryEntryList.union( + RegistryEntryList union = DefaultCustomRegistryEntryLists.union( anvils, corals ); @@ -57,7 +57,7 @@ public void onInitialize() { warnIfFalse(union.contains(anvil), "CustomRegistryEntryList.union doesn't contain anvil"); warnIfFalse(union.contains(coral), "CustomRegistryEntryList.union doesn't contain brain coral"); - RegistryEntryList intersection = CustomRegistryEntryList.intersection( + RegistryEntryList intersection = DefaultCustomRegistryEntryLists.intersection( anvils, corals ); @@ -65,7 +65,7 @@ public void onInitialize() { warnIfFalse(!intersection.contains(anvil), "CustomRegistryEntryList.intersection contains anvil"); warnIfFalse(!intersection.contains(coral), "CustomRegistryEntryList.intersection contains brain coral"); - RegistryEntryList inverse = CustomRegistryEntryList.inverse( + RegistryEntryList inverse = DefaultCustomRegistryEntryLists.inverse( registries.getOrThrow(RegistryKeys.BLOCK), union ); @@ -74,7 +74,7 @@ public void onInitialize() { warnIfFalse(!inverse.contains(coral), "CustomRegistryEntryList.inverse contains brain coral"); warnIfFalse(inverse.contains(log), "CustomRegistryEntryList.inverse doesn't contain oak log"); - RegistryEntryList universal = CustomRegistryEntryList.universal( + RegistryEntryList universal = DefaultCustomRegistryEntryLists.universal( registries.getOrThrow(RegistryKeys.BLOCK) ); @@ -82,7 +82,7 @@ public void onInitialize() { warnIfFalse(universal.contains(coral), "CustomRegistryEntryList.universal doesn't contain brain coral"); warnIfFalse(universal.contains(log), "CustomRegistryEntryList.universal doesn't contain oak log"); - RegistryEntryList subtraction = CustomRegistryEntryList.subtraction( + RegistryEntryList subtraction = DefaultCustomRegistryEntryLists.subtraction( registries.getOrThrow(RegistryKeys.BLOCK), universal, RegistryEntryList.of(registries.getOrThrow(RegistryKeys.BLOCK).getEntry(Blocks.ANVIL)) From 21e6ebf435973e9d64d0961d48e0898188b24630 Mon Sep 17 00:00:00 2001 From: cputnam-a11y Date: Thu, 5 Jun 2025 14:17:37 -0500 Subject: [PATCH 3/8] Changes --- ...omRegistryEntryListSerializerRegistry.java | 18 ------- .../CustomRegistryEntryList.java | 3 +- .../CustomRegistryEntryListSerializer.java | 18 ++++++- ...omRegistryEntryListSerializerRegistry.java | 34 +++++++++++++ .../DefaultCustomRegistryEntryLists.java | 20 +++++++- .../DependentRegistryEntryList.java | 33 +++++++------ ...gistryEntryListSerializerRegistryImpl.java | 20 +++++++- .../DefaultCustomRegistryEntryListsImpl.java | 10 ++-- .../IntersectionRegistryEntryList.java | 6 +-- .../defaults/InverseRegistryEntryList.java | 8 +-- .../defaults/MultiPartRegistryEntryList.java | 4 +- .../defaults/UnionRegistryEntryList.java | 6 +-- .../defaults/UniversalRegistryEntryList.java | 8 +-- .../util/ChannelUtil.java | 10 ++-- ...egistryWrapperFromRegistryEntryLookup.java | 23 +++------ .../util/RegistryWrapperUtils.java | 49 +++++++++---------- .../util/TagKeyCache.java | 2 +- .../registry/sync/FabricRegistryInit.java | 5 +- .../PacketCodecs$25Mixin.java | 9 ++-- .../RegistryEntryListCodecMixin.java | 4 +- .../RegistryEntryListMixin.java | 2 +- .../sync/registryentrylists/TagKeyMixin.java | 2 +- .../src/main/resources/fabric.mod.json | 2 +- .../sync/CustomRegistryEntryListsTest.java | 2 +- 24 files changed, 177 insertions(+), 121 deletions(-) delete mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializerRegistry.java rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/{ => entrylists}/CustomRegistryEntryList.java (93%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/{ => entrylists}/CustomRegistryEntryListSerializer.java (52%) create mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/{ => entrylists}/DefaultCustomRegistryEntryLists.java (57%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/{ => entrylists}/DependentRegistryEntryList.java (70%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/CustomRegistryEntryListSerializerRegistryImpl.java (72%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/defaults/DefaultCustomRegistryEntryListsImpl.java (91%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/defaults/IntersectionRegistryEntryList.java (93%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/defaults/InverseRegistryEntryList.java (94%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/defaults/MultiPartRegistryEntryList.java (95%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/defaults/UnionRegistryEntryList.java (92%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/defaults/UniversalRegistryEntryList.java (92%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/util/ChannelUtil.java (83%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/util/RegistryWrapperFromRegistryEntryLookup.java (85%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/util/RegistryWrapperUtils.java (74%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{sync/registryentrylists => entrylists}/util/TagKeyCache.java (93%) diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializerRegistry.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializerRegistry.java deleted file mode 100644 index 573a8cd6b3..0000000000 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializerRegistry.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.fabricmc.fabric.api.event.registry; - -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListSerializerRegistryImpl; - -import net.minecraft.util.Identifier; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public interface CustomRegistryEntryListSerializerRegistry { - static void registerSerializer(@NotNull CustomRegistryEntryListSerializer serializer) { - CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(serializer); - } - - static @Nullable CustomRegistryEntryListSerializer getSerializer(Identifier id) { - return CustomRegistryEntryListSerializerRegistryImpl.getSerializer(id); - } -} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryList.java similarity index 93% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryList.java index a9427dedd7..caa47b74c2 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryList.java @@ -14,11 +14,10 @@ * limitations under the License. */ -package net.fabricmc.fabric.api.event.registry; +package net.fabricmc.fabric.api.event.registry.entrylists; import net.minecraft.registry.entry.RegistryEntryList; public interface CustomRegistryEntryList extends RegistryEntryList { CustomRegistryEntryListSerializer getSerializer(); - } diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializer.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java similarity index 52% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializer.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java index 0ecde69e2e..82c3031bfc 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/CustomRegistryEntryListSerializer.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java @@ -1,4 +1,20 @@ -package net.fabricmc.fabric.api.event.registry; +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.api.event.registry.entrylists; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java new file mode 100644 index 0000000000..ee58e44f5e --- /dev/null +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.api.event.registry.entrylists; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.impl.registry.entrylists.CustomRegistryEntryListSerializerRegistryImpl; + +public interface CustomRegistryEntryListSerializerRegistry { + static void registerSerializer(@NotNull CustomRegistryEntryListSerializer serializer) { + CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(serializer); + } + + static @Nullable CustomRegistryEntryListSerializer getSerializer(Identifier id) { + return CustomRegistryEntryListSerializerRegistryImpl.getSerializer(id); + } +} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DefaultCustomRegistryEntryLists.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java similarity index 57% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DefaultCustomRegistryEntryLists.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java index de0ae00095..c27bf59339 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DefaultCustomRegistryEntryLists.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java @@ -1,10 +1,26 @@ -package net.fabricmc.fabric.api.event.registry; +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.DefaultCustomRegistryEntryListsImpl; +package net.fabricmc.fabric.api.event.registry.entrylists; import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.entry.RegistryEntryList; +import net.fabricmc.fabric.impl.registry.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; + public class DefaultCustomRegistryEntryLists { @SafeVarargs public static RegistryEntryList union(RegistryEntryList... parts) { diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DependentRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java similarity index 70% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DependentRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java index dab9fd4098..54921fdbed 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/DependentRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package net.fabricmc.fabric.api.event.registry; +package net.fabricmc.fabric.api.event.registry.entrylists; -import java.util.ArrayList; import java.util.Collections; -import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; import com.google.common.collect.MapMaker; import org.jetbrains.annotations.ApiStatus; @@ -31,33 +31,35 @@ @ApiStatus.NonExtendable public interface DependentRegistryEntryList { // creating a cycle in the graph will lead to stack overflow, do with this knowledge what you will - Map, List>> DEPENDENCIES = new MapMaker() - .weakKeys() - .weakValues() - .makeMap(); + Map, Set>> DEPENDENCIES = new MapMaker().weakKeys().makeMap(); - default List> getDependencies() { - return Collections.unmodifiableList(castToT(DEPENDENCIES.get(this.asSelf()))); + default Set> getDependencies() { + return Collections.unmodifiableSet(castToT(DEPENDENCIES.get(this.asSelf()))); } /** - * Unregisters a dependency. + * Unregisters a dependency on this. * Does nothing is the dependency is not registered. * * @param dependency the dependency to unregister */ default void unregisterDependency(RegistryEntryList dependency) { - List> dependencies = castToT(DEPENDENCIES.get(this.asSelf())); + Set> dependencies = castToT(DEPENDENCIES.get(this.asSelf())); if (dependencies != null) { dependencies.remove(dependency); } } + /** + * registers a dependency on this. + * + * @param dependency the dependency to register + */ default void registerDependency(RegistryEntryList dependency) { DEPENDENCIES.computeIfAbsent( this.asSelf(), - k -> new ArrayList<>() + k -> Collections.newSetFromMap(new WeakHashMap<>()) ) .add(dependency); } @@ -66,8 +68,7 @@ default void registerDependency(RegistryEntryList dependency) { * Invalidate dependents is called by this list when it is invalidated. */ private void invalidateDependents() { - DEPENDENCIES.getOrDefault(this.asSelf(), List.of()) - .forEach(DependentRegistryEntryList::invalidate); + DEPENDENCIES.getOrDefault(this.asSelf(), Set.of()).forEach(DependentRegistryEntryList::invalidate); } /** @@ -85,7 +86,7 @@ private RegistryEntryList asSelf() { // why can't java just have field generics or something? @SuppressWarnings("unchecked") - private static List> castToT(List> entryList) { - return (List>) (Object) entryList; + private static Set> castToT(Set> entryList) { + return (Set>) (Object) entryList; } } diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListSerializerRegistryImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java similarity index 72% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListSerializerRegistryImpl.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java index a34e503e11..fd7a1d16b4 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/CustomRegistryEntryListSerializerRegistryImpl.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java @@ -1,4 +1,20 @@ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists; +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.impl.registry.entrylists; import java.util.HashMap; import java.util.Map; @@ -13,7 +29,7 @@ import net.minecraft.util.Identifier; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; public class CustomRegistryEntryListSerializerRegistryImpl { private CustomRegistryEntryListSerializerRegistryImpl() { diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultCustomRegistryEntryListsImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java similarity index 91% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultCustomRegistryEntryListsImpl.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java index 3e2c8f300e..8cdf03d5db 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/DefaultCustomRegistryEntryListsImpl.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; +package net.fabricmc.fabric.impl.registry.entrylists.defaults; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListSerializerRegistryImpl; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.RegistryWrapperUtils; +import java.util.List; +import java.util.Objects; import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.entry.RegistryEntryList; -import java.util.List; -import java.util.Objects; +import net.fabricmc.fabric.impl.registry.entrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.entrylists.util.RegistryWrapperUtils; public class DefaultCustomRegistryEntryListsImpl { private static boolean initialized = false; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/IntersectionRegistryEntryList.java similarity index 93% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/IntersectionRegistryEntryList.java index 3694909349..9cc68629c0 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/IntersectionRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/IntersectionRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; +package net.fabricmc.fabric.impl.registry.entrylists.defaults; import java.util.List; import java.util.Set; @@ -22,7 +22,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; import org.jetbrains.annotations.NotNull; import net.minecraft.network.RegistryByteBuf; @@ -35,7 +34,8 @@ import net.minecraft.registry.entry.RegistryEntryListCodec; import net.minecraft.util.Identifier; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; public class IntersectionRegistryEntryList extends MultiPartRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/InverseRegistryEntryList.java similarity index 94% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/InverseRegistryEntryList.java index b979b80528..23cb318576 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/InverseRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/InverseRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; +package net.fabricmc.fabric.impl.registry.entrylists.defaults; import java.util.Iterator; import java.util.List; @@ -27,7 +27,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -49,8 +48,9 @@ import net.minecraft.util.Util; import net.minecraft.util.math.random.Random; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.RegistryWrapperUtils; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; +import net.fabricmc.fabric.impl.registry.entrylists.util.RegistryWrapperUtils; public class InverseRegistryEntryList implements CustomRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/MultiPartRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/MultiPartRegistryEntryList.java similarity index 95% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/MultiPartRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/MultiPartRegistryEntryList.java index e8a0f327a0..c743fa2d6e 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/MultiPartRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/MultiPartRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; +package net.fabricmc.fabric.impl.registry.entrylists.defaults; import java.util.Iterator; import java.util.List; @@ -34,7 +34,7 @@ import net.minecraft.util.Util; import net.minecraft.util.math.random.Random; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; public abstract class MultiPartRegistryEntryList implements CustomRegistryEntryList { private final ImmutableList> parts; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UnionRegistryEntryList.java similarity index 92% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UnionRegistryEntryList.java index e7b1969b4c..b1f78fb4d5 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UnionRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UnionRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; +package net.fabricmc.fabric.impl.registry.entrylists.defaults; import java.util.List; import java.util.Set; @@ -22,7 +22,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; import org.jetbrains.annotations.NotNull; import net.minecraft.network.RegistryByteBuf; @@ -35,7 +34,8 @@ import net.minecraft.registry.entry.RegistryEntryListCodec; import net.minecraft.util.Identifier; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; public class UnionRegistryEntryList extends MultiPartRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UniversalRegistryEntryList.java similarity index 92% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UniversalRegistryEntryList.java index 4a4e17bd7a..3d59218aeb 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/defaults/UniversalRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UniversalRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults; +package net.fabricmc.fabric.impl.registry.entrylists.defaults; import java.util.Iterator; import java.util.List; @@ -25,7 +25,6 @@ import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; import org.jetbrains.annotations.NotNull; import net.minecraft.block.Blocks; @@ -43,8 +42,9 @@ import net.minecraft.util.Util; import net.minecraft.util.math.random.Random; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.RegistryWrapperUtils; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; +import net.fabricmc.fabric.impl.registry.entrylists.util.RegistryWrapperUtils; public record UniversalRegistryEntryList(RegistryWrapper source) implements CustomRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/ChannelUtil.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/ChannelUtil.java similarity index 83% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/ChannelUtil.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/ChannelUtil.java index f427f7f266..b581d948c2 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/ChannelUtil.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/ChannelUtil.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.util; +package net.fabricmc.fabric.impl.registry.entrylists.util; import java.util.Set; @@ -28,11 +28,15 @@ import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.impl.networking.FabricRegistryByteBuf; +/** + * Allows checking if a {@link RegistryByteBuf} has the registry sync module installed on the other side. + */ public class ChannelUtil { + //this is a dummy, it should never actually be used private static final PacketCodec CODEC = PacketCodec.unit(null); private static final CustomPayload.Id ID = new CustomPayload.Id<>( - Identifier.of("fabric", "is_installed") + Identifier.of("fabric", "is_installed_v0") ); public static void init() { @@ -40,7 +44,7 @@ public static void init() { PayloadTypeRegistry.configurationS2C().register(ID, CODEC); } - @SuppressWarnings({"BooleanMethodIsAlwaysInverted"}) + @SuppressWarnings("BooleanMethodIsAlwaysInverted") public static boolean isInstalled(RegistryByteBuf buf) { if (!(buf instanceof FabricRegistryByteBuf fabricRegistryByteBuf)) { return false; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperFromRegistryEntryLookup.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java similarity index 85% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperFromRegistryEntryLookup.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java index 9f0e05b363..21a6b83d1b 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperFromRegistryEntryLookup.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.util; +package net.fabricmc.fabric.impl.registry.entrylists.util; import java.util.Optional; import java.util.stream.Stream; @@ -28,11 +28,10 @@ import net.fabricmc.fabric.mixin.registry.sync.registryentrylists.RegistryKeyAccessor; -@SuppressWarnings("unchecked") record RegistryWrapperFromRegistryEntryLookup(RegistryEntryLookup entryLookup) implements RegistryWrapper { /** - * @see RegistryWrapperUtils#castOrCreateFromEntryLookup(RegistryEntryLookup) * @param entryLookup the entry lookup backing this wrapper + * @see RegistryWrapperUtils#castOrCreateFromEntryLookup(RegistryEntryLookup) */ RegistryWrapperFromRegistryEntryLookup { if (entryLookup instanceof RegistryWrapper) { @@ -41,27 +40,21 @@ record RegistryWrapperFromRegistryEntryLookup(RegistryEntryLookup entryLoo } @Override + @SuppressWarnings("unchecked") public Stream> streamEntries() { return RegistryKeyAccessor .getInstances() .values() .stream() - .flatMap( - key -> entryLookup - .getOptional((RegistryKey) key) - .stream() - ); + .flatMap(key -> entryLookup.getOptional((RegistryKey) key).stream()); } @Override + @SuppressWarnings("unchecked") public Stream> getTags() { - return TagKeyCache - .stream() - .flatMap( - key -> entryLookup - .getOptional((TagKey) key) - .stream() - ); + return TagKeyCache.stream().flatMap( + key -> entryLookup.getOptional((TagKey) key).stream() + ); } @Override diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperUtils.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperUtils.java similarity index 74% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperUtils.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperUtils.java index 80c7b718cd..12ae046c3f 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/RegistryWrapperUtils.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperUtils.java @@ -14,12 +14,10 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.util; +package net.fabricmc.fabric.impl.registry.entrylists.util; import java.util.stream.Stream; -import com.mojang.datafixers.util.Pair; -import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.MapCodec; @@ -34,6 +32,9 @@ import net.minecraft.registry.RegistryOps; import net.minecraft.registry.RegistryWrapper; +/** + * Utility class for working with {@link RegistryWrapper}s. + */ public class RegistryWrapperUtils { /** * gets a {@link RegistryWrapper} from a {@link RegistryEntryLookup}. @@ -51,10 +52,19 @@ public static RegistryWrapper castOrCreateFromEntryLookup(RegistryEntryLo return new RegistryWrapperFromRegistryEntryLookup<>(registryEntryLookup); } + /** + * Creates a {@link MapCodec} for a {@link RegistryWrapper} based on the provided {@link RegistryKey}. + * the Wrapper is not encoded in any way and is fetched from the RegistryOps on decode. + * + * @param registryKey the key of the registry to create a wrapper for + * @param the type of elements in the registry + * @return a MapCodec that can decode a {@link RegistryWrapper} from the registry key + */ public static MapCodec> createMapCodec(RegistryKey> registryKey) { return new MapCodec<>() { @Override public Stream keys(DynamicOps ops) { + // no keys, this doesn't touch this input or the output return Stream.empty(); } @@ -72,33 +82,20 @@ public DataResult> decode(DynamicOps ops, MapLike i @Override public RecordBuilder encode(RegistryWrapper input, DynamicOps ops, RecordBuilder prefix) { + // No need to encode return prefix; } }; } - public static Codec> createCodec(RegistryKey> registryKey) { - return new Codec<>() { - @Override - public DataResult, T>> decode(DynamicOps ops, T input) { - if (!(ops instanceof RegistryOps registryOps)) { - return DataResult.error(() -> "Can't access registry"); - } - - return registryOps.getEntryLookup(registryKey) - .map(RegistryWrapperUtils::castOrCreateFromEntryLookup) - .map(it -> new Pair<>(it, input)) - .map(DataResult::success) - .orElseGet(() -> DataResult.error(() -> "Registry Not Found")); - } - - @Override - public DataResult encode(RegistryWrapper input, DynamicOps ops, T prefix) { - return DataResult.success(prefix); - } - }; - } - + /** + * Creates a {@link PacketCodec} for a {@link RegistryWrapper} based on the provided {@link RegistryKey}. + * the Wrapper is not encoded in any way and is fetched from the RegistryByteBuf on decode. + * + * @param registryKey the key of the registry to create a wrapper for + * @param the type of elements in the registry + * @return a PacketCodec that can decode a {@link RegistryWrapper} from the registry key + */ public static PacketCodec> createPacketCodec(RegistryKey> registryKey) { return new PacketCodec<>() { @Override @@ -108,7 +105,7 @@ public RegistryWrapper decode(RegistryByteBuf buf) { @Override public void encode(RegistryByteBuf buf, RegistryWrapper value) { - // No need to encode, as the registry is already present in the buffer + // No need to encode } }; } diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/TagKeyCache.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/TagKeyCache.java similarity index 93% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/TagKeyCache.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/TagKeyCache.java index 8d73b62d49..5245562ac5 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/registryentrylists/util/TagKeyCache.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/TagKeyCache.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.sync.registryentrylists.util; +package net.fabricmc.fabric.impl.registry.entrylists.util; import java.util.Set; import java.util.stream.Stream; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java index 5b5384db54..bfa023f596 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java @@ -16,8 +16,6 @@ package net.fabricmc.fabric.impl.registry.sync; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.defaults.DefaultCustomRegistryEntryListsImpl; - import net.minecraft.registry.Registries; import net.fabricmc.api.ModInitializer; @@ -26,8 +24,9 @@ import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerConfigurationConnectionEvents; import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking; +import net.fabricmc.fabric.impl.registry.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; +import net.fabricmc.fabric.impl.registry.entrylists.util.ChannelUtil; import net.fabricmc.fabric.impl.registry.sync.packet.DirectRegistryPacketHandler; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.ChannelUtil; public class FabricRegistryInit implements ModInitializer { @Override diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java index 1992496065..611add5829 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java @@ -22,9 +22,6 @@ import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Cancellable; import io.netty.buffer.ByteBuf; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializer; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryListSerializerRegistry; - import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -42,8 +39,10 @@ import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.util.Identifier; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.ChannelUtil; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializerRegistry; +import net.fabricmc.fabric.impl.registry.entrylists.util.ChannelUtil; @SuppressWarnings("unchecked") @Mixin(targets = "net.minecraft.network.codec.PacketCodecs$25") diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java index 83d57aed65..9de075c8cc 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java @@ -20,7 +20,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.CustomRegistryEntryListSerializerRegistryImpl; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -34,7 +33,8 @@ import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.registry.entry.RegistryEntryListCodec; -import net.fabricmc.fabric.api.event.registry.CustomRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; +import net.fabricmc.fabric.impl.registry.entrylists.CustomRegistryEntryListSerializerRegistryImpl; @SuppressWarnings("unchecked") @Mixin(RegistryEntryListCodec.class) diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java index a07312a350..52fe09f2ed 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java @@ -20,7 +20,7 @@ import net.minecraft.registry.entry.RegistryEntryList; -import net.fabricmc.fabric.api.event.registry.DependentRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.DependentRegistryEntryList; @Mixin(RegistryEntryList.class) interface RegistryEntryListMixin extends DependentRegistryEntryList { diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java index 16dcdbd910..cc78b14d01 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java @@ -28,7 +28,7 @@ import net.minecraft.registry.tag.TagKey; -import net.fabricmc.fabric.impl.registry.sync.registryentrylists.util.TagKeyCache; +import net.fabricmc.fabric.impl.registry.entrylists.util.TagKeyCache; @Mixin(TagKey.class) class TagKeyMixin { diff --git a/fabric-registry-sync-v0/src/main/resources/fabric.mod.json b/fabric-registry-sync-v0/src/main/resources/fabric.mod.json index ad0bf8a7e7..c1b0341bf0 100644 --- a/fabric-registry-sync-v0/src/main/resources/fabric.mod.json +++ b/fabric-registry-sync-v0/src/main/resources/fabric.mod.json @@ -41,7 +41,7 @@ "fabric-api:module-lifecycle": "stable", "loom:injected_interfaces": { "net/minecraft/class_2378": ["net/fabricmc/fabric/api/event/registry/FabricRegistry"], - "net/minecraft/class_6885": ["net/fabricmc/fabric/api/event/registry/DependentRegistryEntryList"] + "net/minecraft/class_6885": ["net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList"] } } } diff --git a/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java b/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java index 1ef3099907..a056514d09 100644 --- a/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java +++ b/fabric-registry-sync-v0/src/testmod/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsTest.java @@ -17,7 +17,6 @@ package net.fabricmc.fabric.test.registry.sync; import com.mojang.logging.LogUtils; -import net.fabricmc.fabric.api.event.registry.DefaultCustomRegistryEntryLists; import org.slf4j.Logger; import net.minecraft.block.Block; @@ -29,6 +28,7 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents; +import net.fabricmc.fabric.api.event.registry.entrylists.DefaultCustomRegistryEntryLists; public class CustomRegistryEntryListsTest implements ModInitializer { private static final Logger LOGGER = LogUtils.getLogger(); From 70a8be764f69632c0bc2797a75c42101b6ed2ff3 Mon Sep 17 00:00:00 2001 From: cputnam-a11y Date: Thu, 5 Jun 2025 14:24:54 -0500 Subject: [PATCH 4/8] rename --- .../util/RegistryWrapperFromRegistryEntryLookup.java | 2 +- .../PacketCodecs$25Mixin.java | 2 +- .../RegistryEntryListCodecMixin.java | 2 +- .../RegistryEntryListMixin.java | 2 +- .../RegistryEntryListNamedMixin.java | 2 +- .../RegistryKeyAccessor.java | 2 +- .../TagKeyMixin.java | 2 +- .../resources/fabric-registry-sync-v0.mixins.json | 12 ++++++------ 8 files changed, 13 insertions(+), 13 deletions(-) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/{registryentrylists => entrylists}/PacketCodecs$25Mixin.java (98%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/{registryentrylists => entrylists}/RegistryEntryListCodecMixin.java (98%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/{registryentrylists => entrylists}/RegistryEntryListMixin.java (93%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/{registryentrylists => entrylists}/RegistryEntryListNamedMixin.java (94%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/{registryentrylists => entrylists}/RegistryKeyAccessor.java (93%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/{registryentrylists => entrylists}/TagKeyMixin.java (95%) diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java index 21a6b83d1b..bfa88a399b 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java @@ -26,7 +26,7 @@ import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.registry.tag.TagKey; -import net.fabricmc.fabric.mixin.registry.sync.registryentrylists.RegistryKeyAccessor; +import net.fabricmc.fabric.mixin.registry.sync.entrylists.RegistryKeyAccessor; record RegistryWrapperFromRegistryEntryLookup(RegistryEntryLookup entryLookup) implements RegistryWrapper { /** diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java similarity index 98% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java index 611add5829..12bb1cabd5 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/PacketCodecs$25Mixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; +package net.fabricmc.fabric.mixin.registry.sync.entrylists; import java.util.HashMap; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java similarity index 98% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java index 9de075c8cc..65db9c28a2 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListCodecMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; +package net.fabricmc.fabric.mixin.registry.sync.entrylists; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListMixin.java similarity index 93% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListMixin.java index 52fe09f2ed..ff5ddb1fb1 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListMixin.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; +package net.fabricmc.fabric.mixin.registry.sync.entrylists; import org.spongepowered.asm.mixin.Mixin; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListNamedMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListNamedMixin.java similarity index 94% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListNamedMixin.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListNamedMixin.java index 60cd2e87ca..3edb60dc62 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryEntryListNamedMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListNamedMixin.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; +package net.fabricmc.fabric.mixin.registry.sync.entrylists; import java.util.List; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryKeyAccessor.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryKeyAccessor.java similarity index 93% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryKeyAccessor.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryKeyAccessor.java index c92578d1b6..1333c2da08 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/RegistryKeyAccessor.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryKeyAccessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; +package net.fabricmc.fabric.mixin.registry.sync.entrylists; import java.util.concurrent.ConcurrentMap; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/TagKeyMixin.java similarity index 95% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/TagKeyMixin.java index cc78b14d01..489b9adb14 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/registryentrylists/TagKeyMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/TagKeyMixin.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.mixin.registry.sync.registryentrylists; +package net.fabricmc.fabric.mixin.registry.sync.entrylists; import java.util.Collections; import java.util.Set; diff --git a/fabric-registry-sync-v0/src/main/resources/fabric-registry-sync-v0.mixins.json b/fabric-registry-sync-v0/src/main/resources/fabric-registry-sync-v0.mixins.json index 3e536c5c60..b1ed3492d1 100644 --- a/fabric-registry-sync-v0/src/main/resources/fabric-registry-sync-v0.mixins.json +++ b/fabric-registry-sync-v0/src/main/resources/fabric-registry-sync-v0.mixins.json @@ -19,12 +19,12 @@ "SerializedChunkMixin", "SimpleRegistryAccessor", "SimpleRegistryMixin", - "registryentrylists.RegistryEntryListNamedMixin", - "registryentrylists.PacketCodecs$25Mixin", - "registryentrylists.RegistryEntryListCodecMixin", - "registryentrylists.RegistryEntryListMixin", - "registryentrylists.RegistryKeyAccessor", - "registryentrylists.TagKeyMixin" + "entrylists.RegistryEntryListNamedMixin", + "entrylists.PacketCodecs$25Mixin", + "entrylists.RegistryEntryListCodecMixin", + "entrylists.RegistryEntryListMixin", + "entrylists.RegistryKeyAccessor", + "entrylists.TagKeyMixin" ], "injectors": { "defaultRequire": 1 From 28ba2dda9c9041253b1dc8d180f41280683cfbd1 Mon Sep 17 00:00:00 2001 From: cputnam-a11y Date: Fri, 6 Jun 2025 10:52:57 -0500 Subject: [PATCH 5/8] Unit Testing & Proper Weakness --- .../DependentRegistryEntryList.java | 5 +- .../CustomRegistryEntryListsUnitTests.java | 123 ++++++++++++++++++ 2 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java index 54921fdbed..5cc82a99b3 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java @@ -21,7 +21,6 @@ import java.util.Set; import java.util.WeakHashMap; -import com.google.common.collect.MapMaker; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.MustBeInvokedByOverriders; @@ -31,10 +30,10 @@ @ApiStatus.NonExtendable public interface DependentRegistryEntryList { // creating a cycle in the graph will lead to stack overflow, do with this knowledge what you will - Map, Set>> DEPENDENCIES = new MapMaker().weakKeys().makeMap(); + Map, Set>> DEPENDENCIES = new WeakHashMap<>(); default Set> getDependencies() { - return Collections.unmodifiableSet(castToT(DEPENDENCIES.get(this.asSelf()))); + return Collections.unmodifiableSet(castToT(DEPENDENCIES.getOrDefault(this.asSelf(), Set.of()))); } /** diff --git a/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java b/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java new file mode 100644 index 0000000000..5b981f4895 --- /dev/null +++ b/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * 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. + */ + +package net.fabricmc.fabric.test.registry.sync; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.stream.Stream; + +import com.google.gson.JsonElement; +import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mockito.invocation.InvocationOnMock; + +import net.minecraft.Bootstrap; +import net.minecraft.SharedConstants; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.registry.DynamicRegistryManager; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryOps; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.entry.RegistryEntryListCodec; + +import net.fabricmc.fabric.impl.registry.entrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; +import net.fabricmc.fabric.impl.registry.entrylists.defaults.InverseRegistryEntryList; + +public class CustomRegistryEntryListsUnitTests { + @BeforeAll + static void beforeAll() { + SharedConstants.createGameVersion(); + Bootstrap.initialize(); + DefaultCustomRegistryEntryListsImpl.register(); + } + + @Test + void testSerialization() { + DynamicRegistryManager drm = mockDRM(); + Registry reg = drm.getOrThrow(RegistryKeys.BLOCK); + RegistryOps ops = drm.getOps(JsonOps.INSTANCE); + RegistryEntryList entryList = RegistryEntryList.of(reg.getEntry(Blocks.ACACIA_LEAVES), reg.getEntry(Blocks.BRAIN_CORAL_BLOCK)); + InverseRegistryEntryList customEntryList = new InverseRegistryEntryList<>(reg, entryList); + Codec> codec = swapType(RegistryEntryListCodec.create(reg.getKey(), reg.getEntryCodec(), false)); + JsonElement serialized = Assertions.assertDoesNotThrow(() -> codec.encodeStart(ops, customEntryList).getOrThrow()); + Assertions.assertTrue(CustomRegistryEntryListSerializerRegistryImpl.isSerializedCustomRegistryEntryList(ops, serialized)); + RegistryEntryList deserialized = Assertions.assertDoesNotThrow(() -> codec.parse(ops, serialized).getOrThrow()); + Assertions.assertInstanceOf(InverseRegistryEntryList.class, deserialized); + } + + @Test + @SuppressWarnings("unchecked") + void testInvalidation() { + RegistryEntryList parent = mockParentList(); + RegistryEntryList child1 = spy(RegistryEntryList.class); + RegistryEntryList child2 = spy(RegistryEntryList.class); + parent.registerDependency(child1); + parent.registerDependency(child2); + parent.invalidate(); + verify(child1, times(1)).invalidate(); + verify(child2, times(1)).invalidate(); + } + + @SuppressWarnings("unchecked") + private static DynamicRegistryManager mockDRM() { + DynamicRegistryManager drm = mock(DynamicRegistryManager.class); + when(drm.getOps(any())).thenReturn((RegistryOps) (Object) RegistryOps.of(JsonOps.INSTANCE, drm)); + when(drm.getOptional(any())).thenAnswer(invocation -> { + RegistryKey key = invocation.getArgument(0); + return Optional.ofNullable(Registries.REGISTRIES.get(key.getValue())); + }); + doAnswer(invocation -> drm.getOptional(invocation.getArgument(0)).orElseThrow( + () -> new NoSuchElementException("No registry found for key: " + invocation.getArgument(0)) + )).when(drm).getOrThrow(any()); + return drm; + } + + @SuppressWarnings("unchecked") + private static RegistryEntryList mockParentList() { + RegistryEntryList parentList = mock(RegistryEntryList.class); + when(parentList.stream()).thenReturn(Stream.empty()); + doAnswer(InvocationOnMock::callRealMethod) + .when(parentList) + .invalidate(); + + doAnswer(InvocationOnMock::callRealMethod) + .when(parentList) + .registerDependency(any()); + return parentList; + } + + @SuppressWarnings("unchecked") + private static Codec swapType(Codec codec) { + return (Codec) codec; + } +} From 78b7e5225d13281ccef8cd0ca886ea7a5c947672 Mon Sep 17 00:00:00 2001 From: cputnam-a11y Date: Fri, 6 Jun 2025 10:55:28 -0500 Subject: [PATCH 6/8] Fix Mistake (This is why we can't have nice things) --- .../CustomRegistryEntryListSerializerRegistry.java | 2 +- .../entrylists/DefaultCustomRegistryEntryLists.java | 2 +- .../fabric/impl/registry/sync/FabricRegistryInit.java | 4 ++-- .../CustomRegistryEntryListSerializerRegistryImpl.java | 2 +- .../defaults/DefaultCustomRegistryEntryListsImpl.java | 6 +++--- .../entrylists/defaults/IntersectionRegistryEntryList.java | 2 +- .../entrylists/defaults/InverseRegistryEntryList.java | 4 ++-- .../entrylists/defaults/MultiPartRegistryEntryList.java | 2 +- .../entrylists/defaults/UnionRegistryEntryList.java | 2 +- .../entrylists/defaults/UniversalRegistryEntryList.java | 4 ++-- .../registry/{ => sync}/entrylists/util/ChannelUtil.java | 2 +- .../util/RegistryWrapperFromRegistryEntryLookup.java | 2 +- .../{ => sync}/entrylists/util/RegistryWrapperUtils.java | 2 +- .../registry/{ => sync}/entrylists/util/TagKeyCache.java | 2 +- .../registry/sync/entrylists/PacketCodecs$25Mixin.java | 2 +- .../sync/entrylists/RegistryEntryListCodecMixin.java | 2 +- .../fabric/mixin/registry/sync/entrylists/TagKeyMixin.java | 2 +- .../registry/sync/CustomRegistryEntryListsUnitTests.java | 6 +++--- 18 files changed, 25 insertions(+), 25 deletions(-) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java (97%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java (91%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/defaults/IntersectionRegistryEntryList.java (98%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/defaults/InverseRegistryEntryList.java (97%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/defaults/MultiPartRegistryEntryList.java (98%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/defaults/UnionRegistryEntryList.java (97%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/defaults/UniversalRegistryEntryList.java (96%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/util/ChannelUtil.java (96%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java (97%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/util/RegistryWrapperUtils.java (98%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/{ => sync}/entrylists/util/TagKeyCache.java (93%) diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java index ee58e44f5e..e2f8caf87d 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java @@ -21,7 +21,7 @@ import net.minecraft.util.Identifier; -import net.fabricmc.fabric.impl.registry.entrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerRegistryImpl; public interface CustomRegistryEntryListSerializerRegistry { static void registerSerializer(@NotNull CustomRegistryEntryListSerializer serializer) { diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java index c27bf59339..eea42ea6df 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java @@ -19,7 +19,7 @@ import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.entry.RegistryEntryList; -import net.fabricmc.fabric.impl.registry.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; public class DefaultCustomRegistryEntryLists { @SafeVarargs diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java index bfa023f596..0b160f1187 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/FabricRegistryInit.java @@ -24,8 +24,8 @@ import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerConfigurationConnectionEvents; import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking; -import net.fabricmc.fabric.impl.registry.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; -import net.fabricmc.fabric.impl.registry.entrylists.util.ChannelUtil; +import net.fabricmc.fabric.impl.registry.sync.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.util.ChannelUtil; import net.fabricmc.fabric.impl.registry.sync.packet.DirectRegistryPacketHandler; public class FabricRegistryInit implements ModInitializer { diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java similarity index 97% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java index fd7a1d16b4..d6e9aa6c79 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists; +package net.fabricmc.fabric.impl.registry.sync.entrylists; import java.util.HashMap; import java.util.Map; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java similarity index 91% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java index 8cdf03d5db..58c87cab31 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.defaults; +package net.fabricmc.fabric.impl.registry.sync.entrylists.defaults; import java.util.List; import java.util.Objects; @@ -22,8 +22,8 @@ import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.entry.RegistryEntryList; -import net.fabricmc.fabric.impl.registry.entrylists.CustomRegistryEntryListSerializerRegistryImpl; -import net.fabricmc.fabric.impl.registry.entrylists.util.RegistryWrapperUtils; +import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.util.RegistryWrapperUtils; public class DefaultCustomRegistryEntryListsImpl { private static boolean initialized = false; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/IntersectionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/IntersectionRegistryEntryList.java similarity index 98% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/IntersectionRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/IntersectionRegistryEntryList.java index 9cc68629c0..60c27677e6 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/IntersectionRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/IntersectionRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.defaults; +package net.fabricmc.fabric.impl.registry.sync.entrylists.defaults; import java.util.List; import java.util.Set; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/InverseRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/InverseRegistryEntryList.java similarity index 97% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/InverseRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/InverseRegistryEntryList.java index 23cb318576..4a848035d6 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/InverseRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/InverseRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.defaults; +package net.fabricmc.fabric.impl.registry.sync.entrylists.defaults; import java.util.Iterator; import java.util.List; @@ -50,7 +50,7 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; -import net.fabricmc.fabric.impl.registry.entrylists.util.RegistryWrapperUtils; +import net.fabricmc.fabric.impl.registry.sync.entrylists.util.RegistryWrapperUtils; public class InverseRegistryEntryList implements CustomRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/MultiPartRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/MultiPartRegistryEntryList.java similarity index 98% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/MultiPartRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/MultiPartRegistryEntryList.java index c743fa2d6e..5a7b9ee4ff 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/MultiPartRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/MultiPartRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.defaults; +package net.fabricmc.fabric.impl.registry.sync.entrylists.defaults; import java.util.Iterator; import java.util.List; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UnionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UnionRegistryEntryList.java similarity index 97% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UnionRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UnionRegistryEntryList.java index b1f78fb4d5..63486440b4 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UnionRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UnionRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.defaults; +package net.fabricmc.fabric.impl.registry.sync.entrylists.defaults; import java.util.List; import java.util.Set; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UniversalRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UniversalRegistryEntryList.java similarity index 96% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UniversalRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UniversalRegistryEntryList.java index 3d59218aeb..4dea2b508b 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/defaults/UniversalRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UniversalRegistryEntryList.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.defaults; +package net.fabricmc.fabric.impl.registry.sync.entrylists.defaults; import java.util.Iterator; import java.util.List; @@ -44,7 +44,7 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; -import net.fabricmc.fabric.impl.registry.entrylists.util.RegistryWrapperUtils; +import net.fabricmc.fabric.impl.registry.sync.entrylists.util.RegistryWrapperUtils; public record UniversalRegistryEntryList(RegistryWrapper source) implements CustomRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/ChannelUtil.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/ChannelUtil.java similarity index 96% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/ChannelUtil.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/ChannelUtil.java index b581d948c2..185ac7d0e2 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/ChannelUtil.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/ChannelUtil.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.util; +package net.fabricmc.fabric.impl.registry.sync.entrylists.util; import java.util.Set; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java similarity index 97% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java index bfa88a399b..bbf41da56f 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/RegistryWrapperFromRegistryEntryLookup.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.util; +package net.fabricmc.fabric.impl.registry.sync.entrylists.util; import java.util.Optional; import java.util.stream.Stream; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperUtils.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/RegistryWrapperUtils.java similarity index 98% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperUtils.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/RegistryWrapperUtils.java index 12ae046c3f..3fafcc6bd6 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/RegistryWrapperUtils.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/RegistryWrapperUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.util; +package net.fabricmc.fabric.impl.registry.sync.entrylists.util; import java.util.stream.Stream; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/TagKeyCache.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/TagKeyCache.java similarity index 93% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/TagKeyCache.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/TagKeyCache.java index 5245562ac5..a05bf08c52 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/entrylists/util/TagKeyCache.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/util/TagKeyCache.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.fabricmc.fabric.impl.registry.entrylists.util; +package net.fabricmc.fabric.impl.registry.sync.entrylists.util; import java.util.Set; import java.util.stream.Stream; diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java index 12bb1cabd5..cef10d1718 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java @@ -42,7 +42,7 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializerRegistry; -import net.fabricmc.fabric.impl.registry.entrylists.util.ChannelUtil; +import net.fabricmc.fabric.impl.registry.sync.entrylists.util.ChannelUtil; @SuppressWarnings("unchecked") @Mixin(targets = "net.minecraft.network.codec.PacketCodecs$25") diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java index 65db9c28a2..4ffaf071d0 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java @@ -34,7 +34,7 @@ import net.minecraft.registry.entry.RegistryEntryListCodec; import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; -import net.fabricmc.fabric.impl.registry.entrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerRegistryImpl; @SuppressWarnings("unchecked") @Mixin(RegistryEntryListCodec.class) diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/TagKeyMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/TagKeyMixin.java index 489b9adb14..9503cbc8e9 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/TagKeyMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/TagKeyMixin.java @@ -28,7 +28,7 @@ import net.minecraft.registry.tag.TagKey; -import net.fabricmc.fabric.impl.registry.entrylists.util.TagKeyCache; +import net.fabricmc.fabric.impl.registry.sync.entrylists.util.TagKeyCache; @Mixin(TagKey.class) class TagKeyMixin { diff --git a/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java b/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java index 5b981f4895..7b56b7e2f8 100644 --- a/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java +++ b/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java @@ -49,9 +49,9 @@ import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.registry.entry.RegistryEntryListCodec; -import net.fabricmc.fabric.impl.registry.entrylists.CustomRegistryEntryListSerializerRegistryImpl; -import net.fabricmc.fabric.impl.registry.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; -import net.fabricmc.fabric.impl.registry.entrylists.defaults.InverseRegistryEntryList; +import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.defaults.InverseRegistryEntryList; public class CustomRegistryEntryListsUnitTests { @BeforeAll From 08744e5e007ec71adad5f801e9e8d89273af6e85 Mon Sep 17 00:00:00 2001 From: cputnam-a11y Date: Mon, 9 Jun 2025 15:16:45 -0500 Subject: [PATCH 7/8] address review comments --- .../CustomRegistryEntryListSerializer.java | 12 +++++++ ...omRegistryEntryListSerializerRegistry.java | 34 ------------------- ...List.java => FabricRegistryEntryList.java} | 4 +-- ...ustomRegistryEntryListSerializerImpl.java} | 6 ++-- .../DefaultCustomRegistryEntryListsImpl.java | 10 +++--- .../sync/entrylists/PacketCodecs$25Mixin.java | 3 +- .../RegistryEntryListCodecMixin.java | 6 ++-- .../entrylists/RegistryEntryListMixin.java | 4 +-- .../src/main/resources/fabric.mod.json | 2 +- .../CustomRegistryEntryListsUnitTests.java | 4 +-- 10 files changed, 31 insertions(+), 54 deletions(-) delete mode 100644 fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/{DependentRegistryEntryList.java => FabricRegistryEntryList.java} (94%) rename fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/{CustomRegistryEntryListSerializerRegistryImpl.java => CustomRegistryEntryListSerializerImpl.java} (93%) diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java index 82c3031bfc..30176cc661 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java @@ -18,6 +18,8 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; @@ -26,7 +28,17 @@ import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.Identifier; +import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerImpl; + public interface CustomRegistryEntryListSerializer { + static void registerSerializer(@NotNull CustomRegistryEntryListSerializer serializer) { + CustomRegistryEntryListSerializerImpl.registerSerializer(serializer); + } + + static @Nullable CustomRegistryEntryListSerializer getSerializer(Identifier id) { + return CustomRegistryEntryListSerializerImpl.getSerializer(id); + } + Identifier getIdentifier(); MapCodec> createCodec(RegistryKey> registryKey, Codec> entryCodec, boolean forceList); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java deleted file mode 100644 index e2f8caf87d..0000000000 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializerRegistry.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * 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. - */ - -package net.fabricmc.fabric.api.event.registry.entrylists; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.util.Identifier; - -import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerRegistryImpl; - -public interface CustomRegistryEntryListSerializerRegistry { - static void registerSerializer(@NotNull CustomRegistryEntryListSerializer serializer) { - CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(serializer); - } - - static @Nullable CustomRegistryEntryListSerializer getSerializer(Identifier id) { - return CustomRegistryEntryListSerializerRegistryImpl.getSerializer(id); - } -} diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/FabricRegistryEntryList.java similarity index 94% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/FabricRegistryEntryList.java index 5cc82a99b3..87574d203c 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/FabricRegistryEntryList.java @@ -28,7 +28,7 @@ // Injected to RegistryEntryList @ApiStatus.NonExtendable -public interface DependentRegistryEntryList { +public interface FabricRegistryEntryList { // creating a cycle in the graph will lead to stack overflow, do with this knowledge what you will Map, Set>> DEPENDENCIES = new WeakHashMap<>(); @@ -67,7 +67,7 @@ default void registerDependency(RegistryEntryList dependency) { * Invalidate dependents is called by this list when it is invalidated. */ private void invalidateDependents() { - DEPENDENCIES.getOrDefault(this.asSelf(), Set.of()).forEach(DependentRegistryEntryList::invalidate); + DEPENDENCIES.getOrDefault(this.asSelf(), Set.of()).forEach(FabricRegistryEntryList::invalidate); } /** diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/CustomRegistryEntryListSerializerImpl.java similarity index 93% rename from fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java rename to fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/CustomRegistryEntryListSerializerImpl.java index d6e9aa6c79..e90a6840a1 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/CustomRegistryEntryListSerializerRegistryImpl.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/CustomRegistryEntryListSerializerImpl.java @@ -31,12 +31,12 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; -public class CustomRegistryEntryListSerializerRegistryImpl { - private CustomRegistryEntryListSerializerRegistryImpl() { +public final class CustomRegistryEntryListSerializerImpl { + private CustomRegistryEntryListSerializerImpl() { throw new UnsupportedOperationException(); } - private static final Logger LOGGER = LoggerFactory.getLogger(CustomRegistryEntryListSerializerRegistryImpl.class); + private static final Logger LOGGER = LoggerFactory.getLogger(CustomRegistryEntryListSerializerImpl.class); private static final Map SERIALIZERS = new HashMap<>(); public static final Codec SERIALIZER_CODEC = Identifier.CODEC.flatXmap( id -> Optional.ofNullable(SERIALIZERS.get(id)) diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java index 58c87cab31..179ebc931f 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/DefaultCustomRegistryEntryListsImpl.java @@ -22,7 +22,7 @@ import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.entry.RegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerImpl; import net.fabricmc.fabric.impl.registry.sync.entrylists.util.RegistryWrapperUtils; public class DefaultCustomRegistryEntryListsImpl { @@ -34,10 +34,10 @@ public static void register() { } initialized = true; - CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(UnionRegistryEntryList.SERIALIZER); - CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(IntersectionRegistryEntryList.SERIALIZER); - CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(InverseRegistryEntryList.SERIALIZER); - CustomRegistryEntryListSerializerRegistryImpl.registerSerializer(UniversalRegistryEntryList.SERIALIZER); + CustomRegistryEntryListSerializerImpl.registerSerializer(UnionRegistryEntryList.SERIALIZER); + CustomRegistryEntryListSerializerImpl.registerSerializer(IntersectionRegistryEntryList.SERIALIZER); + CustomRegistryEntryListSerializerImpl.registerSerializer(InverseRegistryEntryList.SERIALIZER); + CustomRegistryEntryListSerializerImpl.registerSerializer(UniversalRegistryEntryList.SERIALIZER); } public static RegistryEntryList union(RegistryEntryList[] parts) { diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java index cef10d1718..f4cd5d039c 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/PacketCodecs$25Mixin.java @@ -41,7 +41,6 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; -import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializerRegistry; import net.fabricmc.fabric.impl.registry.sync.entrylists.util.ChannelUtil; @SuppressWarnings("unchecked") @@ -97,7 +96,7 @@ private int decodeCustomRegistryEntryList(ByteBuf buf, Operation origin } Identifier identifier = Identifier.PACKET_CODEC.decode(buf); - CustomRegistryEntryListSerializer serializer = CustomRegistryEntryListSerializerRegistry.getSerializer(identifier); + CustomRegistryEntryListSerializer serializer = CustomRegistryEntryListSerializer.getSerializer(identifier); if (serializer == null) { throw new IllegalStateException("Unknown CustomRegistryEntryListSerializer: " + identifier); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java index 4ffaf071d0..f47cbdb201 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListCodecMixin.java @@ -34,7 +34,7 @@ import net.minecraft.registry.entry.RegistryEntryListCodec; import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; -import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerImpl; @SuppressWarnings("unchecked") @Mixin(RegistryEntryListCodec.class) @@ -47,7 +47,7 @@ class RegistryEntryListCodecMixin { at = @At("TAIL") ) private void bindFabricCodec(RegistryKey> registry, Codec> entryCodec, boolean alwaysSerializeAsList, CallbackInfo ci) { - fabric$codec = CustomRegistryEntryListSerializerRegistryImpl.SERIALIZER_CODEC.dispatch( + fabric$codec = CustomRegistryEntryListSerializerImpl.SERIALIZER_CODEC.dispatch( "fabric:type", CustomRegistryEntryList::getSerializer, serializer -> serializer.createCodec(registry, entryCodec, alwaysSerializeAsList) @@ -77,7 +77,7 @@ private void encodeCustomWithCustomCodec(RegistryEntryList registryEnt cancellable = true ) private void decodeCustomWithCustomCodec(DynamicOps ops, T input, CallbackInfoReturnable, T>>> cir) { - if (CustomRegistryEntryListSerializerRegistryImpl.isSerializedCustomRegistryEntryList(ops, input)) { + if (CustomRegistryEntryListSerializerImpl.isSerializedCustomRegistryEntryList(ops, input)) { cir.setReturnValue( fabric$codec.decode(ops, input).map( pair -> pair.mapFirst( diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListMixin.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListMixin.java index ff5ddb1fb1..56438ec3ec 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListMixin.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/entrylists/RegistryEntryListMixin.java @@ -20,8 +20,8 @@ import net.minecraft.registry.entry.RegistryEntryList; -import net.fabricmc.fabric.api.event.registry.entrylists.DependentRegistryEntryList; +import net.fabricmc.fabric.api.event.registry.entrylists.FabricRegistryEntryList; @Mixin(RegistryEntryList.class) -interface RegistryEntryListMixin extends DependentRegistryEntryList { +interface RegistryEntryListMixin extends FabricRegistryEntryList { } diff --git a/fabric-registry-sync-v0/src/main/resources/fabric.mod.json b/fabric-registry-sync-v0/src/main/resources/fabric.mod.json index c1b0341bf0..f9af85110d 100644 --- a/fabric-registry-sync-v0/src/main/resources/fabric.mod.json +++ b/fabric-registry-sync-v0/src/main/resources/fabric.mod.json @@ -41,7 +41,7 @@ "fabric-api:module-lifecycle": "stable", "loom:injected_interfaces": { "net/minecraft/class_2378": ["net/fabricmc/fabric/api/event/registry/FabricRegistry"], - "net/minecraft/class_6885": ["net/fabricmc/fabric/api/event/registry/entrylists/DependentRegistryEntryList"] + "net/minecraft/class_6885": ["net/fabricmc/fabric/api/event/registry/entrylists/FabricRegistryEntryList"] } } } diff --git a/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java b/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java index 7b56b7e2f8..a1766ac245 100644 --- a/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java +++ b/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/CustomRegistryEntryListsUnitTests.java @@ -49,7 +49,7 @@ import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.registry.entry.RegistryEntryListCodec; -import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerRegistryImpl; +import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerImpl; import net.fabricmc.fabric.impl.registry.sync.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; import net.fabricmc.fabric.impl.registry.sync.entrylists.defaults.InverseRegistryEntryList; @@ -70,7 +70,7 @@ void testSerialization() { InverseRegistryEntryList customEntryList = new InverseRegistryEntryList<>(reg, entryList); Codec> codec = swapType(RegistryEntryListCodec.create(reg.getKey(), reg.getEntryCodec(), false)); JsonElement serialized = Assertions.assertDoesNotThrow(() -> codec.encodeStart(ops, customEntryList).getOrThrow()); - Assertions.assertTrue(CustomRegistryEntryListSerializerRegistryImpl.isSerializedCustomRegistryEntryList(ops, serialized)); + Assertions.assertTrue(CustomRegistryEntryListSerializerImpl.isSerializedCustomRegistryEntryList(ops, serialized)); RegistryEntryList deserialized = Assertions.assertDoesNotThrow(() -> codec.parse(ops, serialized).getOrThrow()); Assertions.assertInstanceOf(InverseRegistryEntryList.class, deserialized); } From 79e9ca6fbe6c37bc65210858ede70bada62833f4 Mon Sep 17 00:00:00 2001 From: cputnam-a11y Date: Tue, 10 Jun 2025 20:27:39 -0500 Subject: [PATCH 8/8] javadocs :tada: --- .../entrylists/CustomRegistryEntryList.java | 9 ++++ .../CustomRegistryEntryListSerializer.java | 13 ++++++ .../DefaultCustomRegistryEntryLists.java | 43 +++++++++++++++++++ .../IntersectionRegistryEntryList.java | 7 +++ .../defaults/InverseRegistryEntryList.java | 12 +++--- .../defaults/MultiPartRegistryEntryList.java | 6 +++ .../defaults/UnionRegistryEntryList.java | 6 +++ .../defaults/UniversalRegistryEntryList.java | 16 +++---- 8 files changed, 98 insertions(+), 14 deletions(-) diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryList.java index caa47b74c2..1c4f30ad23 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryList.java @@ -18,6 +18,15 @@ import net.minecraft.registry.entry.RegistryEntryList; +/** + * + * @param the type of elements contained by this list + */ public interface CustomRegistryEntryList extends RegistryEntryList { + /** + * + * @return a registered serializer capable of serializing this list + * @see CustomRegistryEntryListSerializer#registerSerializer + */ CustomRegistryEntryListSerializer getSerializer(); } diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java index 30176cc661..1a7883aaad 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/CustomRegistryEntryListSerializer.java @@ -31,14 +31,27 @@ import net.fabricmc.fabric.impl.registry.sync.entrylists.CustomRegistryEntryListSerializerImpl; public interface CustomRegistryEntryListSerializer { + /** + * registers a {@link CustomRegistryEntryListSerializer}. this must be done before the list is used + * @param serializer the serializer to register + */ static void registerSerializer(@NotNull CustomRegistryEntryListSerializer serializer) { CustomRegistryEntryListSerializerImpl.registerSerializer(serializer); } + /** + * gets a registered serializer. + * @param id the identifier of the serializer + * @return the serializer, or {@code null} if no serializer is registered with the given id + */ static @Nullable CustomRegistryEntryListSerializer getSerializer(Identifier id) { return CustomRegistryEntryListSerializerImpl.getSerializer(id); } + /** + * used to encode the entry list over the network, or in json. + * @return the registry id of this serializer + */ Identifier getIdentifier(); MapCodec> createCodec(RegistryKey> registryKey, Codec> entryCodec, boolean forceList); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java index eea42ea6df..9ae89335c9 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/entrylists/DefaultCustomRegistryEntryLists.java @@ -21,25 +21,68 @@ import net.fabricmc.fabric.impl.registry.sync.entrylists.defaults.DefaultCustomRegistryEntryListsImpl; +/** + * convenience implementations for {@link CustomRegistryEntryList}. + */ public class DefaultCustomRegistryEntryLists { + /** + * creates a {@link RegistryEntryList} that contains anything contained by any element of {@code parts}. + * + * @param parts the component parts to OR + * @param the type of elements contained in all the lists + * @return the custom list + */ @SafeVarargs public static RegistryEntryList union(RegistryEntryList... parts) { return DefaultCustomRegistryEntryListsImpl.union(parts); } + /** + * creates a {@link RegistryEntryList} that contains anything contained by all element of {@code parts}. + * + * @param parts the component parts to AND + * @param the type of elements contained in all the lists + * @return the custom list + */ @SafeVarargs public static RegistryEntryList intersection(RegistryEntryList... parts) { return DefaultCustomRegistryEntryListsImpl.intersection(parts); } + /** + * creates a {@link RegistryEntryList} that contains anything not contained by its opposite. + * + * @param lookup the source registry for this list + * @param opposite the list that contains everything the returned list will not + * @param the type of elements contained in all the lists + * @return the custom list + * @implNote {@link net.minecraft.item.Items#AIR} and {@link net.minecraft.block.Blocks#AIR} are included in the returned list, provided that they are not in opposite. for certain use cases, such as {@link net.minecraft.recipe.Ingredient}s, the caller must ensure that air is not in the end result, or else the ingredient will fail to serialize + */ public static RegistryEntryList inverse(RegistryEntryLookup lookup, RegistryEntryList opposite) { return DefaultCustomRegistryEntryListsImpl.inverse(lookup, opposite); } + /** + * creates a {@link RegistryEntryList} that contains everything in the source lookup. + * + * @param lookup the source registry for this list + * @param the type of elements contained in all the lists + * @return the custom list + * @implNote {@link net.minecraft.item.Items#AIR} and {@link net.minecraft.block.Blocks#AIR} are included in the returned list. for certain use cases, such as {@link net.minecraft.recipe.Ingredient}s, the caller must ensure that air is not in the end result, or else the ingredient will fail to serialize + */ public static RegistryEntryList universal(RegistryEntryLookup lookup) { return DefaultCustomRegistryEntryListsImpl.universal(lookup); } + /** + * creates a {@link RegistryEntryList} that contains everything in {@code initial} that is not also in {@code subtracted}. + * + * @param lookup the source registry for this list + * @param initial the beginning list + * @param subtracted the list to subtract from initial + * @param the type of elements contained in all the lists + * @return the custom list + */ public static RegistryEntryList subtraction(RegistryEntryLookup lookup, RegistryEntryList initial, RegistryEntryList subtracted) { return DefaultCustomRegistryEntryListsImpl.subtraction(lookup, initial, subtracted); } diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/IntersectionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/IntersectionRegistryEntryList.java index 60c27677e6..68225d9f65 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/IntersectionRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/IntersectionRegistryEntryList.java @@ -37,6 +37,13 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; +/** + * A default implementation of {@link RegistryEntryList} that contains everything in all of it's backing lists. + * the resulting list is cached as a set and a list, to provide a consistent iteration order, and O(1) contains + * + * @param type of entries held by this list + */ + public class IntersectionRegistryEntryList extends MultiPartRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/InverseRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/InverseRegistryEntryList.java index 4a848035d6..607198d3ee 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/InverseRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/InverseRegistryEntryList.java @@ -30,9 +30,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import net.minecraft.block.Blocks; -import net.minecraft.fluid.Fluids; -import net.minecraft.item.Items; import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodecs; @@ -52,6 +49,12 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; import net.fabricmc.fabric.impl.registry.sync.entrylists.util.RegistryWrapperUtils; +/** + * A default implementation of {@link RegistryEntryList} that contains everything not in a given list. + * A best effort is made to keep a cache of the values, to avoid iterating the registry for every call. + * + * @param type of entries held by this list + */ public class InverseRegistryEntryList implements CustomRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); @@ -128,9 +131,6 @@ private List> getList() { if (this.cache == null) { this.cache = this.wrapper .streamEntries() - .filter( - it -> !(it.value().equals(Items.AIR) || it.value() == Blocks.AIR || it.value() == Fluids.EMPTY) - ) .filter(Predicate.not(this.opposite::contains)) .collect(Collectors.toUnmodifiableList()); } diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/MultiPartRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/MultiPartRegistryEntryList.java index 5a7b9ee4ff..9fb4ca5938 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/MultiPartRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/MultiPartRegistryEntryList.java @@ -36,6 +36,12 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; +/** + * A default template implementation of {@link RegistryEntryList} that derives it's contents from some set of backing lists. + * the resulting list is cached as a set and a list, to provide a consistent iteration order, and O(1) contains + * + * @param type of entries held by this list + */ public abstract class MultiPartRegistryEntryList implements CustomRegistryEntryList { private final ImmutableList> parts; @Nullable diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UnionRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UnionRegistryEntryList.java index 63486440b4..d3aa032c05 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UnionRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UnionRegistryEntryList.java @@ -37,6 +37,12 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryList; import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; +/** + * A default implementation of {@link RegistryEntryList} that contains everything in any of its backing lists. + * the resulting list is cached as a set and a list, to provide a consistent iteration order, and O(1) contains + * + * @param type of entries held by this list + */ public class UnionRegistryEntryList extends MultiPartRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UniversalRegistryEntryList.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UniversalRegistryEntryList.java index 4dea2b508b..a5c6c52a3d 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UniversalRegistryEntryList.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/entrylists/defaults/UniversalRegistryEntryList.java @@ -27,15 +27,13 @@ import com.mojang.serialization.MapCodec; import org.jetbrains.annotations.NotNull; -import net.minecraft.block.Blocks; -import net.minecraft.fluid.Fluids; -import net.minecraft.item.Items; import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; import net.minecraft.registry.entry.RegistryEntryOwner; import net.minecraft.registry.tag.TagKey; import net.minecraft.util.Identifier; @@ -46,16 +44,18 @@ import net.fabricmc.fabric.api.event.registry.entrylists.CustomRegistryEntryListSerializer; import net.fabricmc.fabric.impl.registry.sync.entrylists.util.RegistryWrapperUtils; +/** + * A default implementation of {@link RegistryEntryList} that contains everything in a given registry + * No caching is done. + * + * @param type of entries held by this list + */ public record UniversalRegistryEntryList(RegistryWrapper source) implements CustomRegistryEntryList { public static final CustomRegistryEntryListSerializer SERIALIZER = new Serializer(); @Override public Stream> stream() { - return source.streamEntries() - .filter( - it -> !(it.value().equals(Items.AIR) || it.value() == Blocks.AIR || it.value() == Fluids.EMPTY) - ) - .map(Function.identity()); + return source.streamEntries().map(Function.identity()); } @Override