Big clean up, more details in the PR (#216)

* Big clean up, more details in the PR

* Fix build

* Deprecate BlockProperties, generate AWs for Item constructors, Block constructors and RenderStateShard fields

* Add a few more RenderType AWs

* Deprecate BlockPropertiesExtension

* Set defaultType on resolving the entity type in SpawnEggItem

* Used the wrong object

* Add license information for generating AWs

* Add link to original PR

* Properly add support for forge vanilla registries

* Bump to 4.1
This commit is contained in:
shedaniel
2022-03-12 00:01:49 +08:00
committed by GitHub
parent 5f63bbafea
commit 36a5aea8aa
48 changed files with 1126 additions and 611 deletions

View File

@@ -34,7 +34,6 @@ import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class FluidStackHooksImpl {
@@ -68,7 +67,7 @@ public class FluidStackHooksImpl {
@OnlyIn(Dist.CLIENT)
@Nullable
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) {
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
if (state.getType() == Fluids.EMPTY) return null;
ResourceLocation texture = state.getType().getAttributes().getStillTexture(level, pos);
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
@@ -76,7 +75,7 @@ public class FluidStackHooksImpl {
@OnlyIn(Dist.CLIENT)
@Nullable
public static TextureAtlasSprite getStillTexture(@NotNull FluidStack stack) {
public static TextureAtlasSprite getStillTexture(FluidStack stack) {
if (stack.getFluid() == Fluids.EMPTY) return null;
ResourceLocation texture = stack.getFluid().getAttributes().getStillTexture(FluidStackHooksForge.toForge(stack));
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
@@ -84,7 +83,7 @@ public class FluidStackHooksImpl {
@OnlyIn(Dist.CLIENT)
@Nullable
public static TextureAtlasSprite getStillTexture(@NotNull Fluid fluid) {
public static TextureAtlasSprite getStillTexture(Fluid fluid) {
if (fluid == Fluids.EMPTY) return null;
ResourceLocation texture = fluid.getAttributes().getStillTexture();
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
@@ -92,7 +91,7 @@ public class FluidStackHooksImpl {
@OnlyIn(Dist.CLIENT)
@Nullable
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) {
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
if (state.getType() == Fluids.EMPTY) return null;
ResourceLocation texture = state.getType().getAttributes().getFlowingTexture(level, pos);
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
@@ -100,7 +99,7 @@ public class FluidStackHooksImpl {
@OnlyIn(Dist.CLIENT)
@Nullable
public static TextureAtlasSprite getFlowingTexture(@NotNull FluidStack stack) {
public static TextureAtlasSprite getFlowingTexture(FluidStack stack) {
if (stack.getFluid() == Fluids.EMPTY) return null;
ResourceLocation texture = stack.getFluid().getAttributes().getFlowingTexture(FluidStackHooksForge.toForge(stack));
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
@@ -108,26 +107,26 @@ public class FluidStackHooksImpl {
@OnlyIn(Dist.CLIENT)
@Nullable
public static TextureAtlasSprite getFlowingTexture(@NotNull Fluid fluid) {
public static TextureAtlasSprite getFlowingTexture(Fluid fluid) {
if (fluid == Fluids.EMPTY) return null;
ResourceLocation texture = fluid.getAttributes().getFlowingTexture();
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
}
@OnlyIn(Dist.CLIENT)
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) {
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
if (state.getType() == Fluids.EMPTY) return -1;
return state.getType().getAttributes().getColor(level, pos);
}
@OnlyIn(Dist.CLIENT)
public static int getColor(@NotNull FluidStack stack) {
public static int getColor(FluidStack stack) {
if (stack.getFluid() == Fluids.EMPTY) return -1;
return stack.getFluid().getAttributes().getColor(FluidStackHooksForge.toForge(stack));
}
@OnlyIn(Dist.CLIENT)
public static int getColor(@NotNull Fluid fluid) {
public static int getColor(Fluid fluid) {
if (fluid == Fluids.EMPTY) return -1;
return fluid.getAttributes().getColor();
}

View File

@@ -31,7 +31,6 @@ import net.minecraftforge.fml.loading.FMLPaths;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
import net.minecraftforge.forgespi.language.IModFileInfo;
import net.minecraftforge.forgespi.language.IModInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
@@ -124,17 +123,17 @@ public class PlatformImpl {
}
@Override
public @NotNull Optional<String> getLogoFile(int i) {
public Optional<String> getLogoFile(int i) {
return this.info.getLogoFile();
}
@Override
public @NotNull Path getFilePath() {
public Path getFilePath() {
return this.info.getOwningFile().getFile().getFilePath();
}
@Override
public @NotNull Collection<String> getAuthors() {
public Collection<String> getAuthors() {
Optional<String> optional = this.info.getConfig().getConfigElement("authors")
.map(String::valueOf);
return optional.isPresent() ? Collections.singleton(optional.get()) : Collections.emptyList();
@@ -146,18 +145,18 @@ public class PlatformImpl {
}
@Override
public @NotNull Optional<String> getHomepage() {
public Optional<String> getHomepage() {
return this.info.getConfig().getConfigElement("displayURL")
.map(String::valueOf);
}
@Override
public @NotNull Optional<String> getSources() {
public Optional<String> getSources() {
return Optional.empty();
}
@Override
public @NotNull Optional<String> getIssueTracker() {
public Optional<String> getIssueTracker() {
IModFileInfo owningFile = this.info.getOwningFile();
if (owningFile instanceof ModFileInfo info) {
return Optional.ofNullable(info.getIssueURL())

View File

@@ -24,9 +24,12 @@ import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.material.MaterialColor;
import org.jetbrains.annotations.ApiStatus;
import java.util.function.Function;
@Deprecated
@ApiStatus.ScheduledForRemoval
public class BlockPropertiesImpl {
public static BlockProperties of(Material material, MaterialColor materialColor) {
return new Impl(material, (state) -> materialColor);

View File

@@ -1,29 +0,0 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.registry.level.advancement.forge;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.advancements.CriterionTrigger;
public class CriteriaTriggersRegistryImpl {
public static <T extends CriterionTrigger<?>> T register(T trigger) {
return CriteriaTriggers.register(trigger);
}
}

View File

@@ -40,7 +40,6 @@ import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
@@ -76,13 +75,11 @@ public class BiomeModificationsImpl {
BiomeProperties properties = new BiomeWrapped(event);
@Override
@NotNull
public ResourceLocation getKey() {
return event.getName();
}
@Override
@NotNull
public BiomeProperties getProperties() {
return properties;
}
@@ -113,32 +110,28 @@ public class BiomeModificationsImpl {
this.spawnProperties = spawnProperties;
}
@NotNull
@Override
public ClimateProperties getClimateProperties() {
return climateProperties;
}
@NotNull
@Override
public EffectsProperties getEffectsProperties() {
return effectsProperties;
}
@NotNull
@Override
public GenerationProperties getGenerationProperties() {
return generationProperties;
}
@NotNull
@Override
public SpawnProperties getSpawnProperties() {
return spawnProperties;
}
@Override
public Biome.@NotNull BiomeCategory getCategory() {
public Biome.BiomeCategory getCategory() {
return event.getCategory();
}
}
@@ -179,12 +172,12 @@ public class BiomeModificationsImpl {
}
@Override
public @NotNull Map<MobCategory, List<MobSpawnSettings.SpawnerData>> getSpawners() {
public Map<MobCategory, List<MobSpawnSettings.SpawnerData>> getSpawners() {
return builder.spawners;
}
@Override
public @NotNull Map<EntityType<?>, MobSpawnSettings.MobSpawnCost> getMobSpawnCosts() {
public Map<EntityType<?>, MobSpawnSettings.MobSpawnCost> getMobSpawnCosts() {
return builder.mobSpawnCosts;
}
}
@@ -200,27 +193,27 @@ public class BiomeModificationsImpl {
}
@Override
public @NotNull ClimateProperties.Mutable getClimateProperties() {
public ClimateProperties.Mutable getClimateProperties() {
return (ClimateProperties.Mutable) super.getClimateProperties();
}
@Override
public @NotNull EffectsProperties.Mutable getEffectsProperties() {
public EffectsProperties.Mutable getEffectsProperties() {
return (EffectsProperties.Mutable) super.getEffectsProperties();
}
@Override
public @NotNull GenerationProperties.Mutable getGenerationProperties() {
public GenerationProperties.Mutable getGenerationProperties() {
return (GenerationProperties.Mutable) super.getGenerationProperties();
}
@Override
public @NotNull SpawnProperties.Mutable getSpawnProperties() {
public SpawnProperties.Mutable getSpawnProperties() {
return (SpawnProperties.Mutable) super.getSpawnProperties();
}
@Override
public @NotNull Mutable setCategory(Biome.@NotNull BiomeCategory category) {
public Mutable setCategory(Biome.BiomeCategory category) {
event.setCategory(category);
return this;
}
@@ -248,7 +241,6 @@ public class BiomeModificationsImpl {
this.downfall = downfall;
}
@NotNull
@Override
public Biome.Precipitation getPrecipitation() {
return precipitation;
@@ -259,7 +251,6 @@ public class BiomeModificationsImpl {
return temperature;
}
@NotNull
@Override
public Biome.TemperatureModifier getTemperatureModifier() {
return temperatureModifier;
@@ -271,28 +262,28 @@ public class BiomeModificationsImpl {
}
@Override
public @NotNull Mutable setPrecipitation(Biome.@NotNull Precipitation precipitation) {
public Mutable setPrecipitation(Biome.Precipitation precipitation) {
this.precipitation = precipitation;
this.dirty = true;
return this;
}
@Override
public @NotNull Mutable setTemperature(float temperature) {
public Mutable setTemperature(float temperature) {
this.temperature = temperature;
this.dirty = true;
return this;
}
@Override
public @NotNull Mutable setTemperatureModifier(Biome.@NotNull TemperatureModifier temperatureModifier) {
public Mutable setTemperatureModifier(Biome.TemperatureModifier temperatureModifier) {
this.temperatureModifier = temperatureModifier;
this.dirty = true;
return this;
}
@Override
public @NotNull Mutable setDownfall(float downfall) {
public Mutable setDownfall(float downfall) {
this.downfall = downfall;
this.dirty = true;
return this;
@@ -336,7 +327,7 @@ public class BiomeModificationsImpl {
}
@Override
public @NotNull Mutable setCreatureProbability(float probability) {
public Mutable setCreatureProbability(float probability) {
builder.creatureGenerationProbability(probability);
return this;
}

View File

@@ -32,9 +32,9 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
public class EntityAttributeRegistryImpl {
private static final Map<Supplier<EntityType<? extends LivingEntity>>, Supplier<AttributeSupplier.Builder>> ATTRIBUTES = new ConcurrentHashMap<>();
private static final Map<Supplier<? extends EntityType<? extends LivingEntity>>, Supplier<AttributeSupplier.Builder>> ATTRIBUTES = new ConcurrentHashMap<>();
public static void register(Supplier<EntityType<? extends LivingEntity>> type, Supplier<AttributeSupplier.Builder> attribute) {
public static void register(Supplier<? extends EntityType<? extends LivingEntity>> type, Supplier<AttributeSupplier.Builder> attribute) {
ATTRIBUTES.put(type, attribute);
}
@@ -46,7 +46,7 @@ public class EntityAttributeRegistryImpl {
@SubscribeEvent
public static void event(EntityAttributeCreationEvent event) {
for (Map.Entry<Supplier<EntityType<? extends LivingEntity>>, Supplier<AttributeSupplier.Builder>> entry : ATTRIBUTES.entrySet()) {
for (Map.Entry<Supplier<? extends EntityType<? extends LivingEntity>>, Supplier<AttributeSupplier.Builder>> entry : ATTRIBUTES.entrySet()) {
event.put(entry.getKey().get(), entry.getValue().get().build());
}
}

View File

@@ -1,46 +0,0 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.registry.level.forge;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.GameRules;
import java.util.function.BiConsumer;
public class GameRuleFactoryImpl {
private GameRuleFactoryImpl() {
}
public static GameRules.Type<GameRules.BooleanValue> createBooleanRule(boolean defaultValue) {
return GameRules.BooleanValue.create(defaultValue);
}
public static GameRules.Type<GameRules.BooleanValue> createBooleanRule(boolean defaultValue, BiConsumer<MinecraftServer, GameRules.BooleanValue> changedCallback) {
return GameRules.BooleanValue.create(defaultValue, changedCallback);
}
public static GameRules.Type<GameRules.IntegerValue> createIntRule(int defaultValue) {
return GameRules.IntegerValue.create(defaultValue);
}
public static GameRules.Type<GameRules.IntegerValue> createIntRule(int defaultValue, BiConsumer<MinecraftServer, GameRules.IntegerValue> changedCallback) {
return GameRules.IntegerValue.create(defaultValue, changedCallback);
}
}

View File

@@ -1,28 +0,0 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.registry.level.forge;
import net.minecraft.world.level.GameRules;
public class GameRuleRegistryImpl {
public static <T extends GameRules.Value<T>> GameRules.Key<T> register(String name, GameRules.Category category, GameRules.Type<T> type) {
return GameRules.register(name, category, type);
}
}

View File

@@ -33,19 +33,29 @@ import dev.architectury.registry.registries.options.StandardRegistrarOption;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.common.world.ForgeWorldPreset;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.registries.*;
import org.jetbrains.annotations.NotNull;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable;
import java.lang.reflect.Type;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class RegistriesImpl {
private static final Logger LOGGER = LogManager.getLogger(RegistriesImpl.class);
private static final Multimap<RegistryEntryId<?>, Consumer<?>> LISTENERS = HashMultimap.create();
private static void listen(ResourceKey<?> resourceKey, ResourceLocation id, Consumer<?> listener, boolean vanilla) {
LISTENERS.put(new RegistryEntryId<>(resourceKey, id), listener);
}
public static Registries.RegistryProvider _get(String modId) {
return new RegistryProviderImpl(modId);
}
@@ -65,21 +75,68 @@ public class RegistriesImpl {
public static class Data {
private boolean collected = false;
private final Map<RegistryObject<?>, Supplier<? extends IForgeRegistryEntry<?>>> objects = new LinkedHashMap<>();
private final Map<ResourceLocation, Supplier<?>> vanillaObjects = new LinkedHashMap<>();
public void register(IForgeRegistry registry, RegistryObject object, Supplier<? extends IForgeRegistryEntry<?>> reference) {
if (!collected) {
objects.put(object, reference);
} else {
registry.register(reference.get());
ResourceKey<? extends Registry<Object>> resourceKey = ResourceKey.createRegistryKey(registry.getRegistryName());
IForgeRegistryEntry<?> value = reference.get();
registry.register(value);
object.updateReference(registry);
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(resourceKey, object.getId());
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
((Consumer<Object>) consumer).accept(value);
}
LISTENERS.removeAll(registryEntryId);
}
}
public <T> void register(Registry<T> registry, ResourceLocation id, Supplier<? extends T> reference) {
if (!collected) {
vanillaObjects.put(id, reference);
} else {
T value = reference.get();
Registry.register(registry, id, value);
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(registry.key(), id);
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
((Consumer<Object>) consumer).accept(value);
}
LISTENERS.removeAll(registryEntryId);
}
}
}
public static class RegistryEntryId<T> {
private final ResourceKey<T> registryKey;
private final ResourceLocation id;
public RegistryEntryId(ResourceKey<T> registryKey, ResourceLocation id) {
this.registryKey = registryKey;
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof RegistryEntryId)) return false;
RegistryEntryId<?> that = (RegistryEntryId<?>) o;
return java.util.Objects.equals(registryKey, that.registryKey) && java.util.Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return java.util.Objects.hash(registryKey, id);
}
}
public static class RegistryProviderImpl implements Registries.RegistryProvider {
private final String modId;
private final Supplier<IEventBus> eventBus;
private final Map<Type, Data> registry = new HashMap<>();
private final Map<ResourceKey<? extends Registry<?>>, Data> registry = new HashMap<>();
private final Multimap<ResourceKey<Registry<?>>, Consumer<Registrar<?>>> listeners = HashMultimap.create();
public RegistryProviderImpl(String modId) {
@@ -101,18 +158,27 @@ public class RegistriesImpl {
@Override
public <T> Registrar<T> get(ResourceKey<net.minecraft.core.Registry<T>> registryKey) {
updateEventBus();
return get(RegistryManager.ACTIVE.getRegistry(registryKey.location()));
ForgeRegistry registry = RegistryManager.ACTIVE.getRegistry(registryKey.location());
if (registry == null) {
Registry<T> ts = (Registry<T>) Registry.REGISTRY.get(registryKey.location());
if (ts == null) {
throw new IllegalArgumentException("Registry " + registryKey + " does not exist!");
} else {
return get(ts);
}
}
return get(registry);
}
public <T> Registrar<T> get(IForgeRegistry registry) {
updateEventBus();
return new ForgeBackedRegistryImpl<>(this.registry, registry);
return new ForgeBackedRegistryImpl<>(modId, this.registry, registry);
}
@Override
public <T> Registrar<T> get(net.minecraft.core.Registry<T> registry) {
updateEventBus();
return new VanillaBackedRegistryImpl<>(registry);
return new VanillaBackedRegistryImpl<>(modId, this.registry, registry);
}
@Override
@@ -129,20 +195,96 @@ public class RegistriesImpl {
}
public class EventListener {
public void handleVanillaRegistries() {
for (Registry<?> vanillaRegistry : Registry.REGISTRY) {
if (RegistryManager.ACTIVE.getRegistry(vanillaRegistry.key().location()) == null) {
// Must be vanilla
Registrar<?> archRegistry = get(vanillaRegistry);
for (Map.Entry<ResourceKey<? extends Registry<?>>, Data> typeDataEntry : RegistryProviderImpl.this.registry.entrySet()) {
ResourceKey<? extends Registry<?>> resourceKey = archRegistry.key();
if (typeDataEntry.getKey().equals(resourceKey)) {
Data data = typeDataEntry.getValue();
data.collected = true;
for (Map.Entry<ResourceLocation, Supplier<?>> entry : data.vanillaObjects.entrySet()) {
Object value = entry.getValue().get();
Registry.register((Registry<Object>) vanillaRegistry, entry.getKey(), value);
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(resourceKey, entry.getKey());
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
((Consumer<Object>) consumer).accept(value);
}
LISTENERS.removeAll(registryEntryId);
}
data.objects.clear();
}
}
for (Map.Entry<ResourceKey<net.minecraft.core.Registry<?>>, Consumer<Registrar<?>>> entry : listeners.entries()) {
if (entry.getKey().equals(vanillaRegistry.key())) {
entry.getValue().accept(archRegistry);
}
}
}
}
}
public void handleVanillaRegistriesPost() {
for (Registry<?> vanillaRegistry : Registry.REGISTRY) {
if (RegistryManager.ACTIVE.getRegistry(vanillaRegistry.key().location()) == null) {
// Must be vanilla
Registrar<?> archRegistry = get(vanillaRegistry);
List<RegistryEntryId<?>> toRemove = new ArrayList<>();
for (Map.Entry<RegistryEntryId<?>, Collection<Consumer<?>>> entry : LISTENERS.asMap().entrySet()) {
if (entry.getKey().registryKey.equals(archRegistry.key())) {
if (vanillaRegistry.containsKey(entry.getKey().id)) {
Object value = vanillaRegistry.get(entry.getKey().id);
for (Consumer<?> consumer : entry.getValue()) {
((Consumer<Object>) consumer).accept(value);
}
toRemove.add(entry.getKey());
} else {
LOGGER.warn("Registry entry listened {} was not realized!", entry.getKey());
}
}
}
for (RegistryEntryId<?> entryId : toRemove) {
LISTENERS.removeAll(entryId);
}
}
}
}
@SubscribeEvent
public void handleEvent(RegistryEvent.Register event) {
if (event.getGenericType() == Block.class) {
handleVanillaRegistries();
}
IForgeRegistry registry = event.getRegistry();
Registrar<Object> archRegistry = get(registry);
for (Map.Entry<Type, Data> typeDataEntry : RegistryProviderImpl.this.registry.entrySet()) {
if (typeDataEntry.getKey() == registry.getRegistrySuperType()) {
for (Map.Entry<ResourceKey<? extends Registry<?>>, Data> typeDataEntry : RegistryProviderImpl.this.registry.entrySet()) {
ResourceKey<? extends Registry<Object>> resourceKey = archRegistry.key();
if (typeDataEntry.getKey().equals(resourceKey)) {
Data data = typeDataEntry.getValue();
data.collected = true;
for (Map.Entry<RegistryObject<?>, Supplier<? extends IForgeRegistryEntry<?>>> entry : data.objects.entrySet()) {
registry.register(entry.getValue().get());
IForgeRegistryEntry<?> value = entry.getValue().get();
registry.register(value);
entry.getKey().updateReference(registry);
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(resourceKey, entry.getKey().getId());
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
((Consumer<Object>) consumer).accept(value);
}
LISTENERS.removeAll(registryEntryId);
}
data.objects.clear();
@@ -155,31 +297,57 @@ public class RegistriesImpl {
}
}
}
@SubscribeEvent(priority = EventPriority.LOWEST)
public void handleEventPost(RegistryEvent.Register event) {
if (event.getGenericType() == ForgeWorldPreset.class) {
handleVanillaRegistriesPost();
}
IForgeRegistry registry = event.getRegistry();
Registrar<Object> archRegistry = get(registry);
ResourceKey<? extends Registry<Object>> resourceKey = archRegistry.key();
List<RegistryEntryId<?>> toRemove = new ArrayList<>();
for (Map.Entry<RegistryEntryId<?>, Collection<Consumer<?>>> entry : LISTENERS.asMap().entrySet()) {
if (entry.getKey().registryKey.equals(resourceKey)) {
if (registry.containsKey(entry.getKey().id)) {
IForgeRegistryEntry value = registry.getValue(entry.getKey().id);
for (Consumer<?> consumer : entry.getValue()) {
((Consumer<Object>) consumer).accept(value);
}
toRemove.add(entry.getKey());
} else {
LOGGER.warn("Registry entry listened {} was not realized!", entry.getKey());
}
}
}
for (RegistryEntryId<?> id : toRemove) {
LISTENERS.removeAll(id);
}
}
}
}
public static class RegistryBuilderWrapper<T> implements RegistrarBuilder<T> {
@NotNull
private final RegistryProviderImpl provider;
@NotNull
private final net.minecraftforge.registries.RegistryBuilder<?> builder;
private boolean saveToDisk = false;
private boolean syncToClients = false;
public RegistryBuilderWrapper(@NotNull RegistryProviderImpl provider, @NotNull net.minecraftforge.registries.RegistryBuilder<?> builder) {
public RegistryBuilderWrapper(RegistryProviderImpl provider, net.minecraftforge.registries.RegistryBuilder<?> builder) {
this.provider = provider;
this.builder = builder;
}
@Override
public @NotNull Registrar<T> build() {
public Registrar<T> build() {
if (!syncToClients) builder.disableSync();
if (!saveToDisk) builder.disableSaving();
return provider.get(builder.create());
}
@Override
public @NotNull RegistrarBuilder<T> option(@NotNull RegistrarOption option) {
public RegistrarBuilder<T> option(RegistrarOption option) {
if (option == StandardRegistrarOption.SAVE_TO_DISC) {
this.saveToDisk = true;
} else if (option == StandardRegistrarOption.SYNC_TO_CLIENTS) {
@@ -190,23 +358,38 @@ public class RegistriesImpl {
}
public static class VanillaBackedRegistryImpl<T> implements Registrar<T> {
private final String modId;
private net.minecraft.core.Registry<T> delegate;
private Map<ResourceKey<? extends Registry<?>>, Data> registry;
public VanillaBackedRegistryImpl(net.minecraft.core.Registry<T> delegate) {
public VanillaBackedRegistryImpl(String modId, Map<ResourceKey<? extends Registry<?>>, Data> registry, net.minecraft.core.Registry<T> delegate) {
this.modId = modId;
this.registry = registry;
this.delegate = delegate;
}
@Override
public @NotNull RegistrySupplier<T> delegate(ResourceLocation id) {
public RegistrySupplier<T> delegate(ResourceLocation id) {
Supplier<T> value = Suppliers.memoize(() -> get(id));
Registrar<T> registrar = this;
return new RegistrySupplier<T>() {
@Override
public @NotNull ResourceLocation getRegistryId() {
public Registries getRegistries() {
return Registries.get(modId);
}
@Override
public Registrar<T> getRegistrar() {
return registrar;
}
@Override
public ResourceLocation getRegistryId() {
return delegate.key().location();
}
@Override
public @NotNull ResourceLocation getId() {
public ResourceLocation getId() {
return id;
}
@@ -241,8 +424,9 @@ public class RegistriesImpl {
}
@Override
public @NotNull <E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier) {
net.minecraft.core.Registry.register(delegate, id, supplier.get());
public <E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier) {
registry.computeIfAbsent(key(), type -> new Data())
.register(delegate, id, supplier);
return (RegistrySupplier<E>) delegate(id);
}
@@ -302,28 +486,51 @@ public class RegistriesImpl {
public Iterator<T> iterator() {
return delegate.iterator();
}
@Override
public void listen(ResourceLocation id, Consumer<T> callback) {
T value = get(id);
if (value != null) {
callback.accept(value);
} else {
RegistriesImpl.listen(key(), id, callback, true);
}
}
}
public static class ForgeBackedRegistryImpl<T extends IForgeRegistryEntry<T>> implements Registrar<T> {
private final String modId;
private IForgeRegistry<T> delegate;
private Map<Type, Data> registry;
private Map<ResourceKey<? extends Registry<?>>, Data> registry;
public ForgeBackedRegistryImpl(Map<Type, Data> registry, IForgeRegistry<T> delegate) {
public ForgeBackedRegistryImpl(String modId, Map<ResourceKey<? extends Registry<?>>, Data> registry, IForgeRegistry<T> delegate) {
this.modId = modId;
this.registry = registry;
this.delegate = delegate;
}
@Override
public @NotNull RegistrySupplier<T> delegate(ResourceLocation id) {
public RegistrySupplier<T> delegate(ResourceLocation id) {
Supplier<T> value = Suppliers.memoize(() -> get(id));
Registrar<T> registrar = this;
return new RegistrySupplier<T>() {
@Override
public @NotNull ResourceLocation getRegistryId() {
public Registries getRegistries() {
return Registries.get(modId);
}
@Override
public Registrar<T> getRegistrar() {
return registrar;
}
@Override
public ResourceLocation getRegistryId() {
return delegate.getRegistryName();
}
@Override
public @NotNull ResourceLocation getId() {
public ResourceLocation getId() {
return id;
}
@@ -358,18 +565,29 @@ public class RegistriesImpl {
}
@Override
public @NotNull <E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier) {
public <E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier) {
RegistryObject registryObject = RegistryObject.of(id, delegate);
registry.computeIfAbsent(delegate.getRegistrySuperType(), type -> new Data())
registry.computeIfAbsent(key(), type -> new Data())
.register(delegate, registryObject, () -> supplier.get().setRegistryName(id));
Registrar<T> registrar = this;
return new RegistrySupplier<E>() {
@Override
public @NotNull ResourceLocation getRegistryId() {
public Registries getRegistries() {
return Registries.get(modId);
}
@Override
public Registrar<E> getRegistrar() {
return (Registrar<E>) registrar;
}
@Override
public ResourceLocation getRegistryId() {
return delegate.getRegistryName();
}
@Override
public @NotNull ResourceLocation getId() {
public ResourceLocation getId() {
return registryObject.getId();
}
@@ -459,5 +677,15 @@ public class RegistriesImpl {
public Iterator<T> iterator() {
return delegate.iterator();
}
@Override
public void listen(ResourceLocation id, Consumer<T> callback) {
T value = get(id);
if (value != null) {
callback.accept(value);
} else {
RegistriesImpl.listen(key(), id, callback, false);
}
}
}
}