Skip to content

Commit

Permalink
rework crafting component loading
Browse files Browse the repository at this point in the history
  • Loading branch information
serenibyss committed Aug 16, 2021
1 parent 612bc74 commit 2100c86
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/main/java/gregtech/GregTechMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import gregtech.common.worldgen.WorldGenRubberTree;
import gregtech.integration.theoneprobe.TheOneProbeCompatibility;
import gregtech.loaders.dungeon.DungeonLootLoader;
import gregtech.loaders.recipe.component.AnnotatedComponentHandlerLoader;
import net.minecraftforge.classloading.FMLForgePlugin;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fml.common.FMLCommonHandler;
Expand Down Expand Up @@ -103,6 +104,9 @@ public void onPreInit(FMLPreInitializationEvent event) {
MetaTileEntities.init();
MetaEntities.init();

// discover annotated crafting component handlers
AnnotatedComponentHandlerLoader.discoverAndLoadAnnotatedComponentHandlers(event.getAsmData());

proxy.onPreLoad();
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/gregtech/common/CommonProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import gregtech.loaders.oreprocessing.RecipeHandlerList;
import gregtech.loaders.oreprocessing.ToolRecipeHandler;
import gregtech.loaders.recipe.*;
import gregtech.loaders.recipe.component.AnnotatedComponentHandlerLoader;
import gregtech.loaders.recipe.component.IComponentHandler;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.enchantment.Enchantment;
Expand Down Expand Up @@ -152,6 +154,7 @@ public static void registerItems(RegistryEvent.Register<Item> event) {
@SubscribeEvent(priority = EventPriority.HIGHEST)
public static void initComponents(RegistryEvent.Register<IRecipe> event) {
CraftingComponent.initializeComponents();
IComponentHandler.runComponentHandlers();
}

//this is called with normal priority, so most mods working with
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package gregtech.loaders.recipe.component;

import gregtech.api.util.GTLog;
import net.minecraftforge.fml.common.discovery.ASMDataTable;
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Set;

public class AnnotatedComponentHandlerLoader {

public static void discoverAndLoadAnnotatedComponentHandlers(ASMDataTable asmDataTable) {
Set<ASMData> annotations = asmDataTable.getAll(IComponentHandler.RegisterComponentHandler.class.getName());
int componentHandlersRegistered = 0;
for (ASMData annotationData :annotations) {
String componentHandlerClassName = annotationData.getClassName();
Class<?> componentHandlerClass;
try {
componentHandlerClass = Class.forName(componentHandlerClassName);
} catch (ClassNotFoundException e) {
GTLog.logger.error("Failed to load annotated component handler class {}. FML annotation data is broken perhaps?", componentHandlerClassName);
continue;
}
String denyReason = null;
Throwable loadingError = null;

Field instanceField = null;
Constructor<?> constructor = null;

if (!IComponentHandler.class.isAssignableFrom(componentHandlerClass)) {
denyReason = "class does not implement IComponentHandler";
} else if (Modifier.isAbstract(componentHandlerClass.getModifiers())) {
denyReason = "class is abstract and cannot be initialized";
}
try {
instanceField = componentHandlerClass.getField("INSTANCE");
if (instanceField.getType() != componentHandlerClass) {
denyReason = "found INSTANCE field, but it's type is not the same as class type";
} else if (!Modifier.isStatic(instanceField.getModifiers())) {
denyReason = "found INSTANCE field, but it's not static and cannot be used";
}
} catch (NoSuchFieldException noSuchField) {
try {
constructor = componentHandlerClass.getConstructor();
} catch (NoSuchMethodException noSuchMethod) {
denyReason = "didn't found public static final INSTANCE field or public no-arg constructor for initialization";
}
}

IComponentHandler componentHandler = null;
if (denyReason == null) {
if (instanceField != null) {
try {
componentHandler = (IComponentHandler) instanceField.get(null);
} catch (ReflectiveOperationException e) {
denyReason = "failed to retrieve INSTANCE field value";
loadingError = e;
}
} else {
try {
componentHandler = (IComponentHandler) constructor.newInstance();
} catch (ReflectiveOperationException e) {
denyReason = "failed to initialize component handler";
loadingError = e;
}
}
}
if (denyReason == null) {
GTLog.logger.info("Registered component handler {}", componentHandler.getClass().getName());
IComponentHandler.registerComponentHandler(componentHandler);
componentHandlersRegistered++;
} else {
GTLog.logger.error("Failed to load material handler class {} from {}: {}",
componentHandlerClassName, annotationData.getCandidate().getModContainer().getName(), denyReason, loadingError);
GTLog.logger.error("Consult the mod author for a fix on their side.");
}
}
GTLog.logger.info("{} annotated component handlers registered", componentHandlersRegistered);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package gregtech.loaders.recipe.component;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;

public interface IComponentHandler {

List<IComponentHandler> componentHandlers = new ArrayList<>();

static void registerComponentHandler(IComponentHandler componentHandler) {
componentHandlers.add(componentHandler);
}

static void runComponentHandlers() {
componentHandlers.forEach(IComponentHandler::onComponentsInit);
}

void onComponentsInit();

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface RegisterComponentHandler {
}
}

0 comments on commit 2100c86

Please sign in to comment.