2017-08-16 01:14:28 +00:00
|
|
|
package WayofTime.bloodmagic.util;
|
|
|
|
|
2018-03-01 01:53:23 +00:00
|
|
|
import WayofTime.bloodmagic.BloodMagic;
|
2018-02-06 01:04:38 +00:00
|
|
|
import WayofTime.bloodmagic.api.BloodMagicPlugin;
|
2018-03-01 01:53:23 +00:00
|
|
|
import WayofTime.bloodmagic.api.IBloodMagicAPI;
|
2018-02-06 01:04:38 +00:00
|
|
|
import WayofTime.bloodmagic.api.IBloodMagicPlugin;
|
2018-02-17 17:48:17 +00:00
|
|
|
import WayofTime.bloodmagic.api.impl.BloodMagicAPI;
|
2018-02-06 01:04:38 +00:00
|
|
|
import WayofTime.bloodmagic.api.impl.BloodMagicCorePlugin;
|
2018-02-17 17:48:17 +00:00
|
|
|
import com.google.common.base.Stopwatch;
|
2017-08-16 01:14:28 +00:00
|
|
|
import com.google.common.collect.Lists;
|
2018-03-01 01:53:23 +00:00
|
|
|
import net.minecraftforge.common.util.EnumHelper;
|
2017-08-16 01:14:28 +00:00
|
|
|
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
|
|
|
import org.apache.commons.lang3.tuple.Pair;
|
|
|
|
|
|
|
|
import javax.annotation.Nonnull;
|
2018-03-01 01:53:23 +00:00
|
|
|
import java.lang.reflect.Field;
|
|
|
|
import java.lang.reflect.Modifier;
|
2017-08-16 01:14:28 +00:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Set;
|
2018-03-01 01:53:23 +00:00
|
|
|
import java.util.function.Consumer;
|
2017-08-16 01:14:28 +00:00
|
|
|
|
|
|
|
public class PluginUtil {
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
@Nonnull
|
2018-02-17 17:48:17 +00:00
|
|
|
public static List<Pair<IBloodMagicPlugin, BloodMagicPlugin>> gatherPlugins(ASMDataTable dataTable) {
|
|
|
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
2017-08-16 01:14:28 +00:00
|
|
|
List<Pair<IBloodMagicPlugin, BloodMagicPlugin>> discoveredAnnotations = Lists.newArrayList();
|
2018-03-01 01:53:23 +00:00
|
|
|
Set<ASMDataTable.ASMData> discoveredPlugins = dataTable.getAll(BloodMagicPlugin.class.getName());
|
2017-08-16 01:14:28 +00:00
|
|
|
|
|
|
|
for (ASMDataTable.ASMData data : discoveredPlugins) {
|
|
|
|
try {
|
|
|
|
Class<?> asmClass = Class.forName(data.getClassName());
|
|
|
|
Class<? extends IBloodMagicPlugin> pluginClass = asmClass.asSubclass(IBloodMagicPlugin.class);
|
|
|
|
|
|
|
|
IBloodMagicPlugin instance = pluginClass.newInstance();
|
|
|
|
|
2018-02-17 17:48:17 +00:00
|
|
|
BMLog.API.info("Discovered plugin at {}", data.getClassName());
|
2017-08-16 01:14:28 +00:00
|
|
|
discoveredAnnotations.add(Pair.of(instance, pluginClass.getAnnotation(BloodMagicPlugin.class)));
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-17 00:29:24 +00:00
|
|
|
// Bring core plugin up to top
|
2018-02-17 17:48:17 +00:00
|
|
|
discoveredAnnotations.sort((o1, o2) -> {
|
|
|
|
if (o1.getLeft().getClass() == BloodMagicCorePlugin.class)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return o1.getClass().getCanonicalName().compareToIgnoreCase(o2.getClass().getCanonicalName());
|
|
|
|
});
|
|
|
|
BMLog.API.info("Discovered {} potential plugin(s) in {}", discoveredAnnotations.size(), stopwatch.stop());
|
2017-08-16 01:14:28 +00:00
|
|
|
return discoveredAnnotations;
|
|
|
|
}
|
2018-02-17 17:48:17 +00:00
|
|
|
|
2018-03-01 01:53:23 +00:00
|
|
|
@Nonnull
|
|
|
|
public static List<Field> gatherInjections(ASMDataTable dataTable) {
|
|
|
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
|
|
|
List<Field> injectees = Lists.newArrayList();
|
|
|
|
Set<ASMDataTable.ASMData> discoveredInjectees = dataTable.getAll(BloodMagicPlugin.Inject.class.getName());
|
|
|
|
|
|
|
|
for (ASMDataTable.ASMData data : discoveredInjectees) {
|
|
|
|
try {
|
|
|
|
Class<?> asmClass = Class.forName(data.getClassName());
|
|
|
|
Field toInject = asmClass.getDeclaredField(data.getObjectName());
|
|
|
|
if (toInject.getType() != IBloodMagicAPI.class) {
|
|
|
|
BMLog.API.error("Mod requested API injection on field {}.{} which is an invalid type.", data.getClassName(), data.getObjectName());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
BMLog.API.info("Discovered injection request at {}.{}", data.getClassName(), data.getObjectName());
|
|
|
|
injectees.add(toInject);
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BMLog.API.info("Discovered {} potential API injection(s) in {}", injectees.size(), stopwatch.stop());
|
|
|
|
return injectees;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void handlePluginStep(RegistrationStep step) {
|
|
|
|
Stopwatch total = Stopwatch.createStarted();
|
|
|
|
int errors = 0;
|
|
|
|
for (Pair<IBloodMagicPlugin, BloodMagicPlugin> plugin : BloodMagic.PLUGINS) {
|
|
|
|
Stopwatch per = Stopwatch.createStarted();
|
|
|
|
try {
|
|
|
|
step.getConsumer().accept(plugin);
|
|
|
|
} catch (Exception e) {
|
|
|
|
errors++;
|
|
|
|
BMLog.DEFAULT.error("Error handling plugin step {} at {}: {}: {}", step, plugin.getLeft().getClass(), e.getClass().getSimpleName(), e.getMessage());
|
|
|
|
}
|
|
|
|
BMLog.API.info("Handled plugin step {} at {} in {}", step, plugin.getLeft().getClass(), per.stop());
|
|
|
|
}
|
|
|
|
|
|
|
|
BMLog.API.info("Handled {} plugin(s) at step {} with {} errors in {}", BloodMagic.PLUGINS.size() - errors, step, errors, total.stop());
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void injectAPIInstances(List<Field> injectees) {
|
2018-02-17 17:48:17 +00:00
|
|
|
Stopwatch total = Stopwatch.createStarted();
|
|
|
|
int errors = 0;
|
2018-03-01 01:53:23 +00:00
|
|
|
|
|
|
|
for (Field injectee : injectees) {
|
2018-02-17 17:48:17 +00:00
|
|
|
Stopwatch per = Stopwatch.createStarted();
|
2018-03-01 01:53:23 +00:00
|
|
|
if (!Modifier.isStatic(injectee.getModifiers()))
|
|
|
|
continue;
|
|
|
|
|
2018-02-17 17:48:17 +00:00
|
|
|
try {
|
2018-03-01 01:53:23 +00:00
|
|
|
EnumHelper.setFailsafeFieldValue(injectee, null, BloodMagicAPI.INSTANCE);
|
2018-02-17 17:48:17 +00:00
|
|
|
} catch (Exception e) {
|
|
|
|
errors++;
|
2018-03-01 01:53:23 +00:00
|
|
|
BMLog.DEFAULT.error("Error injecting API instance at {}.{}", injectee.getDeclaringClass().getCanonicalName(), injectee.getName());
|
2018-02-17 17:48:17 +00:00
|
|
|
}
|
2018-03-01 01:53:23 +00:00
|
|
|
BMLog.API.info("Injected API instance at {}.{} in {}", injectee.getDeclaringClass().getCanonicalName(), injectee.getName(), per.stop());
|
2018-02-17 17:48:17 +00:00
|
|
|
}
|
|
|
|
|
2018-03-01 01:53:23 +00:00
|
|
|
BMLog.API.info("Injected API {} times with {} errors in {}", injectees.size() - errors, errors, total.stop());
|
|
|
|
}
|
|
|
|
|
|
|
|
public enum RegistrationStep {
|
|
|
|
|
|
|
|
PLUGIN_REGISTER(p -> p.getLeft().register(BloodMagicAPI.INSTANCE)),
|
|
|
|
RECIPE_REGISTER(p -> p.getLeft().registerRecipes(BloodMagicAPI.INSTANCE.getRecipeRegistrar()))
|
|
|
|
;
|
|
|
|
|
|
|
|
private final Consumer<Pair<IBloodMagicPlugin, BloodMagicPlugin>> consumer;
|
|
|
|
|
|
|
|
RegistrationStep(Consumer<Pair<IBloodMagicPlugin, BloodMagicPlugin>> consumer) {
|
|
|
|
this.consumer = consumer;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nonnull
|
|
|
|
public Consumer<Pair<IBloodMagicPlugin, BloodMagicPlugin>> getConsumer() {
|
|
|
|
return consumer;
|
|
|
|
}
|
2018-02-17 17:48:17 +00:00
|
|
|
}
|
2017-08-16 01:14:28 +00:00
|
|
|
}
|