From c85f2e388971d5e88e6b81c8e9e8279640a5f368 Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Sun, 19 Jun 2022 20:18:05 +0200 Subject: [PATCH] Fix #2108: FlammableBlockRegistry ignores tags unless /reload (#2326) --- .../registry/FlammableBlockRegistryImpl.java | 93 ++++++------------- .../content/registry/ContentRegistryTest.java | 4 + .../test/content/registry/FlammableTest.java | 39 ++++++++ .../src/testmod/resources/fabric.mod.json | 3 + 4 files changed, 76 insertions(+), 63 deletions(-) create mode 100644 fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/FlammableTest.java diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/content/registry/FlammableBlockRegistryImpl.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/content/registry/FlammableBlockRegistryImpl.java index 7f70fed43..3ba88a8a1 100644 --- a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/content/registry/FlammableBlockRegistryImpl.java +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/content/registry/FlammableBlockRegistryImpl.java @@ -16,78 +16,63 @@ package net.fabricmc.fabric.impl.content.registry; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.Map; import net.minecraft.block.Block; -import net.minecraft.resource.ResourceManager; -import net.minecraft.resource.ResourceType; import net.minecraft.tag.TagKey; -import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryEntry; +import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents; import net.fabricmc.fabric.api.registry.FlammableBlockRegistry; -import net.fabricmc.fabric.api.resource.ResourceManagerHelper; -import net.fabricmc.fabric.api.resource.ResourceReloadListenerKeys; -import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; -public class FlammableBlockRegistryImpl implements FlammableBlockRegistry, SimpleSynchronousResourceReloadListener { +public class FlammableBlockRegistryImpl implements FlammableBlockRegistry { private static final FlammableBlockRegistry.Entry REMOVED = new FlammableBlockRegistry.Entry(0, 0); private static final Map<Block, FlammableBlockRegistryImpl> REGISTRIES = new HashMap<>(); - private static final Collection<Identifier> RELOAD_DEPS = Collections.singletonList(ResourceReloadListenerKeys.TAGS); - private static int idCounter = 0; private final Map<Block, FlammableBlockRegistry.Entry> registeredEntriesBlock = new HashMap<>(); private final Map<TagKey<Block>, FlammableBlockRegistry.Entry> registeredEntriesTag = new HashMap<>(); - private final Map<Block, FlammableBlockRegistry.Entry> computedEntries = new HashMap<>(); - private final Identifier id; + private volatile Map<Block, FlammableBlockRegistry.Entry> computedEntries = null; private final Block key; - private boolean tagsPresent = false; private FlammableBlockRegistryImpl(Block key) { - ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(this); - this.id = new Identifier("fabric:private/fire_registry_" + (++idCounter)); this.key = key; + + // Reset computed values after tags change since they depends on tags. + CommonLifecycleEvents.TAGS_LOADED.register((registries, client) -> { + computedEntries = null; + }); } - // TODO: Asynchronous? - @Override - public void reload(ResourceManager var1) { - reload(); - tagsPresent = true; - } + private Map<Block, FlammableBlockRegistry.Entry> getEntryMap() { + Map<Block, FlammableBlockRegistry.Entry> ret = computedEntries; - private void reload() { - computedEntries.clear(); + if (ret == null) { + ret = new IdentityHashMap<>(); - // tags take precedence before blocks - for (TagKey<Block> tag : registeredEntriesTag.keySet()) { - FlammableBlockRegistry.Entry entry = registeredEntriesTag.get(tag); + // tags take precedence over blocks + for (TagKey<Block> tag : registeredEntriesTag.keySet()) { + FlammableBlockRegistry.Entry entry = registeredEntriesTag.get(tag); - for (RegistryEntry<Block> block : Registry.BLOCK.iterateEntries(tag)) { - computedEntries.put(block.value(), entry); + for (RegistryEntry<Block> block : Registry.BLOCK.iterateEntries(tag)) { + ret.put(block.value(), entry); + } } + + ret.putAll(registeredEntriesBlock); + + computedEntries = ret; } - computedEntries.putAll(registeredEntriesBlock); - - /* computedBurnChances.clear(); - computedSpreadChances.clear(); - - for (Block block : computedEntries.keySet()) { - FlammableBlockRegistry.Entry entry = computedEntries.get(block); - computedBurnChances.put(block, entry.getBurnChance()); - computedSpreadChances.put(block, entry.getSpreadChance()); - } */ + return ret; } // User-facing fire registry interface - queries vanilla fire block @Override public Entry get(Block block) { - Entry entry = computedEntries.get(block); + Entry entry = getEntryMap().get(block); if (entry != null) { return entry; @@ -97,25 +82,21 @@ public class FlammableBlockRegistryImpl implements FlammableBlockRegistry, Simpl } public Entry getFabric(Block block) { - return computedEntries.get(block); + return getEntryMap().get(block); } @Override public void add(Block block, Entry value) { registeredEntriesBlock.put(block, value); - if (tagsPresent) { - reload(); - } + computedEntries = null; } @Override public void add(TagKey<Block> tag, Entry value) { registeredEntriesTag.put(tag, value); - if (tagsPresent) { - reload(); - } + computedEntries = null; } @Override @@ -132,18 +113,14 @@ public class FlammableBlockRegistryImpl implements FlammableBlockRegistry, Simpl public void clear(Block block) { registeredEntriesBlock.remove(block); - if (tagsPresent) { - reload(); - } + computedEntries = null; } @Override public void clear(TagKey<Block> tag) { registeredEntriesTag.remove(tag); - if (tagsPresent) { - reload(); - } + computedEntries = null; } public static FlammableBlockRegistryImpl getInstance(Block block) { @@ -153,14 +130,4 @@ public class FlammableBlockRegistryImpl implements FlammableBlockRegistry, Simpl return REGISTRIES.computeIfAbsent(block, FlammableBlockRegistryImpl::new); } - - @Override - public Identifier getFabricId() { - return id; - } - - @Override - public Collection<Identifier> getFabricDependencies() { - return RELOAD_DEPS; - } } diff --git a/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java b/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java index f5a6b53ba..e3023a901 100644 --- a/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java +++ b/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java @@ -22,10 +22,12 @@ import org.slf4j.LoggerFactory; import net.minecraft.block.Blocks; import net.minecraft.item.HoeItem; import net.minecraft.item.Items; +import net.minecraft.tag.BlockTags; import net.minecraft.util.Identifier; import net.minecraft.village.VillagerProfession; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.registry.FlammableBlockRegistry; import net.fabricmc.fabric.api.registry.FlattenableBlockRegistry; import net.fabricmc.fabric.api.registry.OxidizableBlocksRegistry; import net.fabricmc.fabric.api.registry.StrippableBlockRegistry; @@ -47,7 +49,9 @@ public final class ContentRegistryTest implements ModInitializer { // - villagers can now collect, consume (at the same level of bread) and compost apples // - villagers can now collect and plant oak saplings // - assign a loot table to the nitwit villager type + // - sand is now flammable + FlammableBlockRegistry.getDefaultInstance().add(BlockTags.SAND, 4, 4); FlattenableBlockRegistry.register(Blocks.RED_WOOL, Blocks.YELLOW_WOOL.getDefaultState()); StrippableBlockRegistry.register(Blocks.QUARTZ_PILLAR, Blocks.HAY_BLOCK); diff --git a/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/FlammableTest.java b/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/FlammableTest.java new file mode 100644 index 000000000..fc44af67d --- /dev/null +++ b/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/FlammableTest.java @@ -0,0 +1,39 @@ +/* + * 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.content.registry; + +import net.minecraft.block.Blocks; +import net.minecraft.test.GameTest; +import net.minecraft.test.GameTestException; +import net.minecraft.test.TestContext; + +import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.fabricmc.fabric.api.registry.FlammableBlockRegistry; + +public class FlammableTest { + /** + * Regression test for <a href="https://github.com/FabricMC/fabric/issues/2108">FlammableBlockRegistry ignoring tags on first load</a>. + */ + @GameTest(structureName = FabricGameTest.EMPTY_STRUCTURE) + public void testFlammableTag(TestContext context) { + if (FlammableBlockRegistry.getDefaultInstance().get(Blocks.SAND).getBurnChance() != 4) { + throw new GameTestException("Expected blocks in the sand tag to be flammable!"); + } + + context.complete(); + } +} diff --git a/fabric-content-registries-v0/src/testmod/resources/fabric.mod.json b/fabric-content-registries-v0/src/testmod/resources/fabric.mod.json index a0e697e2f..6cf56a479 100644 --- a/fabric-content-registries-v0/src/testmod/resources/fabric.mod.json +++ b/fabric-content-registries-v0/src/testmod/resources/fabric.mod.json @@ -11,6 +11,9 @@ "entrypoints": { "main": [ "net.fabricmc.fabric.test.content.registry.ContentRegistryTest" + ], + "fabric-gametest": [ + "net.fabricmc.fabric.test.content.registry.FlammableTest" ] } }