Refactor key binding registrations to be more easily expandable

This commit is contained in:
Jonas Herzig
2020-09-05 17:14:28 +02:00
parent f623bb3ee7
commit 83690f4024
7 changed files with 60 additions and 46 deletions

View File

@@ -32,10 +32,12 @@ import org.lwjgl.glfw.GLFW;
//$$ import static com.replaymod.core.versions.MCVer.FML_BUS; //$$ import static com.replaymod.core.versions.MCVer.FML_BUS;
//#endif //#endif
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -45,27 +47,25 @@ public class KeyBindingRegistry extends EventRegistrations {
static { net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry.INSTANCE.addCategory(CATEGORY); } static { net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry.INSTANCE.addCategory(CATEGORY); }
//#endif //#endif
private Map<String, KeyBinding> keyBindings = new HashMap<String, KeyBinding>(); private final Map<String, Binding> bindings = new HashMap<>();
private Set<KeyBinding> onlyInReplay = new HashSet<>(); private Set<KeyBinding> onlyInReplay = new HashSet<>();
private Multimap<KeyBinding, Runnable> keyBindingHandlers = ArrayListMultimap.create();
private Multimap<KeyBinding, Runnable> repeatedKeyBindingHandlers = ArrayListMultimap.create();
private Multimap<Integer, Runnable> rawHandlers = ArrayListMultimap.create(); private Multimap<Integer, Runnable> rawHandlers = ArrayListMultimap.create();
public KeyBinding registerKeyBinding(String name, int keyCode, Runnable whenPressed, boolean onlyInRepay) { public Binding registerKeyBinding(String name, int keyCode, Runnable whenPressed, boolean onlyInRepay) {
KeyBinding keyBinding = registerKeyBinding(name, keyCode, onlyInRepay); Binding binding = registerKeyBinding(name, keyCode, onlyInRepay);
keyBindingHandlers.put(keyBinding, whenPressed); binding.handlers.add(whenPressed);
return keyBinding; return binding;
} }
public KeyBinding registerRepeatedKeyBinding(String name, int keyCode, Runnable whenPressed, boolean onlyInRepay) { public Binding registerRepeatedKeyBinding(String name, int keyCode, Runnable whenPressed, boolean onlyInRepay) {
KeyBinding keyBinding = registerKeyBinding(name, keyCode, onlyInRepay); Binding binding = registerKeyBinding(name, keyCode, onlyInRepay);
repeatedKeyBindingHandlers.put(keyBinding, whenPressed); binding.repeatedHandlers.add(whenPressed);
return keyBinding; return binding;
} }
private KeyBinding registerKeyBinding(String name, int keyCode, boolean onlyInRepay) { private Binding registerKeyBinding(String name, int keyCode, boolean onlyInRepay) {
KeyBinding keyBinding = keyBindings.get(name); Binding binding = bindings.get(name);
if (keyBinding == null) { if (binding == null) {
//#if FABRIC>=1 //#if FABRIC>=1
if (keyCode == 0) { if (keyCode == 0) {
keyCode = -1; keyCode = -1;
@@ -73,27 +73,28 @@ public class KeyBindingRegistry extends EventRegistrations {
Identifier id = new Identifier(MOD_ID, name.substring(LangResourcePack.LEGACY_KEY_PREFIX.length())); Identifier id = new Identifier(MOD_ID, name.substring(LangResourcePack.LEGACY_KEY_PREFIX.length()));
FabricKeyBinding fabricKeyBinding = FabricKeyBinding.Builder.create(id, InputUtil.Type.KEYSYM, keyCode, CATEGORY).build(); FabricKeyBinding fabricKeyBinding = FabricKeyBinding.Builder.create(id, InputUtil.Type.KEYSYM, keyCode, CATEGORY).build();
net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry.INSTANCE.register(fabricKeyBinding); net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry.INSTANCE.register(fabricKeyBinding);
keyBinding = fabricKeyBinding; KeyBinding keyBinding = fabricKeyBinding;
//#else //#else
//$$ keyBinding = new KeyBinding(name, keyCode, CATEGORY); //$$ KeyBinding keyBinding = new KeyBinding(name, keyCode, CATEGORY);
//$$ ClientRegistry.registerKeyBinding(keyBinding); //$$ ClientRegistry.registerKeyBinding(keyBinding);
//#endif //#endif
keyBindings.put(name, keyBinding); binding = new Binding(name, keyBinding);
bindings.put(name, binding);
if (onlyInRepay) { if (onlyInRepay) {
this.onlyInReplay.add(keyBinding); this.onlyInReplay.add(keyBinding);
} }
} else if (!onlyInRepay) { } else if (!onlyInRepay) {
this.onlyInReplay.remove(keyBinding); this.onlyInReplay.remove(binding.keyBinding);
} }
return keyBinding; return binding;
} }
public void registerRaw(int keyCode, Runnable whenPressed) { public void registerRaw(int keyCode, Runnable whenPressed) {
rawHandlers.put(keyCode, whenPressed); rawHandlers.put(keyCode, whenPressed);
} }
public Map<String, KeyBinding> getKeyBindings() { public Map<String, Binding> getBindings() {
return Collections.unmodifiableMap(keyBindings); return Collections.unmodifiableMap(bindings);
} }
public Set<KeyBinding> getOnlyInReplay() { public Set<KeyBinding> getOnlyInReplay() {
@@ -119,29 +120,29 @@ public class KeyBindingRegistry extends EventRegistrations {
//#endif //#endif
public void handleRepeatedKeyBindings() { public void handleRepeatedKeyBindings() {
for (Map.Entry<KeyBinding, Collection<Runnable>> entry : repeatedKeyBindingHandlers.asMap().entrySet()) { for (Binding binding : bindings.values()) {
if (entry.getKey().isPressed()) { if (binding.keyBinding.isPressed()) {
invokeKeyBindingHandlers(entry.getKey(), entry.getValue()); invokeKeyBindingHandlers(binding, binding.repeatedHandlers);
} }
} }
} }
public void handleKeyBindings() { public void handleKeyBindings() {
for (Map.Entry<KeyBinding, Collection<Runnable>> entry : keyBindingHandlers.asMap().entrySet()) { for (Binding binding : bindings.values()) {
while (entry.getKey().wasPressed()) { while (binding.keyBinding.wasPressed()) {
invokeKeyBindingHandlers(entry.getKey(), entry.getValue()); invokeKeyBindingHandlers(binding, binding.handlers);
} }
} }
} }
private void invokeKeyBindingHandlers(KeyBinding keyBinding, Collection<Runnable> handlers) { private void invokeKeyBindingHandlers(Binding binding, Collection<Runnable> handlers) {
for (final Runnable runnable : handlers) { for (final Runnable runnable : handlers) {
try { try {
runnable.run(); runnable.run();
} catch (Throwable cause) { } catch (Throwable cause) {
CrashReport crashReport = CrashReport.create(cause, "Handling Key Binding"); CrashReport crashReport = CrashReport.create(cause, "Handling Key Binding");
CrashReportSection category = crashReport.addElement("Key Binding"); CrashReportSection category = crashReport.addElement("Key Binding");
MCVer.addDetail(category, "Key Binding", keyBinding::toString); MCVer.addDetail(category, "Key Binding", () -> binding.name);
MCVer.addDetail(category, "Handler", runnable::toString); MCVer.addDetail(category, "Handler", runnable::toString);
throw new CrashException(crashReport); throw new CrashException(crashReport);
} }
@@ -167,4 +168,20 @@ public class KeyBindingRegistry extends EventRegistrations {
} }
} }
} }
public static class Binding {
public final String name;
public final KeyBinding keyBinding;
private final List<Runnable> handlers = new ArrayList<>();
private final List<Runnable> repeatedHandlers = new ArrayList<>();
public Binding(String name, KeyBinding keyBinding) {
this.name = name;
this.keyBinding = keyBinding;
}
public String getBoundKey() {
return MCVer.getBoundKey(keyBinding);
}
}
} }

View File

@@ -3,7 +3,6 @@ package com.replaymod.extras;
import com.replaymod.core.KeyBindingRegistry; import com.replaymod.core.KeyBindingRegistry;
import com.replaymod.core.ReplayMod; import com.replaymod.core.ReplayMod;
import com.replaymod.core.mixin.KeyBindingAccessor; import com.replaymod.core.mixin.KeyBindingAccessor;
import com.replaymod.core.versions.MCVer;
import com.replaymod.replay.events.ReplayOpenedCallback; import com.replaymod.replay.events.ReplayOpenedCallback;
import com.replaymod.replay.gui.overlay.GuiReplayOverlay; import com.replaymod.replay.gui.overlay.GuiReplayOverlay;
import de.johni0702.minecraft.gui.GuiRenderer; import de.johni0702.minecraft.gui.GuiRenderer;
@@ -68,14 +67,14 @@ public class HotkeyButtons extends EventRegistrations implements Extra {
}.setLayout(panelLayout = new GridLayout().setSpacingX(5).setSpacingY(5).setColumns(1)); }.setLayout(panelLayout = new GridLayout().setSpacingX(5).setSpacingY(5).setColumns(1));
final KeyBindingRegistry keyBindingRegistry = mod.getKeyBindingRegistry(); final KeyBindingRegistry keyBindingRegistry = mod.getKeyBindingRegistry();
keyBindingRegistry.getKeyBindings().values().stream() keyBindingRegistry.getBindings().values().stream()
.sorted(Comparator.comparing(it -> I18n.translate(it.getTranslationKey()))) .sorted(Comparator.comparing(it -> I18n.translate(it.name)))
.forEachOrdered(keyBinding -> { .forEachOrdered(keyBinding -> {
GuiButton button = new GuiButton(){ GuiButton button = new GuiButton(){
@Override @Override
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) { public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
// There doesn't seem to be an KeyBindingUpdate event, so we'll just update it every time // There doesn't seem to be an KeyBindingUpdate event, so we'll just update it every time
setLabel(MCVer.getBoundKey(keyBinding)); setLabel(keyBinding.getBoundKey());
super.draw(renderer, size, renderInfo); super.draw(renderer, size, renderInfo);
} }
}.onClick(() -> { }.onClick(() -> {
@@ -96,7 +95,7 @@ public class HotkeyButtons extends EventRegistrations implements Extra {
return new Dimension(Math.max(10, button.getMinSize().getWidth()) + 10, 20); return new Dimension(Math.max(10, button.getMinSize().getWidth()) + 10, 20);
} }
}).addElements(null, button), }).addElements(null, button),
new GuiLabel().setI18nText(keyBinding.getTranslationKey()) new GuiLabel().setI18nText(keyBinding.name)
)); ));
}); });

