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

@@ -0,0 +1,87 @@
/*
* 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.core.item;
import dev.architectury.registry.registries.RegistrySupplier;
import net.minecraft.core.BlockSource;
import net.minecraft.core.Direction;
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
import net.minecraft.core.dispenser.DispenseItemBehavior;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.SpawnEggItem;
import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.level.gameevent.GameEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class ArchitecturySpawnEggItem extends SpawnEggItem {
private static final Logger LOGGER = LogManager.getLogger(ArchitecturySpawnEggItem.class);
private final RegistrySupplier<? extends EntityType<? extends Mob>> entityType;
protected static DispenseItemBehavior createDispenseItemBehavior() {
return new DefaultDispenseItemBehavior() {
@Override
public ItemStack execute(BlockSource source, ItemStack stack) {
Direction direction = source.getBlockState().getValue(DispenserBlock.FACING);
EntityType<?> entityType = ((SpawnEggItem) stack.getItem()).getType(stack.getTag());
try {
entityType.spawn(source.getLevel(), stack, null, source.getPos().relative(direction), MobSpawnType.DISPENSER, direction != Direction.UP, false);
} catch (Exception var6) {
LOGGER.error("Error while dispensing spawn egg from dispenser at {}", source.getPos(), var6);
return ItemStack.EMPTY;
}
stack.shrink(1);
source.getLevel().gameEvent(GameEvent.ENTITY_PLACE, source.getPos());
return stack;
}
};
}
public ArchitecturySpawnEggItem(RegistrySupplier<? extends EntityType<? extends Mob>> entityType, int backgroundColor, int highlightColor, Properties properties) {
this(entityType, backgroundColor, highlightColor, properties, createDispenseItemBehavior());
}
public ArchitecturySpawnEggItem(RegistrySupplier<? extends EntityType<? extends Mob>> entityType, int backgroundColor, int highlightColor, Properties properties,
@Nullable DispenseItemBehavior dispenseItemBehavior) {
super(null, backgroundColor, highlightColor, properties);
this.entityType = Objects.requireNonNull(entityType, "entityType");
SpawnEggItem.BY_ID.remove(null);
entityType.listen(type -> {
SpawnEggItem.BY_ID.put(type, this);
this.defaultType = type;
});
}
@Override
public EntityType<?> getType(@Nullable CompoundTag compoundTag) {
EntityType<?> type = super.getType(compoundTag);
return type == null ? entityType.get() : type;
}
}

View File

@@ -24,7 +24,6 @@ import dev.architectury.annotations.ForgeEvent;
import dev.architectury.annotations.ForgeEventCancellable;
import dev.architectury.injectables.annotations.ExpectPlatform;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
@@ -58,7 +57,7 @@ public final class EventFactory {
public static <T> Event<T> createLoop(Class<T> clazz) {
return of(listeners -> (T) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{clazz}, new AbstractInvocationHandler() {
@Override
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
for (var listener : listeners) {
invokeMethod(listener, method, args);
}
@@ -77,7 +76,7 @@ public final class EventFactory {
public static <T> Event<T> createEventResult(Class<T> clazz) {
return of(listeners -> (T) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{clazz}, new AbstractInvocationHandler() {
@Override
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
for (var listener : listeners) {
var result = (EventResult) Objects.requireNonNull(invokeMethod(listener, method, args));
if (result.interruptsFurtherEvaluation()) {
@@ -99,7 +98,7 @@ public final class EventFactory {
public static <T> Event<T> createCompoundEventResult(Class<T> clazz) {
return of(listeners -> (T) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{clazz}, new AbstractInvocationHandler() {
@Override
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
for (var listener : listeners) {
var result = (CompoundEventResult) Objects.requireNonNull(invokeMethod(listener, method, args));
if (result.interruptsFurtherEvaluation()) {
@@ -121,7 +120,7 @@ public final class EventFactory {
public static <T> Event<Consumer<T>> createConsumerLoop(Class<T> clazz) {
Event<Consumer<T>> event = of(listeners -> (Consumer<T>) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{Consumer.class}, new AbstractInvocationHandler() {
@Override
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
for (var listener : listeners) {
invokeMethod(listener, method, args);
}
@@ -148,7 +147,7 @@ public final class EventFactory {
public static <T> Event<EventActor<T>> createEventActorLoop(Class<T> clazz) {
Event<EventActor<T>> event = of(listeners -> (EventActor<T>) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{EventActor.class}, new AbstractInvocationHandler() {
@Override
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
for (var listener : listeners) {
var result = (EventResult) invokeMethod(listener, method, args);
if (result.interruptsFurtherEvaluation()) {

View File

@@ -24,7 +24,6 @@ import dev.architectury.injectables.targets.ArchitecturyTarget;
import dev.architectury.utils.Env;
import net.fabricmc.api.EnvType;
import net.minecraft.SharedConstants;
import org.jetbrains.annotations.NotNull;
import java.nio.file.Path;
import java.util.Collection;

View File

@@ -25,9 +25,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 abstract class BlockProperties extends BlockBehaviour.Properties implements BlockPropertiesExtension {
public BlockProperties(Material material, Function<BlockState, MaterialColor> function) {
super(material, function);

View File

@@ -19,5 +19,9 @@
package dev.architectury.registry.block;
import org.jetbrains.annotations.ApiStatus;
@Deprecated
@ApiStatus.ScheduledForRemoval
public interface BlockPropertiesExtension {
}

View File

@@ -19,9 +19,9 @@
package dev.architectury.registry.level;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.GameRules;
import org.jetbrains.annotations.ApiStatus;
import java.util.function.BiConsumer;
@@ -37,10 +37,12 @@ public final class GameRuleFactory {
*
* @param defaultValue the rule's default value
* @return the created type
* @deprecated Use the method directly.
*/
@ExpectPlatform
@Deprecated
@ApiStatus.ScheduledForRemoval
public static GameRules.Type<GameRules.BooleanValue> createBooleanRule(boolean defaultValue) {
throw new AssertionError();
return GameRules.BooleanValue.create(defaultValue);
}
/**
@@ -49,10 +51,12 @@ public final class GameRuleFactory {
* @param defaultValue the rule's default value
* @param changedCallback a callback that is called when the rule's value is changed
* @return the created type
* @deprecated Use the method directly.
*/
@ExpectPlatform
@Deprecated
@ApiStatus.ScheduledForRemoval
public static GameRules.Type<GameRules.BooleanValue> createBooleanRule(boolean defaultValue, BiConsumer<MinecraftServer, GameRules.BooleanValue> changedCallback) {
throw new AssertionError();
return GameRules.BooleanValue.create(defaultValue, changedCallback);
}
/**
@@ -60,10 +64,12 @@ public final class GameRuleFactory {
*
* @param defaultValue the rule's default value
* @return the created type
* @deprecated Use the method directly.
*/
@ExpectPlatform
@Deprecated
@ApiStatus.ScheduledForRemoval
public static GameRules.Type<GameRules.IntegerValue> createIntRule(int defaultValue) {
throw new AssertionError();
return GameRules.IntegerValue.create(defaultValue);
}
/**
@@ -72,9 +78,11 @@ public final class GameRuleFactory {
* @param defaultValue the rule's default value
* @param changedCallback a callback that is called when the rule's value is changed
* @return the created type
* @deprecated Use the method directly.
*/
@ExpectPlatform
@Deprecated
@ApiStatus.ScheduledForRemoval
public static GameRules.Type<GameRules.IntegerValue> createIntRule(int defaultValue, BiConsumer<MinecraftServer, GameRules.IntegerValue> changedCallback) {
throw new AssertionError();
return GameRules.IntegerValue.create(defaultValue, changedCallback);
}
}

