Files
MinecraftForge/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java
T

135 lines
4.2 KiB
Java
Raw Normal View History

/*
* Copyright (c) Forge Development LLC and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/
2017-06-19 15:02:18 -07:00
package net.minecraftforge.registries;
import java.lang.reflect.Field;
2017-06-19 15:02:18 -07:00
import java.lang.reflect.Modifier;
import java.util.Locale;
import java.util.function.Consumer;
import java.util.function.Predicate;
2014-09-22 22:01:24 -07:00
2021-07-17 00:08:49 -05:00
import net.minecraft.resources.ResourceLocation;
import net.minecraft.ResourceLocationException;
2014-09-22 22:01:24 -07:00
2018-09-06 04:39:01 -07:00
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
2022-06-07 15:31:26 -05:00
import org.jetbrains.annotations.Nullable;
2018-09-06 04:39:01 -07:00
@SuppressWarnings("rawtypes")
class ObjectHolderRef implements Consumer<Predicate<ResourceLocation>>, Runnable
2017-06-19 15:02:18 -07:00
{
2018-09-06 04:39:01 -07:00
private static final Logger LOGGER = LogManager.getLogger();
2022-06-07 15:31:26 -05:00
private final Field field;
private final ResourceLocation injectedObject;
private final ForgeRegistry<?> registry;
2022-06-07 15:31:26 -05:00
@SuppressWarnings("unchecked")
@Nullable
static ObjectHolderRef create(ResourceLocation registryName, Field field, String injectedObject, boolean extractFromExistingValues)
{
2022-06-07 15:31:26 -05:00
ForgeRegistry<?> registry = RegistryManager.ACTIVE.getRegistry(registryName);
if (registry == null)
return null;
2022-06-07 15:31:26 -05:00
ResourceLocation injectedObjectName;
if (extractFromExistingValues)
{
try
{
Object existing = field.get(null);
2022-06-07 15:31:26 -05:00
// Nothing is ever allowed to replace AIR
if (existing == null || existing == registry.getDefault())
return null;
injectedObjectName = ((ForgeRegistry) registry).getKey(existing);
2017-06-19 15:02:18 -07:00
}
catch (IllegalAccessException e)
{
2017-06-19 15:02:18 -07:00
throw new RuntimeException(e);
}
}
else
{
try
{
2022-06-07 15:31:26 -05:00
injectedObjectName = new ResourceLocation(injectedObject);
}
catch (ResourceLocationException e)
{
throw new IllegalArgumentException("Invalid @ObjectHolder annotation on \"" + field.toString() + "\"", e);
}
}
2022-06-07 15:31:26 -05:00
if (injectedObjectName == null)
throw new IllegalStateException(String.format(Locale.ENGLISH, "The ObjectHolder annotation cannot apply to a field that does not map to a registry. Ensure the registry was created during NewRegistryEvent. (found : %s at %s.%s)", field.getType().getName(), field.getDeclaringClass().getName(), field.getName()));
2018-09-06 04:39:01 -07:00
field.setAccessible(true);
if (Modifier.isFinal(field.getModifiers()))
{
2018-09-06 04:39:01 -07:00
throw new RuntimeException("@ObjectHolder on final field, our transformer did not run? " + field.getDeclaringClass().getName() + "/" + field.getName());
}
2022-06-07 15:31:26 -05:00
return new ObjectHolderRef(registry, field, injectedObjectName);
}
2022-06-07 15:31:26 -05:00
private ObjectHolderRef(ForgeRegistry<?> registry, Field field, ResourceLocation injectedObject)
{
2022-06-07 15:31:26 -05:00
this.registry = registry;
this.field = field;
this.injectedObject = injectedObject;
}
2017-06-19 15:02:18 -07:00
@Override
public void accept(Predicate<ResourceLocation> filter)
{
if (registry == null || !filter.test(registry.getRegistryName()))
return;
run();
}
@Override
public void run()
{
Object thing;
2023-04-01 20:45:29 -05:00
if (registry.containsKey(injectedObject))
{
thing = registry.getValue(injectedObject);
}
else
{
thing = null;
}
if (thing == null)
{
2018-09-06 04:39:01 -07:00
LOGGER.debug("Unable to lookup {} for {}. This means the object wasn't registered. It's likely just mod options.", injectedObject, field);
return;
}
try
{
2018-09-06 04:39:01 -07:00
field.set(null, thing);
}
catch (IllegalArgumentException | ReflectiveOperationException e)
{
2018-09-06 04:39:01 -07:00
LOGGER.warn("Unable to set {} with value {} ({})", this.field, thing, this.injectedObject, e);
2017-06-19 15:02:18 -07:00
}
}
@Override
public int hashCode()
{
return field.hashCode();
}
@Override
public boolean equals(Object other)
{
if (!(other instanceof ObjectHolderRef))
return false;
ObjectHolderRef o = (ObjectHolderRef)other;
return this.field.equals(o.field);
}
}