Skip to content

Commit 2100c86

Browse files
committed
rework crafting component loading
1 parent 612bc74 commit 2100c86

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed

src/main/java/gregtech/GregTechMod.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import gregtech.common.worldgen.WorldGenRubberTree;
3737
import gregtech.integration.theoneprobe.TheOneProbeCompatibility;
3838
import gregtech.loaders.dungeon.DungeonLootLoader;
39+
import gregtech.loaders.recipe.component.AnnotatedComponentHandlerLoader;
3940
import net.minecraftforge.classloading.FMLForgePlugin;
4041
import net.minecraftforge.fluids.FluidRegistry;
4142
import net.minecraftforge.fml.common.FMLCommonHandler;
@@ -103,6 +104,9 @@ public void onPreInit(FMLPreInitializationEvent event) {
103104
MetaTileEntities.init();
104105
MetaEntities.init();
105106

107+
// discover annotated crafting component handlers
108+
AnnotatedComponentHandlerLoader.discoverAndLoadAnnotatedComponentHandlers(event.getAsmData());
109+
106110
proxy.onPreLoad();
107111
}
108112

src/main/java/gregtech/common/CommonProxy.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import gregtech.loaders.oreprocessing.RecipeHandlerList;
3030
import gregtech.loaders.oreprocessing.ToolRecipeHandler;
3131
import gregtech.loaders.recipe.*;
32+
import gregtech.loaders.recipe.component.AnnotatedComponentHandlerLoader;
33+
import gregtech.loaders.recipe.component.IComponentHandler;
3234
import net.minecraft.block.Block;
3335
import net.minecraft.block.state.IBlockState;
3436
import net.minecraft.enchantment.Enchantment;
@@ -152,6 +154,7 @@ public static void registerItems(RegistryEvent.Register<Item> event) {
152154
@SubscribeEvent(priority = EventPriority.HIGHEST)
153155
public static void initComponents(RegistryEvent.Register<IRecipe> event) {
154156
CraftingComponent.initializeComponents();
157+
IComponentHandler.runComponentHandlers();
155158
}
156159

157160
//this is called with normal priority, so most mods working with
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package gregtech.loaders.recipe.component;
2+
3+
import gregtech.api.util.GTLog;
4+
import net.minecraftforge.fml.common.discovery.ASMDataTable;
5+
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
6+
7+
import java.lang.reflect.Constructor;
8+
import java.lang.reflect.Field;
9+
import java.lang.reflect.Modifier;
10+
import java.util.Set;
11+
12+
public class AnnotatedComponentHandlerLoader {
13+
14+
public static void discoverAndLoadAnnotatedComponentHandlers(ASMDataTable asmDataTable) {
15+
Set<ASMData> annotations = asmDataTable.getAll(IComponentHandler.RegisterComponentHandler.class.getName());
16+
int componentHandlersRegistered = 0;
17+
for (ASMData annotationData :annotations) {
18+
String componentHandlerClassName = annotationData.getClassName();
19+
Class<?> componentHandlerClass;
20+
try {
21+
componentHandlerClass = Class.forName(componentHandlerClassName);
22+
} catch (ClassNotFoundException e) {
23+
GTLog.logger.error("Failed to load annotated component handler class {}. FML annotation data is broken perhaps?", componentHandlerClassName);
24+
continue;
25+
}
26+
String denyReason = null;
27+
Throwable loadingError = null;
28+
29+
Field instanceField = null;
30+
Constructor<?> constructor = null;
31+
32+
if (!IComponentHandler.class.isAssignableFrom(componentHandlerClass)) {
33+
denyReason = "class does not implement IComponentHandler";
34+
} else if (Modifier.isAbstract(componentHandlerClass.getModifiers())) {
35+
denyReason = "class is abstract and cannot be initialized";
36+
}
37+
try {
38+
instanceField = componentHandlerClass.getField("INSTANCE");
39+
if (instanceField.getType() != componentHandlerClass) {
40+
denyReason = "found INSTANCE field, but it's type is not the same as class type";
41+
} else if (!Modifier.isStatic(instanceField.getModifiers())) {
42+
denyReason = "found INSTANCE field, but it's not static and cannot be used";
43+
}
44+
} catch (NoSuchFieldException noSuchField) {
45+
try {
46+
constructor = componentHandlerClass.getConstructor();
47+
} catch (NoSuchMethodException noSuchMethod) {
48+
denyReason = "didn't found public static final INSTANCE field or public no-arg constructor for initialization";
49+
}
50+
}
51+
52+
IComponentHandler componentHandler = null;
53+
if (denyReason == null) {
54+
if (instanceField != null) {
55+
try {
56+
componentHandler = (IComponentHandler) instanceField.get(null);
57+
} catch (ReflectiveOperationException e) {
58+
denyReason = "failed to retrieve INSTANCE field value";
59+
loadingError = e;
60+
}
61+
} else {
62+
try {
63+
componentHandler = (IComponentHandler) constructor.newInstance();
64+
} catch (ReflectiveOperationException e) {
65+
denyReason = "failed to initialize component handler";
66+
loadingError = e;
67+
}
68+
}
69+
}
70+
if (denyReason == null) {
71+
GTLog.logger.info("Registered component handler {}", componentHandler.getClass().getName());
72+
IComponentHandler.registerComponentHandler(componentHandler);
73+
componentHandlersRegistered++;
74+
} else {
75+
GTLog.logger.error("Failed to load material handler class {} from {}: {}",
76+
componentHandlerClassName, annotationData.getCandidate().getModContainer().getName(), denyReason, loadingError);
77+
GTLog.logger.error("Consult the mod author for a fix on their side.");
78+
}
79+
}
80+
GTLog.logger.info("{} annotated component handlers registered", componentHandlersRegistered);
81+
}
82+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package gregtech.loaders.recipe.component;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
public interface IComponentHandler {
11+
12+
List<IComponentHandler> componentHandlers = new ArrayList<>();
13+
14+
static void registerComponentHandler(IComponentHandler componentHandler) {
15+
componentHandlers.add(componentHandler);
16+
}
17+
18+
static void runComponentHandlers() {
19+
componentHandlers.forEach(IComponentHandler::onComponentsInit);
20+
}
21+
22+
void onComponentsInit();
23+
24+
@Retention(RetentionPolicy.RUNTIME)
25+
@Target(ElementType.TYPE)
26+
@interface RegisterComponentHandler {
27+
}
28+
}

0 commit comments

Comments
 (0)