64 lines
3.0 KiB
Java
64 lines
3.0 KiB
Java
package io.gitlab.jfronny.libjf.unsafe;
|
|
|
|
import net.fabricmc.loader.api.FabricLoader;
|
|
import net.fabricmc.loader.api.ModContainer;
|
|
import net.fabricmc.loader.impl.ModContainerImpl;
|
|
import net.fabricmc.loader.impl.metadata.EntrypointMetadata;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.util.*;
|
|
import java.util.function.Consumer;
|
|
|
|
public class DynamicEntry {
|
|
/**
|
|
* Execute an entrypoint.
|
|
*
|
|
* @param name the name of the entrypoint to execute.
|
|
* @param entrypointType the entrypoint type.
|
|
* @param onExecute entrypoint execution callback with an instance of the entrypoint type.
|
|
* @param <T> the entrypoint type.
|
|
*/
|
|
public static <T> void execute(final String name, final Class<T> entrypointType, final Consumer<ConsumableEntrypoint<T>> onExecute) {
|
|
final List<ConsumableEntrypoint<T>> targets = new ArrayList<>();
|
|
for (final EntrypointContainer entrypoint : getEntrypointTargets(name)) {
|
|
try {
|
|
targets.add(new ConsumableEntrypoint<>(
|
|
entrypointType.cast(Class.forName(entrypoint.entrypoint).getConstructor().newInstance()),
|
|
entrypoint.mod
|
|
));
|
|
} catch (final ClassNotFoundException exception) {
|
|
throw new IllegalArgumentException(String.format("class %s specified in the %s entrypoint of mod %s does not exist", entrypoint.entrypoint, name, entrypoint.mod), exception);
|
|
} catch (final IllegalAccessException | InstantiationException | NoSuchMethodException exception) {
|
|
throw new IllegalStateException(String.format("class %s specified in the %s entrypoint of mod %s cannot be instantiated", entrypoint.entrypoint, name, entrypoint.mod), exception);
|
|
} catch (final InvocationTargetException exception) {
|
|
throw new RuntimeException(String.format("an error was encountered during the instantiation of the %s entrypoint class %s", name, entrypoint.entrypoint), exception);
|
|
}
|
|
}
|
|
|
|
for (ConsumableEntrypoint<T> target : targets) {
|
|
onExecute.accept(target);
|
|
}
|
|
}
|
|
|
|
private static Collection<EntrypointContainer> getEntrypointTargets(final String entrypoint) {
|
|
final List<EntrypointContainer> entrypoints = new LinkedList<>();
|
|
for (final ModContainer mod : FabricLoader.getInstance().getAllMods()) {
|
|
final List<EntrypointMetadata> modEntrypoints = ((ModContainerImpl)mod).getMetadata().getEntrypoints(entrypoint);
|
|
|
|
if (modEntrypoints != null) {
|
|
for (final EntrypointMetadata metadata : modEntrypoints) {
|
|
entrypoints.add(new EntrypointContainer(metadata.getValue(), mod.getMetadata().getId()));
|
|
}
|
|
}
|
|
}
|
|
|
|
return entrypoints;
|
|
}
|
|
|
|
record EntrypointContainer(String entrypoint, String mod) {
|
|
}
|
|
|
|
public record ConsumableEntrypoint<T>(T instance, String modId) {
|
|
}
|
|
}
|