View File

@@ -42,7 +42,7 @@ public class ReplayModReplay implements Module {
public static ReplayModReplay instance; public static ReplayModReplay instance;
private ReplayMod core; private ReplayMod core;
public KeyBinding keyPlayPause; public KeyBindingRegistry.Binding keyPlayPause;
private final CameraControllerRegistry cameraControllerRegistry = new CameraControllerRegistry(); private final CameraControllerRegistry cameraControllerRegistry = new CameraControllerRegistry();

View File

@@ -1,5 +1,6 @@
package com.replaymod.replay.camera; package com.replaymod.replay.camera;
import com.replaymod.core.KeyBindingRegistry;
import com.replaymod.core.ReplayMod; import com.replaymod.core.ReplayMod;
import com.replaymod.core.SettingsRegistry; import com.replaymod.core.SettingsRegistry;
import com.replaymod.core.events.SettingsChangedCallback; import com.replaymod.core.events.SettingsChangedCallback;
@@ -13,7 +14,6 @@ import com.replaymod.replaystudio.util.Location;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.decoration.ItemFrameEntity; import net.minecraft.entity.decoration.ItemFrameEntity;
@@ -567,11 +567,11 @@ public class CameraEntity
handleInputEvents(); handleInputEvents();
Map<String, KeyBinding> keyBindings = ReplayMod.instance.getKeyBindingRegistry().getKeyBindings(); Map<String, KeyBindingRegistry.Binding> keyBindings = ReplayMod.instance.getKeyBindingRegistry().getBindings();
if (keyBindings.get("replaymod.input.rollclockwise").isPressed()) { if (keyBindings.get("replaymod.input.rollclockwise").keyBinding.isPressed()) {
roll += Utils.isCtrlDown() ? 0.2 : 1; roll += Utils.isCtrlDown() ? 0.2 : 1;
} }
if (keyBindings.get("replaymod.input.rollcounterclockwise").isPressed()) { if (keyBindings.get("replaymod.input.rollcounterclockwise").keyBinding.isPressed()) {
roll -= Utils.isCtrlDown() ? 0.2 : 1; roll -= Utils.isCtrlDown() ? 0.2 : 1;
} }

View File

@@ -33,7 +33,6 @@ import org.lwjgl.glfw.GLFW;
//#endif //#endif
import static com.replaymod.core.ReplayMod.TEXTURE_SIZE; import static com.replaymod.core.ReplayMod.TEXTURE_SIZE;
import static com.replaymod.core.versions.MCVer.getBoundKey;
public class GuiReplayOverlay extends AbstractGuiOverlay<GuiReplayOverlay> { public class GuiReplayOverlay extends AbstractGuiOverlay<GuiReplayOverlay> {
@@ -52,7 +51,7 @@ public class GuiReplayOverlay extends AbstractGuiOverlay<GuiReplayOverlay> {
} else { // Pause button } else { // Pause button
label = "replaymod.gui.ingame.menu.pause"; label = "replaymod.gui.ingame.menu.pause";
} }
tooltip.setText(I18n.translate(label) + " (" + getBoundKey(mod.keyPlayPause) + ")"); tooltip.setText(I18n.translate(label) + " (" + mod.keyPlayPause.getBoundKey() + ")");
} }
return tooltip; return tooltip;
} }

