decorate Mixin configs, fix extension invocation for references
All checks were successful
Publish to snapshot maven / build (push) Successful in 22s
All checks were successful
Publish to snapshot maven / build (push) Successful in 22s
- closes #13
This commit is contained in:
parent
a4ab17f5a8
commit
0715c7620d
|
@ -7,7 +7,7 @@ plugins {
|
|||
}
|
||||
|
||||
group = "dev.frogmc"
|
||||
version = "0.0.1-alpha.17"
|
||||
version = "0.0.1-alpha.18"
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package dev.frogmc.frogloader.api.mod;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandleProxies;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -73,10 +77,13 @@ public final class ModExtensions {
|
|||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public <T> void runIfPresent(String key, Consumer<T> action) {
|
||||
Object value = get(key);
|
||||
if (value instanceof Collection c){
|
||||
((Collection<T>)c).forEach(action);
|
||||
} else if (value != null) {
|
||||
action.accept((T)value);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (value instanceof Collection c) {
|
||||
((Collection<T>) c).forEach(action);
|
||||
} else {
|
||||
action.accept((T) value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,37 +99,52 @@ public final class ModExtensions {
|
|||
* @param action The action to run on the newly retrieved instance of the provided class
|
||||
* @param <T> The type of the class
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T> void runIfPresent(String key, Class<T> type, Consumer<T> action) {
|
||||
|
||||
Object value = get(key);
|
||||
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Consumer<String> c = s -> {
|
||||
runIfPresent(key, (Consumer<String>) s -> {
|
||||
try {
|
||||
MethodHandle handle;
|
||||
T object;
|
||||
if (s.contains("::")) {
|
||||
String[] parts = s.split("::");
|
||||
handle = MethodHandles.lookup().findVirtual(Class.forName(parts[0]), parts[1], MethodType.methodType(type));
|
||||
Class<?> extension = Class.forName(parts[0]);
|
||||
object = (T) handleReference(extension, type, parts[1]);
|
||||
} else {
|
||||
handle = MethodHandles.lookup().findConstructor(Class.forName(s), MethodType.methodType(void.class));
|
||||
object = (T) MethodHandles.lookup().findConstructor(Class.forName(s), MethodType.methodType(void.class)).invoke();
|
||||
}
|
||||
T object = (T) handle.invoke();
|
||||
if (object != null) {
|
||||
action.accept(object);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LOGGER.warn("Failed to instantiate Extension: ", e);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
if (value instanceof String s) {
|
||||
c.accept(s);
|
||||
} else if (value instanceof Collection l) {
|
||||
((Collection<String>) l).forEach(c);
|
||||
private Object handleReference(Class<?> clazz, Class<?> type, String ref) throws Throwable {
|
||||
try {
|
||||
Field found = clazz.getDeclaredField(ref);
|
||||
found.setAccessible(true);
|
||||
return found.get(null);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
Method found = null;
|
||||
for (Method method : clazz.getDeclaredMethods()) {
|
||||
if (method.getName().equals(ref)) {
|
||||
if (found != null) {
|
||||
throw new IllegalArgumentException("Ambiguous method reference: "+ref+" in "+clazz.getName());
|
||||
}
|
||||
found = method;
|
||||
}
|
||||
}
|
||||
|
||||
if (found != null) {
|
||||
MethodHandle method = MethodHandles.lookup().unreflect(found);
|
||||
if (!Modifier.isStatic(found.getModifiers())) {
|
||||
method = method.bindTo(MethodHandles.lookup().findConstructor(clazz, MethodType.methodType(void.class)).invoke());
|
||||
}
|
||||
return MethodHandleProxies.asInterfaceInstance(type, method);
|
||||
}
|
||||
throw new IllegalArgumentException("Could not find either a static field or a method named '" + ref + "' in class " + clazz.getName() + "!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import dev.frogmc.frogloader.impl.mod.ModDependencyResolver;
|
|||
import dev.frogmc.frogloader.impl.util.CrashReportGenerator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongepowered.asm.mixin.FabricUtil;
|
||||
import org.spongepowered.asm.mixin.Mixins;
|
||||
|
||||
public class PluginLoader {
|
||||
|
@ -75,14 +76,21 @@ public class PluginLoader {
|
|||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private static void initializeModMixins(Collection<ModProperties> loadedMods) {
|
||||
Map<String, ModProperties> configs = new HashMap<>();
|
||||
loadedMods.forEach(props -> {
|
||||
Object o = props.extensions().get(BuiltinExtensions.MIXIN_CONFIG);
|
||||
if (o instanceof String name) {
|
||||
configs.put(name, props);
|
||||
Mixins.addConfiguration(name);
|
||||
} else if (o instanceof Collection l) {
|
||||
((Collection<String>) l).forEach(Mixins::addConfiguration);
|
||||
((Collection<String>) l).forEach(configFile -> {
|
||||
configs.put(configFile, props);
|
||||
Mixins.addConfiguration(configFile);
|
||||
});
|
||||
}
|
||||
});
|
||||
Mixins.getConfigs().forEach(c ->
|
||||
c.getConfig().decorate(FabricUtil.KEY_MOD_ID, configs.get(c.getName()).id()));
|
||||
}
|
||||
|
||||
public static GamePlugin discoverGamePlugins() {
|
||||
|
|
Loading…
Reference in a new issue