Refactored to expose the ModMenu Integration to other Mods
This commit is contained in:
parent
5808bab08e
commit
0486b56ec3
4 changed files with 136 additions and 50 deletions
12
src/main/java/ru/bclib/gui/modmenu/EntryPoint.java
Normal file
12
src/main/java/ru/bclib/gui/modmenu/EntryPoint.java
Normal file
|
@ -0,0 +1,12 @@
|
|||
package ru.bclib.gui.modmenu;
|
||||
|
||||
import com.terraformersmc.modmenu.util.ModMenuApiMarker;
|
||||
import ru.bclib.integration.ModMenuIntegration;
|
||||
|
||||
public class EntryPoint extends ModMenuIntegration {
|
||||
public static final ModMenuApiMarker entrypointObject = createEntrypoint(new EntryPoint());
|
||||
|
||||
public EntryPoint() {
|
||||
super(MainScreen::new);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package ru.bclib.gui.screens.ModMenu;
|
||||
package ru.bclib.gui.modmenu;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
|
@ -3,23 +3,18 @@ package ru.bclib.integration;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.terraformersmc.modmenu.util.ModMenuApiMarker;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import ru.bclib.gui.screens.ModMenu.MainScreen;
|
||||
import ru.bclib.integration.ModMenuIntegration.ModMenuScreenFactory;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Map;
|
||||
|
||||
@FunctionalInterface
|
||||
interface IModMenuScreenFactory<S extends Screen> {
|
||||
S create(Screen parent);
|
||||
}
|
||||
|
||||
class ModMenuScreenFactory {
|
||||
class ModMenuScreenFactoryImpl {
|
||||
static class ScreenFactoryInvocationHandler implements InvocationHandler {
|
||||
private final IModMenuScreenFactory act;
|
||||
private final ModMenuScreenFactory act;
|
||||
|
||||
public ScreenFactoryInvocationHandler(IModMenuScreenFactory act) {
|
||||
public ScreenFactoryInvocationHandler(ModMenuScreenFactory act) {
|
||||
this.act = act;
|
||||
}
|
||||
|
||||
|
@ -29,7 +24,7 @@ class ModMenuScreenFactory {
|
|||
}
|
||||
}
|
||||
|
||||
public static IModMenuScreenFactory create(IModMenuScreenFactory act) {
|
||||
public static ModMenuScreenFactory create(ModMenuScreenFactory act) {
|
||||
Class<?> iConfigScreenFactory = null;
|
||||
try {
|
||||
iConfigScreenFactory = Class.forName("com.terraformersmc.modmenu.api.ConfigScreenFactory");
|
||||
|
@ -40,14 +35,128 @@ class ModMenuScreenFactory {
|
|||
|
||||
Object o = Proxy.newProxyInstance(
|
||||
ModMenuIntegration.class.getClassLoader(),
|
||||
new Class[] {iConfigScreenFactory, IModMenuScreenFactory.class},
|
||||
new Class[] {iConfigScreenFactory, ModMenuScreenFactory.class},
|
||||
new ScreenFactoryInvocationHandler(act));
|
||||
|
||||
return (IModMenuScreenFactory)o;
|
||||
return (ModMenuScreenFactory)o;
|
||||
}
|
||||
}
|
||||
|
||||
public class ModMenuIntegration {
|
||||
/**
|
||||
* Integration, to provide a custom Screen for ModMenu.
|
||||
* <p>
|
||||
* This integration allows you to use ModMenu without adding a dependency to your project. If the
|
||||
* Mod is installed on the Client, and the correct ModMenu-EntryPoint is registered in your <i>fabric.mod.json</i>
|
||||
* the screen will show up.
|
||||
* <p>
|
||||
* You only need to subclass this class, and initialize a static Field of Type {@link ModMenuApiMarker} using
|
||||
* the {@link #createEntrypoint(ModMenuIntegration)}-Method.
|
||||
* <p>
|
||||
* Example:
|
||||
* <pre>{@code public class ModMenu extends ModMenuIntegration {
|
||||
* public static final ModMenuApiMarker entrypointObject = createEntrypoint(new EntryPoint());
|
||||
*
|
||||
* public EntryPoint() {
|
||||
* super(GridScreen::new);
|
||||
* }
|
||||
* }</pre>
|
||||
* You'd also need to add the ModMenu-Entrypoint to your <i>fabric.mod.json</i>:
|
||||
* <pre>"entrypoints": {
|
||||
* ...
|
||||
* "modmenu": [ "your.mod.ModMenu::entrypointObject" ]
|
||||
* }</pre>
|
||||
*/
|
||||
public abstract class ModMenuIntegration {
|
||||
/**
|
||||
* Creates a new EntryPoint Object that is accepted by ModMenu
|
||||
* @param target The delegate Object that will receive calls from ModMenu
|
||||
* @return A Proxy that conforms to the ModMenu spec
|
||||
*/
|
||||
public static ModMenuApiMarker createEntrypoint(ModMenuIntegration target) {
|
||||
Class<?> iModMenuAPI = null;
|
||||
//Class<?> iModMenuAPIMarker = null;
|
||||
try {
|
||||
iModMenuAPI = Class.forName("com.terraformersmc.modmenu.api.ModMenuApi");
|
||||
//iModMenuAPIMarker = Class.forName("com.terraformersmc.modmenu.util.ModMenuApiMarker");
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return (ModMenuApiMarker)new Object();
|
||||
}
|
||||
|
||||
Object o = Proxy.newProxyInstance(
|
||||
ModMenuIntegration.class.getClassLoader(),
|
||||
new Class[] {iModMenuAPI},
|
||||
new BCLibModMenuInvocationHandler(target));
|
||||
|
||||
return (ModMenuApiMarker)o;
|
||||
}
|
||||
|
||||
protected final ModMenuScreenFactory screenFactory;
|
||||
|
||||
/**
|
||||
* Create a new ModMenu delegate
|
||||
* @param screenFactory A Factory. The Factory receives the currently visible {@code parent}-Screen
|
||||
* and must return a new Screen Object.
|
||||
*/
|
||||
public ModMenuIntegration(ModMenuScreenFactory screenFactory){
|
||||
this.screenFactory = screenFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper class to make a BCLib-Factory conform to the ModMenu-Factory Interface.
|
||||
* @param factory
|
||||
* @return A ModMenu Factory for a Screen
|
||||
*/
|
||||
final protected ModMenuScreenFactory createFactory(ModMenuScreenFactory factory){
|
||||
return ModMenuScreenFactoryImpl.create( factory );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to construct a new config screen instance when your mod's
|
||||
* configuration button is selected on the mod menu screen. The
|
||||
* screen instance parameter is the active mod menu screen.
|
||||
* (Text copied from ModMenu)
|
||||
*
|
||||
* @return A factory for constructing config screen instances.
|
||||
*
|
||||
*/
|
||||
public ModMenuScreenFactory getModConfigScreenFactory() {
|
||||
return createFactory(screenFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to provide config screen factories for other mods. This takes second
|
||||
* priority to a mod's own config screen factory provider. For example, if
|
||||
* mod `xyz` supplies a config screen factory, mod `abc` providing a config
|
||||
* screen to `xyz` will be pointless, as the one provided by `xyz` will be
|
||||
* used.
|
||||
* <p>
|
||||
* This method is NOT meant to be used to add a config screen factory to
|
||||
* your own mod.
|
||||
* (Text copied from ModMenu)
|
||||
*
|
||||
* @return a map of mod ids to screen factories.
|
||||
*/
|
||||
public Map<String, ModMenuScreenFactory> getProvidedConfigScreenFactories() {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A Factory Interface for ModMenu-Screens
|
||||
* <p>
|
||||
* The Interface matches {@code com.terraformersmc.modmenu.api.ConfigScreenFactory}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public static interface ModMenuScreenFactory {
|
||||
Screen create(Screen parent);
|
||||
}
|
||||
|
||||
static class BCLibModMenuInvocationHandler implements InvocationHandler {
|
||||
private final ModMenuIntegration target;
|
||||
|
||||
|
@ -68,39 +177,4 @@ public class ModMenuIntegration {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final ModMenuApiMarker entrypointObject = create();
|
||||
|
||||
public static ModMenuApiMarker create() {
|
||||
Class<?> iModMenuAPI = null;
|
||||
//Class<?> iModMenuAPIMarker = null;
|
||||
try {
|
||||
iModMenuAPI = Class.forName("com.terraformersmc.modmenu.api.ModMenuApi");
|
||||
//iModMenuAPIMarker = Class.forName("com.terraformersmc.modmenu.util.ModMenuApiMarker");
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return (ModMenuApiMarker)new Object();
|
||||
}
|
||||
|
||||
Object o = Proxy.newProxyInstance(
|
||||
ModMenuIntegration.class.getClassLoader(),
|
||||
new Class[] {iModMenuAPI},
|
||||
new BCLibModMenuInvocationHandler(new ModMenuIntegration()));
|
||||
|
||||
return (ModMenuApiMarker)o;
|
||||
}
|
||||
|
||||
IModMenuScreenFactory<?> getModConfigScreenFactory() {
|
||||
return ModMenuScreenFactory.create( MainScreen::new );
|
||||
}
|
||||
|
||||
Map<String, IModMenuScreenFactory<?>> getProvidedConfigScreenFactories() {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
"server": [
|
||||
"ru.bclib.server.BCLibServer"
|
||||
],
|
||||
"modmenu": [ "ru.bclib.integration.ModMenuIntegration::entrypointObject" ]
|
||||
"modmenu": [ "ru.bclib.gui.modmenu.EntryPoint::entrypointObject" ]
|
||||
},
|
||||
"mixins": [
|
||||
"bclib.mixins.common.json",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue