mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-25 00:58:17 -05:00
Merge remote-tracking branch 'origin/1.15' into 1.15
This commit is contained in:
commit
d7f31bf16d
18 changed files with 295 additions and 137 deletions
8
fabric-key-binding-api-v1/build.gradle
Normal file
8
fabric-key-binding-api-v1/build.gradle
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
archivesBaseName = "fabric-key-binding-api-v1"
|
||||||
|
version = getSubprojectVersion(project, "1.0.0")
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testmodCompile project(path: ':fabric-api-base', configuration: 'dev')
|
||||||
|
testmodCompile project(path: ':fabric-events-lifecycle-v0', configuration: 'dev')
|
||||||
|
testmodCompile project(path: ':fabric-resource-loader-v0', configuration: 'dev')
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.api.client.keybinding.v1;
|
||||||
|
|
||||||
|
import net.minecraft.client.options.KeyBinding;
|
||||||
|
import net.minecraft.client.util.InputUtil;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
|
||||||
|
import net.fabricmc.fabric.mixin.client.keybinding.KeyCodeAccessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for registering key bindings.
|
||||||
|
*
|
||||||
|
* <p>Helper class for {@link KeyBinding} for use by Fabric mods.</p>
|
||||||
|
*
|
||||||
|
* <pre><code>
|
||||||
|
* KeyBinding left = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.example.left", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_P, "key.category.example"));
|
||||||
|
* KeyBinding right = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.example.right", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_U, "key.category.example"));
|
||||||
|
* </code></pre>
|
||||||
|
*/
|
||||||
|
public final class KeyBindingHelper {
|
||||||
|
private KeyBindingHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the keybinding and add the keybinding category if required.
|
||||||
|
*
|
||||||
|
* @param keyBinding the keybinding
|
||||||
|
* @return the keybinding itself
|
||||||
|
*/
|
||||||
|
public static KeyBinding registerKeyBinding(KeyBinding keyBinding) {
|
||||||
|
return KeyBindingRegistryImpl.registerKeyBinding(keyBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configured KeyCode bound to the KeyBinding from the player's settings.
|
||||||
|
*
|
||||||
|
* @param keyBinding the keybinding
|
||||||
|
* @return configured KeyCode
|
||||||
|
*/
|
||||||
|
public static InputUtil.KeyCode getBoundKeyOf(KeyBinding keyBinding) {
|
||||||
|
return ((KeyCodeAccessor) keyBinding).getKeyCode();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.impl.client.keybinding;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import net.minecraft.client.options.KeyBinding;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.mixin.client.keybinding.KeyBindingAccessor;
|
||||||
|
|
||||||
|
public final class KeyBindingRegistryImpl {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
|
private static final List<KeyBinding> moddedKeyBindings = Lists.newArrayList();
|
||||||
|
|
||||||
|
private KeyBindingRegistryImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Integer> getCategoryMap() {
|
||||||
|
return KeyBindingAccessor.fabric_getCategoryMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasCategory(String categoryTranslationKey) {
|
||||||
|
return getCategoryMap().containsKey(categoryTranslationKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean addCategory(String categoryTranslationKey) {
|
||||||
|
Map<String, Integer> map = getCategoryMap();
|
||||||
|
|
||||||
|
if (map.containsKey(categoryTranslationKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Integer> largest = map.values().stream().max(Integer::compareTo);
|
||||||
|
int largestInt = largest.orElse(0);
|
||||||
|
map.put(categoryTranslationKey, largestInt + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KeyBinding registerKeyBinding(KeyBinding binding) {
|
||||||
|
for (KeyBinding existingKeyBindings : moddedKeyBindings) {
|
||||||
|
if (existingKeyBindings == binding) {
|
||||||
|
throw null;
|
||||||
|
} else if (existingKeyBindings.getId().equals(binding.getId())) {
|
||||||
|
throw new RuntimeException("Attempted to register two key bindings with equal ID: " + binding.getId() + "!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasCategory(binding.getCategory())) {
|
||||||
|
addCategory(binding.getCategory());
|
||||||
|
}
|
||||||
|
|
||||||
|
return moddedKeyBindings.add(binding) ? binding : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the keybindings array for our modded ones by first removing existing modded keybindings and readding them,
|
||||||
|
* we can make sure that there are no duplicates this way.
|
||||||
|
*/
|
||||||
|
public static KeyBinding[] process(KeyBinding[] keysAll) {
|
||||||
|
List<KeyBinding> newKeysAll = Lists.newArrayList(keysAll);
|
||||||
|
newKeysAll.removeAll(moddedKeyBindings);
|
||||||
|
newKeysAll.addAll(moddedKeyBindings);
|
||||||
|
return newKeysAll.toArray(new KeyBinding[0]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,16 +19,14 @@ package net.fabricmc.fabric.mixin.client.keybinding;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
import net.minecraft.client.options.KeyBinding;
|
import net.minecraft.client.options.KeyBinding;
|
||||||
|
|
||||||
@Mixin(KeyBinding.class)
|
@Mixin(KeyBinding.class)
|
||||||
public class MixinKeyBinding {
|
public interface KeyBindingAccessor {
|
||||||
@Shadow
|
@Accessor("categoryOrderMap")
|
||||||
private static Map<String, Integer> categoryOrderMap;
|
static Map<String, Integer> fabric_getCategoryMap() {
|
||||||
|
throw new AssertionError();
|
||||||
private static Map<String, Integer> fabric_getCategoryMap() {
|
|
||||||
return categoryOrderMap;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,7 +16,9 @@
|
||||||
|
|
||||||
package net.fabricmc.fabric.mixin.client.keybinding;
|
package net.fabricmc.fabric.mixin.client.keybinding;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
@ -29,11 +31,13 @@ import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
|
||||||
|
|
||||||
@Mixin(GameOptions.class)
|
@Mixin(GameOptions.class)
|
||||||
public class MixinGameOptions {
|
public class MixinGameOptions {
|
||||||
|
@Mutable
|
||||||
|
@Final
|
||||||
@Shadow
|
@Shadow
|
||||||
public KeyBinding[] keysAll;
|
public KeyBinding[] keysAll;
|
||||||
|
|
||||||
@Inject(at = @At("HEAD"), method = "load()V")
|
@Inject(at = @At("HEAD"), method = "load()V")
|
||||||
public void loadHook(CallbackInfo info) {
|
public void loadHook(CallbackInfo info) {
|
||||||
keysAll = KeyBindingRegistryImpl.INSTANCE.process(keysAll);
|
keysAll = KeyBindingRegistryImpl.process(keysAll);
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -3,9 +3,9 @@
|
||||||
"package": "net.fabricmc.fabric.mixin.client.keybinding",
|
"package": "net.fabricmc.fabric.mixin.client.keybinding",
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
"client": [
|
"client": [
|
||||||
"MixinGameOptions",
|
"KeyBindingAccessor",
|
||||||
"MixinKeyBinding",
|
"KeyCodeAccessor",
|
||||||
"KeyCodeAccessor"
|
"MixinGameOptions"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
25
fabric-key-binding-api-v1/src/main/resources/fabric.mod.json
Normal file
25
fabric-key-binding-api-v1/src/main/resources/fabric.mod.json
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "fabric-key-binding-api-v1",
|
||||||
|
"name": "Fabric Key Binding API (v1)",
|
||||||
|
"version": "${version}",
|
||||||
|
"environment": "client",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"icon": "assets/fabric-key-binding-api-v1/icon.png",
|
||||||
|
"contact": {
|
||||||
|
"homepage": "https://fabricmc.net",
|
||||||
|
"irc": "irc://irc.esper.net:6667/fabric",
|
||||||
|
"issues": "https://github.com/FabricMC/fabric/issues",
|
||||||
|
"sources": "https://github.com/FabricMC/fabric"
|
||||||
|
},
|
||||||
|
"authors": [
|
||||||
|
"FabricMC"
|
||||||
|
],
|
||||||
|
"depends": {
|
||||||
|
"fabricloader": ">=0.4.0"
|
||||||
|
},
|
||||||
|
"description": "Key Binding registry API.",
|
||||||
|
"mixins": [
|
||||||
|
"fabric-key-binding-api-v1.mixins.json"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.test.client.keybinding;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import net.minecraft.client.options.KeyBinding;
|
||||||
|
import net.minecraft.client.options.StickyKeyBinding;
|
||||||
|
import net.minecraft.client.util.InputUtil;
|
||||||
|
import net.minecraft.text.LiteralText;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||||
|
import net.fabricmc.fabric.api.event.client.ClientTickCallback;
|
||||||
|
|
||||||
|
public class KeyBindingsTest implements ClientModInitializer {
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
KeyBinding binding1 = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.fabric-key-binding-api-v1-testmod.test_keybinding_1", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_P, "key.category.first.test"));
|
||||||
|
KeyBinding binding2 = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.fabric-key-binding-api-v1-testmod.test_keybinding_2", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_U, "key.category.second.test"));
|
||||||
|
KeyBinding stickyBinding = KeyBindingHelper.registerKeyBinding(new StickyKeyBinding("key.fabric-key-binding-api-v1-testmod.test_keybinding_sticky", GLFW.GLFW_KEY_R, "key.category.first.test", () -> true));
|
||||||
|
|
||||||
|
ClientTickCallback.EVENT.register(client -> {
|
||||||
|
while (binding1.wasPressed()) {
|
||||||
|
client.player.sendMessage(new LiteralText("Key 1 was pressed!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (binding2.wasPressed()) {
|
||||||
|
client.player.sendMessage(new LiteralText("Key 2 was pressed!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stickyBinding.isPressed()) {
|
||||||
|
client.player.sendMessage(new LiteralText("Sticky Key was pressed!"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"key.category.first.test": "First Test Category",
|
||||||
|
"key.category.second.test": "Second Test Category",
|
||||||
|
"key.fabric-key-binding-api-v1-testmod.test_keybinding_1": "Test 1",
|
||||||
|
"key.fabric-key-binding-api-v1-testmod.test_keybinding_2": "Test 2",
|
||||||
|
"key.fabric-key-binding-api-v1-testmod.test_keybinding_sticky": "Sticky Test"
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "fabric-key-binding-api-v1-testmod",
|
||||||
|
"name": "Fabric Key Binding API (v1) Test Mod",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"environment": "*",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"depends": {
|
||||||
|
"fabric-api-base": "*",
|
||||||
|
"fabric-events-lifecycle-v0": "*",
|
||||||
|
"fabric-key-binding-api-v1": "*"
|
||||||
|
},
|
||||||
|
"entrypoints": {
|
||||||
|
"client": [
|
||||||
|
"net.fabricmc.fabric.test.client.keybinding.KeyBindingsTest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
archivesBaseName = "fabric-keybindings-v0"
|
archivesBaseName = "fabric-keybindings-v0"
|
||||||
version = getSubprojectVersion(project, "0.1.1")
|
version = getSubprojectVersion(project, "0.2.0")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
compile project(path: ':fabric-key-binding-api-v1', configuration: 'dev')
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,27 +20,33 @@ import net.minecraft.client.options.KeyBinding;
|
||||||
import net.minecraft.client.util.InputUtil;
|
import net.minecraft.client.util.InputUtil;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import net.fabricmc.fabric.mixin.client.keybinding.KeyCodeAccessor;
|
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expanded version of {@link KeyBinding} for use by Fabric mods.
|
* Expanded version of {@link KeyBinding} for use by Fabric mods.
|
||||||
*
|
*
|
||||||
* <p>*ALL* instantiated FabricKeyBindings should be registered in
|
* <p>*ALL* instantiated FabricKeyBindings should be registered in
|
||||||
* {@link KeyBindingRegistry#register(FabricKeyBinding)}!
|
* {@link KeyBindingRegistry#register(FabricKeyBinding)}!</p>
|
||||||
|
*
|
||||||
|
* @deprecated Please migrate to v1. Please use {@link KeyBindingHelper#registerKeyBinding(KeyBinding)} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class FabricKeyBinding extends KeyBinding {
|
public class FabricKeyBinding extends KeyBinding {
|
||||||
protected FabricKeyBinding(Identifier id, InputUtil.Type type, int code, String category) {
|
protected FabricKeyBinding(Identifier id, InputUtil.Type type, int code, String category) {
|
||||||
super("key." + id.toString().replace(':', '.'), type, code, category);
|
super(String.format("key.%s.%s", id.getNamespace(), id.getPath()), type, code, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the configured KeyCode assigned to the KeyBinding from the player's settings.
|
* Returns the configured KeyCode assigned to the KeyBinding from the player's settings.
|
||||||
|
*
|
||||||
* @return configured KeyCode
|
* @return configured KeyCode
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public InputUtil.KeyCode getBoundKey() {
|
public InputUtil.KeyCode getBoundKey() {
|
||||||
return ((KeyCodeAccessor) this).getKeyCode();
|
return KeyBindingHelper.getBoundKeyOf(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
protected final FabricKeyBinding binding;
|
protected final FabricKeyBinding binding;
|
||||||
|
|
||||||
|
|
|
@ -18,15 +18,28 @@ package net.fabricmc.fabric.api.client.keybinding;
|
||||||
|
|
||||||
import net.minecraft.client.options.KeyBinding;
|
import net.minecraft.client.options.KeyBinding;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||||
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
|
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for registering key bindings.
|
* Interface for registering key bindings.
|
||||||
*
|
*
|
||||||
* @see KeyBinding
|
* @see KeyBinding
|
||||||
|
* @deprecated Please migrate to v1. Please use {@link KeyBindingHelper} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public interface KeyBindingRegistry {
|
public interface KeyBindingRegistry {
|
||||||
KeyBindingRegistry INSTANCE = KeyBindingRegistryImpl.INSTANCE;
|
KeyBindingRegistry INSTANCE = new KeyBindingRegistry() {
|
||||||
|
@Override
|
||||||
|
public boolean addCategory(String categoryName) {
|
||||||
|
return KeyBindingRegistryImpl.addCategory(categoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean register(FabricKeyBinding binding) {
|
||||||
|
return KeyBindingRegistryImpl.registerKeyBinding(binding) != null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new key binding category.
|
* Add a new key binding category.
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.fabricmc.fabric.impl.client.keybinding;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
import net.minecraft.client.options.KeyBinding;
|
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
|
|
||||||
import net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry;
|
|
||||||
|
|
||||||
public class KeyBindingRegistryImpl implements KeyBindingRegistry {
|
|
||||||
public static final KeyBindingRegistryImpl INSTANCE = new KeyBindingRegistryImpl();
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
|
||||||
|
|
||||||
private Map<String, Integer> cachedCategoryMap;
|
|
||||||
private List<FabricKeyBinding> fabricKeyBindingList;
|
|
||||||
|
|
||||||
private KeyBindingRegistryImpl() {
|
|
||||||
fabricKeyBindingList = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, Integer> getCategoryMap() {
|
|
||||||
if (cachedCategoryMap == null) {
|
|
||||||
try {
|
|
||||||
//noinspection JavaReflectionMemberAccess
|
|
||||||
Method m = KeyBinding.class.getDeclaredMethod("fabric_getCategoryMap");
|
|
||||||
m.setAccessible(true);
|
|
||||||
|
|
||||||
//noinspection unchecked
|
|
||||||
cachedCategoryMap = (Map<String, Integer>) m.invoke(null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cachedCategoryMap == null) {
|
|
||||||
throw new RuntimeException("Cached key binding category map missing!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cachedCategoryMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasCategory(String categoryName) {
|
|
||||||
return getCategoryMap().containsKey(categoryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addCategory(String categoryName) {
|
|
||||||
Map<String, Integer> map = getCategoryMap();
|
|
||||||
|
|
||||||
if (map.containsKey(categoryName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<Integer> largest = map.values().stream().max(Integer::compareTo);
|
|
||||||
int largestInt = largest.orElse(0);
|
|
||||||
map.put(categoryName, largestInt + 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean register(FabricKeyBinding binding) {
|
|
||||||
for (KeyBinding exBinding : fabricKeyBindingList) {
|
|
||||||
if (exBinding == binding) {
|
|
||||||
return false;
|
|
||||||
} else if (exBinding.getId().equals(binding.getId())) {
|
|
||||||
throw new RuntimeException("Attempted to register two key bindings with equal ID: " + binding.getId() + "!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasCategory(binding.getCategory())) {
|
|
||||||
LOGGER.warn("Tried to register key binding with unregistered category '" + binding.getCategory() + "' - please use addCategory to ensure intended category ordering!");
|
|
||||||
addCategory(binding.getCategory());
|
|
||||||
}
|
|
||||||
|
|
||||||
fabricKeyBindingList.add(binding);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyBinding[] process(KeyBinding[] keysAll) {
|
|
||||||
List<KeyBinding> newKeysAll = new ArrayList<>();
|
|
||||||
|
|
||||||
for (KeyBinding binding : keysAll) {
|
|
||||||
if (!(binding instanceof FabricKeyBinding)) {
|
|
||||||
newKeysAll.add(binding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newKeysAll.addAll(fabricKeyBindingList);
|
|
||||||
return newKeysAll.toArray(new KeyBinding[0]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,10 +17,7 @@
|
||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.4.0",
|
"fabricloader": ">=0.4.0",
|
||||||
"fabric-api-base": "*"
|
"fabric-key-binding-api-v1": "*"
|
||||||
},
|
},
|
||||||
"description": "Keybinding registry API.",
|
"description": "Keybinding registry API."
|
||||||
"mixins": [
|
|
||||||
"fabric-keybindings-v0.mixins.json"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ include 'fabric-events-interaction-v0'
|
||||||
include 'fabric-events-lifecycle-v0'
|
include 'fabric-events-lifecycle-v0'
|
||||||
include 'fabric-item-groups-v0'
|
include 'fabric-item-groups-v0'
|
||||||
include 'fabric-keybindings-v0'
|
include 'fabric-keybindings-v0'
|
||||||
|
include 'fabric-key-binding-api-v1'
|
||||||
include 'fabric-loot-tables-v1'
|
include 'fabric-loot-tables-v1'
|
||||||
include 'fabric-mining-levels-v0'
|
include 'fabric-mining-levels-v0'
|
||||||
include 'fabric-models-v0'
|
include 'fabric-models-v0'
|
||||||
|
|
Loading…
Reference in a new issue