View File

@@ -21,7 +21,6 @@ import com.replaymod.replaystudio.replay.ReplayFile;
import com.replaymod.simplepathing.SPTimeline.SPPath; import com.replaymod.simplepathing.SPTimeline.SPPath;
import com.replaymod.simplepathing.gui.GuiPathing; import com.replaymod.simplepathing.gui.GuiPathing;
import com.replaymod.simplepathing.preview.PathPreview; import com.replaymod.simplepathing.preview.PathPreview;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.util.crash.CrashReport; import net.minecraft.util.crash.CrashReport;
import net.minecraft.util.crash.CrashException; import net.minecraft.util.crash.CrashException;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@@ -40,8 +39,8 @@ public class ReplayModSimplePathing extends EventRegistrations implements Module
public static ReplayModSimplePathing instance; public static ReplayModSimplePathing instance;
private ReplayMod core; private ReplayMod core;
public KeyBinding keyPositionKeyframe; public KeyBindingRegistry.Binding keyPositionKeyframe;
public KeyBinding keyTimeKeyframe; public KeyBindingRegistry.Binding keyTimeKeyframe;
public static Logger LOGGER = LogManager.getLogger(); public static Logger LOGGER = LogManager.getLogger();

View File

@@ -135,7 +135,7 @@ public class GuiPathing {
label = "replaymod.gui.ingame.menu.removespeckeyframe"; label = "replaymod.gui.ingame.menu.removespeckeyframe";
} }
} }
tooltip.setText(I18n.translate(label) + " (" + getBoundKey(mod.keyPositionKeyframe) + ")"); tooltip.setText(I18n.translate(label) + " (" + mod.keyPositionKeyframe.getBoundKey() + ")");
} }
return tooltip; return tooltip;
} }
@@ -152,7 +152,7 @@ public class GuiPathing {
} else { // Remove time keyframe } else { // Remove time keyframe
label = "replaymod.gui.ingame.menu.removetimekeyframe"; label = "replaymod.gui.ingame.menu.removetimekeyframe";
} }
tooltip.setText(I18n.translate(label) + " (" + getBoundKey(mod.keyTimeKeyframe) + ")"); tooltip.setText(I18n.translate(label) + " (" + mod.keyTimeKeyframe.getBoundKey() + ")");
} }
return tooltip; return tooltip;
} }