1
0
forked from Clones/Controlify

registry for screenop

This commit is contained in:
isXander
2023-03-27 19:11:11 +01:00
parent b426312a8e
commit 8f5d42e5aa
13 changed files with 370 additions and 106 deletions

View File

@ -124,7 +124,6 @@ public class Controlify implements ControlifyApi {
}
public void tick(Minecraft client) {
var minecraft = Minecraft.getInstance();
if (minecraft.getOverlay() == null) {
if (!calibrationQueue.isEmpty()) {
Screen screen = minecraft.screen;

View File

@ -12,7 +12,7 @@ import java.util.function.Function;
* Adds a guide to a button. This does not invoke the button press on binding trigger, only renders the guide.
* This should be called every time a button is initialised, like in {@link Screen#init()}
*/
public interface ButtonGuideApi {
public final class ButtonGuideApi {
/**
* Makes the button render the image of the binding specified.
* This does not invoke the button press on binding trigger, only renders the guide.
@ -23,7 +23,7 @@ public interface ButtonGuideApi {
* @param position where the guide should be rendered relative to the button
* @param renderPredicate whether the guide should be rendered
*/
static <T extends AbstractButton> void addGuideToButton(
public static <T extends AbstractButton> void addGuideToButton(
T button,
Function<ControllerBindings<?>, ControllerBinding<?>> binding,
ButtonRenderPosition position,

View File

@ -1,7 +1,9 @@
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
package dev.isxander.controlify.mixins.feature.screenop;
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
import dev.isxander.controlify.screenop.ScreenProcessor;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@ -21,6 +23,13 @@ public class ScreenMixin implements ScreenProcessorProvider {
@Inject(method = "rebuildWidgets", at = @At("RETURN"))
private void onScreenInit(CallbackInfo ci) {
screenProcessor().onWidgetRebuild();
// cannot use screenProcessor() because it may be overriden by registry
ScreenProcessorProvider.provide((Screen) (Object) this).onWidgetRebuild();
}
@Inject(method = "init(Lnet/minecraft/client/Minecraft;II)V", at = @At("HEAD"))
private void clearRegistryCaches(Minecraft client, int width, int height, CallbackInfo ci) {
ScreenProcessorProvider.REGISTRY.clearCache();
ComponentProcessorProvider.REGISTRY.clearCache();
}
}

View File

@ -8,6 +8,10 @@ public interface ComponentProcessorProvider {
static ComponentProcessor provide(GuiEventListener component) {
if (component instanceof ComponentProcessorProvider provider)
return provider.componentProcessor();
return ComponentProcessor.EMPTY;
return REGISTRY.get(component).orElse(ComponentProcessor.EMPTY);
}
Registry<GuiEventListener, ComponentProcessor> REGISTRY = new Registry<>();
}

View File

@ -0,0 +1,50 @@
package dev.isxander.controlify.screenop;
import org.jetbrains.annotations.ApiStatus;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
@SuppressWarnings("unchecked")
public class Registry<T, U> {
private final Map<Class<? extends T>, Function<T, U>> registry;
private final Map<T, U> cache;
public Registry() {
this.registry = new HashMap<>();
this.cache = new HashMap<>();
}
/**
* Registers a constructor for a class
*
* @param clazz the class to bind the constructor to
* @param constructor function to build the object from the class
* @param <V> type of class
*/
public <V extends T> void register(Class<V> clazz, Function<V, U> constructor) {
registry.put(clazz, (Function<T, U>) constructor);
}
Optional<U> get(T object) {
U cached = this.cache.get(object);
if (cached != null)
return Optional.of(cached);
Class<? extends T> clazz = (Class<? extends T>) object.getClass();
Function<T, U> constructor = registry.get(clazz);
if (constructor == null)
return Optional.empty();
U constructed = constructor.apply(object);
this.cache.put(object, constructed);
return Optional.of(constructed);
}
@ApiStatus.Internal
public void clearCache() {
this.cache.clear();
}
}

View File

@ -2,10 +2,20 @@ package dev.isxander.controlify.screenop;
import net.minecraft.client.gui.screens.Screen;
import java.util.Optional;
public interface ScreenProcessorProvider {
ScreenProcessor<?> screenProcessor();
static ScreenProcessor<?> provide(Screen screen) {
Optional<ScreenProcessor<?>> optional = REGISTRY.get(screen);
if (optional.isPresent()) return optional.get();
return ((ScreenProcessorProvider) screen).screenProcessor();
}
/**
* Register a screen processor for a screen from an entrypoint
*/
Registry<Screen, ScreenProcessor<?>> REGISTRY = new Registry<>();
}