diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java index b0c53982dc..f18ac54bcb 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -11,7 +11,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -20,12 +19,16 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.TreeMap; -import java.util.TreeSet; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntRBTreeSet; +import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntRBTreeMap; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.tags.TagKey; @@ -56,9 +59,12 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * Internal - use the public {@link IForgeRegistry} and {@link ForgeRegistries} APIs to get the data + */ @ApiStatus.Internal public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegistryModifiable { - public static Marker REGISTRIES = MarkerManager.getMarker("REGISTRIES"); + public static final Marker REGISTRIES = MarkerManager.getMarker("REGISTRIES"); private static final Marker REGISTRYDUMP = MarkerManager.getMarker("REGISTRYDUMP"); private static final Logger LOGGER = LogManager.getLogger(); private final RegistryManager stage; @@ -76,7 +82,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist private final BakeCallback bake; private final MissingFactory missing; private final BitSet availabilityMap; - private final Set blocked = new HashSet<>(); + private final IntSet blocked = new IntOpenHashSet(); private final Multimap overrides = ArrayListMultimap.create(); private final Map> delegatesByName = new HashMap<>(); private final Map> delegatesByValue = new HashMap<>(); @@ -708,12 +714,12 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist private record DumpRow(String id, String key, String value) {} - public void loadIds(Map ids, Map overrides, Map missing, Map remapped, ForgeRegistry old, ResourceLocation name) { + public void loadIds(Object2IntMap ids, Map overrides, Object2IntMap missing, Map remapped, ForgeRegistry old, ResourceLocation name) { Map ovs = new HashMap<>(overrides); - for (Map.Entry entry : ids.entrySet()) { + for (Object2IntMap.Entry entry : ids.object2IntEntrySet()) { ResourceLocation itemName = entry.getKey(); - int newId = entry.getValue(); + int newId = entry.getIntValue(); int currId = old.getIDRaw(itemName); if (currId == -1) { @@ -832,10 +838,10 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } public static class Snapshot { - private static final Comparator sorter = (a,b) -> a.compareNamespaced(b); - public final Map ids = new TreeMap<>(sorter); + private static final Comparator sorter = ResourceLocation::compareNamespaced; + public final Object2IntMap ids = new Object2IntRBTreeMap<>(sorter); public final Map aliases = new TreeMap<>(sorter); - public final Set blocked = new TreeSet<>(); + public final IntSet blocked = new IntRBTreeSet(); public final Map overrides = new TreeMap<>(sorter); private FriendlyByteBuf binary = null; @@ -843,16 +849,16 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist CompoundTag data = new CompoundTag(); ListTag ids = new ListTag(); - this.ids.entrySet().stream().forEach(e -> { + this.ids.object2IntEntrySet().forEach(e -> { CompoundTag tag = new CompoundTag(); tag.putString("K", e.getKey().toString()); - tag.putInt("V", e.getValue()); + tag.putInt("V", e.getIntValue()); ids.add(tag); }); data.put("ids", ids); ListTag aliases = new ListTag(); - this.aliases.entrySet().stream().forEach(e -> { + this.aliases.entrySet().forEach(e -> { CompoundTag tag = new CompoundTag(); tag.putString("K", e.getKey().toString()); tag.putString("V", e.getValue().toString()); @@ -861,7 +867,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist data.put("aliases", aliases); ListTag overrides = new ListTag(); - this.overrides.entrySet().stream().forEach(e -> { + this.overrides.entrySet().forEach(e -> { CompoundTag tag = new CompoundTag(); tag.putString("K", e.getKey().toString()); tag.putString("V", e.getValue()); @@ -869,7 +875,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist }); data.put("overrides", overrides); - int[] blocked = this.blocked.stream().mapToInt(x->x).sorted().toArray(); + int[] blocked = this.blocked.intStream().sorted().toArray(); data.putIntArray("blocked", blocked); return data; @@ -932,14 +938,14 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } @SuppressWarnings("unchecked") - public MissingMappingsEvent getMissingEvent(ResourceLocation name, Map map) { + public MissingMappingsEvent getMissingEvent(ResourceLocation name, Object2IntMap map) { List> lst = new ArrayList<>(); ForgeRegistry pool = RegistryManager.ACTIVE.getRegistry(name); - map.forEach((rl, id) -> lst.add(new MissingMappingsEvent.Mapping<>(this, pool, rl, id))); + map.object2IntEntrySet().forEach(entry -> lst.add(new MissingMappingsEvent.Mapping<>(this, pool, entry.getKey(), entry.getIntValue()))); return new MissingMappingsEvent(ResourceKey.createRegistryKey(name), this, (Collection>) (Collection) lst); } - void processMissingEvent(ResourceLocation name, ForgeRegistry pool, List> mappings, Map missing, Map remaps, Collection defaulted, Collection failed, boolean injectNetworkDummies) { + void processMissingEvent(ResourceLocation name, ForgeRegistry pool, List> mappings, Object2IntMap missing, Map remaps, Collection defaulted, Collection failed, boolean injectNetworkDummies) { LOGGER.debug(REGISTRIES,"Processing missing event for {}:", name); int ignored = 0; @@ -952,7 +958,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist ResourceLocation newName = pool.getKey(remap.target); LOGGER.debug(REGISTRIES," Remapping {} -> {}.", remap.key, newName); - missing.remove(remap.key); + missing.removeInt(remap.key); //I don't think this will work, but I dont think it ever worked.. the item is already in the map with a different id... we want to fix that.. int realId = this.add(remap.id, newName, remap.target); if (realId != remap.id) diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index c564bdf9af..c58fcc8085 100644 --- a/src/main/java/net/minecraftforge/registries/GameData.java +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -7,7 +7,6 @@ package net.minecraftforge.registries; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.mojang.serialization.Codec; import com.mojang.serialization.Lifecycle; @@ -23,6 +22,9 @@ import java.util.Map; import java.util.Set; import java.util.function.BiConsumer; import java.util.stream.Collectors; + +import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.IdMapper; import net.minecraft.core.MappedRegistry; import net.minecraft.core.Registry; @@ -69,12 +71,13 @@ import org.jetbrains.annotations.Nullable; /** * INTERNAL ONLY * MODDERS SHOULD HAVE NO REASON TO USE THIS CLASS + *

Use the public {@link IForgeRegistry} and {@link ForgeRegistries} APIs to get the data

*/ @ApiStatus.Internal public class GameData { private static final Logger LOGGER = LogManager.getLogger(); - private static Marker REGISTRIES = ForgeRegistry.REGISTRIES; + private static final Marker REGISTRIES = ForgeRegistry.REGISTRIES; private static final int MAX_VARINT = Integer.MAX_VALUE - 1; //We were told it is their intention to have everything in a reg be unlimited, so assume that until we find cases where it isnt. private static final ResourceLocation BLOCK_TO_ITEM = new ResourceLocation("minecraft:blocktoitemmap"); @@ -368,10 +371,9 @@ public class GameData @SuppressWarnings("unused") void remove(I key) { - @SuppressWarnings("deprecation") - Integer prev = this.tToId.remove(key); - if (prev != null) - { + boolean hadId = this.tToId.containsKey(key); + int prev = this.tToId.removeInt(key); + if (hadId) { this.idToT.set(prev, null); } } @@ -421,22 +423,17 @@ public class GameData @Override public void onCreate(IForgeRegistryInternal owner, RegistryManager stage) { - final ClearableObjectIntIdentityMap idMap = new ClearableObjectIntIdentityMap() + final ClearableObjectIntIdentityMap idMap = new ClearableObjectIntIdentityMap<>() { @SuppressWarnings("deprecation") @Override public int getId(BlockState key) { - Integer integer = (Integer)this.tToId.get(key); - // There are some cases where this map is queried to serialize a state that is valid, - //but somehow not in this list, so attempt to get real metadata. Doing this hear saves us 7 patches - //if (integer == null && key != null) - // integer = this.identityMap.get(key.getBlock().getStateFromMeta(key.getBlock().getMetaFromState(key))); - return integer == null ? -1 : integer.intValue(); + return this.tToId.containsKey(key) ? this.tToId.getInt(key) : -1; } }; owner.setSlaveMap(BLOCKSTATE_TO_ID, idMap); - owner.setSlaveMap(BLOCK_TO_ITEM, Maps.newHashMap()); + owner.setSlaveMap(BLOCK_TO_ITEM, new HashMap<>()); } @Override @@ -597,11 +594,11 @@ public class GameData if (isLocalWorld) { - List missingRegs = snapshot.keySet().stream().filter(name -> !RegistryManager.ACTIVE.registries.containsKey(name)).collect(Collectors.toList()); - if (missingRegs.size() > 0) + ResourceLocation[] missingRegs = snapshot.keySet().stream().filter(name -> !RegistryManager.ACTIVE.registries.containsKey(name)).toArray(ResourceLocation[]::new); + if (missingRegs.length > 0) { String header = "Forge Mod Loader detected missing/unknown registrie(s).\n\n" + - "There are " + missingRegs.size() + " missing registries in this save.\n" + + "There are " + missingRegs.length + " missing registries in this save.\n" + "If you continue the missing registries will get removed.\n" + "This may cause issues, it is advised that you create a world backup before continuing.\n\n"; @@ -617,13 +614,13 @@ public class GameData RegistryManager STAGING = new RegistryManager(); - final Map> remaps = Maps.newHashMap(); - final LinkedHashMap> missing = Maps.newLinkedHashMap(); + final Map> remaps = new HashMap<>(); + final LinkedHashMap> missing = new LinkedHashMap<>(); // Load the snapshot into the "STAGING" registry snapshot.forEach((key, value) -> { - remaps.put(key, Maps.newLinkedHashMap()); - missing.put(key, Maps.newLinkedHashMap()); + remaps.put(key, new LinkedHashMap<>()); + missing.put(key, new Object2IntLinkedOpenHashMap<>()); loadPersistentDataToStagingRegistry(RegistryManager.ACTIVE, STAGING, remaps.get(key), missing.get(key), key, value); }); @@ -634,11 +631,12 @@ public class GameData Multimap defaulted = ArrayListMultimap.create(); Multimap failed = ArrayListMultimap.create(); - missing.entrySet().stream().filter(e -> e.getValue().size() > 0).forEach(m -> + missing.entrySet().stream().filter(e -> !e.getValue().isEmpty()).forEach(m -> { ResourceLocation name = m.getKey(); ForgeRegistry reg = STAGING.getRegistry(name); - MissingMappingsEvent event = reg.getMissingEvent(name, m.getValue()); + Object2IntMap missingIds = m.getValue(); + MissingMappingsEvent event = reg.getMissingEvent(name, missingIds); MinecraftForge.EVENT_BUS.post(event); List> lst = event.getAllMappings(reg.getRegistryKey()).stream() @@ -656,7 +654,7 @@ public class GameData .filter(e -> e.action == MissingMappingsEvent.Action.FAIL) .forEach(fail -> failed.put(name, fail.key)); - processMissing(name, STAGING, event, m.getValue(), remaps.get(name), defaulted.get(name), failed.get(name), !isLocalWorld); + processMissing(name, STAGING, event, missingIds, remaps.get(name), defaulted.get(name), failed.get(name), !isLocalWorld); }); if (!defaulted.isEmpty() && !isLocalWorld) @@ -673,7 +671,7 @@ public class GameData defaulted.asMap().forEach((name, entries) -> { buf.append("Missing ").append(name).append(":\n"); - entries.stream().sorted((o1, o2) -> o1.compareNamespaced(o2)).forEach(rl -> buf.append(" ").append(rl).append("\n")); + entries.stream().sorted(ResourceLocation::compareNamespaced).forEach(rl -> buf.append(" ").append(rl).append("\n")); buf.append("\n"); }); @@ -731,7 +729,7 @@ public class GameData } //Has to be split because of generics, Yay! - private static void loadPersistentDataToStagingRegistry(RegistryManager pool, RegistryManager to, Map remaps, Map missing, ResourceLocation name, ForgeRegistry.Snapshot snap) + private static void loadPersistentDataToStagingRegistry(RegistryManager pool, RegistryManager to, Map remaps, Object2IntMap missing, ResourceLocation name, ForgeRegistry.Snapshot snap) { ForgeRegistry active = pool.getRegistry(name); if (active == null) @@ -743,7 +741,7 @@ public class GameData } //Another bouncer for generic reasons - private static void processMissing(ResourceLocation name, RegistryManager STAGING, MissingMappingsEvent e, Map missing, Map remaps, Collection defaulted, Collection failed, boolean injectNetworkDummies) + private static void processMissing(ResourceLocation name, RegistryManager STAGING, MissingMappingsEvent e, Object2IntMap missing, Map remaps, Collection defaulted, Collection failed, boolean injectNetworkDummies) { List> mappings = e.getAllMappings(ResourceKey.createRegistryKey(name)); ForgeRegistry active = RegistryManager.ACTIVE.getRegistry(name); @@ -755,9 +753,9 @@ public class GameData { ForgeRegistry frozen = RegistryManager.FROZEN.getRegistry(name); ForgeRegistry newRegistry = STAGING.getRegistry(name, RegistryManager.FROZEN); - Map _new = Maps.newLinkedHashMap(); + Object2IntMap _new = new Object2IntLinkedOpenHashMap<>(); frozen.getKeys().stream().filter(key -> !newRegistry.containsKey(key)).forEach(key -> _new.put(key, frozen.getID(key))); - newRegistry.loadIds(_new, frozen.getOverrideOwners(), Maps.newLinkedHashMap(), remaps, frozen, name); + newRegistry.loadIds(_new, frozen.getOverrideOwners(), new Object2IntLinkedOpenHashMap<>(), remaps, frozen, name); } /** @@ -776,7 +774,7 @@ public class GameData String oldPrefix = index == -1 ? "" : name.substring(0, index).toLowerCase(Locale.ROOT); name = index == -1 ? name : name.substring(index + 1); String prefix = ModLoadingContext.get().getActiveNamespace(); - if (warnOverrides && !oldPrefix.equals(prefix) && oldPrefix.length() > 0) + if (warnOverrides && !oldPrefix.equals(prefix) && !oldPrefix.isEmpty()) { LogManager.getLogger().debug("Mod `{}` attempting to register `{}` to the namespace `{}`. This could be intended, but likely means an EventBusSubscriber without a modid.", prefix, name, oldPrefix); prefix = oldPrefix;