View File

@@ -19,8 +19,8 @@
package dev.architectury.registry.level;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.world.level.GameRules;
import org.jetbrains.annotations.ApiStatus;
/**
* A registry for registering game rules.
@@ -37,9 +37,11 @@ public final class GameRuleRegistry {
* @param type the type of the rule
* @param <T> the type of the rule value
* @return a key for the registered rule
* @deprecated Use the method directly.
*/
@ExpectPlatform
@Deprecated
@ApiStatus.ScheduledForRemoval
public static <T extends GameRules.Value<T>> GameRules.Key<T> register(String name, GameRules.Category category, GameRules.Type<T> type) {
throw new AssertionError();
return GameRules.register(name, category, type);
}
}

View File

@@ -19,8 +19,9 @@
package dev.architectury.registry.level.advancement;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.advancements.CriterionTrigger;
import org.jetbrains.annotations.ApiStatus;
public final class CriteriaTriggersRegistry {
private CriteriaTriggersRegistry() {
@@ -32,9 +33,11 @@ public final class CriteriaTriggersRegistry {
* @param trigger The trigger to register
* @param <T> The type of trigger
* @return The trigger registered
* @deprecated Use the method directly.
*/
@ExpectPlatform
@Deprecated
@ApiStatus.ScheduledForRemoval
public static <T extends CriterionTrigger<?>> T register(T trigger) {
throw new AssertionError();
return CriteriaTriggers.register(trigger);
}
}

View File

@@ -38,7 +38,7 @@ public final class EntityAttributeRegistry {
* @see net.minecraft.world.entity.ai.attributes.DefaultAttributes
*/
@ExpectPlatform
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) {
throw new AssertionError();
}
}

View File

@@ -23,7 +23,6 @@ import com.google.common.base.Suppliers;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -61,7 +60,7 @@ public class DeferredRegister<T> implements Iterable<RegistrySupplier<T>> {
var entry = new Entry<T>(id, (Supplier<T>) supplier);
this.entries.add(entry);
if (registered) {
var registrar = registriesSupplier.get().get(key);
var registrar = getRegistrar();
entry.value = registrar.register(entry.id, entry.supplier);
}
return (RegistrySupplier<R>) entry;
@@ -72,18 +71,25 @@ public class DeferredRegister<T> implements Iterable<RegistrySupplier<T>> {
throw new IllegalStateException("Cannot register a deferred register twice!");
}
registered = true;
var registrar = registriesSupplier.get().get(key);
var registrar = getRegistrar();
for (var entry : entries) {
entry.value = registrar.register(entry.id, entry.supplier);
}
}
@NotNull
@Override
public Iterator<RegistrySupplier<T>> iterator() {
return entryView.iterator();
}
public Registries getRegistries() {
return registriesSupplier.get();
}
public Registrar<T> getRegistrar() {
return registriesSupplier.get().get(key);
}
private class Entry<R> implements RegistrySupplier<R> {
private final ResourceLocation id;
private final Supplier<R> supplier;
@@ -94,6 +100,16 @@ public class DeferredRegister<T> implements Iterable<RegistrySupplier<T>> {
this.supplier = supplier;
}
@Override
public Registries getRegistries() {
return DeferredRegister.this.getRegistries();
}
@Override
public Registrar<R> getRegistrar() {
return (Registrar<R>) DeferredRegister.this.getRegistrar();
}
@Override
public ResourceLocation getRegistryId() {
return key.location();

View File

@@ -27,11 +27,22 @@ import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;
public interface Registrar<T> extends Iterable<T> {
RegistrySupplier<T> delegate(ResourceLocation id);
default <R extends T> RegistrySupplier<R> wrap(R obj) {
ResourceLocation id = getId(obj);
if (id == null) {
throw new IllegalArgumentException("Cannot wrap an object without an id: " + obj);
} else {
return (RegistrySupplier<R>) delegate(id);
}
}
<E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier);
@Nullable
@@ -56,4 +67,32 @@ public interface Registrar<T> extends Iterable<T> {
Set<Map.Entry<ResourceKey<T>, T>> entrySet();
ResourceKey<? extends Registry<T>> key();
/**
* Listens to when the registry entry is registered, and calls the given action.
* Evaluates immediately if the entry is already registered.
* <p>
* Whenever the callback is called is dependent on the registry implementation.
* On fabric, this will be called when the registry entry is registered.
* On forge, this will be called when the registry entry is registered or when Minecraft has started.
*
* @param supplier the entry to listen to
* @param callback the action to call when the registry entry is registered
*/
default <R extends T> void listen(RegistrySupplier<R> supplier, Consumer<R> callback) {
listen(supplier.getId(), obj -> callback.accept((R) obj));
}
/**
* Listens to when the registry entry is registered, and calls the given action.
* Evaluates immediately if the entry is already registered.
* <p>
* Whenever the callback is called is dependent on the registry implementation.
* On fabric, this will be called when the registry entry is registered.
* On forge, this will be called when the registry entry is registered or when Minecraft has started.
*
* @param id the entry to listen to
* @param callback the action to call when the registry entry is registered
*/
void listen(ResourceLocation id, Consumer<T> callback);
}

View File

@@ -19,7 +19,10 @@
package dev.architectury.registry.registries;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
@@ -27,12 +30,24 @@ import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Stream;
@ApiStatus.NonExtendable
public interface RegistrySupplier<T> extends Supplier<T> {
Registries getRegistries();
Registrar<T> getRegistrar();
/**
* @return the identifier of the registry
*/
ResourceLocation getRegistryId();
/**
* @return the identifier of the registry
*/
default ResourceKey<Registry<T>> getRegistryKey() {
return ResourceKey.createRegistryKey(getRegistryId());
}
/**
* @return the identifier of the entry
*/
@@ -84,4 +99,14 @@ public interface RegistrySupplier<T> extends Supplier<T> {
default T orElseGet(Supplier<? extends T> supplier) {
return isPresent() ? get() : supplier.get();
}
/**
* Listens to when the registry entry is registered, and calls the given action.
* Evaluates immediately if the entry is already registered.
*
* @param callback the action to call when the registry entry is registered
*/
default void listen(Consumer<T> callback) {
getRegistrar().listen(this, callback);
}
}