From cdba403ab6f70605e7173428e4d4c55c474efe2e Mon Sep 17 00:00:00 2001 From: J-RAP Date: Wed, 29 Nov 2023 13:11:55 -0600 Subject: [PATCH] Backport of Registries optimization, now uses fastutils collections to minimize boxing --- .../registries/ForgeRegistries.java | 2 +- .../registries/ForgeRegistry.java | 552 ++++++------------ .../minecraftforge/registries/GameData.java | 148 +++-- .../registries/RegistryBuilder.java | 15 +- 4 files changed, 271 insertions(+), 446 deletions(-) diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistries.java b/src/main/java/net/minecraftforge/registries/ForgeRegistries.java index 2e14b2bd90..054c07ceef 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistries.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistries.java @@ -138,7 +138,7 @@ public class ForgeRegistries * Calling {@link Supplier#get()} before {@link NewRegistryEvent} is fired will result in a null registry returned. * Use {@link Keys#HOLDER_SET_TYPES} to create a {@link DeferredRegister}. */ - public static final Supplier> HOLDER_SET_TYPES = DEFERRED_HOLDER_SET_TYPES.makeRegistry(GameData::getHolderSetTypeRegistryBuilder); + public static final Supplier> HOLDER_SET_TYPES = DEFERRED_HOLDER_SET_TYPES.makeRegistry(GameData::makeUnsavedAndUnsynced); static final DeferredRegister DEFERRED_DISPLAY_CONTEXTS = DeferredRegister.create(Keys.DISPLAY_CONTEXTS, "forge"); /** diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java index a1a0d7caf3..51a737cc63 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -5,21 +5,35 @@ package net.minecraftforge.registries; -import java.util.*; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.Map.Entry; -import java.util.function.IntFunction; +import java.util.Optional; +import java.util.Set; +import java.util.TreeMap; 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; -import net.minecraft.world.level.biome.Biome; import net.minecraftforge.common.util.LogMessageAdapter; import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import net.minecraftforge.registries.tags.ITagManager; import org.apache.commons.lang3.Validate; @@ -27,15 +41,11 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; import io.netty.buffer.Unpooled; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.StringTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -48,22 +58,23 @@ import org.apache.logging.log4j.MarkerManager; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.VisibleForTesting; +/** + * 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"); - private static Marker REGISTRYDUMP = MarkerManager.getMarker("REGISTRYDUMP"); - private static Logger LOGGER = LogManager.getLogger(); +public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegistryModifiable { + 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; private final BiMap ids = HashBiMap.create(); private final BiMap names = HashBiMap.create(); private final BiMap, V> keys = HashBiMap.create(); - private final Map aliases = Maps.newHashMap(); - final Map slaves = Maps.newHashMap(); + private final Map aliases = new HashMap<>(); + final Map slaves = new HashMap<>(); private final ResourceLocation defaultKey; - private final ResourceKey defaultResourceKey; + //private final ResourceKey defaultResourceKey; private final CreateCallback create; private final AddCallback add; private final ClearCallback clear; @@ -71,10 +82,10 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist private final BakeCallback bake; private final MissingFactory missing; private final BitSet availabilityMap; - private final Set blocked = Sets.newHashSet(); + private final IntSet blocked = new IntOpenHashSet(); private final Multimap overrides = ArrayListMultimap.create(); - private final Map> delegatesByName = Maps.newHashMap(); - private final Map> delegatesByValue = Maps.newHashMap(); + private final Map> delegatesByName = new HashMap<>(); + private final Map> delegatesByValue = new HashMap<>(); private final BiMap, V> owners = HashBiMap.create(); private final ForgeRegistryTagManager tagManager; private final int min; @@ -92,15 +103,13 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist private final Codec codec = new RegistryCodec(); - @SuppressWarnings("unchecked") - ForgeRegistry(RegistryManager stage, ResourceLocation name, RegistryBuilder builder) - { + ForgeRegistry(RegistryManager stage, ResourceLocation name, RegistryBuilder builder) { this.name = name; this.key = ResourceKey.createRegistryKey(name); this.builder = builder; this.stage = stage; this.defaultKey = builder.getDefault(); - this.defaultResourceKey = ResourceKey.create(key, defaultKey); + //this.defaultResourceKey = ResourceKey.create(key, defaultKey); this.min = builder.getMinId(); this.max = builder.getMaxId(); this.availabilityMap = new BitSet(Math.min(max + 1, 0x0FFF)); @@ -119,34 +128,29 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } @Override - public void register(String key, V value) - { + public void register(String key, V value) { register(GameData.checkPrefix(key, true), value); } @Override - public void register(ResourceLocation key, V value) - { + public void register(ResourceLocation key, V value) { add(-1, key, value); } @Override public Iterator iterator() { - return new Iterator() - { + return new Iterator() { int cur = -1; V next = null; { next(); } @Override - public boolean hasNext() - { + public boolean hasNext() { return next != null; } @Override - public V next() - { + public V next() { V ret = next; do { cur = availabilityMap.nextSetBit(cur + 1); @@ -159,28 +163,23 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } @Override - public ResourceLocation getRegistryName() - { + public ResourceLocation getRegistryName() { return this.name; } @Override - public ResourceKey> getRegistryKey() - { + public ResourceKey> getRegistryKey() { return this.key; } @NotNull - public Codec getCodec() - { + public Codec getCodec() { return this.codec; } @Override - public boolean containsKey(ResourceLocation key) - { - while (key != null) - { + public boolean containsKey(ResourceLocation key) { + while (key != null) { if (this.names.containsKey(key)) return true; key = this.aliases.get(key); @@ -189,29 +188,24 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } @Override - public boolean containsValue(V value) - { + public boolean containsValue(V value) { return this.names.containsValue(value); } @Override - public boolean isEmpty() - { + public boolean isEmpty() { return this.names.isEmpty(); } - int size() - { + int size() { return this.names.size(); } @Override - public V getValue(ResourceLocation key) - { + public V getValue(ResourceLocation key) { V ret = this.names.get(key); key = this.aliases.get(key); - while (ret == null && key != null) - { + while (ret == null && key != null) { ret = this.names.get(key); key = this.aliases.get(key); } @@ -219,23 +213,20 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } @Override - public ResourceLocation getKey(V value) - { + public ResourceLocation getKey(V value) { return getResourceKey(value).map(ResourceKey::location).orElse(this.defaultKey); } @NotNull @Override - public Optional> getResourceKey(V value) - { + public Optional> getResourceKey(V value) { // We use 'owners' here because we want to return the key for the inactive overridden items, not just the active set. return Optional.ofNullable(this.owners.inverse().get(value)).map(OverrideOwner::key); } @SuppressWarnings("unchecked") @Nullable - NamespacedWrapper getWrapper() - { + NamespacedWrapper getWrapper() { if (!this.hasWrapper) return null; @@ -245,8 +236,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } @NotNull - NamespacedWrapper getWrapperOrThrow() - { + NamespacedWrapper getWrapperOrThrow() { NamespacedWrapper wrapper = getWrapper(); if (wrapper == null) @@ -255,131 +245,113 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist return wrapper; } - void onBindTags(Map, HolderSet.Named> tags, Set> defaultedTags) - { + void onBindTags(Map, HolderSet.Named> tags, Set> defaultedTags) { if (this.tagManager != null) this.tagManager.bind(tags, defaultedTags); } @NotNull @Override - public Optional> getHolder(ResourceKey key) - { + public Optional> getHolder(ResourceKey key) { return Optional.ofNullable(this.getWrapper()).flatMap(wrapper -> wrapper.getHolder(key)); } @NotNull @Override - public Optional> getHolder(ResourceLocation location) - { + public Optional> getHolder(ResourceLocation location) { return Optional.ofNullable(this.getWrapper()).flatMap(wrapper -> wrapper.getHolder(location)); } @NotNull @Override - public Optional> getHolder(V value) - { + public Optional> getHolder(V value) { return Optional.ofNullable(this.getWrapper()).flatMap(wrapper -> wrapper.getHolder(value)); } @Nullable @Override - public ITagManager tags() - { + public ITagManager tags() { return this.tagManager; } @NotNull @Override - public Set getKeys() - { + public Set getKeys() { return Collections.unmodifiableSet(this.names.keySet()); } @NotNull - Set> getResourceKeys() - { + Set> getResourceKeys() { return Collections.unmodifiableSet(this.keys.keySet()); } @NotNull @Override - public Collection getValues() - { + public Collection getValues() { return Collections.unmodifiableSet(this.names.values()); } @NotNull @Override - public Set, V>> getEntries() - { + public Set, V>> getEntries() { return Collections.unmodifiableSet(this.keys.entrySet()); } @SuppressWarnings("unchecked") @Override - public T getSlaveMap(ResourceLocation name, Class type) - { + public T getSlaveMap(ResourceLocation name, Class type) { return (T)this.slaves.get(name); } @SuppressWarnings("unchecked") @Override - public void setSlaveMap(ResourceLocation name, Object obj) - { + public void setSlaveMap(ResourceLocation name, Object obj) { ((Map)this.slaves).put(name, obj); } - public int getID(V value) - { + public int getID(V value) { Integer ret = this.ids.inverse().get(value); if (ret == null && this.defaultValue != null) ret = this.ids.inverse().get(this.defaultValue); return ret == null ? -1 : ret.intValue(); } - public int getID(ResourceLocation name) - { + public int getID(ResourceLocation name) { return getID(this.names.get(name)); } - private int getIDRaw(V value) - { + + private int getIDRaw(V value) { Integer ret = this.ids.inverse().get(value); return ret == null ? -1 : ret.intValue(); } - private int getIDRaw(ResourceLocation name) - { + + private int getIDRaw(ResourceLocation name) { return getIDRaw(this.names.get(name)); } @Override - public V getValue(int id) - { + public V getValue(int id) { V ret = this.ids.get(id); return ret == null ? this.defaultValue : ret; } @Nullable - public ResourceKey getKey(int id) - { + public ResourceKey getKey(int id) { V value = getValue(id); return this.keys.inverse().get(value); } - void validateKey() - { + void validateKey() { if (this.defaultKey != null) Validate.notNull(this.defaultValue, "Missing default of ForgeRegistry: " + this.defaultKey + " Name: " + this.name); } @Nullable - public ResourceLocation getDefaultKey() - { + public ResourceLocation getDefaultKey() { return this.defaultKey; } - ForgeRegistry copy(RegistryManager stage) - { + ForgeRegistry copy(RegistryManager stage) { return new ForgeRegistry<>(stage, name, builder); } @@ -388,14 +360,12 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist add(id, key, value, key.getNamespace()); } - int add(int id, ResourceLocation key, V value) - { + int add(int id, ResourceLocation key, V value) { final String owner = ModLoadingContext.get().getActiveNamespace(); return add(id, key, value, owner); } - int add(int id, ResourceLocation key, V value, String owner) - { + int add(int id, ResourceLocation key, V value, String owner) { Preconditions.checkNotNull(key, "Can't use a null-name for the registry, object %s.", value); Preconditions.checkNotNull(value, "Can't add null-object to the registry, name %s.", key); @@ -407,13 +377,12 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist throw new RuntimeException(String.format(Locale.ENGLISH, "Invalid id %d - maximum id range exceeded.", idToUse)); V oldEntry = getRaw(key); - if (oldEntry == value) // already registered, return prev registration's id - { + if (oldEntry == value) { // already registered, return prev registration's id LOGGER.warn(REGISTRIES,"Registry {}: The object {} has been registered twice for the same name {}.", this.name, value, key); return this.getID(value); } - if (oldEntry != null) // duplicate name - { + + if (oldEntry != null) { // duplicate name if (!this.allowOverrides) throw new IllegalArgumentException(String.format(Locale.ENGLISH, "The name %s has been registered twice, for %s and %s.", key, getRaw(key), value)); if (owner == null) @@ -423,8 +392,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } Integer foundId = this.ids.inverse().get(value); //Is this ever possible to trigger with otherThing being different? - if (foundId != null) - { + if (foundId != null) { V otherThing = this.ids.get(foundId); throw new IllegalArgumentException(String.format(Locale.ENGLISH, "The object %s{%x} has been registered twice, using the names %s and %s. (Other object at this id is %s{%x})", value, System.identityHashCode(value), getKey(value), key, otherThing, System.identityHashCode(otherThing))); } @@ -432,8 +400,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist if (isLocked()) throw new IllegalStateException(String.format(Locale.ENGLISH, "The object %s (name %s) is being added too late.", value, key)); - if (defaultKey != null && defaultKey.equals(key)) - { + if (defaultKey != null && defaultKey.equals(key)) { if (this.defaultValue != null) throw new IllegalStateException(String.format(Locale.ENGLISH, "Attemped to override already set default value. This is not allowed: The object %s (name %s)", value, key)); this.defaultValue = value; @@ -446,11 +413,9 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist this.availabilityMap.set(idToUse); this.owners.put(new OverrideOwner(owner == null ? key.getNamespace() : owner, rkey), value); - if (hasWrapper) - { - Holder.Reference delegate = bindDelegate(rkey, value); - if (oldEntry != null) - { + if (hasWrapper) { + bindDelegate(rkey, value); + if (oldEntry != null) { if (!this.overrides.get(key).contains(oldEntry)) this.overrides.put(key, oldEntry); this.overrides.get(key).remove(value); @@ -465,12 +430,10 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist return idToUse; } - public V getRaw(ResourceLocation key) - { + public V getRaw(ResourceLocation key) { V ret = this.names.get(key); key = this.aliases.get(key); - while (ret == null && key != null) - { + while (ret == null && key != null) { ret = this.names.get(key); key = this.aliases.get(key); } @@ -485,13 +448,11 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist * * TODO: Add as public API in IForgeRegistry and DeferredRegister. */ - public void addAlias(ResourceLocation src, ResourceLocation dst) - { + public void addAlias(ResourceLocation src, ResourceLocation dst) { if (this.isLocked()) throw new IllegalStateException(String.format(Locale.ENGLISH, "Attempted to register the alias %s -> %s too late", src, dst)); - if (src.equals(dst)) - { + if (src.equals(dst)) { LOGGER.warn(REGISTRIES, "Registry {} Ignoring invalid alias: {} -> {}", this.name, src, dst); return; } @@ -502,48 +463,41 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist @NotNull @Override - public Optional> getDelegate(ResourceKey rkey) - { + public Optional> getDelegate(ResourceKey rkey) { return Optional.ofNullable(delegatesByName.get(rkey.location())); } @NotNull @Override - public Holder.Reference getDelegateOrThrow(ResourceKey rkey) - { + public Holder.Reference getDelegateOrThrow(ResourceKey rkey) { return getDelegate(rkey).orElseThrow(() -> new IllegalArgumentException(String.format(Locale.ENGLISH, "No delegate exists for key %s", rkey))); } @NotNull @Override - public Optional> getDelegate(ResourceLocation key) - { + public Optional> getDelegate(ResourceLocation key) { return Optional.ofNullable(delegatesByName.get(key)); } @NotNull @Override - public Holder.Reference getDelegateOrThrow(ResourceLocation key) - { + public Holder.Reference getDelegateOrThrow(ResourceLocation key) { return getDelegate(key).orElseThrow(() -> new IllegalArgumentException(String.format(Locale.ENGLISH, "No delegate exists for key %s", key))); } @NotNull @Override - public Optional> getDelegate(V value) - { + public Optional> getDelegate(V value) { return Optional.ofNullable(delegatesByValue.get(value)); } @NotNull @Override - public Holder.Reference getDelegateOrThrow(V value) - { + public Holder.Reference getDelegateOrThrow(V value) { return getDelegate(value).orElseThrow(() -> new IllegalArgumentException(String.format(Locale.ENGLISH, "No delegate exists for value %s", value))); } - private Holder.Reference bindDelegate(ResourceKey rkey, V value) - { + private Holder.Reference bindDelegate(ResourceKey rkey, V value) { Holder.Reference delegate = delegatesByName.computeIfAbsent(rkey.location(), k -> Holder.Reference.createStandAlone(this.getWrapperOrThrow().holderOwner(), rkey)); delegate.bindKey(rkey); delegate.bindValue(value); @@ -551,8 +505,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist return delegate; } - void resetDelegates() - { + void resetDelegates() { if (!this.hasWrapper) return; @@ -563,25 +516,12 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist bindDelegate(ResourceKey.create(this.key, entry.getKey()), entry.getValue()); } - V getDefault() - { + V getDefault() { return this.defaultValue; } - - void validateContent(ResourceLocation registryName) - { - try - { - ObfuscationReflectionHelper.findMethod(BitSet.class, "trimToSize").invoke(this.availabilityMap); - } - catch (Exception e) - { - //We don't care... Just a micro-optimization - } - - for (V obj : this) - { + void validateContent(ResourceLocation registryName) { + for (V obj : this) { int id = getID(obj); ResourceLocation name = getKey(obj); @@ -617,14 +557,12 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } } - public void bake() - { + public void bake() { if (this.bake != null) this.bake.onBake(this, this.stage); } - void sync(ResourceLocation name, ForgeRegistry from) - { + void sync(ResourceLocation name, ForgeRegistry from) { LOGGER.debug(REGISTRIES,"Registry {} Sync: {} -> {}", this.name, this.stage.getName(), from.stage.getName()); if (this == from) throw new IllegalArgumentException("WTF We are the same!?!?!"); @@ -640,12 +578,9 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist this.min = from.min; */ // Aliases from the active registry take priority over those from the staged (loaded) registry. - for (var entry : from.aliases.entrySet()) - { + for (var entry : from.aliases.entrySet()) { if (!this.aliases.containsKey(entry.getKey())) - { this.aliases.put(entry.getKey(), entry.getValue()); - } } this.ids.clear(); @@ -658,34 +593,27 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist boolean errored = false; - for (Entry entry : from.names.entrySet()) - { - List overrides = Lists.newArrayList(from.overrides.get(entry.getKey())); + for (Entry entry : from.names.entrySet()) { + List overrides = new ArrayList<>(from.overrides.get(entry.getKey())); int id = from.getID(entry.getKey()); - if (overrides.isEmpty()) - { + if (overrides.isEmpty()) { int realId = add(id, entry.getKey(), entry.getValue()); - if (id != realId && id != -1) - { + if (id != realId && id != -1) { LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.name, entry.getKey(), id, realId); errored = true; } - } - else - { + } else { overrides.add(entry.getValue()); - for (V value : overrides) - { + for (V value : overrides) { OverrideOwner owner = from.owners.inverse().get(value); - if (owner == null) - { + if (owner == null) { LOGGER.warn(REGISTRIES,"Registry {}: Override did not have an associated owner object. Name: {} Value: {}", this.name, entry.getKey(), value); errored = true; continue; } + int realId = add(id, entry.getKey(), value, owner.owner); - if (id != realId && id != -1) - { + if (id != realId && id != -1) { LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.name, entry.getKey(), id, realId); errored = true; } @@ -698,8 +626,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } @Override - public void clear() - { + public void clear() { if (!this.isModifiable) throw new UnsupportedOperationException("Attempted to clear a non-modifiable Forge Registry"); @@ -719,8 +646,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } @Override - public V remove(ResourceLocation key) - { + public V remove(ResourceLocation key) { if (!this.isModifiable) throw new UnsupportedOperationException("Attempted to remove from a non-modifiable Forge Registry"); @@ -728,8 +654,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist throw new IllegalStateException("Attempted to remove from the registry to late."); V value = this.names.remove(key); - if (value != null) - { + if (value != null) { ResourceKey rkey = this.keys.inverse().remove(value); if (rkey == null) throw new IllegalStateException("Removed a entry that did not have an associated RegistryKey: " + key + " " + value.toString() + " This should never happen unless hackery!"); @@ -744,15 +669,13 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist return value; } - void block(int id) - { + void block(int id) { this.blocked.add(id); this.availabilityMap.set(id); } @Override - public boolean isLocked() - { + public boolean isLocked() { return this.isFrozen; } @@ -760,34 +683,29 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist * Used to control the times where people can modify this registry. * Users should only ever register things in the {@literal Register} events! */ - public void freeze() - { + public void freeze() { this.isFrozen = true; } - public void unfreeze() - { + public void unfreeze() { this.isFrozen = false; } - void dump(ResourceLocation name) - { + void dump(ResourceLocation name) { // Building a good looking table is not cheap, so only do it if the debug logger is enabled. - if (LOGGER.isDebugEnabled(REGISTRYDUMP)) - { + if (LOGGER.isDebugEnabled(REGISTRYDUMP)) { TablePrinter tab = new TablePrinter() .header("ID", r -> r.id) .header("Key", r -> r.key) .header("Value", r -> r.value); - LOGGER.debug(REGISTRYDUMP, ()-> LogMessageAdapter.adapt(sb -> - { + LOGGER.debug(REGISTRYDUMP, ()-> LogMessageAdapter.adapt(sb -> { sb.append("Registry Name: ").append(name).append('\n'); tab.clearRows(); getKeys().stream().map(this::getID).sorted().map(id -> { V val = getValue(id); - ResourceLocation key = getKey(val); - return new DumpRow(Integer.toString(id), getKey(val).toString(), val.toString()); + var key = getKey(val); + return new DumpRow(Integer.toString(id), key.toString(), val.toString()); }).forEach(tab::add); tab.build(sb); })); @@ -796,24 +714,19 @@ 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) - { - Map ovs = Maps.newHashMap(overrides); - for (Map.Entry entry : ids.entrySet()) - { + public void loadIds(Object2IntMap ids, Map overrides, Object2IntMap missing, Map remapped, ForgeRegistry old, ResourceLocation name) { + Map ovs = new HashMap<>(overrides); + 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) - { + if (currId == -1) { LOGGER.info(REGISTRIES,"Registry {}: Found a missing id from the world {}", this.name, itemName); missing.put(itemName, newId); continue; // no block/item -> nothing to add - } - else if (currId != newId) - { + } else if (currId != newId) { LOGGER.debug(REGISTRIES,"Registry {}: Fixed {} id mismatch {}: {} (init) -> {} (map).", this.name, name, itemName, currId, newId); remapped.put(itemName, new IdMappingEvent.IdRemapping(currId, newId)); } @@ -821,25 +734,20 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist V obj = old.getRaw(itemName); Preconditions.checkState(obj != null, "objectKey has an ID but no object. Reflection/ASM hackery? Registry bug?"); - List lst = Lists.newArrayList(old.overrides.get(itemName)); + List lst = new ArrayList<>(old.overrides.get(itemName)); String primaryName = null; - if (old.overrides.containsKey(itemName)) - { - if (!overrides.containsKey(itemName)) - { + if (old.overrides.containsKey(itemName)) { + if (!overrides.containsKey(itemName)) { lst.add(obj); obj = old.overrides.get(itemName).iterator().next(); //Get the first one in the list, Which should be the first one registered primaryName = old.owners.inverse().get(obj).owner; - } - else + } else primaryName = overrides.get(itemName); } - for (V value : lst) - { + for (V value : lst) { OverrideOwner owner = old.owners.inverse().get(value); - if (owner == null) - { + if (owner == null) { LOGGER.warn(REGISTRIES,"Registry {}: Override did not have an associated owner object. Name: {} Value: {}", this.name, entry.getKey(), value); continue; } @@ -858,16 +766,13 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist ovs.remove(itemName); } - for (Map.Entry entry : ovs.entrySet()) - { + for (Map.Entry entry : ovs.entrySet()) { ResourceLocation itemName = entry.getKey(); String owner = entry.getValue(); String current = this.owners.inverse().get(this.getRaw(itemName)).owner; - if (!owner.equals(current)) - { + if (!owner.equals(current)) { V _new = this.owners.get(new OverrideOwner(owner, ResourceKey.create(this.key, itemName))); - if (_new == null) - { + if (_new == null) { LOGGER.warn(REGISTRIES,"Registry {}: Skipping override for {}, Unknown owner {}", this.name, itemName, owner); continue; } @@ -883,8 +788,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } //Public for tests - public Snapshot makeSnapshot() - { + public Snapshot makeSnapshot() { Snapshot ret = new Snapshot(); this.ids.forEach((id, value) -> ret.ids.put(getKey(value), id)); ret.aliases.putAll(this.aliases); @@ -893,11 +797,9 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist return ret; } - Map getOverrideOwners() - { - Map ret = Maps.newHashMap(); - for (ResourceLocation key : this.overrides.keySet()) - { + Map getOverrideOwners() { + Map ret = new HashMap<>(); + for (ResourceLocation key : this.overrides.keySet()) { V obj = this.names.get(key); OverrideOwner owner = this.owners.inverse().get(obj); if (owner == null) @@ -907,26 +809,18 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist return ret; } - private class RegistryCodec implements Codec - { + private class RegistryCodec implements Codec { @Override - public DataResult> decode(DynamicOps ops, T input) - { - if (ops.compressMaps()) - { - return ops.getNumberValue(input).flatMap(n -> - { + public DataResult> decode(DynamicOps ops, T input) { + if (ops.compressMaps()) { + return ops.getNumberValue(input).flatMap(n -> { int id = n.intValue(); if (ids.get(id) == null) - { return DataResult.error(() -> "Unknown registry id in " + ForgeRegistry.this.key + ": " + n); - } V val = ForgeRegistry.this.getValue(id); return DataResult.success(val); }).map(v -> Pair.of(v, ops.empty())); - } - else - { + } else { return ResourceLocation.CODEC.decode(ops, input).flatMap(keyValuePair -> !ForgeRegistry.this.containsKey(keyValuePair.getFirst()) ? DataResult.error(() -> "Unknown registry key in " + ForgeRegistry.this.key + ": " + keyValuePair.getFirst()) : DataResult.success(keyValuePair.mapFirst(ForgeRegistry.this::getValue))); @@ -934,44 +828,37 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } @Override - public DataResult encode(V input, DynamicOps ops, T prefix) - { + public DataResult encode(V input, DynamicOps ops, T prefix) { ResourceLocation key = getKey(input); if (key == null) - { return DataResult.error(() -> "Unknown registry element in " + ForgeRegistry.this.key + ": " + input); - } T toMerge = ops.compressMaps() ? ops.createInt(getID(input)) : ops.createString(key.toString()); return ops.mergeToPrimitive(prefix, toMerge); } } - public static class Snapshot - { - private static final Comparator sorter = (a,b) -> a.compareNamespaced(b); - public final Map ids = Maps.newTreeMap(sorter); - public final Map aliases = Maps.newTreeMap(sorter); - public final Set blocked = Sets.newTreeSet(); - public final Map overrides = Maps.newTreeMap(sorter); + public static class Snapshot { + private static final Comparator sorter = ResourceLocation::compareNamespaced; + public final Object2IntMap ids = new Object2IntRBTreeMap<>(sorter); + public final Map aliases = new TreeMap<>(sorter); + public final IntSet blocked = new IntRBTreeSet(); + public final Map overrides = new TreeMap<>(sorter); private FriendlyByteBuf binary = null; - public CompoundTag write() - { + public CompoundTag write() { 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()); @@ -980,8 +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()); @@ -989,135 +875,90 @@ 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; } - public static Snapshot read(CompoundTag nbt) - { + public static Snapshot read(CompoundTag nbt) { Snapshot ret = new Snapshot(); if (nbt == null) - { return ret; - } ListTag list = nbt.getList("ids", 10); - list.forEach(e -> - { + list.forEach(e -> { CompoundTag comp = (CompoundTag)e; ret.ids.put(new ResourceLocation(comp.getString("K")), comp.getInt("V")); }); list = nbt.getList("aliases", 10); - list.forEach(e -> - { + list.forEach(e -> { CompoundTag comp = (CompoundTag)e; ret.aliases.put(new ResourceLocation(comp.getString("K")), new ResourceLocation(comp.getString("V"))); }); list = nbt.getList("overrides", 10); - list.forEach(e -> - { + list.forEach(e -> { CompoundTag comp = (CompoundTag)e; ret.overrides.put(new ResourceLocation(comp.getString("K")), comp.getString("V")); }); int[] blocked = nbt.getIntArray("blocked"); for (int i : blocked) - { ret.blocked.add(i); - } return ret; } - public synchronized FriendlyByteBuf getPacketData() - { + public synchronized FriendlyByteBuf getPacketData() { if (binary == null) { FriendlyByteBuf pkt = new FriendlyByteBuf(Unpooled.buffer()); - - pkt.writeVarInt(this.ids.size()); - this.ids.forEach((k,v) -> { - pkt.writeResourceLocation(k); - pkt.writeVarInt(v); - }); - - pkt.writeVarInt(this.aliases.size()); - this.aliases.forEach((k, v) -> { - pkt.writeResourceLocation(k); - pkt.writeResourceLocation(v); - }); - - pkt.writeVarInt(this.overrides.size()); - this.overrides.forEach((k, v) -> { - pkt.writeResourceLocation(k); - pkt.writeUtf(v, 0x100); - }); - - pkt.writeVarInt(this.blocked.size()); - this.blocked.forEach(pkt::writeVarInt); - + pkt.writeMap(this.ids, FriendlyByteBuf::writeResourceLocation, FriendlyByteBuf::writeVarInt); + pkt.writeMap(this.aliases, FriendlyByteBuf::writeResourceLocation, FriendlyByteBuf::writeResourceLocation); + pkt.writeMap(this.overrides, FriendlyByteBuf::writeResourceLocation, (b,v) -> b.writeUtf(v, 0x100)); + pkt.writeCollection(this.blocked, FriendlyByteBuf::writeVarInt); this.binary = pkt; } return new FriendlyByteBuf(binary.slice()); } - public static Snapshot read(FriendlyByteBuf buff) - { - if (buff == null) + public static Snapshot read(FriendlyByteBuf buf) { + if (buf == null) return new Snapshot(); - Snapshot ret = new Snapshot(); - - int len = buff.readVarInt(); - for (int x = 0; x < len; x++) - ret.ids.put(buff.readResourceLocation(), buff.readVarInt()); - - len = buff.readVarInt(); - for (int x = 0; x < len; x++) - ret.aliases.put(buff.readResourceLocation(), buff.readResourceLocation()); - - len = buff.readVarInt(); - for (int x = 0; x < len; x++) - ret.overrides.put(buff.readResourceLocation(), buff.readUtf(0x100)); - - len = buff.readVarInt(); - for (int x = 0; x < len; x++) - ret.blocked.add(buff.readVarInt()); - + var ret = new Snapshot(); + ret.ids.putAll(buf.readMap(FriendlyByteBuf::readResourceLocation, FriendlyByteBuf::readVarInt)); + ret.aliases.putAll(buf.readMap(FriendlyByteBuf::readResourceLocation, FriendlyByteBuf::readResourceLocation)); + ret.overrides.putAll(buf.readMap(FriendlyByteBuf::readResourceLocation, b -> b.readUtf(0x100))); + ret.blocked.addAll(buf.readList(FriendlyByteBuf::readVarInt)); return ret; } } @SuppressWarnings("unchecked") - public MissingMappingsEvent getMissingEvent(ResourceLocation name, Map map) - { - List> lst = Lists.newArrayList(); + 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; - for (MissingMappingsEvent.Mapping remap : mappings) - { + for (MissingMappingsEvent.Mapping remap : mappings) { MissingMappingsEvent.Action action = remap.action; - if (action == MissingMappingsEvent.Action.REMAP) - { + if (action == MissingMappingsEvent.Action.REMAP) { // entry re-mapped, finish the registration with the new name/object, but the old id int currId = getID(remap.target); 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) @@ -1125,35 +966,25 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist this.addAlias(remap.key, newName); - if (currId != realId) - { + if (currId != realId) { LOGGER.info(REGISTRIES,"Fixed id mismatch {}: {} (init) -> {} (map).", newName, currId, realId); remaps.put(newName, new IdMappingEvent.IdRemapping(currId, realId)); } - } - else - { + } else { // block item missing, warn as requested and block the id - if (action == MissingMappingsEvent.Action.DEFAULT) - { + if (action == MissingMappingsEvent.Action.DEFAULT) { V m = this.missing == null ? null : this.missing.createMissing(remap.key, injectNetworkDummies); if (m == null) defaulted.add(remap.key); else this.add(remap.id, remap.key, m, remap.key.getNamespace()); - } - else if (action == MissingMappingsEvent.Action.IGNORE) - { + } else if (action == MissingMappingsEvent.Action.IGNORE) { LOGGER.debug(REGISTRIES,"Ignoring {}", remap.key); ignored++; - } - else if (action == MissingMappingsEvent.Action.FAIL) - { + } else if (action == MissingMappingsEvent.Action.FAIL) { LOGGER.debug(REGISTRIES,"Failing {}!", remap.key); failed.add(remap.key); - } - else if (action == MissingMappingsEvent.Action.WARN) - { + } else if (action == MissingMappingsEvent.Action.WARN) { LOGGER.warn(REGISTRIES,"{} may cause world breakage!", remap.key); } this.block(remap.id); @@ -1164,10 +995,9 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist LOGGER.debug(REGISTRIES,"There were {} missing mappings that have been ignored", ignored); } - RegistryBuilder getBuilder() - { + RegistryBuilder getBuilder() { return this.builder; } private record OverrideOwner(String owner, ResourceKey key){}; -} +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index 2f806d19fa..8244919d92 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; @@ -30,6 +32,7 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.syncher.EntityDataSerializer; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.effect.MobEffect; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.SpawnPlacements; import net.minecraft.world.entity.ai.attributes.Attribute; @@ -38,7 +41,10 @@ import net.minecraft.world.entity.ai.village.poi.PoiType; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.alchemy.Potion; +import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.levelgen.DebugLevelSource; @@ -57,7 +63,6 @@ import net.minecraftforge.fml.StartupMessageManager; import net.minecraftforge.fml.util.EnhancedRuntimeException; import net.minecraftforge.fml.util.thread.EffectiveSide; import net.minecraftforge.registries.ForgeRegistries.Keys; -import net.minecraftforge.registries.holdersets.HolderSetType; import org.apache.commons.lang3.Validate; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -68,12 +73,12 @@ 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 -{ +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"); @@ -82,16 +87,15 @@ public class GameData private static boolean hasInit = false; private static final boolean DISABLE_VANILLA_REGISTRIES = Boolean.parseBoolean(System.getProperty("forge.disableVanillaGameData", "false")); // Use for unit tests/debugging - private static final BiConsumer> LOCK_VANILLA = (name, reg) -> reg.slaves.values().stream().filter(o -> o instanceof ILockableRegistry).forEach(o -> ((ILockableRegistry)o).lock()); + private static final BiConsumer> LOCK_VANILLA = (name, reg) -> reg.slaves.values().stream().filter(o -> o instanceof ILockableRegistry).forEach(o -> ((ILockableRegistry) o).lock()); static { init(); } - public static void init() - { - if (DISABLE_VANILLA_REGISTRIES) - { + @SuppressWarnings("deprecation") + public static void init() { + if (DISABLE_VANILLA_REGISTRIES) { LOGGER.warn(REGISTRIES, "DISABLING VANILLA REGISTRY CREATION AS PER SYSTEM VARIABLE SETTING! forge.disableVanillaGameData"); return; } @@ -138,59 +142,50 @@ public class GameData makeRegistry(Keys.BIOMES).disableSync().create(); } - static RegistryBuilder> getDataSerializersRegistryBuilder() - { + static RegistryBuilder> getDataSerializersRegistryBuilder() { return makeRegistry(Keys.ENTITY_DATA_SERIALIZERS, 256 /*vanilla space*/, MAX_VARINT).disableSaving().disableOverrides(); } - static RegistryBuilder> getGLMSerializersRegistryBuilder() - { + static RegistryBuilder> getGLMSerializersRegistryBuilder() { return makeRegistry(Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS).disableSaving().disableSync(); } - static RegistryBuilder> getBiomeModifierSerializersRegistryBuilder() - { + static RegistryBuilder> getBiomeModifierSerializersRegistryBuilder() { return new RegistryBuilder>().disableSaving().disableSync(); } - static RegistryBuilder> getStructureModifierSerializersRegistryBuilder() - { + static RegistryBuilder> getStructureModifierSerializersRegistryBuilder() { return new RegistryBuilder>().disableSaving().disableSync(); } - static RegistryBuilder getFluidTypeRegistryBuilder() - { + static RegistryBuilder getFluidTypeRegistryBuilder() { return makeRegistry(Keys.FLUID_TYPES).disableSaving(); } - static RegistryBuilder getHolderSetTypeRegistryBuilder() - { - return new RegistryBuilder().disableSaving().disableSync(); + static RegistryBuilder makeUnsavedAndUnsynced() { + return RegistryBuilder.of().disableSaving().disableSync(); } - static RegistryBuilder getItemDisplayContextRegistryBuilder() - { + static RegistryBuilder getItemDisplayContextRegistryBuilder() { return new RegistryBuilder() - .setMaxID(128 * 2) /* 0 -> 127 gets positive ID, 128 -> 256 gets negative ID */.disableOverrides().disableSaving() - .setDefaultKey(new ResourceLocation("minecraft:none")) - .onAdd(ItemDisplayContext.ADD_CALLBACK); + .setMaxID(128 * 2) /* 0 -> 127 gets positive ID, 128 -> 256 gets negative ID */.disableOverrides().disableSaving() + .setDefaultKey(new ResourceLocation("minecraft:none")) + .onAdd(ItemDisplayContext.ADD_CALLBACK); } - private static RegistryBuilder makeRegistry(ResourceKey> key) - { + private static RegistryBuilder makeRegistry(ResourceKey> key) { return new RegistryBuilder().setName(key.location()).setMaxID(MAX_VARINT).hasWrapper(); } - private static RegistryBuilder makeRegistry(ResourceKey> key, int min, int max) - { + + private static RegistryBuilder makeRegistry(ResourceKey> key, int min, int max) { return new RegistryBuilder().setName(key.location()).setIDRange(min, max).hasWrapper(); } - private static RegistryBuilder makeRegistry(ResourceKey> key, String _default) - { + + private static RegistryBuilder makeRegistry(ResourceKey> key, String _default) { return new RegistryBuilder().setName(key.location()).setMaxID(MAX_VARINT).hasWrapper().setDefaultKey(new ResourceLocation(_default)); } - public static MappedRegistry getWrapper(ResourceKey> key, Lifecycle lifecycle) - { + public static MappedRegistry getWrapper(ResourceKey> key, Lifecycle lifecycle) { IForgeRegistry reg = RegistryManager.ACTIVE.getRegistry(key); Validate.notNull(reg, "Attempted to get vanilla wrapper for unknown registry: " + key.toString()); @SuppressWarnings("unchecked") @@ -199,8 +194,7 @@ public class GameData return ret; } - public static MappedRegistry getWrapper(ResourceKey> key, Lifecycle lifecycle, String defKey) - { + public static MappedRegistry getWrapper(ResourceKey> key, Lifecycle lifecycle, String defKey) { IForgeRegistry reg = RegistryManager.ACTIVE.getRegistry(key); Validate.notNull(reg, "Attempted to get vanilla wrapper for unknown registry: " + key.toString()); @SuppressWarnings("unchecked") @@ -210,26 +204,21 @@ public class GameData } @SuppressWarnings("unchecked") - public static Map getBlockItemMap() - { + public static Map getBlockItemMap() { return RegistryManager.ACTIVE.getRegistry(Keys.ITEMS).getSlaveMap(BLOCK_TO_ITEM, Map.class); } @SuppressWarnings("unchecked") - public static IdMapper getBlockStateIDMap() - { + public static IdMapper getBlockStateIDMap() { return RegistryManager.ACTIVE.getRegistry(Keys.BLOCKS).getSlaveMap(BLOCKSTATE_TO_ID, IdMapper.class); } @SuppressWarnings("unchecked") - public static Map getBlockStatePointOfInterestTypeMap() - { + public static Map getBlockStatePointOfInterestTypeMap() { return RegistryManager.ACTIVE.getRegistry(Keys.POI_TYPES).getSlaveMap(BLOCKSTATE_TO_POINT_OF_INTEREST_TYPE, Map.class); } - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static void vanillaSnapshot() - { + public static void vanillaSnapshot() { LOGGER.debug(REGISTRIES, "Creating vanilla freeze snapshot"); for (Map.Entry> r : RegistryManager.ACTIVE.registries.entrySet()) { @@ -245,13 +234,12 @@ public class GameData LOGGER.debug(REGISTRIES, "Vanilla freeze snapshot created"); } - public static void unfreezeData() - { + @SuppressWarnings("deprecation") + public static void unfreezeData() { LOGGER.debug(REGISTRIES, "Unfreezing vanilla registries"); BuiltInRegistries.REGISTRY.stream().filter(r -> r instanceof MappedRegistry).forEach(r -> ((MappedRegistry)r).unfreeze()); } - @SuppressWarnings({ "rawtypes", "unchecked" }) public static void freezeData() { LOGGER.debug(REGISTRIES, "Freezing registries"); @@ -281,7 +269,7 @@ public class GameData public static void revertToFrozen() { revertTo(RegistryManager.FROZEN, true); } - @SuppressWarnings({ "unchecked", "rawtypes" }) + public static void revertTo(final RegistryManager target, boolean fireEvents) { if (target.registries.isEmpty()) @@ -307,7 +295,6 @@ public class GameData LOGGER.debug(REGISTRIES, "{} state restored.", target.getName()); } - @SuppressWarnings({ "rawtypes", "unchecked" }) public static void revert(RegistryManager state, ResourceLocation registry, boolean lock) { LOGGER.debug(REGISTRIES, "Reverting {} to {}", registry, state.getName()); @@ -376,11 +363,12 @@ public class GameData this.nextId = 0; } + @SuppressWarnings("unused") void remove(I key) { - 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); } } @@ -430,21 +418,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 @@ -522,6 +506,7 @@ public class GameData @Override public void onAdd(IForgeRegistryInternal owner, RegistryManager stage, int id, ResourceKey key, PoiType obj, @Nullable PoiType oldObj) { + @SuppressWarnings("unchecked") Map map = owner.getSlaveMap(BLOCKSTATE_TO_POINT_OF_INTEREST_TYPE, Map.class); if (oldObj != null) { @@ -590,7 +575,6 @@ public class GameData } - @SuppressWarnings({ "unchecked", "rawtypes" }) public static Multimap injectSnapshot(Map snapshot, boolean injectFrozenData, boolean isLocalWorld) { LOGGER.info(REGISTRIES, "Injecting existing registry data into this {} instance", EffectiveSide.get()); @@ -605,11 +589,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"; @@ -625,13 +609,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); }); @@ -642,11 +626,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() @@ -664,7 +649,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) @@ -681,7 +666,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"); }); @@ -739,7 +724,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) @@ -751,8 +736,7 @@ public class GameData } //Another bouncer for generic reasons - @SuppressWarnings("unchecked") - 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); @@ -764,9 +748,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); } /** @@ -785,11 +769,11 @@ 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; } return new ResourceLocation(prefix, name); } -} +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/registries/RegistryBuilder.java b/src/main/java/net/minecraftforge/registries/RegistryBuilder.java index f4e0b153a4..c922197b47 100644 --- a/src/main/java/net/minecraftforge/registries/RegistryBuilder.java +++ b/src/main/java/net/minecraftforge/registries/RegistryBuilder.java @@ -20,8 +20,19 @@ import java.util.List; import java.util.Set; import java.util.function.Function; -public class RegistryBuilder -{ +public class RegistryBuilder { + public static RegistryBuilder of() { + return new RegistryBuilder(); + } + + public static RegistryBuilder of(String name) { + return of(new ResourceLocation(name)); + } + + public static RegistryBuilder of(ResourceLocation name) { + return new RegistryBuilder().setName(name); + } + private static final int MAX_ID = Integer.MAX_VALUE - 1; private ResourceLocation registryName;