From e66a935b8eada3e6a36843d259a4ca44c35d20cb Mon Sep 17 00:00:00 2001 From: isxander Date: Fri, 9 Oct 2026 23:58:48 +0100 Subject: [PATCH 01/12] start on the new input pipeline --- .../isxander/controlify/input/SensorType.java | 23 ++++ .../controlify/input/action/Accumulator.java | 11 ++ .../controlify/input/action/Action.java | 24 ++++ .../controlify/input/action/ActionSpec.java | 15 ++ .../controlify/input/action/Activator.java | 18 +++ .../controlify/input/action/Channel.java | 37 +++++ .../controlify/input/action/ChannelKind.java | 7 + .../action/activator/ActivatorFactory.java | 8 ++ .../activator/ActivatorSerialization.java | 20 +++ .../activator/RepeatLatchPulseActivator.java | 96 +++++++++++++ .../action/activator/TapPulseActivator.java | 34 +++++ .../activator/ToggleLatchActivator.java | 59 ++++++++ .../input/logical/LogicalInput.java | 26 ++++ .../input/logical/LogicalSignal.java | 42 ++++++ .../input/logical/PhysicalToLogicalStage.java | 30 ++++ .../input/logical/SensorAccumulatorStage.java | 130 ++++++++++++++++++ .../input/physical/DeadzoneStage.java | 47 +++++++ .../physical/InputDomainExpansionStage.java | 47 +++++++ .../input/physical/PhysicalInputSignal.java | 20 +++ .../input/physical/PhysicalSensorSignal.java | 11 ++ .../input/physical/PhysicalSignal.java | 8 ++ .../controlify/utils/event/EventSink.java | 6 + .../controlify/utils/event/EventStage.java | 14 ++ .../utils/event/UnaryEventStage.java | 5 + 24 files changed, 738 insertions(+) create mode 100644 src/main/java/dev/isxander/controlify/input/SensorType.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/Accumulator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/Action.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionSpec.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/Activator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/Channel.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ChannelKind.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ActivatorFactory.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ActivatorSerialization.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java create mode 100644 src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java create mode 100644 src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java create mode 100644 src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java create mode 100644 src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java create mode 100644 src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java create mode 100644 src/main/java/dev/isxander/controlify/input/physical/PhysicalInputSignal.java create mode 100644 src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java create mode 100644 src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java create mode 100644 src/main/java/dev/isxander/controlify/utils/event/EventSink.java create mode 100644 src/main/java/dev/isxander/controlify/utils/event/EventStage.java create mode 100644 src/main/java/dev/isxander/controlify/utils/event/UnaryEventStage.java diff --git a/src/main/java/dev/isxander/controlify/input/SensorType.java b/src/main/java/dev/isxander/controlify/input/SensorType.java new file mode 100644 index 000000000..220cba2cc --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/SensorType.java @@ -0,0 +1,23 @@ +package dev.isxander.controlify.input; + +public enum SensorType { + /// Sensor components are `xyz` and in radians. + GYROSCOPE, + /// Sensor components are `xyz` and in radians. + GYROSCOPE_L, + /// Sensor components are `xyz` and in radians. + GYROSCOPE_R, + /// Sensor components are `xyz` and in m/s^2. + ACCELEROMETER, + /// Sensor components are `xyz` and in m/s^2. + ACCELEROMETER_L, + /// Sensor components are `xyz` and in m/s^2. + ACCELEROMETER_R; + + public boolean isGyroscope() { + return this == GYROSCOPE || this == GYROSCOPE_L || this == GYROSCOPE_R; + } + public boolean isAccelerometer() { + return this == ACCELEROMETER || this == ACCELEROMETER_L || this == ACCELEROMETER_R; + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/Accumulator.java b/src/main/java/dev/isxander/controlify/input/action/Accumulator.java new file mode 100644 index 000000000..00470df98 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/Accumulator.java @@ -0,0 +1,11 @@ +package dev.isxander.controlify.input.action; + +/// Accepts action state. +public interface Accumulator { + default void firePulse() {} + + default void toggleLatch() {} + default void setLatch(boolean active) {} + + default void setContinuous(float value) {} +} diff --git a/src/main/java/dev/isxander/controlify/input/action/Action.java b/src/main/java/dev/isxander/controlify/input/action/Action.java new file mode 100644 index 000000000..833d2a6c0 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/Action.java @@ -0,0 +1,24 @@ +package dev.isxander.controlify.input.action; + +import dev.isxander.controlify.input.logical.LogicalInput; +import net.minecraft.network.chat.Component; +import org.jspecify.annotations.Nullable; + +/// An action is bound to a logical input and has one or more activators +/// that determine how its output channels respond to input signals. +public interface Action { + + ActionSpec spec(); + + Channel.Pulse pulse(); + Channel.Latch latch(); + Channel.Continuous continuous(); + + Component inputGlyph(); + + void setBoundInput(@Nullable LogicalInput input); + + @Nullable LogicalInput boundInput(); + + @Nullable LogicalInput defaultInput(); +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java b/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java new file mode 100644 index 000000000..bc9a895ff --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java @@ -0,0 +1,15 @@ +package dev.isxander.controlify.input.action; + +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; + +import java.util.Set; + +public record ActionSpec( + Identifier id, + Component name, + Component description, + Component category, + Set contexts +) { +} diff --git a/src/main/java/dev/isxander/controlify/input/action/Activator.java b/src/main/java/dev/isxander/controlify/input/action/Activator.java new file mode 100644 index 000000000..8ccab37aa --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/Activator.java @@ -0,0 +1,18 @@ +package dev.isxander.controlify.input.action; + +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Processes signals and activates an {@link Action}. +public interface Activator { + + /// Accepts a {@link LogicalSignal} from layer1 and potentially + /// submits state into the action accumulator. + void onSignal(LogicalSignal signal, Accumulator acc); + + /// The logical input this is bound to. + LogicalInput boundInput(); + + String describe(); + +} diff --git a/src/main/java/dev/isxander/controlify/input/action/Channel.java b/src/main/java/dev/isxander/controlify/input/action/Channel.java new file mode 100644 index 000000000..08f9f69ba --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/Channel.java @@ -0,0 +1,37 @@ +package dev.isxander.controlify.input.action; + +/// A channel is a way of interpreting the output state of a given {@link Action}. +/// An {@link Action action's} bindings sends output to any of these channels. +public sealed interface Channel { + ChannelKind kind(); + + /// A channel which gives a continuous float value, such as an axis/joystick. + non-sealed interface Continuous extends Channel { + float getContinuous(); + + @Override + default ChannelKind kind() { + return ChannelKind.CONTINUOUS; + } + } + + /// A channel which gives single pulses, for example a button press causing a jump. + non-sealed interface Pulse extends Channel { + boolean consumePulse(); + + @Override + default ChannelKind kind() { + return ChannelKind.PULSE; + } + } + + /// A channel which gives a stateful digital output of the action, for example a physical switch's state. + non-sealed interface Latch extends Channel { + boolean isLatchActive(); + + @Override + default ChannelKind kind() { + return ChannelKind.LATCH; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ChannelKind.java b/src/main/java/dev/isxander/controlify/input/action/ChannelKind.java new file mode 100644 index 000000000..d87739fb6 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ChannelKind.java @@ -0,0 +1,7 @@ +package dev.isxander.controlify.input.action; + +public enum ChannelKind { + PULSE, + LATCH, + CONTINUOUS +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorFactory.java b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorFactory.java new file mode 100644 index 000000000..0c969448c --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorFactory.java @@ -0,0 +1,8 @@ +package dev.isxander.controlify.input.action.activator; + +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; + +public interface ActivatorFactory { + T create(LogicalInput boundInput); +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorSerialization.java b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorSerialization.java new file mode 100644 index 000000000..bf6efd8e4 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorSerialization.java @@ -0,0 +1,20 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Activator; +import net.minecraft.util.StringRepresentable; + +public final class ActivatorSerialization { + + private ActivatorSerialization() { + } + + public record Type>(String id, MapCodec mapCodec) implements StringRepresentable { + public static final Type TAP_PULSE = + new Type<>(TapPulseActivator.TapPulseActivatorConfig.TYPE_ID, TapPulseActivator.TapPulseActivatorConfig.MAP_CODEC); + + } + + public static final Codec> FACTORY_CODEC = null; +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java new file mode 100644 index 000000000..bc054b43e --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java @@ -0,0 +1,96 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Accepts another latch binding, and sends repeat pulses out while the latch is active. +public class RepeatLatchPulseActivator implements Activator { + + private final Activator latchActivator; + private final long initialDelayNs, repeatDelayNs; + private final HoldRepeatAccumulator holdRepeatAccumulator; + + private boolean down; + private long nextDue; + + public RepeatLatchPulseActivator( + Activator latchActivator, + long initialDelayNs, long repeatDelayNs + ) { + this.latchActivator = latchActivator; + this.initialDelayNs = initialDelayNs; + this.repeatDelayNs = repeatDelayNs; + this.holdRepeatAccumulator = new HoldRepeatAccumulator(); + } + + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + this.holdRepeatAccumulator.target = acc; + this.holdRepeatAccumulator.time = signal.timeNanos(); + + this.latchActivator.onSignal(signal, this.holdRepeatAccumulator); + + if (signal instanceof LogicalSignal.Tick) { + while (down && signal.timeNanos() >= nextDue) { + acc.firePulse(); + nextDue += repeatDelayNs; + } + } + } + + @Override + public LogicalInput boundInput() { + return this.latchActivator.boundInput(); + } + + @Override + public String describe() { + return "HoldRepeat[" + latchActivator.describe() + ", initialDelay=" + initialDelayNs + "ns, repeatDelay=" + repeatDelayNs + "ns]"; + } + + private class HoldRepeatAccumulator implements Accumulator { + private Accumulator target; + private long time; + + @Override + public void setLatch(boolean active) { + if (active) { + down = true; + nextDue = time + initialDelayNs; + target.firePulse(); + } else { + down = false; + nextDue = Long.MAX_VALUE; + } + } + + @Override + public void toggleLatch() { + this.setLatch(!down); + } + } + + public record RepeatLatchPulseActivatorConfig( + ActivatorFactory latchBinding, + int initialDelayTicks, int repeatDelayTicks + ) implements ActivatorFactory { + public static final String TYPE_ID = "pulse_repeat_latch"; + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + ActivatorSerialization.FACTORY_CODEC.fieldOf("source_latch").forGetter(RepeatLatchPulseActivatorConfig::latchBinding), + Codec.intRange(0, Integer.MAX_VALUE).optionalFieldOf("initial_delay_ticks", 5).forGetter(RepeatLatchPulseActivatorConfig::initialDelayTicks), + Codec.intRange(1, Integer.MAX_VALUE).optionalFieldOf("repeat_delay_ticks", 1).forGetter(RepeatLatchPulseActivatorConfig::repeatDelayTicks) + ).apply(instance, RepeatLatchPulseActivatorConfig::new)); + + @Override + public RepeatLatchPulseActivator create(LogicalInput boundInput) { + long initialDelayNs = this.initialDelayTicks * 50_000_000L; + long repeatDelayNs = this.repeatDelayTicks * 50_000_000L; + return new RepeatLatchPulseActivator(this.latchBinding.create(boundInput), initialDelayNs, repeatDelayNs); + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java new file mode 100644 index 000000000..78f407e5c --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java @@ -0,0 +1,34 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Produces a pulse when the input is tapped. +public record TapPulseActivator(LogicalInput boundInput) implements Activator { + + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + if (signal instanceof LogicalSignal.Tapped(_, LogicalInput input) && this.boundInput.equals(input)) { + acc.firePulse(); + } + } + + @Override + public String describe() { + return "Tap[" + boundInput.toString() + "]"; + } + + public record TapPulseActivatorConfig() implements ActivatorFactory { + public static final String TYPE_ID = "pulse_tap"; + public static final TapPulseActivatorConfig INSTANCE = new TapPulseActivatorConfig(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + @Override + public TapPulseActivator create(LogicalInput boundInput) { + return new TapPulseActivator(boundInput); + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java new file mode 100644 index 000000000..d045081f7 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java @@ -0,0 +1,59 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Accepts another pulse binding, and converts pulses into toggling a latch. +public class ToggleLatchActivator implements Activator { + + private final Activator pulseActivator; + private final PulseToToggleAcc pulseToToggleAcc; + + public ToggleLatchActivator(Activator pulseActivator) { + this.pulseActivator = pulseActivator; + this.pulseToToggleAcc = new PulseToToggleAcc(); + } + + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + this.pulseToToggleAcc.target = acc; + this.pulseActivator.onSignal(signal, this.pulseToToggleAcc); + } + + @Override + public LogicalInput boundInput() { + return this.pulseActivator.boundInput(); + } + + @Override + public String describe() { + return "Toggle[" + this.pulseActivator.describe() + "]"; + } + + private static final class PulseToToggleAcc implements Accumulator { + private Accumulator target; + + @Override + public void firePulse() { + target.toggleLatch(); + } + } + + public record ToggleLatchActivatorConfig( + ActivatorFactory pulseBinding + ) implements ActivatorFactory { + public static final String TYPE_ID = "latch_toggle"; + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + ActivatorSerialization.FACTORY_CODEC.fieldOf("source_pulse").forGetter(ToggleLatchActivatorConfig::pulseBinding) + ).apply(instance, ToggleLatchActivatorConfig::new)); + + @Override + public ToggleLatchActivator create(LogicalInput boundInput) { + return new ToggleLatchActivator(this.pulseBinding.create(boundInput)); + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java b/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java new file mode 100644 index 000000000..ee6188fbc --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java @@ -0,0 +1,26 @@ +package dev.isxander.controlify.input.logical; + +import net.minecraft.resources.Identifier; + +import java.util.Set; + +/// A reference to a logical button, axis, or sensor. +/// +/// A logical input's domain is the type of input, meaning that +/// a logical input that refers to the same physical inputs can be +/// safely duplicated between continuous and digital signals. +/// +/// Most of the time this will refer to a single physical button or axis, +/// like the `A` button or `Left Stick` left, but it may also refer to +/// a chord, like `A` + `B`. +public sealed interface LogicalInput { + /// A logical input with a direct relationship with a physical input. + record Single(Identifier physicalInput) implements LogicalInput { + + } + + /// A logical input that triggers only after all modifiers are already pressed. + record Modified(Set modifiers, Identifier trigger) implements LogicalInput { + + } +} diff --git a/src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java b/src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java new file mode 100644 index 000000000..f4041e2cd --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java @@ -0,0 +1,42 @@ +package dev.isxander.controlify.input.logical; + +import dev.isxander.controlify.input.SensorType; + +public sealed interface LogicalSignal { + /// The time this signal occurred. + /// Every signal will have the same epoch. + long timeNanos(); + + /// Submitted once per frame. + /// Allows bindings to accumulate state between ticks. + record Tick(long timeNanos, long deltaTimeNanos) implements LogicalSignal {} + + sealed interface InputSignal extends LogicalSignal { + LogicalInput input(); + } + /// When the button is pressed down + record ButtonDown(long timeNanos, LogicalInput input) implements InputSignal {} + + /// When the button is released + record ButtonUp(long timeNanos, LogicalInput input) implements InputSignal {} + + /// When button is pressed and released in quick succession + record Tapped(long timeNanos, LogicalInput input) implements InputSignal {} + + /// When two {@link Tapped taps} occur in quick succession + record DoubleTapped(long timeNanos, LogicalInput input) implements InputSignal {} + + /// When a button is pressed and released, where no GUI navigation happened in between + record GuiPress(long timeNanos, LogicalInput input) implements InputSignal {} + + /// When a button is held for a long period of time. Signaled whilst still held. + record Held(long timeNanos, LogicalInput input) implements InputSignal {} + + /// When an axis value changes + record AxisMoved(long timeNanos, LogicalInput input, float value, float delta) implements InputSignal {} + + /// Represents sensor data, which can be multi-dimensional. + /// The data is expected to be tick-integrated deltas. They are not individual IMU samples. + /// @see SensorAccumulatorStage + record SensorInterval(long timeNanos, long deltaTimeNanos, SensorType sensorType, float x, float y, float z) implements LogicalSignal {} +} diff --git a/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java b/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java new file mode 100644 index 000000000..df4db3c03 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java @@ -0,0 +1,30 @@ +package dev.isxander.controlify.input.logical; + +import dev.isxander.controlify.input.physical.PhysicalSensorSignal; +import dev.isxander.controlify.input.physical.PhysicalSignal; +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.EventStage; + +/// The event stage that converts physical signals into logical ones. +/// This stage is responsible for recognizing chords, integrating sensor data, and emitting logical signals. +public class PhysicalToLogicalStage implements EventStage { + private final SensorAccumulatorStage sensorAccumulatorStage; + + public PhysicalToLogicalStage(SensorAccumulatorStage sensorAccumulatorStage) { + this.sensorAccumulatorStage = sensorAccumulatorStage; + } + + @Override + public void onEvent(PhysicalSignal event, EventSink downstream) { + switch (event) { + case PhysicalSignal.Tick(long timeNanos, long deltaTimeNanos) -> { + this.sensorAccumulatorStage.onEvent(event, downstream); + + downstream.accept(new LogicalSignal.Tick(timeNanos, deltaTimeNanos)); + } + + case PhysicalSensorSignal sensorSignal -> + this.sensorAccumulatorStage.onEvent(sensorSignal, downstream); + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java b/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java new file mode 100644 index 000000000..279eb1d55 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java @@ -0,0 +1,130 @@ +package dev.isxander.controlify.input.logical; + +import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.input.physical.PhysicalSensorSignal; +import dev.isxander.controlify.input.physical.PhysicalSignal; +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.EventStage; + +import java.util.EnumMap; +import java.util.Map; + +public class SensorAccumulatorStage implements EventStage { + // prevent stale readings from being continually accumulated + private static final long MAX_SAMPLE_AGE_NANOS = 50_000_000L; + + private final Map accSensorValues = new EnumMap<>(SensorType.class); + + @Override + public void onEvent( + PhysicalSignal event, + EventSink downstream + ) { + switch (event) { + case PhysicalSignal.Tick(long timeNanos, _) -> { + this.accSensorValues.forEach((sensorType, acc) -> { + if (acc.lastNs == -1) { + return; + } + + acc.integrateUntil(timeNanos); + + if (acc.accumulatedNanos > 0) { + float x = acc.x; + float y = acc.y; + float z = acc.z; + + if (sensorType.isAccelerometer()) { + float durationSeconds = acc.accumulatedNanos * 1e-9f; + + x /= durationSeconds; + y /= durationSeconds; + z /= durationSeconds; + } + + downstream.accept(new LogicalSignal.SensorInterval( + timeNanos, + acc.accumulatedNanos, + sensorType, + x, + y, + z + )); + } + + acc.resetAccumulation(); + }); + } + + case PhysicalSensorSignal(long timeNanos, SensorType sensorType, float x, float y, float z) -> { + Acc acc = this.accSensorValues.computeIfAbsent(sensorType, _ -> new Acc()); + + if (acc.lastNs != -1 && timeNanos <= acc.lastNs) { + return; + } + + acc.integrateUntil(timeNanos); + + acc.velocityX = x; + acc.velocityY = y; + acc.velocityZ = z; + acc.lastSampleNanos = timeNanos; + } + + default -> { + } + } + } + + private static final class Acc { + private long lastNs = -1; + private long lastSampleNanos = -1; + + private float velocityX; + private float velocityY; + private float velocityZ; + + private float x; + private float y; + private float z; + + private long accumulatedNanos; + + public void integrateUntil(long timeNanos) { + if (lastNs == -1) { + lastNs = timeNanos; + return; + } + + long deltaNanos = timeNanos - lastNs; + + if (deltaNanos <= 0) { + return; + } + + // Integrate only while the last sensor reading is considered valid. + long validUntilNanos = lastSampleNanos + MAX_SAMPLE_AGE_NANOS; + long integrationEndNanos = Math.min(timeNanos, validUntilNanos); + + if (integrationEndNanos > lastNs) { + long integrationNanos = integrationEndNanos - lastNs; + float deltaSeconds = integrationNanos * 1e-9f; + + x += velocityX * deltaSeconds; + y += velocityY * deltaSeconds; + z += velocityZ * deltaSeconds; + + accumulatedNanos += integrationNanos; + } + + lastNs = timeNanos; + } + + public void resetAccumulation() { + x = 0.0f; + y = 0.0f; + z = 0.0f; + accumulatedNanos = 0; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java b/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java new file mode 100644 index 000000000..26f8156f7 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java @@ -0,0 +1,47 @@ +package dev.isxander.controlify.input.physical; + +import dev.isxander.controlify.utils.ControllerUtils; +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.UnaryEventStage; +import net.minecraft.resources.Identifier; + +import java.util.HashSet; +import java.util.Set; +import java.util.function.Function; + +/// Applies deadzones to physical axes. +// TODO: radial deadzones +public class DeadzoneStage implements UnaryEventStage { + private final Function deadzoneSupplier; + + private final Set axisWasZero; + + public DeadzoneStage(Function axisToDeadzoneSupplier) { + this.deadzoneSupplier = axisToDeadzoneSupplier; + this.axisWasZero = new HashSet<>(); + } + + @Override + public void onEvent(PhysicalSignal event, EventSink downstream) { + if (event instanceof PhysicalInputSignal.AxisMoved(long timeNanos, Identifier input, float value)) { + float deadzone = this.deadzoneSupplier.apply(input); + + if (deadzone > 0) { + // TODO: prevent duplicate zeros passing downstream + float newValue = ControllerUtils.deadzone(value, deadzone); + + if (newValue != 0 || this.axisWasZero.add(input)) { + downstream.accept(new PhysicalInputSignal.AxisMoved(timeNanos, input, newValue)); + if (newValue != 0) { + this.axisWasZero.remove(input); + } + } + return; + } else { + this.axisWasZero.remove(input); + } + } + + downstream.accept(event); + } +} diff --git a/src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java b/src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java new file mode 100644 index 000000000..f300ddb9a --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java @@ -0,0 +1,47 @@ +package dev.isxander.controlify.input.physical; + +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.UnaryEventStage; +import net.minecraft.resources.Identifier; + +import java.util.HashSet; +import java.util.Set; + +/// Expands the domain of physical inputs. +/// - Expands button presses and releases into axis moved events. +/// - Expands axis moved events into button presses and releases when passing threshold. +public class InputDomainExpansionStage implements UnaryEventStage { + + private final Set pressedButtons; + private final float actuation, release, pressedValue, releasedValue; + + public InputDomainExpansionStage(float actuation, float release, float pressedValue, float releasedValue) { + this.pressedButtons = new HashSet<>(); + this.actuation = actuation; + this.release = release; + this.pressedValue = pressedValue; + this.releasedValue = releasedValue; + } + + @Override + public void onEvent(PhysicalInputSignal event, EventSink downstream) { + downstream.accept(event); + + switch (event) { + case PhysicalInputSignal.AxisMoved(long timeNanos, Identifier input, float value) -> { + if (value >= actuation) { + if (!this.pressedButtons.add(input)) { + downstream.accept(new PhysicalInputSignal.ButtonChanged(timeNanos, input, true)); + } + } else if (value <= release) { + if (!this.pressedButtons.remove(input)) { + downstream.accept(new PhysicalInputSignal.ButtonChanged(timeNanos, input, false)); + } + } + } + case PhysicalInputSignal.ButtonChanged(long timeNanos, Identifier input, boolean state) -> { + downstream.accept(new PhysicalInputSignal.AxisMoved(timeNanos, input, state ? pressedValue : releasedValue)); + } + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/physical/PhysicalInputSignal.java b/src/main/java/dev/isxander/controlify/input/physical/PhysicalInputSignal.java new file mode 100644 index 000000000..aa6b8d064 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/physical/PhysicalInputSignal.java @@ -0,0 +1,20 @@ +package dev.isxander.controlify.input.physical; + +import net.minecraft.resources.Identifier; + +public sealed interface PhysicalInputSignal extends PhysicalSignal { + /// @return the identifier of the physical input + Identifier input(); + + /// Represents a button press/release event. + /// @param timeNanos the timestamp of the event in nanoseconds + /// @param input the identifier of the physical button + /// @param state the state of the button, where true indicates pressed and false indicates released + record ButtonChanged(long timeNanos, Identifier input, boolean state) implements PhysicalInputSignal {} + + /// Represents an axis movement event. + /// @param timeNanos the timestamp of the event in nanoseconds + /// @param input the identifier of the physical axis + /// @param value the position of the axis, *always* in the range `[0.0, 1.0]` + record AxisMoved(long timeNanos, Identifier input, float value) implements PhysicalInputSignal {} +} diff --git a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java new file mode 100644 index 000000000..57ef156be --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java @@ -0,0 +1,11 @@ +package dev.isxander.controlify.input.physical; + +import dev.isxander.controlify.input.SensorType; + +/// Represents a single IMU sample +public record PhysicalSensorSignal( + long timeNanos, + SensorType sensorType, + float x, float y, float z +) implements PhysicalSignal { +} diff --git a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java new file mode 100644 index 000000000..c92946936 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java @@ -0,0 +1,8 @@ +package dev.isxander.controlify.input.physical; + +public sealed interface PhysicalSignal permits PhysicalInputSignal, PhysicalSensorSignal, PhysicalSignal.Tick { + long timeNanos(); + + /// Emitted at the end of each polling / every frame. + record Tick(long timeNanos, long deltaTimeNanos) implements PhysicalSignal {} +} diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventSink.java b/src/main/java/dev/isxander/controlify/utils/event/EventSink.java new file mode 100644 index 000000000..ef93c6831 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/utils/event/EventSink.java @@ -0,0 +1,6 @@ +package dev.isxander.controlify.utils.event; + +@FunctionalInterface +public interface EventSink { + void accept(T event); +} diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventStage.java b/src/main/java/dev/isxander/controlify/utils/event/EventStage.java new file mode 100644 index 000000000..086ba51ce --- /dev/null +++ b/src/main/java/dev/isxander/controlify/utils/event/EventStage.java @@ -0,0 +1,14 @@ +package dev.isxander.controlify.utils.event; + +@FunctionalInterface +public interface EventStage { + void onEvent(I event, EventSink downstream); + + default EventStage andThen(EventStage next) { + return (event, downstream) -> this.onEvent(event, x -> next.onEvent(x, downstream)); + } + + static UnaryEventStage identity() { + return (event, downstream) -> downstream.accept(event); + } +} diff --git a/src/main/java/dev/isxander/controlify/utils/event/UnaryEventStage.java b/src/main/java/dev/isxander/controlify/utils/event/UnaryEventStage.java new file mode 100644 index 000000000..cbf80fb8e --- /dev/null +++ b/src/main/java/dev/isxander/controlify/utils/event/UnaryEventStage.java @@ -0,0 +1,5 @@ +package dev.isxander.controlify.utils.event; + +@FunctionalInterface +public interface UnaryEventStage extends EventStage { +} From 560c6d0b2b83d7664c5349afbd6215dd30189842 Mon Sep 17 00:00:00 2001 From: isxander Date: Sat, 10 Oct 2026 18:17:59 +0100 Subject: [PATCH 02/12] activator system & more --- .../input/action/ActionAccessor.java | 27 ++++ .../controlify/input/action/ActionGraph.java | 56 +++++++ .../controlify/input/action/ActionImpl.java | 55 +++++++ .../controlify/input/action/ActionSpec.java | 9 +- .../input/action/ActionSpecBuilder.java | 20 +++ .../input/action/ActionSpecRegistry.java | 5 + .../controlify/input/action/ActionState.java | 46 ++++++ .../controlify/input/action/Activator.java | 3 +- .../controlify/input/action/Channel.java | 17 -- .../controlify/input/action/ChannelKind.java | 7 - .../action/activator/ActivatorConfig.java | 18 +++ .../action/activator/ActivatorConfigType.java | 55 +++++++ .../action/activator/ActivatorFactory.java | 8 - .../activator/ActivatorSerialization.java | 20 --- .../action/activator/CompoundActivator.java | 48 ++++++ .../action/activator/ContinuousActivator.java | 37 +++++ .../activator/DoubleTapPulseActivator.java | 38 +++++ .../activator/GuiPressPulseActivator.java | 38 +++++ .../action/activator/HoldLatchActivator.java | 48 ++++++ .../action/activator/HoldPulseActivator.java | 38 +++++ .../input/action/activator/NoopActivator.java | 23 +++ .../action/activator/PressPulseActivator.java | 38 +++++ .../activator/ReleasePulseActivator.java | 38 +++++ .../activator/RepeatLatchPulseActivator.java | 21 ++- .../action/activator/TapPulseActivator.java | 11 +- .../activator/ToggleLatchActivator.java | 17 +- .../input/logical/LogicalInput.java | 2 +- .../input/logical/LogicalSignal.java | 4 +- .../input/logical/PhysicalToLogicalStage.java | 153 +++++++++++++++++- .../input/physical/GestureInputs.java | 12 ++ .../physical/GestureRecogniserStage.java | 15 ++ 31 files changed, 848 insertions(+), 79 deletions(-) create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionGraph.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionImpl.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionState.java delete mode 100644 src/main/java/dev/isxander/controlify/input/action/ChannelKind.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java delete mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ActivatorFactory.java delete mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ActivatorSerialization.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/CompoundActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/NoopActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java create mode 100644 src/main/java/dev/isxander/controlify/input/physical/GestureInputs.java create mode 100644 src/main/java/dev/isxander/controlify/input/physical/GestureRecogniserStage.java diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java b/src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java new file mode 100644 index 000000000..040ba8eda --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java @@ -0,0 +1,27 @@ +package dev.isxander.controlify.input.action; + +import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.controller.input.InputComponent; +import net.minecraft.resources.Identifier; +import org.jspecify.annotations.Nullable; + +/// An accessor to get an existing action from an input component +public interface ActionAccessor { + @Nullable Action onOrNull(InputComponent inputComponent); + + Identifier actionId(); + + default @Nullable Action onOrNull(ControllerEntity controller) { + return onOrNull(controller.input().orElseThrow()); + } + + default Action on(InputComponent inputComponent) { + Action action = onOrNull(inputComponent); + if (action == null) throw new NullPointerException("No action bound to input component " + actionId()); + return action; + } + + default Action on(ControllerEntity controller) { + return on(controller.input().orElseThrow()); + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionGraph.java b/src/main/java/dev/isxander/controlify/input/action/ActionGraph.java new file mode 100644 index 000000000..6afe890fd --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionGraph.java @@ -0,0 +1,56 @@ +package dev.isxander.controlify.input.action; + +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.utils.event.EventSink; +import net.minecraft.resources.Identifier; + +import java.util.*; + +public class ActionGraph implements EventSink { + private final Set allActions = new TreeSet<>(); + + // Context ID -> Logical Input -> set of ActionImpl + // the same compiled binding can be registered for multiple contexts and inputs + // this allows for more efficient lookup when processing signals + // by avoiding the need to iterate over all bindings for each signal + private final Map>> graph = new HashMap<>(); + + public void addAction(ActionImpl action) { + this.allActions.add(action); + for (var contextId : action.spec().contexts()) { + var byInputMap = this.graph.computeIfAbsent(contextId, _ -> new HashMap<>()); + byInputMap.computeIfAbsent(action.boundInput(), _ -> new TreeSet<>()) + .add(action); + } + } + + public void removeAction(ActionImpl action) { + for (var contextId : action.spec().contexts()) { + var byInputMap = this.graph.getOrDefault(contextId, Map.of()); + for (var set : byInputMap.values()) { + set.remove(action); + } + } + this.allActions.remove(action); + } + + @Override + public void accept(LogicalSignal event) { + switch (event) { + case LogicalSignal.Tick tick -> this.processTick(tick); + case LogicalSignal.InputSignal inputSignal -> this.processInput(inputSignal); + case LogicalSignal.SensorInterval _ -> {} // ignore sensor data + } + } + + private void processTick(LogicalSignal.Tick tick) { + for (ActionImpl action : this.allActions) { + action.activator().onSignal(tick, action.state()); + } + } + + private void processInput(LogicalSignal.InputSignal inputSignal) { + + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionImpl.java b/src/main/java/dev/isxander/controlify/input/action/ActionImpl.java new file mode 100644 index 000000000..eed9128a8 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionImpl.java @@ -0,0 +1,55 @@ +package dev.isxander.controlify.input.action; + +import dev.isxander.controlify.input.action.activator.ActivatorConfig; +import dev.isxander.controlify.input.action.activator.NoopActivator; +import dev.isxander.controlify.input.logical.LogicalInput; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public class ActionImpl implements Action, Comparable { + private final ActionSpec spec; + private final ActionState state; + private @Nullable LogicalInput boundInput; + private final @Nullable LogicalInput defaultInput; + private Activator activator; + private final ActivatorConfig activatorConfig; + + public ActionImpl( + ActionSpec spec, + @Nullable LogicalInput boundInput, + @Nullable LogicalInput defaultInput, + ActivatorConfig activator + ) { + this.spec = spec; + this.defaultInput = defaultInput; + this.activatorConfig = activator; + this.setBoundInput(boundInput); + this.state = new ActionState(); + } + + @Override + public @Nullable LogicalInput boundInput() { + return this.boundInput; + } + + @Override + public void setBoundInput(@Nullable LogicalInput boundInput) { + this.boundInput = boundInput; + this.activator = boundInput != null + ? this.activatorConfig.create(boundInput) + : new NoopActivator(); + } + + public ActionState state() { + return this.state; + } + + public Activator activator() { + return this.activator; + } + + @Override + public int compareTo(@NonNull ActionImpl o) { + return this.spec().compareTo(o.spec()); + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java b/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java index bc9a895ff..7da547c3f 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java +++ b/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java @@ -2,7 +2,9 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; +import org.jspecify.annotations.NonNull; +import java.util.Comparator; import java.util.Set; public record ActionSpec( @@ -11,5 +13,10 @@ public record ActionSpec( Component description, Component category, Set contexts -) { +) implements Comparable { + @Override + public int compareTo(@NonNull ActionSpec o) { + return Comparator.comparing(ActionSpec::id) + .compare(this, o); + } } diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java b/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java new file mode 100644 index 000000000..f343f82e8 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java @@ -0,0 +1,20 @@ +package dev.isxander.controlify.input.action; + +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; + +public interface ActionSpecBuilder { + ActionSpecBuilder id(Identifier id); + + ActionSpecBuilder name(Component name); + + ActionSpecBuilder description(Component name); + + ActionSpecBuilder category(Component category); + + ActionSpecBuilder context(Identifier... contexts); + + ActionSpec build(); + + ActionAccessor buildAndRegister(ActionSpecRegistry registry); +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java b/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java new file mode 100644 index 000000000..aa1753630 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java @@ -0,0 +1,5 @@ +package dev.isxander.controlify.input.action; + +public interface ActionSpecRegistry { + void register(ActionSpec actionSpec); +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionState.java b/src/main/java/dev/isxander/controlify/input/action/ActionState.java new file mode 100644 index 000000000..1a248b5e5 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionState.java @@ -0,0 +1,46 @@ +package dev.isxander.controlify.input.action; + +public final class ActionState implements Accumulator, Channel.Continuous, Channel.Latch, Channel.Pulse { + private int pulses = 0; + private boolean latchActive = false; + private float continuousValue = 0; + + @Override + public float getContinuous() { + return this.continuousValue; + } + + @Override + public boolean isLatchActive() { + return this.latchActive; + } + + @Override + public boolean consumePulse() { + if (this.pulses > 0) { + this.pulses--; + return true; + } + return false; + } + + @Override + public void toggleLatch() { + this.setLatch(!this.isLatchActive()); + } + + @Override + public void setLatch(boolean active) { + this.latchActive = active; + } + + @Override + public void firePulse() { + this.pulses++; + } + + @Override + public void setContinuous(float value) { + this.continuousValue = Math.clamp(value, 0f, 1f); + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/Activator.java b/src/main/java/dev/isxander/controlify/input/action/Activator.java index 8ccab37aa..7e5b0db02 100644 --- a/src/main/java/dev/isxander/controlify/input/action/Activator.java +++ b/src/main/java/dev/isxander/controlify/input/action/Activator.java @@ -6,13 +6,14 @@ /// Processes signals and activates an {@link Action}. public interface Activator { - /// Accepts a {@link LogicalSignal} from layer1 and potentially + /// Accepts a {@link LogicalSignal} and potentially /// submits state into the action accumulator. void onSignal(LogicalSignal signal, Accumulator acc); /// The logical input this is bound to. LogicalInput boundInput(); + /// gives a string representation of this activator String describe(); } diff --git a/src/main/java/dev/isxander/controlify/input/action/Channel.java b/src/main/java/dev/isxander/controlify/input/action/Channel.java index 08f9f69ba..064d29c4c 100644 --- a/src/main/java/dev/isxander/controlify/input/action/Channel.java +++ b/src/main/java/dev/isxander/controlify/input/action/Channel.java @@ -3,35 +3,18 @@ /// A channel is a way of interpreting the output state of a given {@link Action}. /// An {@link Action action's} bindings sends output to any of these channels. public sealed interface Channel { - ChannelKind kind(); - /// A channel which gives a continuous float value, such as an axis/joystick. non-sealed interface Continuous extends Channel { float getContinuous(); - - @Override - default ChannelKind kind() { - return ChannelKind.CONTINUOUS; - } } /// A channel which gives single pulses, for example a button press causing a jump. non-sealed interface Pulse extends Channel { boolean consumePulse(); - - @Override - default ChannelKind kind() { - return ChannelKind.PULSE; - } } /// A channel which gives a stateful digital output of the action, for example a physical switch's state. non-sealed interface Latch extends Channel { boolean isLatchActive(); - - @Override - default ChannelKind kind() { - return ChannelKind.LATCH; - } } } diff --git a/src/main/java/dev/isxander/controlify/input/action/ChannelKind.java b/src/main/java/dev/isxander/controlify/input/action/ChannelKind.java deleted file mode 100644 index d87739fb6..000000000 --- a/src/main/java/dev/isxander/controlify/input/action/ChannelKind.java +++ /dev/null @@ -1,7 +0,0 @@ -package dev.isxander.controlify.input.action; - -public enum ChannelKind { - PULSE, - LATCH, - CONTINUOUS -} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java new file mode 100644 index 000000000..cf4adc412 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java @@ -0,0 +1,18 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.Codec; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import net.minecraft.util.StringRepresentable; + +/// An immutable structure typically containing the configuration +/// for an {@link Activator} type, allowing you to create instances +/// of the activator using the configuration and a given bound logical input. +public interface ActivatorConfig { + T create(LogicalInput boundInput); + + ActivatorConfigType type(); + + Codec> CODEC = StringRepresentable.fromValues(() -> ActivatorConfigType.TYPES) + .dispatch("type", ActivatorConfig::type, ActivatorConfigType::mapCodec); +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java new file mode 100644 index 000000000..8cae0e58f --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java @@ -0,0 +1,55 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Activator; +import net.minecraft.util.StringRepresentable; +import org.jetbrains.annotations.NotNull; + +public record ActivatorConfigType>( + String id, + MapCodec mapCodec +) implements StringRepresentable { + public static final ActivatorConfigType COMPOUND = + new ActivatorConfigType<>(CompoundActivator.Config.TYPE_ID, CompoundActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType CONTINUOUS = + new ActivatorConfigType<>(ContinuousActivator.Config.TYPE_ID, ContinuousActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType HOLD_LATCH = + new ActivatorConfigType<>(HoldLatchActivator.Config.TYPE_ID, HoldLatchActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType PRESS_PULSE = + new ActivatorConfigType<>(PressPulseActivator.Config.TYPE_ID, PressPulseActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType RELEASE_PULSE = + new ActivatorConfigType<>(ReleasePulseActivator.Config.TYPE_ID, ReleasePulseActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType REPEAT_LATCH_PULSE = + new ActivatorConfigType<>(RepeatLatchPulseActivator.Config.TYPE_ID, RepeatLatchPulseActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType TAP_PULSE = + new ActivatorConfigType<>(TapPulseActivator.Config.TYPE_ID, TapPulseActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType DOUBLE_TAP_PULSE = + new ActivatorConfigType<>(DoubleTapPulseActivator.Config.TYPE_ID, DoubleTapPulseActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType GUI_PRESS_PULSE = + new ActivatorConfigType<>(GuiPressPulseActivator.Config.TYPE_ID, GuiPressPulseActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType HOLD_PULSE = + new ActivatorConfigType<>(HoldPulseActivator.Config.TYPE_ID, HoldPulseActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType TOGGLE_LATCH = + new ActivatorConfigType<>(ToggleLatchActivator.Config.TYPE_ID, ToggleLatchActivator.Config.MAP_CODEC); + + public static final ActivatorConfigType[] TYPES = new ActivatorConfigType[]{ + COMPOUND, CONTINUOUS, HOLD_LATCH, PRESS_PULSE, RELEASE_PULSE, + REPEAT_LATCH_PULSE, TAP_PULSE, DOUBLE_TAP_PULSE, GUI_PRESS_PULSE, + HOLD_PULSE, TOGGLE_LATCH + }; + + @Override + public @NotNull String getSerializedName() { + return this.id(); + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorFactory.java b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorFactory.java deleted file mode 100644 index 0c969448c..000000000 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorFactory.java +++ /dev/null @@ -1,8 +0,0 @@ -package dev.isxander.controlify.input.action.activator; - -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; - -public interface ActivatorFactory { - T create(LogicalInput boundInput); -} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorSerialization.java b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorSerialization.java deleted file mode 100644 index bf6efd8e4..000000000 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorSerialization.java +++ /dev/null @@ -1,20 +0,0 @@ -package dev.isxander.controlify.input.action.activator; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Activator; -import net.minecraft.util.StringRepresentable; - -public final class ActivatorSerialization { - - private ActivatorSerialization() { - } - - public record Type>(String id, MapCodec mapCodec) implements StringRepresentable { - public static final Type TAP_PULSE = - new Type<>(TapPulseActivator.TapPulseActivatorConfig.TYPE_ID, TapPulseActivator.TapPulseActivatorConfig.MAP_CODEC); - - } - - public static final Codec> FACTORY_CODEC = null; -} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/CompoundActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/CompoundActivator.java new file mode 100644 index 000000000..916a1beb0 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/CompoundActivator.java @@ -0,0 +1,48 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +import java.util.List; +import java.util.stream.Collectors; + +public record CompoundActivator(LogicalInput boundInput, List activators) implements Activator { + + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + for (var activator : activators) { + activator.onSignal(signal, acc); + } + } + + @Override + public String describe() { + return activators().stream() + .map(Activator::describe) + .collect(Collectors.joining(",", "Compound[", "]")); + } + + public record Config(List> activators) implements ActivatorConfig { + public static final String TYPE_ID = "compound"; + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + ActivatorConfig.CODEC.listOf().fieldOf("activators").forGetter(Config::activators) + ).apply(instance, Config::new)); + + @Override + public CompoundActivator create(LogicalInput boundInput) { + var activators = this.activators.stream() + .map(config -> config.create(boundInput)) + .toList(); + return new CompoundActivator(boundInput, activators); + } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.COMPOUND; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java new file mode 100644 index 000000000..31d67366d --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java @@ -0,0 +1,37 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +public record ContinuousActivator(LogicalInput boundInput) implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + if (signal instanceof LogicalSignal.AxisMoved s && s.input().equals(this.boundInput)) { + acc.setContinuous(s.value()); + } + } + + @Override + public String describe() { + return "Continuous[" + boundInput().toString() + "]"; + } + + public record Config() implements ActivatorConfig { + public static final String TYPE_ID = "continuous"; + public static final Config INSTANCE = new Config(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + @Override + public ContinuousActivator create(LogicalInput boundInput) { + return new ContinuousActivator(boundInput); + } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.CONTINUOUS; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java new file mode 100644 index 000000000..8d271dad6 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java @@ -0,0 +1,38 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Produces a pulse when the input is double tapped. +public record DoubleTapPulseActivator(LogicalInput boundInput) implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + if (signal instanceof LogicalSignal.DoubleTapped(_, LogicalInput input) && this.boundInput.equals(input)) { + acc.firePulse(); + } + } + + @Override + public String describe() { + return "DoubleTap[" + boundInput.toString() + "]"; + } + + public record Config() implements ActivatorConfig { + public static final String TYPE_ID = "pulse_double_tap"; + public static final Config INSTANCE = new Config(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + @Override + public DoubleTapPulseActivator create(LogicalInput boundInput) { + return new DoubleTapPulseActivator(boundInput); + } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.DOUBLE_TAP_PULSE; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java new file mode 100644 index 000000000..9d8fec1af --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java @@ -0,0 +1,38 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Produces a pulse on release when no GUI navigation consumed the press. +public record GuiPressPulseActivator(LogicalInput boundInput) implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + if (signal instanceof LogicalSignal.GuiPress(_, LogicalInput input) && this.boundInput.equals(input)) { + acc.firePulse(); + } + } + + @Override + public String describe() { + return "GuiPress[" + boundInput.toString() + "]"; + } + + public record Config() implements ActivatorConfig { + public static final String TYPE_ID = "pulse_gui_press"; + public static final Config INSTANCE = new Config(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + @Override + public GuiPressPulseActivator create(LogicalInput boundInput) { + return new GuiPressPulseActivator(boundInput); + } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.GUI_PRESS_PULSE; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java new file mode 100644 index 000000000..8d7921d7f --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java @@ -0,0 +1,48 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Keeps the latch active from button press until release, without a hold delay. +public record HoldLatchActivator(LogicalInput boundInput) implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + switch (signal) { + case LogicalSignal.ButtonPress(_, LogicalInput input) -> { + if (this.boundInput.equals(input)) { + acc.setLatch(true); + } + } + case LogicalSignal.ButtonRelease(_, LogicalInput input) -> { + if (this.boundInput.equals(input)) { + acc.setLatch(false); + } + } + default -> {} + } + } + + @Override + public String describe() { + return "HoldLatch[" + boundInput.toString() + "]"; + } + + public record Config() implements ActivatorConfig { + public static final String TYPE_ID = "latch_hold"; + public static final Config INSTANCE = new Config(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + @Override + public HoldLatchActivator create(LogicalInput boundInput) { + return new HoldLatchActivator(boundInput); + } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.HOLD_LATCH; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java new file mode 100644 index 000000000..d68f5da45 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java @@ -0,0 +1,38 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Produces a pulse once the input reaches the hold duration. +public record HoldPulseActivator(LogicalInput boundInput) implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + if (signal instanceof LogicalSignal.Held(_, LogicalInput input) && this.boundInput.equals(input)) { + acc.firePulse(); + } + } + + @Override + public String describe() { + return "Hold[" + boundInput.toString() + "]"; + } + + public record Config() implements ActivatorConfig { + public static final String TYPE_ID = "pulse_hold"; + public static final Config INSTANCE = new Config(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + @Override + public HoldPulseActivator create(LogicalInput boundInput) { + return new HoldPulseActivator(boundInput); + } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.HOLD_PULSE; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/NoopActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/NoopActivator.java new file mode 100644 index 000000000..dde0bf7e6 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/NoopActivator.java @@ -0,0 +1,23 @@ +package dev.isxander.controlify.input.action.activator; + +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +public class NoopActivator implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + + } + + @Override + public LogicalInput boundInput() { + return null; + } + + @Override + public String describe() { + return "Noop"; + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java new file mode 100644 index 000000000..58f38263c --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java @@ -0,0 +1,38 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Produces a pulse when the input is pressed. +public record PressPulseActivator(LogicalInput boundInput) implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + if (signal instanceof LogicalSignal.ButtonPress(_, LogicalInput input) && this.boundInput.equals(input)) { + acc.firePulse(); + } + } + + @Override + public String describe() { + return "Press[" + boundInput.toString() + "]"; + } + + public record Config() implements ActivatorConfig { + public static final String TYPE_ID = "pulse_press"; + public static final Config INSTANCE = new Config(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + @Override + public PressPulseActivator create(LogicalInput boundInput) { + return new PressPulseActivator(boundInput); + } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.PRESS_PULSE; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java new file mode 100644 index 000000000..3199708c0 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java @@ -0,0 +1,38 @@ +package dev.isxander.controlify.input.action.activator; + +import com.mojang.serialization.MapCodec; +import dev.isxander.controlify.input.action.Accumulator; +import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.logical.LogicalSignal; + +/// Produces a pulse when the input is released. +public record ReleasePulseActivator(LogicalInput boundInput) implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + if (signal instanceof LogicalSignal.ButtonRelease(_, LogicalInput input) && this.boundInput.equals(input)) { + acc.firePulse(); + } + } + + @Override + public String describe() { + return "Release[" + boundInput.toString() + "]"; + } + + public record Config() implements ActivatorConfig { + public static final String TYPE_ID = "pulse_release"; + public static final Config INSTANCE = new Config(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + @Override + public ReleasePulseActivator create(LogicalInput boundInput) { + return new ReleasePulseActivator(boundInput); + } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.RELEASE_PULSE; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java index bc054b43e..fd37620e8 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java @@ -75,16 +75,16 @@ public void toggleLatch() { } } - public record RepeatLatchPulseActivatorConfig( - ActivatorFactory latchBinding, + public record Config( + ActivatorConfig latchBinding, int initialDelayTicks, int repeatDelayTicks - ) implements ActivatorFactory { + ) implements ActivatorConfig { public static final String TYPE_ID = "pulse_repeat_latch"; - public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActivatorSerialization.FACTORY_CODEC.fieldOf("source_latch").forGetter(RepeatLatchPulseActivatorConfig::latchBinding), - Codec.intRange(0, Integer.MAX_VALUE).optionalFieldOf("initial_delay_ticks", 5).forGetter(RepeatLatchPulseActivatorConfig::initialDelayTicks), - Codec.intRange(1, Integer.MAX_VALUE).optionalFieldOf("repeat_delay_ticks", 1).forGetter(RepeatLatchPulseActivatorConfig::repeatDelayTicks) - ).apply(instance, RepeatLatchPulseActivatorConfig::new)); + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + ActivatorConfig.CODEC.fieldOf("source_latch").forGetter(Config::latchBinding), + Codec.intRange(0, Integer.MAX_VALUE).optionalFieldOf("initial_delay_ticks", 5).forGetter(Config::initialDelayTicks), + Codec.intRange(1, Integer.MAX_VALUE).optionalFieldOf("repeat_delay_ticks", 1).forGetter(Config::repeatDelayTicks) + ).apply(instance, Config::new)); @Override public RepeatLatchPulseActivator create(LogicalInput boundInput) { @@ -92,5 +92,10 @@ public RepeatLatchPulseActivator create(LogicalInput boundInput) { long repeatDelayNs = this.repeatDelayTicks * 50_000_000L; return new RepeatLatchPulseActivator(this.latchBinding.create(boundInput), initialDelayNs, repeatDelayNs); } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.REPEAT_LATCH_PULSE; + } } } diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java index 78f407e5c..11a227aac 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java @@ -21,14 +21,19 @@ public String describe() { return "Tap[" + boundInput.toString() + "]"; } - public record TapPulseActivatorConfig() implements ActivatorFactory { + public record Config() implements ActivatorConfig { public static final String TYPE_ID = "pulse_tap"; - public static final TapPulseActivatorConfig INSTANCE = new TapPulseActivatorConfig(); - public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + public static final Config INSTANCE = new Config(); + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); @Override public TapPulseActivator create(LogicalInput boundInput) { return new TapPulseActivator(boundInput); } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.TAP_PULSE; + } } } diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java index d045081f7..3c8df2b38 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java @@ -43,17 +43,22 @@ public void firePulse() { } } - public record ToggleLatchActivatorConfig( - ActivatorFactory pulseBinding - ) implements ActivatorFactory { + public record Config( + ActivatorConfig pulseBinding + ) implements ActivatorConfig { public static final String TYPE_ID = "latch_toggle"; - public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ActivatorSerialization.FACTORY_CODEC.fieldOf("source_pulse").forGetter(ToggleLatchActivatorConfig::pulseBinding) - ).apply(instance, ToggleLatchActivatorConfig::new)); + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + ActivatorConfig.CODEC.fieldOf("source_pulse").forGetter(Config::pulseBinding) + ).apply(instance, Config::new)); @Override public ToggleLatchActivator create(LogicalInput boundInput) { return new ToggleLatchActivator(this.pulseBinding.create(boundInput)); } + + @Override + public ActivatorConfigType type() { + return ActivatorConfigType.TOGGLE_LATCH; + } } } diff --git a/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java b/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java index ee6188fbc..eeacbfeb7 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java +++ b/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java @@ -20,7 +20,7 @@ record Single(Identifier physicalInput) implements LogicalInput { } /// A logical input that triggers only after all modifiers are already pressed. - record Modified(Set modifiers, Identifier trigger) implements LogicalInput { + record ModifiedChord(Set modifiers, Identifier trigger) implements LogicalInput { } } diff --git a/src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java b/src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java index f4041e2cd..8c3a4e871 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java +++ b/src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java @@ -15,10 +15,10 @@ sealed interface InputSignal extends LogicalSignal { LogicalInput input(); } /// When the button is pressed down - record ButtonDown(long timeNanos, LogicalInput input) implements InputSignal {} + record ButtonPress(long timeNanos, LogicalInput input) implements InputSignal {} /// When the button is released - record ButtonUp(long timeNanos, LogicalInput input) implements InputSignal {} + record ButtonRelease(long timeNanos, LogicalInput input) implements InputSignal {} /// When button is pressed and released in quick succession record Tapped(long timeNanos, LogicalInput input) implements InputSignal {} diff --git a/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java b/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java index df4db3c03..2694993d6 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java +++ b/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java @@ -1,17 +1,62 @@ package dev.isxander.controlify.input.logical; +import dev.isxander.controlify.input.physical.PhysicalInputSignal; import dev.isxander.controlify.input.physical.PhysicalSensorSignal; import dev.isxander.controlify.input.physical.PhysicalSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.EventStage; +import net.minecraft.resources.Identifier; -/// The event stage that converts physical signals into logical ones. -/// This stage is responsible for recognizing chords, integrating sensor data, and emitting logical signals. +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/// Converts physical inputs into single inputs and arbitrary modifier chords. +/// Each trigger uses the most recently pressed button still held as its sole +/// modifier. The chord keeps that modifier until either button is released, +/// and follows the same gesture lifecycle as a single button. +/// +/// Button gestures use event timestamps, with holds emitted once on a tick. +/// Call {@link #onGuiNavigate()} when GUI navigation consumes a pending press. +/// Sensor integration is delegated to {@link SensorAccumulatorStage}. public class PhysicalToLogicalStage implements EventStage { + public static final long DEFAULT_TAP_MAX_NANOS = 200_000_000L; + public static final long DEFAULT_DOUBLE_TAP_MAX_NANOS = 300_000_000L; + public static final long DEFAULT_HOLD_NANOS = 500_000_000L; + private final SensorAccumulatorStage sensorAccumulatorStage; + private final long tapMaxNanos, doubleTapMaxNanos, holdNanos; + + // Press order lets an older held button become the latest modifier again when a newer one is released. + private final LinkedHashSet pressedButtons = new LinkedHashSet<>(); + private final Map activeButtons = new LinkedHashMap<>(); + private final Map lastTaps = new HashMap<>(); + private final Map axisValues = new HashMap<>(); public PhysicalToLogicalStage(SensorAccumulatorStage sensorAccumulatorStage) { - this.sensorAccumulatorStage = sensorAccumulatorStage; + this(sensorAccumulatorStage, DEFAULT_TAP_MAX_NANOS, + DEFAULT_DOUBLE_TAP_MAX_NANOS, DEFAULT_HOLD_NANOS); + } + + public PhysicalToLogicalStage( + SensorAccumulatorStage sensorAccumulatorStage, + long tapMaxNanos, long doubleTapMaxNanos, long holdNanos + ) { + this.sensorAccumulatorStage = Objects.requireNonNull(sensorAccumulatorStage); + if (tapMaxNanos < 0 || doubleTapMaxNanos < 0 || holdNanos <= tapMaxNanos) { + throw new IllegalArgumentException("Gesture durations must be nonnegative and hold must exceed tap"); + } + this.tapMaxNanos = tapMaxNanos; + this.doubleTapMaxNanos = doubleTapMaxNanos; + this.holdNanos = holdNanos; + } + + /// Cancels GUI presses for buttons already held; subsequent presses remain eligible. + public void onGuiNavigate() { + this.activeButtons.values().forEach(state -> state.guiPressEligible = false); } @Override @@ -19,12 +64,110 @@ public void onEvent(PhysicalSignal event, EventSink downs switch (event) { case PhysicalSignal.Tick(long timeNanos, long deltaTimeNanos) -> { this.sensorAccumulatorStage.onEvent(event, downstream); - + // Holds must fire even without new input events, before downstream actions process this frame's tick. + this.activeButtons.forEach((input, state) -> { + if (!state.held && timeNanos - state.pressedAt >= this.holdNanos) { + state.held = true; + downstream.accept(new LogicalSignal.Held(timeNanos, input)); + } + }); + this.lastTaps.values().removeIf(time -> timeNanos - time > this.doubleTapMaxNanos); downstream.accept(new LogicalSignal.Tick(timeNanos, deltaTimeNanos)); } - case PhysicalSensorSignal sensorSignal -> this.sensorAccumulatorStage.onEvent(sensorSignal, downstream); + case PhysicalInputSignal.ButtonChanged(long timeNanos, Identifier input, boolean state) -> + this.onButton(timeNanos, input, state, downstream); + case PhysicalInputSignal.AxisMoved(long timeNanos, Identifier input, float value) -> + this.onAxis(timeNanos, input, value, downstream); + } + } + + private void onButton(long time, Identifier input, boolean pressed, EventSink downstream) { + if (this.pressedButtons.contains(input) == pressed) { + // Duplicate edges must not restart gesture timers or change modifier priority. + return; + } + var single = new LogicalInput.Single(input); + if (pressed) { + // Only buttons held before this press can modify it; adding the trigger first would select itself. + LogicalInput.ModifiedChord chord = this.recogniseChord(input); + this.press(time, single, downstream); + if (chord != null) { + this.press(time, chord, downstream); + } + this.pressedButtons.add(input); + } else { + this.pressedButtons.remove(input); + this.release(time, single, downstream); + // Use the chords captured on press, so later presses cannot change which chord gets released. + // Snapshot because releasing a chord removes it from activeButtons. + for (var logicalInput : this.activeButtons.keySet().stream().toList()) { + if (logicalInput instanceof LogicalInput.ModifiedChord chord + && (chord.trigger().equals(input) || chord.modifiers().contains(input))) { + this.release(time, chord, downstream); + } + } + } + } + + private void press(long time, LogicalInput input, EventSink downstream) { + this.activeButtons.put(input, new ButtonState(time)); + downstream.accept(new LogicalSignal.ButtonPress(time, input)); + } + + private void release(long time, LogicalInput input, EventSink downstream) { + ButtonState state = this.activeButtons.remove(input); + if (state == null) { + return; + } + downstream.accept(new LogicalSignal.ButtonRelease(time, input)); + long duration = time - state.pressedAt; + if (!state.held && duration >= 0 && duration <= this.tapMaxNanos) { + downstream.accept(new LogicalSignal.Tapped(time, input)); + // Consume the first tap so three quick taps form one double tap, rather than overlapping pairs. + Long previousTap = this.lastTaps.remove(input); + if (previousTap != null && time >= previousTap && time - previousTap <= this.doubleTapMaxNanos) { + downstream.accept(new LogicalSignal.DoubleTapped(time, input)); + } else { + this.lastTaps.put(input, time); + } + } else { + this.lastTaps.remove(input); + } + if (state.guiPressEligible && duration >= 0) { + downstream.accept(new LogicalSignal.GuiPress(time, input)); + } + } + + private void onAxis(long time, Identifier input, float value, EventSink downstream) { + // Domain expansion supplies button edges for axis gestures; raw values only need continuous deltas here. + float previous = this.axisValues.getOrDefault(input, 0.0f); + if (value == previous) { + return; + } + if (value == 0.0f) { + this.axisValues.remove(input); + } else { + this.axisValues.put(input, value); + } + downstream.accept(new LogicalSignal.AxisMoved(time, new LogicalInput.Single(input), value, value - previous)); + } + + private LogicalInput.ModifiedChord recogniseChord(Identifier trigger) { + if (!this.pressedButtons.isEmpty()) { + return new LogicalInput.ModifiedChord(Set.of(this.pressedButtons.getLast()), trigger); + } + return null; + } + + private static final class ButtonState { + private final long pressedAt; + private boolean held; + private boolean guiPressEligible = true; + + private ButtonState(long pressedAt) { + this.pressedAt = pressedAt; } } } diff --git a/src/main/java/dev/isxander/controlify/input/physical/GestureInputs.java b/src/main/java/dev/isxander/controlify/input/physical/GestureInputs.java new file mode 100644 index 000000000..939cb4ba0 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/physical/GestureInputs.java @@ -0,0 +1,12 @@ +package dev.isxander.controlify.input.physical; + +import dev.isxander.controlify.utils.CUtil; +import net.minecraft.resources.Identifier; + +public final class GestureInputs { + + private GestureInputs() { + } + + public static final Identifier SHAKE = CUtil.rl("gesture/shake"); +} diff --git a/src/main/java/dev/isxander/controlify/input/physical/GestureRecogniserStage.java b/src/main/java/dev/isxander/controlify/input/physical/GestureRecogniserStage.java new file mode 100644 index 000000000..36b9c320f --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/physical/GestureRecogniserStage.java @@ -0,0 +1,15 @@ +package dev.isxander.controlify.input.physical; + +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.UnaryEventStage; + +/// Processes sensor data and recognizes distinct gestures such as shaking of the controller. +/// This stage then emits {@link dev.isxander.controlify.input.physical.PhysicalInputSignal.ButtonChanged} events +/// for when the gesture begins and ends using input identifiers from {@link GestureInputs}. +public class GestureRecogniserStage implements UnaryEventStage { + @Override + public void onEvent(PhysicalSignal event, EventSink downstream) { + // TODO + downstream.accept(event); + } +} From b1438518043c3fae4dac3d7f02af78f5f3a12c70 Mon Sep 17 00:00:00 2001 From: isxander Date: Sun, 11 Oct 2026 23:38:19 +0100 Subject: [PATCH 03/12] flesh out the pipeline and start wiring things up --- .../dev/isxander/controlify/Controlify.java | 40 ++-- .../bindings/InputBindingBuilderImpl.java | 2 +- .../bindings/RadialIconManager.java | 6 +- .../defaults/DefaultBindProvider.java | 4 +- .../defaults/LayeredDefaultBindProvider.java | 6 +- .../MapBackedDefaultBindProvider.java | 10 +- .../config/dto/profile/InputConfig.java | 6 +- .../settings/profile/InputSettings.java | 6 +- .../controlify/gui/screen/RadialItems.java | 6 +- .../gui/screen/RadialMenuEditScreen.java | 4 +- .../controlify/input/InputComponent.java | 173 ++++++++++++++++++ .../controlify/input/InputPipeline.java | 87 +++++++++ .../controlify/input/action/Action.java | 4 - .../input/action/ActionAccessor.java | 2 +- .../input/action/ActionAccessorImpl.java | 12 ++ .../input/action/ActionContext.java | 11 ++ .../controlify/input/action/ActionGraph.java | 58 +++++- .../controlify/input/action/ActionImpl.java | 43 ++++- .../controlify/input/action/ActionSpec.java | 17 +- .../input/action/ActionSpecBuilder.java | 9 +- .../input/action/ActionSpecBuilderImpl.java | 76 ++++++++ .../input/action/ActionSpecRegistry.java | 2 +- .../input/action/ActionSpecRegistryImpl.java | 42 +++++ .../controlify/input/action/ActionState.java | 6 + .../action/activator/ActivatorConfig.java | 17 +- .../action/activator/ActivatorConfigType.java | 29 ++- .../action/activator/ContinuousActivator.java | 1 - .../activator/DoubleTapPulseActivator.java | 1 - .../activator/GuiPressPulseActivator.java | 1 - .../action/activator/HoldLatchActivator.java | 1 - .../action/activator/HoldPulseActivator.java | 1 - .../action/activator/PressPulseActivator.java | 1 - .../activator/ReleasePulseActivator.java | 1 - .../activator/RepeatLatchPulseActivator.java | 10 +- .../action/activator/TapPulseActivator.java | 1 - .../input/logical/LogicalInput.java | 20 +- .../input/logical/PhysicalToLogicalStage.java | 2 +- .../input/logical/SensorAccumulatorStage.java | 2 +- .../input/physical/DeadzoneStage.java | 15 +- .../physical/InputDomainExpansionStage.java | 9 +- .../input/physical/PhysicalSignal.java | 4 +- .../input/physical/SensorProcessorStage.java | 95 ++++++++++ .../controlify/utils/codec/CExtraCodecs.java | 6 +- .../controlify/utils/event/EventSource.java | 11 ++ .../controlify/utils/event/EventStage.java | 24 ++- .../controlify/utils/event/EventTap.java | 44 +++++ 46 files changed, 832 insertions(+), 96 deletions(-) create mode 100644 src/main/java/dev/isxander/controlify/input/InputComponent.java create mode 100644 src/main/java/dev/isxander/controlify/input/InputPipeline.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionAccessorImpl.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionContext.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilderImpl.java create mode 100644 src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistryImpl.java create mode 100644 src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java create mode 100644 src/main/java/dev/isxander/controlify/utils/event/EventSource.java create mode 100644 src/main/java/dev/isxander/controlify/utils/event/EventTap.java diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index 7b6b59380..dfd09084c 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -40,6 +40,7 @@ import dev.isxander.controlify.gui.screen.*; import dev.isxander.controlify.debug.DebugProperties; import dev.isxander.controlify.ingame.ControllerPlayerMovement; +import dev.isxander.controlify.input.action.activator.ActivatorConfigManager; import dev.isxander.controlify.platform.client.PlatformClientUtil; import dev.isxander.controlify.platform.main.PlatformMainUtil; import dev.isxander.controlify.platform.network.SidedNetworkApi; @@ -93,6 +94,8 @@ public class Controlify implements ControlifyApi { private DefaultConfigManager defaultConfigManager; private ControllerTypeManager controllerTypeManager; private KeyboardLayoutManager keyboardLayoutManager; + private RadialIconManager radialIconManager; + private ActivatorConfigManager activatorConfigManager; private TriggerEffectManager triggerEffectManager; @@ -139,13 +142,16 @@ public void preInitialiseControlify() { this.defaultConfigManager = new DefaultConfigManager(); this.controllerTypeManager = new ControllerTypeManager(); this.keyboardLayoutManager = new KeyboardLayoutManager(); - - PlatformClientUtil.registerAssetReloadListener(inputFontMapper); - PlatformClientUtil.registerAssetReloadListener(defaultBindManager); - PlatformClientUtil.registerAssetReloadListener(defaultConfigManager); - PlatformClientUtil.registerAssetReloadListener(controllerTypeManager); - PlatformClientUtil.registerAssetReloadListener(keyboardLayoutManager); - PlatformClientUtil.registerAssetReloadListener(RadialIconManager.INSTANCE); + this.radialIconManager = new RadialIconManager(); + this.activatorConfigManager = new ActivatorConfigManager(); + + PlatformClientUtil.registerAssetReloadListener(this.inputFontMapper); + PlatformClientUtil.registerAssetReloadListener(this.defaultBindManager); + PlatformClientUtil.registerAssetReloadListener(this.defaultConfigManager); + PlatformClientUtil.registerAssetReloadListener(this.controllerTypeManager); + PlatformClientUtil.registerAssetReloadListener(this.keyboardLayoutManager); + PlatformClientUtil.registerAssetReloadListener(this.radialIconManager); + PlatformClientUtil.registerAssetReloadListener(this.activatorConfigManager); PlatformClientUtil.registerAssetReloadListener(RuleSetManager.GUIDE_RULES); PlatformClientUtil.registerAssetReloadListener(RuleSetManager.TRIGGER_EFFECT_RULES); ContextualDomains.touch(); @@ -756,27 +762,35 @@ private void restoreVirtualCursor() { } public InputFontMapper inputFontMapper() { - return inputFontMapper; + return this.inputFontMapper; } public DefaultBindManager defaultBindManager() { - return defaultBindManager; + return this.defaultBindManager; } public DefaultConfigManager defaultConfigManager() { - return defaultConfigManager; + return this.defaultConfigManager; } public ControllerTypeManager controllerTypeManager() { - return controllerTypeManager; + return this.controllerTypeManager; } public KeyboardLayoutManager keyboardLayoutManager() { - return keyboardLayoutManager; + return this.keyboardLayoutManager; + } + + public RadialIconManager radialIconManager() { + return this.radialIconManager; + } + + public ActivatorConfigManager activatorConfigManager() { + return this.activatorConfigManager; } public TriggerEffectManager triggerEffectManager() { - return triggerEffectManager; + return this.triggerEffectManager; } public Set thisTickBindContexts() { diff --git a/src/main/java/dev/isxander/controlify/bindings/InputBindingBuilderImpl.java b/src/main/java/dev/isxander/controlify/bindings/InputBindingBuilderImpl.java index e4f9c7634..063f68487 100644 --- a/src/main/java/dev/isxander/controlify/bindings/InputBindingBuilderImpl.java +++ b/src/main/java/dev/isxander/controlify/bindings/InputBindingBuilderImpl.java @@ -145,7 +145,7 @@ public InputBindingImpl build(@Nullable ControllerEntity controller) { controllerType ); - Input input = provider.getDefaultBind(id); + Input input = provider.getDefaultInput(id); if (input == null) input = defaultInput; if (input == null) input = EmptyInput.INSTANCE; diff --git a/src/main/java/dev/isxander/controlify/bindings/RadialIconManager.java b/src/main/java/dev/isxander/controlify/bindings/RadialIconManager.java index 62537bac9..d6e86dda1 100644 --- a/src/main/java/dev/isxander/controlify/bindings/RadialIconManager.java +++ b/src/main/java/dev/isxander/controlify/bindings/RadialIconManager.java @@ -25,8 +25,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -public final class RadialIconManager implements SimpleControlifyReloadListener> { - public static final RadialIconManager INSTANCE = new RadialIconManager(); +public class RadialIconManager implements SimpleControlifyReloadListener> { public static final Identifier EMPTY = CUtil.rl("empty"); private static final Identifier DEFINITIONS = CUtil.rl("radial_icons.json"); @@ -82,7 +81,4 @@ public CompletableFuture apply(Map data, ResourceM public Identifier getReloadId() { return CUtil.rl("radial_icons"); } - - private RadialIconManager() { - } } diff --git a/src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindProvider.java b/src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindProvider.java index ff97f57a7..dfcb82a0a 100644 --- a/src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindProvider.java +++ b/src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindProvider.java @@ -6,12 +6,12 @@ */ package dev.isxander.controlify.bindings.defaults; -import dev.isxander.controlify.bindings.input.Input; +import dev.isxander.controlify.input.logical.LogicalInput; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; public interface DefaultBindProvider { - @Nullable Input getDefaultBind(Identifier bindId); + @Nullable LogicalInput getDefaultInput(Identifier actionId); DefaultBindProvider EMPTY = bind -> null; } diff --git a/src/main/java/dev/isxander/controlify/bindings/defaults/LayeredDefaultBindProvider.java b/src/main/java/dev/isxander/controlify/bindings/defaults/LayeredDefaultBindProvider.java index 9271dbd06..3ee8345f1 100644 --- a/src/main/java/dev/isxander/controlify/bindings/defaults/LayeredDefaultBindProvider.java +++ b/src/main/java/dev/isxander/controlify/bindings/defaults/LayeredDefaultBindProvider.java @@ -8,7 +8,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.bindings.input.Input; +import dev.isxander.controlify.input.logical.LogicalInput; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; @@ -24,9 +24,9 @@ public static DefaultBindProvider of(Layer... layers) { } @Override - @Nullable public Input getDefaultBind(Identifier bindId) { + @Nullable public LogicalInput getDefaultInput(Identifier actionId) { for (var layer : layers()) { - Input input = layer.provider().getDefaultBind(bindId); + var input = layer.provider().getDefaultInput(actionId); if (input != null) return input; if (layer.clearBelow()) return null; } diff --git a/src/main/java/dev/isxander/controlify/bindings/defaults/MapBackedDefaultBindProvider.java b/src/main/java/dev/isxander/controlify/bindings/defaults/MapBackedDefaultBindProvider.java index 229c59cde..238aff79d 100644 --- a/src/main/java/dev/isxander/controlify/bindings/defaults/MapBackedDefaultBindProvider.java +++ b/src/main/java/dev/isxander/controlify/bindings/defaults/MapBackedDefaultBindProvider.java @@ -10,20 +10,20 @@ import com.mojang.serialization.Keyable; import com.mojang.serialization.MapCodec; import dev.isxander.controlify.api.bind.ControlifyBindApi; -import dev.isxander.controlify.bindings.input.Input; +import dev.isxander.controlify.input.logical.LogicalInput; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; import java.util.Map; -public record MapBackedDefaultBindProvider(Map map) implements DefaultBindProvider { +public record MapBackedDefaultBindProvider(Map map) implements DefaultBindProvider { public static final MapCodec MAP_CODEC = Codec.simpleMap( - Identifier.CODEC, Input.CODEC, + Identifier.CODEC, LogicalInput.CODEC, Keyable.forStrings(() -> ControlifyBindApi.get().getAllBindIds().map(Identifier::toString)) ).xmap(MapBackedDefaultBindProvider::new, MapBackedDefaultBindProvider::map); @Override - public @Nullable Input getDefaultBind(Identifier bindId) { - return map.get(bindId); + public @Nullable LogicalInput getDefaultInput(Identifier actionId) { + return map.get(actionId); } } diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java b/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java index dfab3b6ea..fb5fd7e32 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java +++ b/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java @@ -8,8 +8,8 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.bindings.input.Input; import dev.isxander.controlify.ingame.InputCurves; +import dev.isxander.controlify.input.logical.LogicalInput; import net.minecraft.resources.Identifier; import java.util.List; @@ -31,11 +31,11 @@ public record InputConfig( ).apply(instance, InputConfig::new)); public record BindingsConfig( - Map bindings + Map bindings ) { public static final BindingsConfig EMPTY = new BindingsConfig(Map.of()); - public static final Codec CODEC = Codec.unboundedMap(Identifier.CODEC, Input.CODEC) + public static final Codec CODEC = Codec.unboundedMap(Identifier.CODEC, LogicalInput.CODEC) .xmap(BindingsConfig::new, BindingsConfig::bindings); public BindingsConfig { diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java b/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java index cf91cf920..c113f89ea 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java +++ b/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.config.settings.profile; -import dev.isxander.controlify.bindings.input.Input; import dev.isxander.controlify.config.dto.profile.InputConfig; import dev.isxander.controlify.ingame.InputCurves; +import dev.isxander.controlify.input.logical.LogicalInput; import net.minecraft.resources.Identifier; import java.util.HashMap; @@ -59,9 +59,9 @@ public InputConfig toDTO() { } public static class BindingsSettings { - public Map bindings; + public Map bindings; - public BindingsSettings(Map bindings) { + public BindingsSettings(Map bindings) { this.bindings = new HashMap<>(bindings); } diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java b/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java index 2436f1db5..477c5d82b 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java @@ -6,6 +6,7 @@ */ package dev.isxander.controlify.gui.screen; +import dev.isxander.controlify.Controlify; import dev.isxander.controlify.api.bind.InputBinding; import dev.isxander.controlify.api.bind.InputBindingSupplier; import dev.isxander.controlify.api.bind.RadialIcon; @@ -181,15 +182,16 @@ private static RadialIcon getIconForItem(ItemStack stack) { private static RadialMenuScreen.RadialItem getItemForBinding(Identifier id, ControllerEntity controller) { InputBinding binding = controller.input().orElseThrow().getBinding(id); + RadialIconManager radialIconManager = Controlify.instance().radialIconManager(); - if (binding == null || !RadialIconManager.INSTANCE.isRadialCandidate(binding)) { + if (binding == null || !radialIconManager.isRadialCandidate(binding)) { CUtil.LOGGER.warn("Binding {} does not exist or is not a radial candidate", binding); return EMPTY_ACTION; } return new RadialItemRecord( binding.name(), - RadialIconManager.INSTANCE.getIcon(binding), + radialIconManager.getIcon(binding), () -> { binding.fakePress(); return true; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java b/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java index bca14447d..ab306dfcc 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java @@ -82,7 +82,7 @@ public RadialMenuEditScreen(Screen parent, ControllerEntity controller) { this.controller = controller; this.model = new RadialMenuEditModel(controller.settings().input.radialMenu.radialActions); this.candidates = controller.input().orElseThrow().getAllBindings().stream() - .filter(RadialIconManager.INSTANCE::isRadialCandidate) + .filter(Controlify.instance().radialIconManager()::isRadialCandidate) .toList(); this.candidatesById = candidates.stream().collect(Collectors.toMap( InputBinding::id, @@ -548,7 +548,7 @@ private ActionEntry(Identifier id, Component name, boolean equipped, int positio InputBinding binding = candidatesById.get(id); this.icon = binding == null ? RadialIcon.EMPTY - : RadialIconManager.INSTANCE.getIcon(binding); + : Controlify.instance().radialIconManager().getIcon(binding); } @Override diff --git a/src/main/java/dev/isxander/controlify/input/InputComponent.java b/src/main/java/dev/isxander/controlify/input/InputComponent.java new file mode 100644 index 000000000..9fe15db21 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/InputComponent.java @@ -0,0 +1,173 @@ +package dev.isxander.controlify.input; + +import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.bindings.defaults.DefaultBindProvider; +import dev.isxander.controlify.config.settings.device.DeviceSettings; +import dev.isxander.controlify.config.settings.profile.InputSettings; +import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.controller.impl.ECSComponentImpl; +import dev.isxander.controlify.controller.input.DeadzoneGroup; +import dev.isxander.controlify.input.action.ActionGraph; +import dev.isxander.controlify.input.action.ActionImpl; +import dev.isxander.controlify.input.action.ActionSpec; +import dev.isxander.controlify.input.action.ActionSpecRegistryImpl; +import dev.isxander.controlify.input.action.activator.ActivatorConfig; +import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.physical.SensorProcessorStage; +import dev.isxander.controlify.utils.CUtil; +import net.minecraft.resources.Identifier; +import net.minecraft.util.Util; +import org.jspecify.annotations.Nullable; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class InputComponent extends ECSComponentImpl { + public static final Identifier ID = CUtil.rl("input"); + + private final Identifier controllerType; + private DeviceSettings deviceSettings; + + private final InputPipeline inputPipeline; + private final ActionGraph actionGraph; + + private final Map actions; + + private final Set physicalButtons, physicalAxes; + private final Map deadzoneGroups; + private final boolean isGamepad; + private final Set supportedSensors; + + public InputComponent( + Identifier controllerType, + InputPipeline inputPipeline, + Set physicalButtons, + Set physicalAxes, + Set deadzoneGroups, + boolean isGamepad, + Set supportedSensors + ) { + this.controllerType = controllerType; + this.inputPipeline = inputPipeline; + + this.physicalButtons = Set.copyOf(physicalButtons); + this.physicalAxes = Set.copyOf(physicalAxes); + this.deadzoneGroups = deadzoneGroups.stream() + .flatMap(g -> g.axes().stream().map(a -> Map.entry(a, g))) + .collect(Util.toMap()); + this.isGamepad = isGamepad; + this.supportedSensors = Set.copyOf(supportedSensors); + + this.actionGraph = new ActionGraph(); + this.actions = new LinkedHashMap<>(); + } + + @Override + public void attach(ControllerEntity controller) { + super.attach(controller); + + this.deviceSettings = Controlify.instance().config().getSettings() + .getOrCreateDeviceSettings(controller.uid()); + + // we need to wait for settings to load before getting current binding + this.reloadActions(); + + this.inputPipeline.sourceLogicalSignals().subscribe(this.actionGraph); + this.inputPipeline.stageDeadzone().setDeadzoneSupplier(axis -> { + DeadzoneGroup group = this.deadzoneGroups.get(axis); + if (group == null) { + return 0f; + } + return this.controller().settings().input.sensitivity.getDeadzone(group.name()); + }); + this.inputPipeline.stageSensorProcessor().setProcessors(sensorType -> { + if (sensorType.isGyroscope()) { + return List.of( + new SensorProcessorStage.BiasCorrection(() -> this.deviceSettings.gyroCalibration.offset), + new SensorProcessorStage.LowPassFilter(() -> 15.0) // TODO: make this configurable + ); + } else { + return List.of(); + } + }); + } + + public @Nullable ActionImpl getAction(Identifier actionId) { + return this.actions.get(actionId); + } + + public void reloadActions() { + this.actions.clear(); + this.actionGraph.clearActions(); + + for (ActionSpec spec : ActionSpecRegistryImpl.INSTANCE.getActionSpecs()) { + ActionImpl action = this.createAction(spec); + this.actions.put(spec.id(), action); + this.actionGraph.addAction(action); + } + } + + public void onGuiNavigate() { + this.inputPipeline.stagePhysicalToLogical().onGuiNavigate(); + } + + @Override + public Identifier id() { + return ID; + } + + public InputSettings settings() { + return this.controller().settings().input; + } + + public InputSettings defaultSettings() { + return this.controller().defaultSettings().input; + } + + public boolean isGamepad() { + return this.isGamepad; + } + + public Set physicalButtons() { + return this.physicalButtons; + } + + public Set physicalAxes() { + return this.physicalAxes; + } + + public boolean supportsSensor(SensorType type) { + return this.supportedSensors.contains(type); + } + + public boolean supportsGyro() { + return this.supportedSensors.stream().anyMatch(SensorType::isGyroscope); + } + + public boolean supportsAccelerometer() { + return this.supportedSensors.stream().anyMatch(SensorType::isAccelerometer); + } + + private ActionImpl createAction(ActionSpec spec) { + DefaultBindProvider bindProvider = Controlify.instance().defaultBindManager() + .getDefaultBindProvider(this.controllerType); + LogicalInput defaultBoundInput = bindProvider.getDefaultInput(spec.id()); + + LogicalInput currentBoundInput = settings().bindings.bindings.get(spec.id()); + + ActivatorConfig activatorConfig = Controlify.instance().activatorConfigManager().getConfig(spec.id()); + + ActionImpl action = new ActionImpl( + spec, + currentBoundInput, + defaultBoundInput, + activatorConfig, + this.actionGraph + ); + action.reset(); + + return action; + } +} diff --git a/src/main/java/dev/isxander/controlify/input/InputPipeline.java b/src/main/java/dev/isxander/controlify/input/InputPipeline.java new file mode 100644 index 000000000..faf952ab7 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/InputPipeline.java @@ -0,0 +1,87 @@ +package dev.isxander.controlify.input; + +import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.input.logical.PhysicalToLogicalStage; +import dev.isxander.controlify.input.logical.SensorAccumulatorStage; +import dev.isxander.controlify.input.physical.*; +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.EventSource; +import dev.isxander.controlify.utils.event.EventTap; + +public class InputPipeline implements EventSink { + private final EventTap tapRawPhysicalSignals; + private final SensorProcessorStage stageSensorProcessor; + private final DeadzoneStage stageDeadzone; + private final GestureRecogniserStage stageGestureRecogniser; + private final InputDomainExpansionStage stageInputDomainExpansion; + private final EventTap tapProcessedPhysicalSignals; + + private final SensorAccumulatorStage stageSensorAccumulator; + private final PhysicalToLogicalStage stagePhysicalToLogical; + private final EventTap tapLogicalSignals; + + private final EventSink fullPipeline; + + public InputPipeline() { + this.tapRawPhysicalSignals = new EventTap<>(); + this.stageSensorProcessor = new SensorProcessorStage(); + this.stageDeadzone = new DeadzoneStage(); + this.stageGestureRecogniser = new GestureRecogniserStage(); + this.stageInputDomainExpansion = new InputDomainExpansionStage(0.5f, 0.49f, 1f, 0f); + this.tapProcessedPhysicalSignals = new EventTap<>(); + this.stageSensorAccumulator = new SensorAccumulatorStage(); + this.stagePhysicalToLogical = new PhysicalToLogicalStage(this.stageSensorAccumulator); + this.tapLogicalSignals = new EventTap<>(); + + this.fullPipeline = this.tapRawPhysicalSignals + .andThen(this.stageSensorProcessor) + .andThen(this.stageDeadzone) + .andThen(this.stageGestureRecogniser) + .andThen(this.stageInputDomainExpansion) + .andThen(this.tapProcessedPhysicalSignals) + .andThen(this.stagePhysicalToLogical) + .andThen(this.tapLogicalSignals) + .discardDownstream(); + } + + @Override + public void accept(PhysicalSignal event) { + this.fullPipeline.accept(event); + } + + public EventSource sourceRawPhysicalSignals() { + return this.tapRawPhysicalSignals; + } + + public SensorProcessorStage stageSensorProcessor() { + return this.stageSensorProcessor; + } + + public DeadzoneStage stageDeadzone() { + return this.stageDeadzone; + } + + public GestureRecogniserStage stageGestureRecogniser() { + return this.stageGestureRecogniser; + } + + public InputDomainExpansionStage stageInputDomainExpansion() { + return this.stageInputDomainExpansion; + } + + public EventSource sourceProcessedPhysicalSignals() { + return this.tapProcessedPhysicalSignals; + } + + public SensorAccumulatorStage stageSensorAccumulator() { + return this.stageSensorAccumulator; + } + + public PhysicalToLogicalStage stagePhysicalToLogical() { + return this.stagePhysicalToLogical; + } + + public EventSource sourceLogicalSignals() { + return this.tapLogicalSignals; + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/Action.java b/src/main/java/dev/isxander/controlify/input/action/Action.java index 833d2a6c0..fb6ec58af 100644 --- a/src/main/java/dev/isxander/controlify/input/action/Action.java +++ b/src/main/java/dev/isxander/controlify/input/action/Action.java @@ -1,21 +1,17 @@ package dev.isxander.controlify.input.action; import dev.isxander.controlify.input.logical.LogicalInput; -import net.minecraft.network.chat.Component; import org.jspecify.annotations.Nullable; /// An action is bound to a logical input and has one or more activators /// that determine how its output channels respond to input signals. public interface Action { - ActionSpec spec(); Channel.Pulse pulse(); Channel.Latch latch(); Channel.Continuous continuous(); - Component inputGlyph(); - void setBoundInput(@Nullable LogicalInput input); @Nullable LogicalInput boundInput(); diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java b/src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java index 040ba8eda..366a6575c 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java +++ b/src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java @@ -1,7 +1,7 @@ package dev.isxander.controlify.input.action; import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.input.InputComponent; +import dev.isxander.controlify.input.InputComponent; import net.minecraft.resources.Identifier; import org.jspecify.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionAccessorImpl.java b/src/main/java/dev/isxander/controlify/input/action/ActionAccessorImpl.java new file mode 100644 index 000000000..db1419c9a --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionAccessorImpl.java @@ -0,0 +1,12 @@ +package dev.isxander.controlify.input.action; + +import dev.isxander.controlify.input.InputComponent; +import net.minecraft.resources.Identifier; +import org.jspecify.annotations.Nullable; + +public record ActionAccessorImpl(Identifier actionId) implements ActionAccessor { + @Override + public @Nullable Action onOrNull(InputComponent inputComponent) { + return inputComponent.getAction(this.actionId); + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionContext.java b/src/main/java/dev/isxander/controlify/input/action/ActionContext.java new file mode 100644 index 000000000..477527a15 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionContext.java @@ -0,0 +1,11 @@ +package dev.isxander.controlify.input.action; + +import net.minecraft.resources.Identifier; +import org.jspecify.annotations.NonNull; + +public record ActionContext(Identifier id) implements Comparable { + @Override + public int compareTo(@NonNull ActionContext o) { + return this.id().compareTo(o.id()); + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionGraph.java b/src/main/java/dev/isxander/controlify/input/action/ActionGraph.java index 6afe890fd..4c76b1161 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionGraph.java +++ b/src/main/java/dev/isxander/controlify/input/action/ActionGraph.java @@ -8,6 +8,7 @@ import java.util.*; public class ActionGraph implements EventSink { + // use a sorted set to have deterministic ordering private final Set allActions = new TreeSet<>(); // Context ID -> Logical Input -> set of ActionImpl @@ -16,8 +17,14 @@ public class ActionGraph implements EventSink { // by avoiding the need to iterate over all bindings for each signal private final Map>> graph = new HashMap<>(); + private final Set currentContexts = new TreeSet<>(); + // mutable set to avoid set allocation on every signal + private final Set dispatchCandidates = new TreeSet<>(); + public void addAction(ActionImpl action) { - this.allActions.add(action); + if (!this.allActions.add(action)) { + throw new IllegalArgumentException("This action has already been added"); + } for (var contextId : action.spec().contexts()) { var byInputMap = this.graph.computeIfAbsent(contextId, _ -> new HashMap<>()); byInputMap.computeIfAbsent(action.boundInput(), _ -> new TreeSet<>()) @@ -35,6 +42,33 @@ public void removeAction(ActionImpl action) { this.allActions.remove(action); } + public void clearActions() { + this.allActions.clear(); + this.graph.clear(); + } + + public void onActionBindingChange(ActionImpl action) { + // re-indexes the action in the graph + this.removeAction(action); + this.addAction(action); + } + + public void setCurrentContexts(Set contexts) { + // Reset only actions that lose their last active context. + for (ActionImpl action : this.allActions) { + boolean wasActive = this.currentContexts.stream() + .anyMatch(context -> action.spec().contexts().contains(context.id())); + boolean isActive = contexts.stream() + .anyMatch(context -> action.spec().contexts().contains(context.id())); + if (wasActive && !isActive) { + action.reset(); + } + } + + this.currentContexts.clear(); + this.currentContexts.addAll(contexts); + } + @Override public void accept(LogicalSignal event) { switch (event) { @@ -51,6 +85,28 @@ private void processTick(LogicalSignal.Tick tick) { } private void processInput(LogicalSignal.InputSignal inputSignal) { + this.dispatchCandidates.clear(); + + // collect all actions monitoring this logical input in the current context + // actions in multiple contexts are automatically deduplicated by the set + for (ActionContext context : this.currentContexts) { + Map> byInput = this.graph.get(context.id()); + + if (byInput == null) { + continue; + } + + Set actionSet = byInput.get(inputSignal.input()); + if (actionSet == null) { + continue; + } + + this.dispatchCandidates.addAll(actionSet); + } + + for (ActionImpl action : this.dispatchCandidates) { + action.activator().onSignal(inputSignal, action.state()); + } } } diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionImpl.java b/src/main/java/dev/isxander/controlify/input/action/ActionImpl.java index eed9128a8..317369bc1 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionImpl.java +++ b/src/main/java/dev/isxander/controlify/input/action/ActionImpl.java @@ -14,17 +14,26 @@ public class ActionImpl implements Action, Comparable { private Activator activator; private final ActivatorConfig activatorConfig; + private final ActionGraph actionGraph; + public ActionImpl( ActionSpec spec, @Nullable LogicalInput boundInput, @Nullable LogicalInput defaultInput, - ActivatorConfig activator + ActivatorConfig activator, + ActionGraph actionGraph ) { this.spec = spec; this.defaultInput = defaultInput; this.activatorConfig = activator; - this.setBoundInput(boundInput); this.state = new ActionState(); + this.actionGraph = actionGraph; + this.boundInput = boundInput; + } + + @Override + public ActionSpec spec() { + return this.spec; } @Override @@ -35,9 +44,35 @@ public ActionImpl( @Override public void setBoundInput(@Nullable LogicalInput boundInput) { this.boundInput = boundInput; - this.activator = boundInput != null - ? this.activatorConfig.create(boundInput) + this.reset(); + this.actionGraph.onActionBindingChange(this); + } + + @Override + public @Nullable LogicalInput defaultInput() { + return this.defaultInput; + } + + @Override + public Channel.Pulse pulse() { + return this.state(); + } + + @Override + public Channel.Latch latch() { + return this.state(); + } + + @Override + public Channel.Continuous continuous() { + return this.state(); + } + + public void reset() { + this.activator = this.boundInput() != null + ? this.activatorConfig.create(this.boundInput()) : new NoopActivator(); + this.state.reset(); } public ActionState state() { diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java b/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java index 7da547c3f..44b31a138 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java +++ b/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java @@ -1,22 +1,37 @@ package dev.isxander.controlify.input.action; +import dev.isxander.controlify.controller.ControllerEntity; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; import org.jspecify.annotations.NonNull; import java.util.Comparator; import java.util.Set; +import java.util.function.Predicate; +/// Immutable information about an {@link Action}. +/// @param id the unique identifier for the action +/// @param name the display name for the action +/// @param description the display description for the action +/// @param category the category for the action +/// @param contexts the set of context IDs that this action should work in +/// @param shouldExpose predicate deciding if the action should be visible in the settings and available +/// to bind for the current controller public record ActionSpec( Identifier id, Component name, Component description, Component category, - Set contexts + Set contexts, + Predicate shouldExpose ) implements Comparable { @Override public int compareTo(@NonNull ActionSpec o) { return Comparator.comparing(ActionSpec::id) .compare(this, o); } + + public static ActionSpecBuilder builder() { + return new ActionSpecBuilderImpl(); + } } diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java b/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java index f343f82e8..631bf5290 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java +++ b/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java @@ -1,20 +1,23 @@ package dev.isxander.controlify.input.action; +import dev.isxander.controlify.controller.ControllerEntity; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; +import java.util.function.Predicate; + public interface ActionSpecBuilder { ActionSpecBuilder id(Identifier id); ActionSpecBuilder name(Component name); - ActionSpecBuilder description(Component name); + ActionSpecBuilder description(Component description); ActionSpecBuilder category(Component category); ActionSpecBuilder context(Identifier... contexts); - ActionSpec build(); + ActionSpecBuilder shouldExpose(Predicate predicate); - ActionAccessor buildAndRegister(ActionSpecRegistry registry); + ActionSpec build(); } diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilderImpl.java b/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilderImpl.java new file mode 100644 index 000000000..e653e1ecb --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilderImpl.java @@ -0,0 +1,76 @@ +package dev.isxander.controlify.input.action; + +import dev.isxander.controlify.controller.ControllerEntity; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import org.apache.commons.lang3.Validate; +import org.jspecify.annotations.Nullable; + +import java.util.*; +import java.util.function.Predicate; + +public class ActionSpecBuilderImpl implements ActionSpecBuilder { + private @Nullable Identifier id; + private @Nullable Component name; + private @Nullable Component description; + private @Nullable Component category; + private final Set contexts = new TreeSet<>(); + private Predicate shouldExpose = _ -> true; + + @Override + public ActionSpecBuilder id(Identifier id) { + this.id = id; + return this; + } + + @Override + public ActionSpecBuilder name(Component name) { + this.name = name; + return this; + } + + @Override + public ActionSpecBuilder description(Component description) { + this.description = description; + return this; + } + + @Override + public ActionSpecBuilder category(Component category) { + this.category = category; + return this; + } + + @Override + public ActionSpecBuilder context(Identifier... contexts) { + this.contexts.addAll(List.of(contexts)); + return this; + } + + @Override + public ActionSpecBuilder shouldExpose(Predicate predicate) { + this.shouldExpose = predicate; + return this; + } + + @Override + public ActionSpec build() { + Validate.notNull(this.id, "An action spec needs an id"); + Validate.notNull(this.category, "An action spec needs a category"); + Validate.isTrue(!this.contexts.isEmpty(), "An action spec needs at least one context"); + + Component name = Optional.ofNullable(this.name) + .orElseGet(() -> Component.translatable(this.id.toLanguageKey("controlify.action"))); + Component description = Optional.ofNullable(this.description) + .orElseGet(() -> Component.translatable(this.id.toLanguageKey("controlify.action", "desc"))); + + return new ActionSpec( + this.id, + name, + description, + this.category, + Collections.unmodifiableSet(this.contexts), + this.shouldExpose + ); + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java b/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java index aa1753630..26101ca60 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java +++ b/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java @@ -1,5 +1,5 @@ package dev.isxander.controlify.input.action; public interface ActionSpecRegistry { - void register(ActionSpec actionSpec); + ActionAccessor register(ActionSpec actionSpec); } diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistryImpl.java b/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistryImpl.java new file mode 100644 index 000000000..ec5104397 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistryImpl.java @@ -0,0 +1,42 @@ +package dev.isxander.controlify.input.action; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ActionSpecRegistryImpl implements ActionSpecRegistry { + public static final ActionSpecRegistryImpl INSTANCE = new ActionSpecRegistryImpl(); + + private final List registeredSpecs = new ArrayList<>(); + + private boolean locked = false; + + @Override + public ActionAccessor register(ActionSpec actionSpec) { + this.checkLocked(false); + this.registeredSpecs.add(actionSpec); + + return new ActionAccessorImpl(actionSpec.id()); + } + + public List getActionSpecs() { + this.checkLocked(true); + return Collections.unmodifiableList(this.registeredSpecs); + } + + public void lock() { + this.locked = true; + } + + private void checkLocked(boolean required) { + if (required) { + if (!this.locked) { + throw new IllegalStateException("Registry must be locked to perform this operation."); + } + } else { + if (this.locked) { + throw new IllegalStateException("Registry must be unlocked to perform this operation."); + } + } + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionState.java b/src/main/java/dev/isxander/controlify/input/action/ActionState.java index 1a248b5e5..159457849 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionState.java +++ b/src/main/java/dev/isxander/controlify/input/action/ActionState.java @@ -43,4 +43,10 @@ public void firePulse() { public void setContinuous(float value) { this.continuousValue = Math.clamp(value, 0f, 1f); } + + public void reset() { + this.pulses = 0; + this.latchActive = false; + this.continuousValue = 0f; + } } diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java index cf4adc412..189aa34a8 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java @@ -1,6 +1,7 @@ package dev.isxander.controlify.input.action.activator; import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; import dev.isxander.controlify.input.action.Activator; import dev.isxander.controlify.input.logical.LogicalInput; import net.minecraft.util.StringRepresentable; @@ -13,6 +14,18 @@ public interface ActivatorConfig { ActivatorConfigType type(); - Codec> CODEC = StringRepresentable.fromValues(() -> ActivatorConfigType.TYPES) - .dispatch("type", ActivatorConfig::type, ActivatorConfigType::mapCodec); + Codec> CODEC = Codec.recursive("ActivatorConfig", self -> { + Codec> typeCodec = StringRepresentable.fromValues(() -> ActivatorConfigType.TYPES); + Codec> fullCodec = typeCodec.dispatch("type", ActivatorConfig::type, ActivatorConfigType::mapCodec); + Codec> shorthandCodec = typeCodec.flatXmap( + type -> type.unitConfig() + .>>map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> "Activator type '" + type.id() + "' requires an object configuration")), + config -> DataResult.success(config.type()) + ); + + // Alternatives are accepted when decoding; encoding always uses the full object form. + return fullCodec.withAlternative(shorthandCodec) + .withAlternative(self.listOf(), CompoundActivator.Config::new); + }); } diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java index 8cae0e58f..4f2bd4809 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java @@ -5,39 +5,50 @@ import net.minecraft.util.StringRepresentable; import org.jetbrains.annotations.NotNull; +import java.util.Optional; + public record ActivatorConfigType>( String id, - MapCodec mapCodec + MapCodec mapCodec, + Optional unitConfig ) implements StringRepresentable { + public ActivatorConfigType(String id, MapCodec mapCodec) { + this(id, mapCodec, Optional.empty()); + } + + public ActivatorConfigType(String id, C unitConfig) { + this(id, MapCodec.unit(unitConfig), Optional.of(unitConfig)); + } + public static final ActivatorConfigType COMPOUND = new ActivatorConfigType<>(CompoundActivator.Config.TYPE_ID, CompoundActivator.Config.MAP_CODEC); public static final ActivatorConfigType CONTINUOUS = - new ActivatorConfigType<>(ContinuousActivator.Config.TYPE_ID, ContinuousActivator.Config.MAP_CODEC); + new ActivatorConfigType<>(ContinuousActivator.Config.TYPE_ID, ContinuousActivator.Config.INSTANCE); public static final ActivatorConfigType HOLD_LATCH = - new ActivatorConfigType<>(HoldLatchActivator.Config.TYPE_ID, HoldLatchActivator.Config.MAP_CODEC); + new ActivatorConfigType<>(HoldLatchActivator.Config.TYPE_ID, HoldLatchActivator.Config.INSTANCE); public static final ActivatorConfigType PRESS_PULSE = - new ActivatorConfigType<>(PressPulseActivator.Config.TYPE_ID, PressPulseActivator.Config.MAP_CODEC); + new ActivatorConfigType<>(PressPulseActivator.Config.TYPE_ID, PressPulseActivator.Config.INSTANCE); public static final ActivatorConfigType RELEASE_PULSE = - new ActivatorConfigType<>(ReleasePulseActivator.Config.TYPE_ID, ReleasePulseActivator.Config.MAP_CODEC); + new ActivatorConfigType<>(ReleasePulseActivator.Config.TYPE_ID, ReleasePulseActivator.Config.INSTANCE); public static final ActivatorConfigType REPEAT_LATCH_PULSE = new ActivatorConfigType<>(RepeatLatchPulseActivator.Config.TYPE_ID, RepeatLatchPulseActivator.Config.MAP_CODEC); public static final ActivatorConfigType TAP_PULSE = - new ActivatorConfigType<>(TapPulseActivator.Config.TYPE_ID, TapPulseActivator.Config.MAP_CODEC); + new ActivatorConfigType<>(TapPulseActivator.Config.TYPE_ID, TapPulseActivator.Config.INSTANCE); public static final ActivatorConfigType DOUBLE_TAP_PULSE = - new ActivatorConfigType<>(DoubleTapPulseActivator.Config.TYPE_ID, DoubleTapPulseActivator.Config.MAP_CODEC); + new ActivatorConfigType<>(DoubleTapPulseActivator.Config.TYPE_ID, DoubleTapPulseActivator.Config.INSTANCE); public static final ActivatorConfigType GUI_PRESS_PULSE = - new ActivatorConfigType<>(GuiPressPulseActivator.Config.TYPE_ID, GuiPressPulseActivator.Config.MAP_CODEC); + new ActivatorConfigType<>(GuiPressPulseActivator.Config.TYPE_ID, GuiPressPulseActivator.Config.INSTANCE); public static final ActivatorConfigType HOLD_PULSE = - new ActivatorConfigType<>(HoldPulseActivator.Config.TYPE_ID, HoldPulseActivator.Config.MAP_CODEC); + new ActivatorConfigType<>(HoldPulseActivator.Config.TYPE_ID, HoldPulseActivator.Config.INSTANCE); public static final ActivatorConfigType TOGGLE_LATCH = new ActivatorConfigType<>(ToggleLatchActivator.Config.TYPE_ID, ToggleLatchActivator.Config.MAP_CODEC); diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java index 31d67366d..503e71b17 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java @@ -22,7 +22,6 @@ public String describe() { public record Config() implements ActivatorConfig { public static final String TYPE_ID = "continuous"; public static final Config INSTANCE = new Config(); - public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); @Override public ContinuousActivator create(LogicalInput boundInput) { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java index 8d271dad6..6ca8373c0 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java @@ -23,7 +23,6 @@ public String describe() { public record Config() implements ActivatorConfig { public static final String TYPE_ID = "pulse_double_tap"; public static final Config INSTANCE = new Config(); - public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); @Override public DoubleTapPulseActivator create(LogicalInput boundInput) { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java index 9d8fec1af..2760ea5e4 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java @@ -23,7 +23,6 @@ public String describe() { public record Config() implements ActivatorConfig { public static final String TYPE_ID = "pulse_gui_press"; public static final Config INSTANCE = new Config(); - public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); @Override public GuiPressPulseActivator create(LogicalInput boundInput) { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java index 8d7921d7f..3a0954e38 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java @@ -33,7 +33,6 @@ public String describe() { public record Config() implements ActivatorConfig { public static final String TYPE_ID = "latch_hold"; public static final Config INSTANCE = new Config(); - public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); @Override public HoldLatchActivator create(LogicalInput boundInput) { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java index d68f5da45..abeb8a984 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java @@ -23,7 +23,6 @@ public String describe() { public record Config() implements ActivatorConfig { public static final String TYPE_ID = "pulse_hold"; public static final Config INSTANCE = new Config(); - public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); @Override public HoldPulseActivator create(LogicalInput boundInput) { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java index 58f38263c..4f7d6ad03 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java @@ -23,7 +23,6 @@ public String describe() { public record Config() implements ActivatorConfig { public static final String TYPE_ID = "pulse_press"; public static final Config INSTANCE = new Config(); - public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); @Override public PressPulseActivator create(LogicalInput boundInput) { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java index 3199708c0..9e065ab52 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java @@ -23,7 +23,6 @@ public String describe() { public record Config() implements ActivatorConfig { public static final String TYPE_ID = "pulse_release"; public static final Config INSTANCE = new Config(); - public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); @Override public ReleasePulseActivator create(LogicalInput boundInput) { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java index fd37620e8..35a6523c5 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java @@ -77,19 +77,19 @@ public void toggleLatch() { public record Config( ActivatorConfig latchBinding, - int initialDelayTicks, int repeatDelayTicks + int initialDelayMs, int repeatDelayMs ) implements ActivatorConfig { public static final String TYPE_ID = "pulse_repeat_latch"; public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( ActivatorConfig.CODEC.fieldOf("source_latch").forGetter(Config::latchBinding), - Codec.intRange(0, Integer.MAX_VALUE).optionalFieldOf("initial_delay_ticks", 5).forGetter(Config::initialDelayTicks), - Codec.intRange(1, Integer.MAX_VALUE).optionalFieldOf("repeat_delay_ticks", 1).forGetter(Config::repeatDelayTicks) + Codec.intRange(0, Integer.MAX_VALUE).optionalFieldOf("initial_delay_ms", 5).forGetter(Config::initialDelayMs), + Codec.intRange(1, Integer.MAX_VALUE).optionalFieldOf("repeat_delay_ms", 1).forGetter(Config::repeatDelayMs) ).apply(instance, Config::new)); @Override public RepeatLatchPulseActivator create(LogicalInput boundInput) { - long initialDelayNs = this.initialDelayTicks * 50_000_000L; - long repeatDelayNs = this.repeatDelayTicks * 50_000_000L; + long initialDelayNs = this.initialDelayMs * 1_000_000L; + long repeatDelayNs = this.repeatDelayMs * 1_000_000L; return new RepeatLatchPulseActivator(this.latchBinding.create(boundInput), initialDelayNs, repeatDelayNs); } diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java index 11a227aac..ba7c4d377 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java @@ -24,7 +24,6 @@ public String describe() { public record Config() implements ActivatorConfig { public static final String TYPE_ID = "pulse_tap"; public static final Config INSTANCE = new Config(); - public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); @Override public TapPulseActivator create(LogicalInput boundInput) { diff --git a/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java b/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java index eeacbfeb7..7b17ff27b 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java +++ b/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java @@ -1,7 +1,11 @@ package dev.isxander.controlify.input.logical; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.isxander.controlify.utils.codec.CExtraCodecs; import net.minecraft.resources.Identifier; +import java.util.List; import java.util.Set; /// A reference to a logical button, axis, or sensor. @@ -14,13 +18,25 @@ /// like the `A` button or `Left Stick` left, but it may also refer to /// a chord, like `A` + `B`. public sealed interface LogicalInput { + Codec CODEC = CExtraCodecs.fuzzy( + List.of(Single.CODEC, ModifiedChord.CODEC), + input -> switch (input) { + case Single _ -> Single.CODEC; + case ModifiedChord _ -> ModifiedChord.CODEC; + } + ); + /// A logical input with a direct relationship with a physical input. record Single(Identifier physicalInput) implements LogicalInput { - + public static final Codec CODEC = + Identifier.CODEC.xmap(Single::new, Single::physicalInput); } /// A logical input that triggers only after all modifiers are already pressed. record ModifiedChord(Set modifiers, Identifier trigger) implements LogicalInput { - + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + CExtraCodecs.set(Identifier.CODEC).fieldOf("modifiers").forGetter(ModifiedChord::modifiers), + Identifier.CODEC.fieldOf("trigger").forGetter(ModifiedChord::trigger) + ).apply(instance, ModifiedChord::new)); } } diff --git a/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java b/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java index 2694993d6..b83e7ee0f 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java +++ b/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java @@ -62,7 +62,7 @@ public void onGuiNavigate() { @Override public void onEvent(PhysicalSignal event, EventSink downstream) { switch (event) { - case PhysicalSignal.Tick(long timeNanos, long deltaTimeNanos) -> { + case PhysicalSignal.Frame(long timeNanos, long deltaTimeNanos) -> { this.sensorAccumulatorStage.onEvent(event, downstream); // Holds must fire even without new input events, before downstream actions process this frame's tick. this.activeButtons.forEach((input, state) -> { diff --git a/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java b/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java index 279eb1d55..7f5505da5 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java +++ b/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java @@ -21,7 +21,7 @@ public void onEvent( EventSink downstream ) { switch (event) { - case PhysicalSignal.Tick(long timeNanos, _) -> { + case PhysicalSignal.Frame(long timeNanos, _) -> { this.accSensorValues.forEach((sensorType, acc) -> { if (acc.lastNs == -1) { return; diff --git a/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java b/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java index 26f8156f7..a1ef784b5 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java +++ b/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java @@ -12,22 +12,25 @@ /// Applies deadzones to physical axes. // TODO: radial deadzones public class DeadzoneStage implements UnaryEventStage { - private final Function deadzoneSupplier; + private Function deadzoneSupplier; private final Set axisWasZero; - public DeadzoneStage(Function axisToDeadzoneSupplier) { - this.deadzoneSupplier = axisToDeadzoneSupplier; + public DeadzoneStage(Function deadzoneSupplier) { + this.deadzoneSupplier = deadzoneSupplier; this.axisWasZero = new HashSet<>(); } + public DeadzoneStage() { + this(_ -> 0f); + } + @Override public void onEvent(PhysicalSignal event, EventSink downstream) { if (event instanceof PhysicalInputSignal.AxisMoved(long timeNanos, Identifier input, float value)) { float deadzone = this.deadzoneSupplier.apply(input); if (deadzone > 0) { - // TODO: prevent duplicate zeros passing downstream float newValue = ControllerUtils.deadzone(value, deadzone); if (newValue != 0 || this.axisWasZero.add(input)) { @@ -44,4 +47,8 @@ public void onEvent(PhysicalSignal event, EventSink down downstream.accept(event); } + + public void setDeadzoneSupplier(Function deadzoneSupplier) { + this.deadzoneSupplier = deadzoneSupplier; + } } diff --git a/src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java b/src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java index f300ddb9a..d41e478d9 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java +++ b/src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java @@ -10,7 +10,7 @@ /// Expands the domain of physical inputs. /// - Expands button presses and releases into axis moved events. /// - Expands axis moved events into button presses and releases when passing threshold. -public class InputDomainExpansionStage implements UnaryEventStage { +public class InputDomainExpansionStage implements UnaryEventStage { private final Set pressedButtons; private final float actuation, release, pressedValue, releasedValue; @@ -24,17 +24,17 @@ public InputDomainExpansionStage(float actuation, float release, float pressedVa } @Override - public void onEvent(PhysicalInputSignal event, EventSink downstream) { + public void onEvent(PhysicalSignal event, EventSink downstream) { downstream.accept(event); switch (event) { case PhysicalInputSignal.AxisMoved(long timeNanos, Identifier input, float value) -> { if (value >= actuation) { - if (!this.pressedButtons.add(input)) { + if (this.pressedButtons.add(input)) { downstream.accept(new PhysicalInputSignal.ButtonChanged(timeNanos, input, true)); } } else if (value <= release) { - if (!this.pressedButtons.remove(input)) { + if (this.pressedButtons.remove(input)) { downstream.accept(new PhysicalInputSignal.ButtonChanged(timeNanos, input, false)); } } @@ -42,6 +42,7 @@ public void onEvent(PhysicalInputSignal event, EventSink { downstream.accept(new PhysicalInputSignal.AxisMoved(timeNanos, input, state ? pressedValue : releasedValue)); } + default -> {} } } } diff --git a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java index c92946936..f61d23a3c 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java +++ b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java @@ -1,8 +1,8 @@ package dev.isxander.controlify.input.physical; -public sealed interface PhysicalSignal permits PhysicalInputSignal, PhysicalSensorSignal, PhysicalSignal.Tick { +public sealed interface PhysicalSignal permits PhysicalInputSignal, PhysicalSensorSignal, PhysicalSignal.Frame { long timeNanos(); /// Emitted at the end of each polling / every frame. - record Tick(long timeNanos, long deltaTimeNanos) implements PhysicalSignal {} + record Frame(long timeNanos, long deltaTimeNanos) implements PhysicalSignal {} } diff --git a/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java b/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java new file mode 100644 index 000000000..2817f81b2 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java @@ -0,0 +1,95 @@ +package dev.isxander.controlify.input.physical; + +import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.UnaryEventStage; +import org.joml.Vector3f; +import org.joml.Vector3fc; +import org.jspecify.annotations.Nullable; + +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.function.DoubleSupplier; +import java.util.function.Function; +import java.util.function.Supplier; + +public class SensorProcessorStage implements UnaryEventStage { + private final Map> processors; + + public SensorProcessorStage() { + this(_ -> List.of()); + } + + public SensorProcessorStage(Function> processorFactory) { + this.processors = new EnumMap<>(SensorType.class); + this.setProcessors(processorFactory); + } + + public void setProcessors(Function> processorFactory) { + this.processors.clear(); + for (SensorType sensorType : SensorType.values()) { + this.processors.put(sensorType, List.copyOf(processorFactory.apply(sensorType))); + } + } + + @Override + public void onEvent(PhysicalSignal event, EventSink downstream) { + switch (event) { + case PhysicalSensorSignal(long timeNanos, SensorType sensorType, float x, float y, float z) + when !this.processors.get(sensorType).isEmpty() -> { + var data = new Vector3f(x, y, z); + + for (SensorProcessor processor : this.processors.get(sensorType)) { + processor.process(data, timeNanos); + } + + // TODO: port GyroCalibrator here, and do other stuff like low pass + downstream.accept(new PhysicalSensorSignal(timeNanos, sensorType, data.x, data.y, data.z)); + } + default -> downstream.accept(event); + } + } + + public interface SensorProcessor { + void process(Vector3f data, long timeNanos); + } + + public record BiasCorrection(Supplier bias) implements SensorProcessor { + @Override + public void process(Vector3f data, long timeNanos) { + data.sub(this.bias.get()); + } + } + + /// A first-order low-pass filter with a finite, positive cutoff frequency in Hz. + /// Lower frequencies smooth more strongly. The first sample passes through unchanged. + public static class LowPassFilter implements SensorProcessor { + private final DoubleSupplier cutoffHz; + private @Nullable Vector3f previous; + private long previousTimeNanos; + + public LowPassFilter(DoubleSupplier cutoffHz) { + this.cutoffHz = cutoffHz; + } + + @Override + public void process(Vector3f data, long timeNanos) { + if (this.previous == null) { + this.previous = new Vector3f(data); + this.previousTimeNanos = timeNanos; + } else { + long elapsedNanos = timeNanos - this.previousTimeNanos; + if (elapsedNanos > 0) { + // Exponential decay keeps the response consistent across sample rates. + // expm1 preserves precision for very short sample intervals. + double decayPerNano = 2.0 * Math.PI * this.cutoffHz.getAsDouble() * 1e-9; + float blend = (float) -Math.expm1(-elapsedNanos * decayPerNano); + this.previous.lerp(data, blend); + this.previousTimeNanos = timeNanos; + } + data.set(this.previous); + } + } + } +} diff --git a/src/main/java/dev/isxander/controlify/utils/codec/CExtraCodecs.java b/src/main/java/dev/isxander/controlify/utils/codec/CExtraCodecs.java index 1dc3e2128..8b33daf6c 100644 --- a/src/main/java/dev/isxander/controlify/utils/codec/CExtraCodecs.java +++ b/src/main/java/dev/isxander/controlify/utils/codec/CExtraCodecs.java @@ -21,13 +21,15 @@ public final class CExtraCodecs { public static Codec fuzzy( List> codecs, - Function> encoderGetter) { + Function> encoderGetter + ) { return new FuzzyCodec<>(codecs, encoderGetter); } public static MapCodec fuzzyMap( List> codecs, - Function> encoderGetter) { + Function> encoderGetter + ) { return new FuzzyMapCodec<>(codecs, encoderGetter); } diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventSource.java b/src/main/java/dev/isxander/controlify/utils/event/EventSource.java new file mode 100644 index 000000000..69a1d8416 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/utils/event/EventSource.java @@ -0,0 +1,11 @@ +package dev.isxander.controlify.utils.event; + +public interface EventSource { + Subscription subscribe(EventSink listener); + + @FunctionalInterface + interface Subscription extends AutoCloseable { + @Override + void close(); // unsubscribe; no checked exception + } +} diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventStage.java b/src/main/java/dev/isxander/controlify/utils/event/EventStage.java index 086ba51ce..8d9de4c17 100644 --- a/src/main/java/dev/isxander/controlify/utils/event/EventStage.java +++ b/src/main/java/dev/isxander/controlify/utils/event/EventStage.java @@ -4,8 +4,28 @@ public interface EventStage { void onEvent(I event, EventSink downstream); - default EventStage andThen(EventStage next) { - return (event, downstream) -> this.onEvent(event, x -> next.onEvent(x, downstream)); + default EventStage andThen(EventStage next) { + EventStage first = this; + return new EventStage<>() { + @Override + public void onEvent(I event, EventSink downstream) { + first.onEvent(event, x -> next.onEvent(x, downstream)); + } + + @Override + public EventSink bind(EventSink downstream) { + return first.bind(next.bind(downstream)); + } + }; + } + + /// Connects this stage and any composed stages to a fixed downstream sink once. + default EventSink bind(EventSink downstream) { + return event -> this.onEvent(event, downstream); + } + + default EventSink discardDownstream() { + return this.bind(_ -> {}); } static UnaryEventStage identity() { diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventTap.java b/src/main/java/dev/isxander/controlify/utils/event/EventTap.java new file mode 100644 index 000000000..b8658c026 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/utils/event/EventTap.java @@ -0,0 +1,44 @@ +package dev.isxander.controlify.utils.event; + +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; + +/// Notifies listeners synchronously on the emitting thread before forwarding an event. +/// Each emission uses a snapshot of subscriptions; changes made during a callback +/// apply to subsequent emissions. Listener exceptions propagate to the caller. +public class EventTap implements EventSource, UnaryEventStage { + private final CopyOnWriteArrayList listeners = new CopyOnWriteArrayList<>(); + + @Override + public void onEvent(T event, EventSink downstream) { + this.emit(event); + downstream.accept(event); + } + + /// Notifies subscribers without forwarding to another stage. + public void emit(T event) { + for (Registration registration : this.listeners) { + registration.listener.accept(event); + } + } + + @Override + public Subscription subscribe(EventSink listener) { + Registration registration = new Registration(Objects.requireNonNull(listener, "listener")); + this.listeners.add(registration); + return registration; + } + + private final class Registration implements Subscription { + private final EventSink listener; + + private Registration(EventSink listener) { + this.listener = listener; + } + + @Override + public void close() { + EventTap.this.listeners.remove(this); + } + } +} From 006d8e4c4146eecd1166352be24ed52a6fd21f2e Mon Sep 17 00:00:00 2001 From: isxander Date: Mon, 12 Oct 2026 16:06:36 +0100 Subject: [PATCH 04/12] forgot to git add --- .../activator/ActivatorConfigManager.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigManager.java diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigManager.java b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigManager.java new file mode 100644 index 000000000..d19a8dee2 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigManager.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.input.action.activator; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; +import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.input.InputComponent; +import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.utils.CUtil; +import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; + +import java.io.BufferedReader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +public class ActivatorConfigManager implements SimpleControlifyReloadListener>> { + private static final Identifier DEFINITIONS = CUtil.rl("activators.json"); + private static final Codec>> CODEC = Codec.unboundedMap(Identifier.CODEC, ActivatorConfig.CODEC); + private static final ActivatorConfig FALLBACK = new CompoundActivator.Config(List.of()); + + private volatile Map> configsByAction = Map.of(); + + public ActivatorConfig getConfig(Identifier actionId) { + return configsByAction.getOrDefault(actionId, FALLBACK); + } + + @Override + public CompletableFuture>> load(ResourceManager manager, Executor executor) { + return CompletableFuture.supplyAsync(() -> { + Map> mappings = new HashMap<>(); + + // Resource stacks are returned from lowest to highest priority, so later + // packs overwrite individual actions from earlier packs. + for (Resource resource : manager.getResourceStack(DEFINITIONS)) { + try (BufferedReader reader = resource.openAsReader()) { + JsonElement json = JsonParser.parseReader(reader); + CODEC.parse(JsonOps.INSTANCE, json) + .resultOrPartial(error -> CUtil.LOGGER.error( + "Failed to parse activator configs from pack '{}': {}", + resource.sourcePackId(), + error + )) + .ifPresent(mappings::putAll); + } catch (Exception e) { + CUtil.LOGGER.error("Failed to load activator configs from pack '{}'", resource.sourcePackId(), e); + } + } + + return Map.copyOf(mappings); + }, executor); + } + + @Override + public CompletableFuture apply(Map> data, ResourceManager manager, Executor executor) { + return CompletableFuture.runAsync(() -> { + configsByAction = data; + Controlify.instance().getControllerManager().ifPresent(controllerManager -> { + for (var controller : controllerManager.getConnectedControllers()) { + // TODO + if (controller.getAllComponents().get(InputComponent.ID) instanceof InputComponent input) { + input.reloadActions(); + } + } + }); + }, executor); + } + + @Override + public Identifier getReloadId() { + return CUtil.rl("activators"); + } +} From d1286ce653db367ad4cc7be14ab06540a77947d8 Mon Sep 17 00:00:00 2001 From: isxander Date: Mon, 12 Oct 2026 16:39:35 +0100 Subject: [PATCH 05/12] allow gyro low pass cutoff hz to be configured --- .../config/dto/dfu/ControlifyDataFixer.java | 20 +++++----- .../config/dto/dfu/ControlifySchemas.java | 6 +++ .../config/dto/dfu/fixes/GyroLowPassFix.java | 37 +++++++++++++++++++ .../config/dto/profile/GyroConfig.java | 12 +++++- .../config/settings/profile/GyroSettings.java | 11 ++++-- .../controlify/input/InputComponent.java | 4 +- .../input/physical/SensorProcessorStage.java | 8 +++- 7 files changed, 79 insertions(+), 19 deletions(-) create mode 100644 src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GyroLowPassFix.java diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyDataFixer.java b/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyDataFixer.java index f67b2f46d..f10e97d35 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyDataFixer.java +++ b/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyDataFixer.java @@ -13,7 +13,7 @@ import dev.isxander.controlify.config.settings.profile.ProfileSettings; public final class ControlifyDataFixer { - public static final int CURRENT_VERSION = 8; + public static final int CURRENT_VERSION = 9; public static DataFixer getFixer() { return ProductionFixerHolder.FIXER; @@ -31,30 +31,30 @@ private static DataFixer createFixer(GlobalSettings globalDefaults, ProfileSetti var builder = new DataFixerBuilder(CURRENT_VERSION); var v0 = builder.addSchema(0, ControlifySchemas.V0::new); - var v1 = builder.addSchema(1, ControlifySchemas.V1::new); - var v2 = builder.addSchema(2, ControlifySchemas.V2::new); - var v3 = builder.addSchema(3, ControlifySchemas.V3::new); - var v6 = builder.addSchema(6, ControlifySchemas.V6::new); - var v7 = builder.addSchema(7, ControlifySchemas.V7::new); - var v8 = builder.addSchema(8, ControlifySchemas.V8::new); - // v1 + var v1 = builder.addSchema(1, ControlifySchemas.V1::new); builder.addFixer(new TheHolyMigrationFix(v1, globalDefaults, profileDefaults)); - // v2 + var v2 = builder.addSchema(2, ControlifySchemas.V2::new); builder.addFixer(new AnalogueMovementWhitelistFix(v2)); builder.addFixer(new HorizontalLookInvertFix(v2)); - // v6 + var v3 = builder.addSchema(3, ControlifySchemas.V3::new); + var v6 = builder.addSchema(6, ControlifySchemas.V6::new); builder.addFixer(new DualsenseConfigFix(v6, profileDefaults)); // v7 + var v7 = builder.addSchema(7, ControlifySchemas.V7::new); builder.addFixer(new GuideGuiScaleFix(v7, profileDefaults)); // v8 + var v8 = builder.addSchema(8, ControlifySchemas.V8::new); builder.addFixer(new GeneratedBindingIdsFix(v8)); builder.addFixer(new RadialMenuActionsFix(v8)); + var v9 = builder.addSchema(9, ControlifySchemas.V9::new); + builder.addFixer(new GyroLowPassFix(v9, profileDefaults)); + return builder.build().fixer(); } diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifySchemas.java b/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifySchemas.java index 173c5b123..3c01b75f4 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifySchemas.java +++ b/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifySchemas.java @@ -88,4 +88,10 @@ public V8(int versionKey, Schema parent) { super(versionKey, parent); } } + + public static class V9 extends Schema { + public V9(int versionKey, Schema parent) { + super(versionKey, parent); + } + } } diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GyroLowPassFix.java b/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GyroLowPassFix.java new file mode 100644 index 000000000..27c2fef8d --- /dev/null +++ b/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GyroLowPassFix.java @@ -0,0 +1,37 @@ +package dev.isxander.controlify.config.dto.dfu.fixes; + +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.DataFix; +import com.mojang.datafixers.TypeRewriteRule; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.serialization.Dynamic; +import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.config.settings.profile.ProfileSettings; + +public class GyroLowPassFix extends DataFix { + private final ProfileSettings profileDefaults; + + public GyroLowPassFix(Schema outputSchema, ProfileSettings profileDefaults) { + super(outputSchema, true); + this.profileDefaults = profileDefaults; + } + + @Override + protected TypeRewriteRule makeRule() { + var profileType = getInputSchema().getType(ControlifyTypeReferences.PROFILE_CONFIG); + + return fixTypeEverywhereTyped( + "Controlify: add gyro low pass hz setting", + profileType, + typed -> typed.update(DSL.remainderFinder(), this::rewriteProfile) + ); + } + + private Dynamic rewriteProfile(Dynamic root) { + var gyro = root.get("gyro").orElseEmptyMap(); + + gyro = gyro.set("low_pass_cutoff_hz", root.createFloat(profileDefaults.gyro.lowPassCutoffHz)); + + return root.set("gyro", gyro); + } +} diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/GyroConfig.java b/src/main/java/dev/isxander/controlify/config/dto/profile/GyroConfig.java index 5c925796e..21682d7c8 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/GyroConfig.java +++ b/src/main/java/dev/isxander/controlify/config/dto/profile/GyroConfig.java @@ -7,6 +7,7 @@ package dev.isxander.controlify.config.dto.profile; import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.isxander.controlify.controller.gyro.GyroButtonMode; import dev.isxander.controlify.controller.gyro.GyroYawMode; @@ -18,7 +19,8 @@ public record GyroConfig( boolean invertYaw, GyroButtonMode buttonMode, GyroYawMode yawMode, - boolean flickStick + boolean flickStick, + float lowPassCutoffHz ) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.FLOAT.fieldOf("look_sensitivity").forGetter(GyroConfig::lookSensitivity), @@ -27,7 +29,13 @@ public record GyroConfig( Codec.BOOL.fieldOf("invert_yaw").forGetter(GyroConfig::invertYaw), GyroButtonMode.CODEC.fieldOf("button_mode").forGetter(GyroConfig::buttonMode), GyroYawMode.CODEC.fieldOf("yaw_mode").forGetter(GyroConfig::yawMode), - Codec.BOOL.fieldOf("flick_stick").forGetter(GyroConfig::flickStick) + Codec.BOOL.fieldOf("flick_stick").forGetter(GyroConfig::flickStick), + Codec.FLOAT + .validate(f -> Float.isFinite(f) && f >= 0 + ? DataResult.success(f) + : DataResult.error(() -> "low pass cutoff hz must be finite and positive")) + .fieldOf("low_pass_cutoff_hz") + .forGetter(GyroConfig::lowPassCutoffHz) ).apply(instance, GyroConfig::new)); } diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/GyroSettings.java b/src/main/java/dev/isxander/controlify/config/settings/profile/GyroSettings.java index 806fd23e0..1a3b669c1 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/GyroSettings.java +++ b/src/main/java/dev/isxander/controlify/config/settings/profile/GyroSettings.java @@ -18,6 +18,7 @@ public class GyroSettings { public GyroButtonMode buttonMode; public GyroYawMode yawMode; public boolean flickStick; + public float lowPassCutoffHz; public GyroSettings( float lookSensitivity, @@ -26,7 +27,8 @@ public GyroSettings( boolean invertYaw, GyroButtonMode buttonMode, GyroYawMode yawMode, - boolean flickStick + boolean flickStick, + float lowPassCutoffHz ) { this.lookSensitivity = lookSensitivity; this.relativeMode = relativeMode; @@ -35,6 +37,7 @@ public GyroSettings( this.buttonMode = buttonMode; this.yawMode = yawMode; this.flickStick = flickStick; + this.lowPassCutoffHz = lowPassCutoffHz; } public static GyroSettings fromDTO(GyroConfig dto) { @@ -45,7 +48,8 @@ public static GyroSettings fromDTO(GyroConfig dto) { dto.invertYaw(), dto.buttonMode(), dto.yawMode(), - dto.flickStick() + dto.flickStick(), + dto.lowPassCutoffHz() ); } @@ -57,7 +61,8 @@ public GyroConfig toDTO() { invertYaw, buttonMode, yawMode, - flickStick + flickStick, + lowPassCutoffHz ); } } diff --git a/src/main/java/dev/isxander/controlify/input/InputComponent.java b/src/main/java/dev/isxander/controlify/input/InputComponent.java index 9fe15db21..817a9885c 100644 --- a/src/main/java/dev/isxander/controlify/input/InputComponent.java +++ b/src/main/java/dev/isxander/controlify/input/InputComponent.java @@ -80,13 +80,13 @@ public void attach(ControllerEntity controller) { if (group == null) { return 0f; } - return this.controller().settings().input.sensitivity.getDeadzone(group.name()); + return settings().sensitivity.getDeadzone(group.name()); }); this.inputPipeline.stageSensorProcessor().setProcessors(sensorType -> { if (sensorType.isGyroscope()) { return List.of( new SensorProcessorStage.BiasCorrection(() -> this.deviceSettings.gyroCalibration.offset), - new SensorProcessorStage.LowPassFilter(() -> 15.0) // TODO: make this configurable + new SensorProcessorStage.LowPassFilter(() -> this.controller().settings().gyro.lowPassCutoffHz) ); } else { return List.of(); diff --git a/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java b/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java index 2817f81b2..6e3e41c4c 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java +++ b/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java @@ -64,6 +64,8 @@ public void process(Vector3f data, long timeNanos) { /// A first-order low-pass filter with a finite, positive cutoff frequency in Hz. /// Lower frequencies smooth more strongly. The first sample passes through unchanged. + /// + /// If the frequency is set to 0, the filter is bypassed. public static class LowPassFilter implements SensorProcessor { private final DoubleSupplier cutoffHz; private @Nullable Vector3f previous; @@ -75,7 +77,9 @@ public LowPassFilter(DoubleSupplier cutoffHz) { @Override public void process(Vector3f data, long timeNanos) { - if (this.previous == null) { + double cutoffHz = this.cutoffHz.getAsDouble(); + + if (cutoffHz == 0 || this.previous == null) { this.previous = new Vector3f(data); this.previousTimeNanos = timeNanos; } else { @@ -83,7 +87,7 @@ public void process(Vector3f data, long timeNanos) { if (elapsedNanos > 0) { // Exponential decay keeps the response consistent across sample rates. // expm1 preserves precision for very short sample intervals. - double decayPerNano = 2.0 * Math.PI * this.cutoffHz.getAsDouble() * 1e-9; + double decayPerNano = 2.0 * Math.PI * cutoffHz * 1e-9; float blend = (float) -Math.expm1(-elapsedNanos * decayPerNano); this.previous.lerp(data, blend); this.previousTimeNanos = timeNanos; From b2df9759c68f4b6250b7ef022c0745f69a3e0e3a Mon Sep 17 00:00:00 2001 From: isxander Date: Mon, 12 Oct 2026 23:43:26 +0100 Subject: [PATCH 06/12] start to wire up the drivers to the new event system; start rewriting controller manager --- .../controller/TestControllerContext.java | 4 +- .../mixin/SDLControllerManagerMixin.java | 3 +- .../controller/ControllerEntity.java | 3 +- .../controlify/controller/ECSComponent.java | 4 + .../controller/info/ControllerInfo.java | 3 +- .../SDLControllerManager.java | 17 -- .../SDLUniqueControllerID.java | 23 ++ .../controllermanager2/ControllerManager.java | 22 ++ .../ControllerManagerBackend.java | 12 ++ .../SDLControllerManagerBackend.java | 167 ++++++++++++++ .../driver/sdl/SDL3GamepadDriver.java | 203 ++++++------------ .../driver/sdl/SDL3JoystickDriver.java | 81 +++---- .../driver/sdl/SDLCommonDriver.java | 115 ++++++---- .../driver/sdl/SDLControllerEvent.java | 192 +++++++++++++++++ .../driver/sdl/SDLControllerEventStage.java | 65 ++++++ .../driver/sdl/SDLInputConversions.java | 133 ++++++++++++ .../driver/sdl/SDLToPhysicalStage.java | 92 ++++++++ .../controlify/input/InputComponent.java | 16 +- .../input/logical/SensorAccumulatorStage.java | 2 +- .../input/physical/PhysicalSensorSignal.java | 10 + .../input/physical/PhysicalSignal.java | 1 + .../input/physical/SensorProcessorStage.java | 8 +- .../controlify/utils/event/EventSource.java | 14 ++ 23 files changed, 929 insertions(+), 261 deletions(-) create mode 100644 src/main/java/dev/isxander/controlify/controllermanager/SDLUniqueControllerID.java create mode 100644 src/main/java/dev/isxander/controlify/controllermanager2/ControllerManager.java create mode 100644 src/main/java/dev/isxander/controlify/controllermanager2/ControllerManagerBackend.java create mode 100644 src/main/java/dev/isxander/controlify/controllermanager2/SDLControllerManagerBackend.java create mode 100644 src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java create mode 100644 src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEventStage.java create mode 100644 src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java create mode 100644 src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java diff --git a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/TestControllerContext.java b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/TestControllerContext.java index 6ebef7144..b4a958cfe 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/TestControllerContext.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/TestControllerContext.java @@ -8,7 +8,7 @@ import dev.isxander.controlify.Controlify; import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controllermanager.SDLControllerManager; +import dev.isxander.controlify.controllermanager.SDLUniqueControllerID; import dev.isxander.controlify.driver.sdl.SDLException; import dev.isxander.controlify.utils.CUtil; import dev.isxander.sdl.Sdl; @@ -48,7 +48,7 @@ public TestControllerContext( public ControllerEntity getControllerEntity() { return Controlify.instance().getControllerManager().orElseThrow() .getConnectedControllers().stream() - .filter(c -> c.info().ucid().equals(new SDLControllerManager.SDLUniqueControllerID(this.joystickId))) + .filter(c -> c.info().ucid().equals(new SDLUniqueControllerID(this.joystickId))) .findAny() .orElseThrow(); } diff --git a/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerMixin.java b/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerMixin.java index fa6ab7d8c..e06af92b4 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerMixin.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerMixin.java @@ -10,6 +10,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.controllermanager.SDLControllerManager; +import dev.isxander.controlify.controllermanager.SDLUniqueControllerID; import dev.isxander.controlify.controllermanager.UniqueControllerID; import dev.isxander.controlify.hid.ControllerHIDInfo; import dev.isxander.controlify.utils.log.ControlifyLogger; @@ -35,7 +36,7 @@ private Optional preventNonVirtual( ControlifyLogger controllerLogger, Operation> original ) { - SdlJoystickId jid = ((SDLControllerManager.SDLUniqueControllerID) ucid).jid(); + SdlJoystickId jid = ((SDLUniqueControllerID) ucid).jid(); if (!sdl.joystick().SDL_IsJoystickVirtual(jid)) { controllerLogger.warn("Suppressing creation of controller as the test environment permits only virtual controllers"); diff --git a/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java b/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java index 412aabcbe..6481592a2 100644 --- a/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java +++ b/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java @@ -17,12 +17,12 @@ import dev.isxander.controlify.controller.led.LEDComponent; import dev.isxander.controlify.controller.gyro.GyroComponent; import dev.isxander.controlify.controller.impl.ECSEntityImpl; -import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.controller.misc.BluetoothDeviceComponent; import dev.isxander.controlify.controller.rumble.RumbleComponent; import dev.isxander.controlify.controller.rumble.TriggerRumbleComponent; import dev.isxander.controlify.controller.touchpad.TouchpadComponent; import dev.isxander.controlify.driver.Driver; +import dev.isxander.controlify.input.InputComponent; import dev.isxander.controlify.utils.log.ControlifyLogger; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Contract; @@ -152,6 +152,7 @@ public void update(boolean outOfFocus) { } public void close() { + this.getAllComponents().values().forEach(ECSComponent::close); this.driver.close(); } diff --git a/src/main/java/dev/isxander/controlify/controller/ECSComponent.java b/src/main/java/dev/isxander/controlify/controller/ECSComponent.java index 38b5b29e7..dd0ee1a4c 100644 --- a/src/main/java/dev/isxander/controlify/controller/ECSComponent.java +++ b/src/main/java/dev/isxander/controlify/controller/ECSComponent.java @@ -14,4 +14,8 @@ public interface ECSComponent { default void attach(ControllerEntity controller) { } + + default void close() { + + } } diff --git a/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java b/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java index d1e3433a1..553dd853a 100644 --- a/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java +++ b/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java @@ -9,8 +9,9 @@ import dev.isxander.controlify.controller.id.ControllerType; import dev.isxander.controlify.controllermanager.UniqueControllerID; import dev.isxander.controlify.hid.HIDDevice; +import dev.isxander.controlify.hid.HIDID; import java.util.Optional; -public record ControllerInfo(UniqueControllerID ucid, ControllerType type, Optional hid) { +public record ControllerInfo(UniqueControllerID ucid, ControllerType type, HIDID hid) { } diff --git a/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerManager.java b/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerManager.java index 7e10dd3d3..280f6a224 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerManager.java +++ b/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerManager.java @@ -28,7 +28,6 @@ import dev.isxander.sdl.*; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceProvider; -import org.jetbrains.annotations.NotNull; import java.io.InputStream; import java.nio.ByteBuffer; @@ -239,20 +238,4 @@ private static Optional fetchTypeFromSDL(Sdl sdl, SdlJoystick return Optional.empty(); } - public record SDLUniqueControllerID(@NotNull SdlJoystickId jid) implements UniqueControllerID { - @Override - public boolean equals(Object obj) { - return obj instanceof SDLUniqueControllerID && ((SDLUniqueControllerID) obj).jid.equals(jid); - } - - @Override - public String toString() { - return "SDL-" + jid.value(); - } - - @Override - public int hashCode() { - return Objects.hash(jid.value()); - } - } } diff --git a/src/main/java/dev/isxander/controlify/controllermanager/SDLUniqueControllerID.java b/src/main/java/dev/isxander/controlify/controllermanager/SDLUniqueControllerID.java new file mode 100644 index 000000000..f888c57ef --- /dev/null +++ b/src/main/java/dev/isxander/controlify/controllermanager/SDLUniqueControllerID.java @@ -0,0 +1,23 @@ +package dev.isxander.controlify.controllermanager; + +import dev.isxander.sdl.SdlJoystickId; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public record SDLUniqueControllerID(@NotNull SdlJoystickId jid) implements UniqueControllerID { + @Override + public boolean equals(Object obj) { + return obj instanceof SDLUniqueControllerID && ((SDLUniqueControllerID) obj).jid.equals(jid); + } + + @Override + public String toString() { + return "SDL-" + jid.value(); + } + + @Override + public int hashCode() { + return Objects.hash(jid.value()); + } +} diff --git a/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManager.java b/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManager.java new file mode 100644 index 000000000..a74a58593 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManager.java @@ -0,0 +1,22 @@ +package dev.isxander.controlify.controllermanager2; + +import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.controller.id.ControllerType; +import dev.isxander.controlify.controllermanager.UniqueControllerID; +import dev.isxander.controlify.hid.HIDID; +import dev.isxander.controlify.utils.log.ControlifyLogger; + +public interface ControllerManager { + boolean canAddController( + UniqueControllerID ucid, + HIDID hidid, + ControllerType controllerType, + ControlifyLogger controllerLogger + ); + + void addController(ControllerEntity controller); + + void removeController(UniqueControllerID controller); + + ControllerType getControllerType(HIDID hidId); +} diff --git a/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManagerBackend.java b/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManagerBackend.java new file mode 100644 index 000000000..78a77c5be --- /dev/null +++ b/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManagerBackend.java @@ -0,0 +1,12 @@ +package dev.isxander.controlify.controllermanager2; + +import dev.isxander.controlify.controller.ControllerEntity; + +public interface ControllerManagerBackend { + + void setup(); + + void pollEvents(); + + void closeController(ControllerEntity controller); +} diff --git a/src/main/java/dev/isxander/controlify/controllermanager2/SDLControllerManagerBackend.java b/src/main/java/dev/isxander/controlify/controllermanager2/SDLControllerManagerBackend.java new file mode 100644 index 000000000..4d3e8ade4 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/controllermanager2/SDLControllerManagerBackend.java @@ -0,0 +1,167 @@ +package dev.isxander.controlify.controllermanager2; + +import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.controller.id.ControllerType; +import dev.isxander.controlify.controller.info.ControllerInfo; +import dev.isxander.controlify.controllermanager.SDLUniqueControllerID; +import dev.isxander.controlify.debug.DebugProperties; +import dev.isxander.controlify.driver.Driver; +import dev.isxander.controlify.driver.sdl.*; +import dev.isxander.controlify.hid.HIDID; +import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.utils.event.EventSource; +import dev.isxander.controlify.utils.event.EventTap; +import dev.isxander.controlify.utils.log.ControlifyLogger; +import dev.isxander.sdl.*; +import net.minecraft.client.Minecraft; +import net.minecraft.server.packs.resources.Resource; + +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.util.Optional; + +public class SDLControllerManagerBackend implements ControllerManagerBackend { + private final Sdl sdl; + private final ControllerManager controllerManager; + private final ControlifyLogger logger; + private final SDLControllerEventStage controllerEventStage; + private final EventTap controllerEventTap; + + private SdlEvent event; + + public SDLControllerManagerBackend(Sdl sdl, ControllerManager controllerManager) { + this.sdl = sdl; + this.controllerManager = controllerManager; + this.logger = CUtil.LOGGER.createSubLogger("SDLControllerManagerBackend"); + this.controllerEventStage = new SDLControllerEventStage(); + this.controllerEventTap = new EventTap<>(); + this.event = new SdlEvent(); + } + + @Override + public void setup() { + this.logger.debugLog("Loading gamepad mappings..."); + + Optional resourceOpt = Minecraft.getInstance().getResourceManager() + .getResource(CUtil.rl("controllers/gamecontrollerdb-sdl3.txt")); + if (resourceOpt.isEmpty()) { + this.logger.error("Failed to find game controller database."); + return; + } + + try (InputStream is = resourceOpt.get().open()) { + byte[] bytes = is.readAllBytes(); + ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bytes.length); + byteBuffer.put(bytes); + byteBuffer.flip(); + + SdlIoStreamHandle stream = null; + try { + stream = this.sdl.ioStream().SDL_IOFromConstMem(byteBuffer); + if (stream.isNull()) throw new IllegalStateException("Failed to open stream"); + + int count = this.sdl.gamepad().SDL_AddGamepadMappingsFromIO(stream, true); + if (count < 0) { + this.logger.error("Failed to load gamepad mappings: {}", this.sdl.error().SDL_GetError()); + } else if (count == 0) { + this.logger.warn("Successfully applied gamepad mappings but none were applied. Unsupported OS?"); + } else { + this.logger.log("Successfully loaded {} gamepad mapping entries!", count); + } + } finally { + if (stream != null) { + this.sdl.ioStream().SDL_CloseIO(stream); + } + } + } catch (Throwable e) { + this.logger.error("Failed to load gamepad mappings", e); + } + } + + @Override + public void pollEvents() { + if (this.event == null) { + this.logger.warn("SDL_Event has somehow been set to null. Recreating..."); + this.event = new SdlEvent(); + } + + while (this.sdl.events().SDL_PollEvent(this.event)) { + this.controllerEventStage.onEvent(this.event, this::onControllerEvent); + } + } + + private void onControllerEvent(SDLControllerEvent event) { + this.controllerEventTap.emit(event); + + switch (event) { + case SDLControllerEvent.JoyDevice(SdlJoystickId which, _, SDLControllerEvent.DeviceEvent.Type eventType) + when eventType == SDLControllerEvent.DeviceEvent.Type.ADDED -> { + var ucid = new SDLUniqueControllerID(which); + + var logger = this.logger.createSubLogger("Controller #" + ucid); + logger.debugLog("New controller detected!"); + + HIDID hidId = this.getJoystickHIDID(which); + ControllerType type = this.controllerManager.getControllerType(hidId); + + if (this.controllerManager.canAddController(ucid, hidId, type, logger)) { + this.createAndAddController(ucid, hidId, type, logger); + } + } + + case SDLControllerEvent.JoyDevice(SdlJoystickId which, _, SDLControllerEvent.DeviceEvent.Type type) + when type == SDLControllerEvent.DeviceEvent.Type.REMOVED -> { + this.controllerManager.removeController(new SDLUniqueControllerID(which)); + } + + default -> {} + } + } + + private void createAndAddController(SDLUniqueControllerID ucid, HIDID hidId, ControllerType type, ControlifyLogger controllerLogger) { + SdlJoystickId jid = ucid.jid(); + controllerLogger.debugLog("Creating controller: {}", jid.value()); + + boolean isGamepad = this.sdl.gamepad().SDL_IsGamepad(jid) && !DebugProperties.FORCE_JOYSTICK; + controllerLogger.debugLog("Controller is gamepad: {}", isGamepad); + + EventSource controllerEventSource = this.controllerEventTap + .filter(event -> event.which().equals(jid)); + + Driver driver; + + if (isGamepad) { + SdlGamepadHandle gamepadHandle = SDLUtil.openGamepad(this.sdl, jid); + driver = new SDL3GamepadDriver(this.sdl, gamepadHandle, controllerEventSource, jid, type, controllerLogger); + } else { + SdlJoystickHandle joystickHandle = SDLUtil.openJoystick(this.sdl, jid); + driver = new SDL3JoystickDriver(this.sdl, joystickHandle, controllerEventSource, jid, type, controllerLogger); + } + + var controllerInfo = new ControllerInfo(ucid, type, hidId); + var controller = new ControllerEntity( + controllerInfo, + driver, + Controlify.instance().config().getActiveProfile(), + ProfileSettings.createDefault(), + controllerLogger + ); + + this.controllerManager.addController(controller); + + } + + @Override + public void closeController(ControllerEntity controller) { + + } + + private HIDID getJoystickHIDID(SdlJoystickId jid) { + int vid = this.sdl.joystick().SDL_GetJoystickVendorForID(jid); + int pid = this.sdl.joystick().SDL_GetJoystickProductForID(jid); + + return new HIDID(vid, pid); + } +} diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java index d9f981cfb..f719323c8 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java @@ -12,125 +12,98 @@ import dev.isxander.controlify.controller.input.GamepadInputs; import dev.isxander.controlify.controller.gyro.GyroState; import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.controller.impl.ControllerStateImpl; -import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.controller.touchpad.Touchpads; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.input.InputComponent; +import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.utils.event.EventSource; import dev.isxander.controlify.utils.log.ControlifyLogger; import dev.isxander.sdl.*; -import org.joml.Vector2f; +import net.minecraft.resources.Identifier; -import java.lang.foreign.MemorySegment; -import java.lang.foreign.ValueLayout; import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.util.ArrayList; -import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; -import static dev.isxander.controlify.utils.CUtil.*; import static dev.isxander.sdl.SdlGamepad.*; public class SDL3GamepadDriver extends SDLCommonDriver { - private static final int GYRO_AXIS_COUNT = 3; - private static final List INPUT_MAPPINGS = List.of( - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.LEFT_STICK_AXIS_RIGHT, SDL_GAMEPAD_AXIS_LEFTX, true), - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.LEFT_STICK_AXIS_LEFT, SDL_GAMEPAD_AXIS_LEFTX, false), - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.LEFT_STICK_AXIS_DOWN, SDL_GAMEPAD_AXIS_LEFTY, true), - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.LEFT_STICK_AXIS_UP, SDL_GAMEPAD_AXIS_LEFTY, false), - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.RIGHT_STICK_AXIS_RIGHT, SDL_GAMEPAD_AXIS_RIGHTX, true), - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.RIGHT_STICK_AXIS_LEFT, SDL_GAMEPAD_AXIS_RIGHTX, false), - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.RIGHT_STICK_AXIS_DOWN, SDL_GAMEPAD_AXIS_RIGHTY, true), - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.RIGHT_STICK_AXIS_UP, SDL_GAMEPAD_AXIS_RIGHTY, false), - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.LEFT_TRIGGER_AXIS, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, true), - new SDLGamepadInputMapping.AxisMapping(GamepadInputs.RIGHT_TRIGGER_AXIS, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, true), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.SOUTH_BUTTON, SDL_GAMEPAD_BUTTON_SOUTH), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.EAST_BUTTON, SDL_GAMEPAD_BUTTON_EAST), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.WEST_BUTTON, SDL_GAMEPAD_BUTTON_WEST), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.NORTH_BUTTON, SDL_GAMEPAD_BUTTON_NORTH), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.LEFT_SHOULDER_BUTTON, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.RIGHT_SHOULDER_BUTTON, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.BACK_BUTTON, SDL_GAMEPAD_BUTTON_BACK), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.START_BUTTON, SDL_GAMEPAD_BUTTON_START), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.GUIDE_BUTTON, SDL_GAMEPAD_BUTTON_GUIDE), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.DPAD_UP_BUTTON, SDL_GAMEPAD_BUTTON_DPAD_UP), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.DPAD_DOWN_BUTTON, SDL_GAMEPAD_BUTTON_DPAD_DOWN), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.DPAD_LEFT_BUTTON, SDL_GAMEPAD_BUTTON_DPAD_LEFT), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.DPAD_RIGHT_BUTTON, SDL_GAMEPAD_BUTTON_DPAD_RIGHT), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.LEFT_STICK_BUTTON, SDL_GAMEPAD_BUTTON_LEFT_STICK), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.RIGHT_STICK_BUTTON, SDL_GAMEPAD_BUTTON_RIGHT_STICK), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.MISC_1_BUTTON, SDL_GAMEPAD_BUTTON_MISC1), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.MISC_2_BUTTON, SDL_GAMEPAD_BUTTON_MISC2), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.MISC_3_BUTTON, SDL_GAMEPAD_BUTTON_MISC3), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.MISC_4_BUTTON, SDL_GAMEPAD_BUTTON_MISC4), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.MISC_5_BUTTON, SDL_GAMEPAD_BUTTON_MISC5), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.MISC_6_BUTTON, SDL_GAMEPAD_BUTTON_MISC6), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.LEFT_PADDLE_1_BUTTON, SDL_GAMEPAD_BUTTON_LEFT_PADDLE1), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.LEFT_PADDLE_2_BUTTON, SDL_GAMEPAD_BUTTON_LEFT_PADDLE2), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.RIGHT_PADDLE_1_BUTTON, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.RIGHT_PADDLE_2_BUTTON, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2), - new SDLGamepadInputMapping.ButtonMapping(GamepadInputs.TOUCHPAD_1_BUTTON, SDL_GAMEPAD_BUTTON_TOUCHPAD) - ); - private InputComponent inputComponent; private GyroComponent gyroComponent; private TouchpadComponent touchpadComponent; + private final Set supportedButtons; + private final Set supportedAxes; + private final Set supportedSensors; + private final boolean isGryoSupported; private final int numTouchpads; - private final MemorySegment gyroMemory; - private final FloatBuffer gyroBuffer; - - public SDL3GamepadDriver(Sdl sdl, SdlGamepadHandle ptrController, SdlJoystickId jid, ControllerType type, ControlifyLogger logger) { - super(sdl, ptrController, jid, type, logger); - - this.isGryoSupported = sdl.gamepad().SDL_GamepadHasSensor(ptrController, SDL_SENSOR_GYRO); - this.numTouchpads = sdl.gamepad().SDL_GetNumGamepadTouchpads(ptrController); - + public SDL3GamepadDriver(Sdl sdl, SdlGamepadHandle ptrController, EventSource eventSource, SdlJoystickId jid, ControllerType type, ControlifyLogger logger) { + super(sdl, ptrController, jid, eventSource, type, logger); + + this.supportedButtons = IntStream.range(0, SDL_GAMEPAD_BUTTON_COUNT) + .filter(i -> this.sdl.gamepad().SDL_GamepadHasButton(this.ptrController, i)) + .mapToObj(SDLInputConversions::getGamepadButton) + .collect(Collectors.toSet()); + this.supportedAxes = IntStream.range(0, SDL_GAMEPAD_AXIS_COUNT) + .filter(i -> this.sdl.gamepad().SDL_GamepadHasAxis(this.ptrController, i)) + .boxed() + .flatMap(i -> Stream.of(SDLInputConversions.getGamepadAxis(i, true), SDLInputConversions.getGamepadAxis(i, false))) + .collect(Collectors.toSet()); + this.supportedSensors = IntStream.range(0, SDL_SENSOR_COUNT) + .filter(i -> this.sdl.gamepad().SDL_GamepadHasSensor(this.ptrController, i)) + .mapToObj(SDLInputConversions::getSensorType) + .collect(Collectors.toSet()); + + this.isGryoSupported = this.supportedSensors.contains(SensorType.GYROSCOPE); if (this.isGryoSupported) { sdl.gamepad().SDL_SetGamepadSensorEnabled(ptrController, SDL_SENSOR_GYRO, true); - - this.gyroMemory = this.arena.allocate(ValueLayout.JAVA_FLOAT, GYRO_AXIS_COUNT); - } else { - this.gyroMemory = MemorySegment.NULL; } - this.gyroBuffer = this.gyroMemory.asByteBuffer() - .order(ByteOrder.nativeOrder()) - .asFloatBuffer(); + this.numTouchpads = sdl.gamepad().SDL_GetNumGamepadTouchpads(ptrController); } @Override public void addComponents(ControllerEntity controller) { super.addComponents(controller); - int buttonCount = (int) INPUT_MAPPINGS.stream() - .filter(m -> m instanceof SDLGamepadInputMapping.ButtonMapping) - .filter(m -> m.hasInput(sdl.gamepad(), ptrController)) - .count(); - int axisCount = (int) INPUT_MAPPINGS.stream() - .filter(m -> m instanceof SDLGamepadInputMapping.AxisMapping) - .filter(m -> m.hasInput(sdl.gamepad(), ptrController)) - .count(); - controller.setComponent( this.inputComponent = new InputComponent( - controller, - buttonCount, - axisCount, - 0, - true, + this.controllerType.namespace(), + this.inputPipeline, + this.supportedButtons, + this.supportedAxes, GamepadInputs.DEADZONE_GROUPS, - controller.info().type().mappingId() + true, + this.supportedSensors ) ); if (this.isGryoSupported) { controller.setComponent(this.gyroComponent = new GyroComponent()); + + // TODO: this is not the final way of doing this + // but this is an idea of how gyro would be given to the GyroComponent instead of having everything + // through InputComponent, potentially GyroComponent should further accumulate this until handled + // although most of the time it would only have one sample, so maybe accumulation isn't necessary + // this would be queried at the same time MouseHandler.handleAccumulatedMouseMovement + // this subscription is also never closed atm, nor is deltaTime handled (does it need to be?) + // EDIT: no, this is a bad idea, remember we are in SDL3GamepadDriver but we are purposefully listening + // to the generic processed signals, this should probably be done elsewhere outside of the driver + // EDIT2: we could give the same InputPipeline to GyroComponent similarly to how we give it to InputComponent + // InputComponent subscribes the ActionGraph, while GyroComponent subscribes itself + this.inputPipeline.sourceLogicalSignals().subscribe(sig -> { + if (sig instanceof LogicalSignal.SensorInterval(long timeNanos, long deltaTimeNanos, SensorType sensorType, float x, float y, float z)) { + if (sensorType == SensorType.GYROSCOPE) { + this.gyroComponent.setState(new GyroState(x, y, z)); + } + } + }); } if (this.numTouchpads > 0) { @@ -148,65 +121,27 @@ public void addComponents(ControllerEntity controller) { } @Override - public void update(ControllerEntity controller, boolean outOfFocus) { - super.update(controller, outOfFocus); - - this.updateInput(); - this.updateGyro(); - this.updateTouchpad(); - } + protected void onEvent(SDLControllerEvent event) { + super.onEvent(event); - private void updateInput() { - ControllerStateImpl state = new ControllerStateImpl(); + switch (event) { + case SDLControllerEvent.GamepadTouchpad touchpad -> + this.onTouchpadEvent(touchpad); - for (SDLGamepadInputMapping m : INPUT_MAPPINGS) { - m.applyState(sdl.gamepad(), ptrController, state); + default -> {} } - - this.inputComponent.pushState(state); } - private void updateGyro() { - if (!isGryoSupported) return; - - if (sdl.gamepad().SDL_GetGamepadSensorData(ptrController, SDL_SENSOR_GYRO, gyroBuffer)) { - this.gyroComponent.setState( - new GyroState(gyroBuffer.get(0), gyroBuffer.get(1), gyroBuffer.get(2)) - ); - } else { - CUtil.LOGGER.error("Could not get gyro data: {}", sdl.error().SDL_GetError()); - } + @Override + public void update(ControllerEntity controller, boolean outOfFocus) { + super.update(controller, outOfFocus); } - private void updateTouchpad() { - if (numTouchpads < 1) return; - - for (int touchpadIdx = 0; touchpadIdx < numTouchpads; touchpadIdx++) { - Touchpads.Touchpad touchpad = this.touchpadComponent.touchpads()[touchpadIdx]; - - List fingers = new ArrayList<>(); - for (int fingerIdx = 0; fingerIdx < touchpad.maxFingers(); fingerIdx++) { - var fingerState = new SdlRefs.ByteRef(); - var x = new SdlRefs.FloatRef(); - var y = new SdlRefs.FloatRef(); - var pressure = new SdlRefs.FloatRef(); - - if (!sdl.gamepad().SDL_GetGamepadTouchpadFinger(ptrController, touchpadIdx, fingerIdx, fingerState, x, y, pressure)) { - CUtil.LOGGER.error("Failed to fetch touchpad finger: {}", sdl.error().SDL_GetError()); - } else if (fingerState.value == 1) { - fingers.add( - new Touchpads.Finger( - fingerIdx, - // SDL already returns the correct range for touchpad position and pressure - new Vector2f(x.value, y.value), - pressure.value - ) - ); - } - } - - touchpad.pushFingers(fingers); - } + private void onTouchpadEvent(SDLControllerEvent.GamepadTouchpad event) { + // TODO: touchpad component probably needs redoing, it was designed to receive + // complete snapshots of touchpad data, not continuous updates + // TODO: touchpad events should probably be fed down the physical input pipeline + // so we can recognise gestures from finger swipes } @Override diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java index c9fad7e39..8165911a3 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java @@ -7,84 +7,61 @@ package dev.isxander.controlify.driver.sdl; import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.controller.input.HatState; -import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.controller.input.JoystickInputs; import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.controller.impl.ControllerStateImpl; +import dev.isxander.controlify.input.InputComponent; +import dev.isxander.controlify.utils.event.EventSource; import dev.isxander.controlify.utils.log.ControlifyLogger; import dev.isxander.sdl.*; -import net.minecraft.util.Mth; +import net.minecraft.resources.Identifier; import java.nio.ByteBuffer; import java.util.Set; - -import static dev.isxander.sdl.SdlJoystick.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; public class SDL3JoystickDriver extends SDLCommonDriver { private InputComponent inputComponent; - private final int numAxes, numButtons, numHats; - public SDL3JoystickDriver(Sdl sdl, SdlJoystickHandle ptrJoystick, SdlJoystickId jid, ControllerType type, ControlifyLogger logger) { - super(sdl, ptrJoystick, jid, type, logger); + private final int numAxes, numButtons; + private final Set supportedAxes; + private final Set supportedButtons; + + public SDL3JoystickDriver(Sdl sdl, SdlJoystickHandle ptrJoystick, EventSource eventSource, SdlJoystickId jid, ControllerType type, ControlifyLogger logger) { + super(sdl, ptrJoystick, jid, eventSource, type, logger); this.numAxes = sdl.joystick().SDL_GetNumJoystickAxes(ptrJoystick); this.numButtons = sdl.joystick().SDL_GetNumJoystickButtons(ptrJoystick); - this.numHats = sdl.joystick().SDL_GetNumJoystickHats(ptrJoystick); + + this.supportedAxes = IntStream.range(0, this.numAxes) + .boxed() + .flatMap(i -> Stream.of(JoystickInputs.axis(i, false), JoystickInputs.axis(i, true))) + .collect(Collectors.toSet()); + this.supportedButtons = IntStream.range(0, this.numButtons) + .mapToObj(JoystickInputs::button) + .collect(Collectors.toSet()); } @Override public void addComponents(ControllerEntity controller) { super.addComponents(controller); - controller.setComponent(this.inputComponent = new InputComponent(controller, numButtons, numAxes * 2, numHats, false, Set.of(), controller.info().type().mappingId())); + controller.setComponent(this.inputComponent = new InputComponent( + this.controllerType.namespace(), + this.inputPipeline, + this.supportedButtons, + this.supportedAxes, + Set.of(), + false, + Set.of() + )); } @Override public void update(ControllerEntity controller, boolean outOfFocus) { super.update(controller, outOfFocus); - - this.updateInput(); - } - - private void updateInput() { - ControllerStateImpl state = new ControllerStateImpl(); - - for (int i = 0; i < numAxes; i++) { - float axis = mapShortToFloat(sdl.joystick().SDL_GetJoystickAxis(ptrController, i)); - - state.setAxis(JoystickInputs.axis(i, true), Math.max(axis, 0)); - state.setAxis(JoystickInputs.axis(i, false), -Math.min(axis, 0)); - } - - for (int i = 0; i < numButtons; i++) { - state.setButton(JoystickInputs.button(i), sdl.joystick().SDL_GetJoystickButton(ptrController, i)); - } - - for (int i = 0; i < numHats; i++) { - HatState hatState = switch (sdl.joystick().SDL_GetJoystickHat(ptrController, i)) { - case SDL_HAT_CENTERED -> HatState.CENTERED; - case SDL_HAT_UP -> HatState.UP; - case SDL_HAT_RIGHT -> HatState.RIGHT; - case SDL_HAT_DOWN -> HatState.DOWN; - case SDL_HAT_LEFT -> HatState.LEFT; - case SDL_HAT_RIGHTUP -> HatState.RIGHT_UP; - case SDL_HAT_RIGHTDOWN -> HatState.RIGHT_DOWN; - case SDL_HAT_LEFTUP -> HatState.LEFT_UP; - case SDL_HAT_LEFTDOWN -> HatState.LEFT_DOWN; - default -> throw new IllegalStateException("Unexpected value: " + sdl.joystick().SDL_GetJoystickHat(ptrController, i)); - }; - - state.setHat(JoystickInputs.hat(i), hatState); - } - - this.inputComponent.pushState(state); - } - - private static float mapShortToFloat(short value) { - return Mth.clampedMap(value, Short.MIN_VALUE, 0, -1f, 0f) - + Mth.clampedMap(value, 0, Short.MAX_VALUE, 0f, 1f); } @Override diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java index 1e75f2c6c..a4b48168c 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java @@ -24,9 +24,11 @@ import dev.isxander.controlify.driver.Driver; import dev.isxander.controlify.driver.dualsense.DualsenseEffectsState; import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; +import dev.isxander.controlify.input.InputPipeline; import dev.isxander.controlify.rumble.RumbleState; import dev.isxander.controlify.rumble.TriggerRumbleState; import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.utils.event.EventSource; import dev.isxander.controlify.utils.log.ControlifyLogger; import dev.isxander.sdl.*; import net.minecraft.util.Util; @@ -43,7 +45,6 @@ import java.util.Optional; import static dev.isxander.sdl.SdlAudio.*; -import static dev.isxander.sdl.SdlGamepad.*; import static dev.isxander.sdl.SdlInit.*; import static dev.isxander.sdl.SdlProperties.*; @@ -57,6 +58,11 @@ public abstract class SDLCommonDriver implements Driver { protected SdlController ptrController; + protected final EventSource sdlEventSource; + protected final InputPipeline inputPipeline; + private final SDLToPhysicalStage sdlToPhysicalStage; + private EventSource.Subscription eventSubscription; + protected BatteryLevelComponent batteryLevelComponent; protected RumbleComponent rumbleComponent; protected TriggerRumbleComponent triggerRumbleComponent; @@ -75,19 +81,22 @@ public abstract class SDLCommonDriver implements Driver { protected final SdlPropertiesId props; protected final short vendorId, productId; protected final SDLJoystickConnectionState connectionState; + protected final ControllerType controllerType; @Nullable protected SdlAudioDeviceId dualsenseAudioDev; @Nullable protected SdlAudioSpec dualsenseAudioSpec; protected final List dualsenseAudioHandles; - public SDLCommonDriver(Sdl sdl, SdlController ptrController, SdlJoystickId jid, ControllerType type, ControlifyLogger logger) { + public SDLCommonDriver(Sdl sdl, SdlController ptrController, SdlJoystickId jid, EventSource eventSource, ControllerType type, ControlifyLogger logger) { this.sdl = sdl; this.arena = Arena.ofConfined(); this.ptrController = ptrController; + this.sdlEventSource = eventSource; this.logger = logger; this.props = SDL_GetControllerProperties(ptrController); + this.controllerType = type; this.name = Optional.ofNullable(SDL_GetControllerName(ptrController)) .orElse("SDL Controller"); @@ -113,6 +122,9 @@ public SDLCommonDriver(Sdl sdl, SdlController ptrController, SdlJoystickId jid, DecodedGUID decodedGuid = DecodedGUID.fromGUID(this.guid); logger.log("SDL GUID driver signature: {}", decodedGuid.getDriverHint()); + this.inputPipeline = new InputPipeline(); + this.sdlToPhysicalStage = new SDLToPhysicalStage(); + // open audio device for dualsense hd haptics this.dualsenseAudioHandles = new ArrayList<>(); @@ -176,6 +188,29 @@ public void addComponents(ControllerEntity controller) { } } + protected void onEvent(SDLControllerEvent event) { + this.sdlToPhysicalStage.onEvent(event, this.inputPipeline); + + switch (event) { + case SDLControllerEvent.Battery battery -> + this.onBatteryEvent(battery); + + default -> {} + } + } + + private void onBatteryEvent(SDLControllerEvent.Battery event) { + PowerState level = switch (event.state()) { + case ERROR, UNKNOWN -> new PowerState.Unknown(); + case ON_BATTERY -> new PowerState.Depleting(event.percent()); + case NO_BATTERY -> new PowerState.WiredOnly(); + case CHARGING -> new PowerState.Charging(event.percent()); + case CHARGED -> new PowerState.Full(); + }; + + this.batteryLevelComponent.setBatteryLevel(level); + } + @Override public void update(ControllerEntity controller, boolean outOfFocus) { if (ptrController == null) { @@ -183,39 +218,11 @@ public void update(ControllerEntity controller, boolean outOfFocus) { } updateRumble(); - updateBatteryLevel(); updateLED(); updateDualSense(); updateHDHaptic(); } - @Override - public void close() { - if (ptrController == null) { - throw new IllegalStateException("Tried to close controller when it's already closed."); - } - - if (dualSenseComponent != null) { - dualSenseComponent.setLeftTriggerEffect(DualsenseTriggerEffect.Off.INSTANCE); - dualSenseComponent.setRightTriggerEffect(DualsenseTriggerEffect.Off.INSTANCE); - dualSenseComponent.setMuteLight(false); - updateDualSense(); - } - - SDL_CloseController(ptrController); - ptrController = null; - - if (dualsenseAudioDev != null) { - sdl.audio().SDL_CloseAudioDevice(dualsenseAudioDev); - dualsenseAudioDev = null; - for (AudioStreamHandle handle : dualsenseAudioHandles) { - handle.close(); - } - } - - arena.close(); - } - protected void updateRumble() { if (isRumbleSupported) { Optional stateOpt = this.rumbleComponent.consumeRumble(); @@ -238,22 +245,6 @@ protected void updateRumble() { } } - private void updateBatteryLevel() { - SdlRefs.IntRef percent = new SdlRefs.IntRef(); - int powerState = SDL_GetControllerPowerInfo(ptrController, percent); - - PowerState level = switch (powerState) { - case SDL_POWERSTATE_ERROR, SDL_POWERSTATE_UNKNOWN -> new PowerState.Unknown(); - case SDL_POWERSTATE_ON_BATTERY -> new PowerState.Depleting(percent.value); - case SDL_POWERSTATE_NO_BATTERY -> new PowerState.WiredOnly(); - case SDL_POWERSTATE_CHARGING -> new PowerState.Charging(percent.value); - case SDL_POWERSTATE_CHARGED -> new PowerState.Full(); - default -> throw new IllegalStateException("Unexpected value"); - }; - - this.batteryLevelComponent.setBatteryLevel(level); - } - private void updateLED() { if (ledComponent == null) return; @@ -314,6 +305,38 @@ private void updateHDHaptic() { } } + @Override + public void close() { + if (ptrController == null) { + throw new IllegalStateException("Tried to close controller when it's already closed."); + } + + if (this.eventSubscription != null) { + this.eventSubscription.close(); + this.eventSubscription = null; + } + + if (dualSenseComponent != null) { + dualSenseComponent.setLeftTriggerEffect(DualsenseTriggerEffect.Off.INSTANCE); + dualSenseComponent.setRightTriggerEffect(DualsenseTriggerEffect.Off.INSTANCE); + dualSenseComponent.setMuteLight(false); + updateDualSense(); + } + + SDL_CloseController(ptrController); + ptrController = null; + + if (dualsenseAudioDev != null) { + sdl.audio().SDL_CloseAudioDevice(dualsenseAudioDev); + dualsenseAudioDev = null; + for (AudioStreamHandle handle : dualsenseAudioHandles) { + handle.close(); + } + } + + arena.close(); + } + private void playHaptic(CompleteSoundData sound) { if (ptrController == null || dualsenseAudioDev == null || dualsenseAudioSpec == null) { return; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java new file mode 100644 index 000000000..60a8ba551 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java @@ -0,0 +1,192 @@ +package dev.isxander.controlify.driver.sdl; + +import dev.isxander.sdl.SdlJoystickId; + +public sealed interface SDLControllerEvent { + + long timeNanos(); + + SdlJoystickId which(); + + sealed interface JoystickEvent extends SDLControllerEvent {} + sealed interface GamepadEvent extends SDLControllerEvent {} + + sealed interface DeviceEvent extends SDLControllerEvent { + Type type(); + + enum Type { + ADDED, + REMOVED, + UPDATE_COMPLETE, + /// Gamepad only + REMAPPED, + /// Gamepad only + STEAM_HANDLE_UPDATED, + } + } + + sealed interface AxisEvent extends SDLControllerEvent { + /// The axis. It may be an index or a constant, depending on the event type. + byte axis(); + + /// The axis value, in the range [-32768, 32767] + short value(); + } + + sealed interface ButtonEvent extends SDLControllerEvent { + /// The button. It may be an index or a constant, depending on the event type. + byte button(); + + /// True if the button is pressed, false if released. + boolean down(); + } + + /// A joystick device event. + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param type the type of device event + record JoyDevice( + SdlJoystickId which, + long timeNanos, + Type type + ) implements JoystickEvent, DeviceEvent {} + + /// A joystick axis motion event. + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param axis the axis index + /// @param value the axis value, in the range [-32768, 32767] + record JoyAxis( + SdlJoystickId which, + long timeNanos, + byte axis, + short value + ) implements JoystickEvent, AxisEvent {} + + /// A joystick button event. + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param button the button index + /// @param down true if the button is pressed, false if released + record JoyButton( + SdlJoystickId which, + long timeNanos, + byte button, + boolean down + ) implements JoystickEvent, ButtonEvent {} + + /// A controller battery level change event. + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param state the power state + /// @param percent the battery percentage, in the range [0, 100], or -1 if unknown + record Battery( + SdlJoystickId which, + long timeNanos, + PowerState state, + int percent + ) implements SDLControllerEvent { + public enum PowerState { + ERROR, + UNKNOWN, + ON_BATTERY, + NO_BATTERY, + CHARGING, + CHARGED, + } + } + + /// A gamepad device event. + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param type the type of device event + record GamepadDevice( + SdlJoystickId which, + long timeNanos, + Type type + ) implements GamepadEvent, DeviceEvent {} + + /// A gamepad axis motion event. + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param axis the axis + /// @param value the axis value, in the range [-32768, 32767] + record GamepadAxis( + SdlJoystickId which, + long timeNanos, + byte axis, + short value + ) implements GamepadEvent, AxisEvent {} + + /// A gamepad button event. + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param button the button + /// @param down true if the button is pressed, false if released + record GamepadButton( + SdlJoystickId which, + long timeNanos, + byte button, + boolean down + ) implements GamepadEvent, ButtonEvent {} + + /// A gamepad touchpad event. + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param action the action this event represents + /// @param touchpad the index of the touchpad + /// @param finger the index of the finger on the touchpad + /// @param x normalized in the range [0, 1] with 0 being on the left + /// @param y normalized in the range [0, 1] with 0 being at the top + /// @param pressure normalized in the range [0, 1] + record GamepadTouchpad( + SdlJoystickId which, + long timeNanos, + Action action, + int touchpad, + int finger, + float x, + float y, + float pressure + ) implements GamepadEvent { + public enum Action { + DOWN, + MOTION, + UP, + } + } + + /// A gamepad capsense event. + /// Monitors capacitive touch sensors on controllers. + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param capsense the capsense type + /// @param down true if the capsense is touched + record GamepadCapSense( + SdlJoystickId which, + long timeNanos, + byte capsense, + boolean down + ) implements GamepadEvent {} + + /// A gamepad sensor event + /// @param which the joystick ID + /// @param timeNanos the event timestamp in nanoseconds + /// @param sensor the sensor type + /// @param x the first component of the sensor data + /// @param y the second component of the sensor data, + /// may be 0 if the sensor type is 1-dimensional + /// @param z the third component of the sensor data, + /// may be 0 if the sensor type is not 3-dimensional + /// @param sensorTimestamp the timestamp of the sensor reading in nanoseconds, + /// not necessarily synchronized with the system clock + record GamepadSensor( + SdlJoystickId which, + long timeNanos, + int sensor, + float x, + float y, + float z, + long sensorTimestamp + ) implements GamepadEvent {} +} diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEventStage.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEventStage.java new file mode 100644 index 000000000..dc862b7a9 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEventStage.java @@ -0,0 +1,65 @@ +package dev.isxander.controlify.driver.sdl; + +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.EventStage; +import dev.isxander.sdl.*; + +public class SDLControllerEventStage implements EventStage { + @Override + public void onEvent(SdlEvent event, EventSink downstream) { + long timeNanos = event.timestamp(); + + switch (event.data()) { + case SdlEvent.JoyAxis(SdlJoystickId which, byte axis, short value) -> + downstream.accept(new SDLControllerEvent.JoyAxis(which, timeNanos, axis, value)); + + case SdlEvent.JoyButton(SdlJoystickId which, byte button, boolean down) -> + downstream.accept(new SDLControllerEvent.JoyButton(which, timeNanos, button, down)); + + case SdlEvent.JoyDevice(SdlJoystickId which) -> { + var type = SDLInputConversions.getDeviceEventType(event.type()); + if (type != null) { + downstream.accept(new SDLControllerEvent.JoyDevice(which, timeNanos, type)); + } + } + + case SdlEvent.JoyBattery(SdlJoystickId which, int state, int percent) -> { + var stateEnum = SDLInputConversions.getPowerState(state); + if (stateEnum != null) { + downstream.accept(new SDLControllerEvent.Battery(which, timeNanos, stateEnum, percent)); + } + } + + case SdlEvent.GamepadAxis(SdlJoystickId which, byte axis, short value) -> + downstream.accept(new SDLControllerEvent.GamepadAxis(which, timeNanos, axis, value)); + + case SdlEvent.GamepadButton(SdlJoystickId which, byte button, boolean down) -> + downstream.accept(new SDLControllerEvent.GamepadButton(which, timeNanos, button, down)); + + case SdlEvent.GamepadDevice(SdlJoystickId which) -> { + var type = SDLInputConversions.getDeviceEventType(event.type()); + if (type != null) { + downstream.accept(new SDLControllerEvent.GamepadDevice(which, timeNanos, type)); + } + } + + case SdlEvent.GamepadTouchpad(SdlJoystickId which, int touchpad, int finger, float x, float y, float pressure) -> { + var action = SDLInputConversions.getTouchpadAction(event.type()); + if (action != null) { + downstream.accept(new SDLControllerEvent.GamepadTouchpad(which, timeNanos, action, touchpad, finger, x, y, pressure)); + } + } + + case SdlEvent.GamepadSensor(SdlJoystickId which, int sensor, float[] values, long sensorTimestamp) -> { + float x = values.length >= 1 ? values[0] : 0f; + float y = values.length >= 2 ? values[1] : 0f; + float z = values.length >= 3 ? values[2] : 0f; + downstream.accept(new SDLControllerEvent.GamepadSensor(which, timeNanos, sensor, x, y, z, sensorTimestamp)); + } + + default -> {} + } + } + + +} diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java new file mode 100644 index 000000000..92b36ae82 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java @@ -0,0 +1,133 @@ +package dev.isxander.controlify.driver.sdl; + +import dev.isxander.controlify.controller.input.GamepadInputs; +import dev.isxander.controlify.input.SensorType; +import dev.isxander.sdl.SdlEvents; +import dev.isxander.sdl.SdlGamepad; +import net.minecraft.resources.Identifier; +import org.jspecify.annotations.Nullable; + +import java.util.stream.IntStream; + +import static dev.isxander.sdl.SdlGamepad.*; + +public final class SDLInputConversions { + private static final Identifier[] GAMEPAD_AXES = IntStream.range(0, SDL_GAMEPAD_AXIS_COUNT << 1) + .mapToObj(i -> switch (i) { + case (SDL_GAMEPAD_AXIS_LEFTX << 1) -> GamepadInputs.LEFT_STICK_AXIS_RIGHT; + case (SDL_GAMEPAD_AXIS_LEFTX << 1) | 1 -> GamepadInputs.LEFT_STICK_AXIS_LEFT; + case (SDL_GAMEPAD_AXIS_LEFTY << 1) -> GamepadInputs.LEFT_STICK_AXIS_DOWN; + case (SDL_GAMEPAD_AXIS_LEFTY << 1) | 1 -> GamepadInputs.LEFT_STICK_AXIS_UP; + case (SDL_GAMEPAD_AXIS_RIGHTX << 1) -> GamepadInputs.RIGHT_STICK_AXIS_RIGHT; + case (SDL_GAMEPAD_AXIS_RIGHTX << 1) | 1 -> GamepadInputs.RIGHT_STICK_AXIS_LEFT; + case (SDL_GAMEPAD_AXIS_RIGHTY << 1) -> GamepadInputs.RIGHT_STICK_AXIS_DOWN; + case (SDL_GAMEPAD_AXIS_RIGHTY << 1) | 1 -> GamepadInputs.RIGHT_STICK_AXIS_UP; + case (SDL_GAMEPAD_AXIS_LEFT_TRIGGER << 1), + (SDL_GAMEPAD_AXIS_LEFT_TRIGGER << 1) | 1 -> GamepadInputs.LEFT_TRIGGER_AXIS; + case (SDL_GAMEPAD_AXIS_RIGHT_TRIGGER << 1), + (SDL_GAMEPAD_AXIS_RIGHT_TRIGGER << 1) | 1 -> GamepadInputs.RIGHT_TRIGGER_AXIS; + default -> throw new IllegalArgumentException("Unknown axis"); + }) + .toArray(Identifier[]::new); + private static final Identifier[] GAMEPAD_BUTTONS = IntStream.range(0, SDL_GAMEPAD_BUTTON_COUNT) + .mapToObj(i -> switch (i) { + case SDL_GAMEPAD_BUTTON_SOUTH -> GamepadInputs.SOUTH_BUTTON; + case SDL_GAMEPAD_BUTTON_EAST -> GamepadInputs.EAST_BUTTON; + case SDL_GAMEPAD_BUTTON_WEST -> GamepadInputs.WEST_BUTTON; + case SDL_GAMEPAD_BUTTON_NORTH -> GamepadInputs.NORTH_BUTTON; + case SDL_GAMEPAD_BUTTON_BACK -> GamepadInputs.BACK_BUTTON; + case SDL_GAMEPAD_BUTTON_GUIDE -> GamepadInputs.GUIDE_BUTTON; + case SDL_GAMEPAD_BUTTON_START -> GamepadInputs.START_BUTTON; + case SDL_GAMEPAD_BUTTON_LEFT_STICK -> GamepadInputs.LEFT_STICK_BUTTON; + case SDL_GAMEPAD_BUTTON_RIGHT_STICK -> GamepadInputs.RIGHT_STICK_BUTTON; + case SDL_GAMEPAD_BUTTON_LEFT_SHOULDER -> GamepadInputs.LEFT_SHOULDER_BUTTON; + case SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER -> GamepadInputs.RIGHT_SHOULDER_BUTTON; + case SDL_GAMEPAD_BUTTON_DPAD_UP -> GamepadInputs.DPAD_UP_BUTTON; + case SDL_GAMEPAD_BUTTON_DPAD_DOWN -> GamepadInputs.DPAD_DOWN_BUTTON; + case SDL_GAMEPAD_BUTTON_DPAD_LEFT -> GamepadInputs.DPAD_LEFT_BUTTON; + case SDL_GAMEPAD_BUTTON_DPAD_RIGHT -> GamepadInputs.DPAD_RIGHT_BUTTON; + case SDL_GAMEPAD_BUTTON_MISC1 -> GamepadInputs.MISC_1_BUTTON; + case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 -> GamepadInputs.RIGHT_PADDLE_1_BUTTON; + case SDL_GAMEPAD_BUTTON_LEFT_PADDLE1 -> GamepadInputs.LEFT_PADDLE_1_BUTTON; + case SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2 -> GamepadInputs.RIGHT_PADDLE_2_BUTTON; + case SDL_GAMEPAD_BUTTON_LEFT_PADDLE2 -> GamepadInputs.LEFT_PADDLE_2_BUTTON; + case SDL_GAMEPAD_BUTTON_TOUCHPAD -> GamepadInputs.TOUCHPAD_1_BUTTON; + case SDL_GAMEPAD_BUTTON_MISC2 -> GamepadInputs.MISC_2_BUTTON; + case SDL_GAMEPAD_BUTTON_MISC3 -> GamepadInputs.MISC_3_BUTTON; + case SDL_GAMEPAD_BUTTON_MISC4 -> GamepadInputs.MISC_4_BUTTON; + case SDL_GAMEPAD_BUTTON_MISC5 -> GamepadInputs.MISC_5_BUTTON; + case SDL_GAMEPAD_BUTTON_MISC6 -> GamepadInputs.MISC_6_BUTTON; + default -> throw new IllegalArgumentException("Unknown button"); + + }) + .toArray(Identifier[]::new); + + private static final SensorType[] GAMEPAD_SENSOR_TYPES = IntStream.range(0, SDL_SENSOR_COUNT) + .mapToObj(i -> switch (i) { + case SDL_SENSOR_GYRO -> SensorType.GYROSCOPE; + case SDL_SENSOR_GYRO_L -> SensorType.GYROSCOPE_L; + case SDL_SENSOR_GYRO_R -> SensorType.GYROSCOPE_R; + case SDL_SENSOR_ACCEL -> SensorType.ACCELEROMETER; + case SDL_SENSOR_ACCEL_L -> SensorType.ACCELEROMETER_L; + case SDL_SENSOR_ACCEL_R -> SensorType.ACCELEROMETER_R; + default -> null; + }) + .toArray(SensorType[]::new); + + public static @Nullable Identifier getGamepadButton(int button) { + if (button < 0 || button >= GAMEPAD_BUTTONS.length) { + return null; + } + return GAMEPAD_BUTTONS[button]; + } + + public static @Nullable Identifier getGamepadAxis(int axis, boolean positive) { + int index = (axis << 1) | (positive ? 0 : 1); + if (index < 0 || index >= GAMEPAD_AXES.length) { + return null; + } + return GAMEPAD_AXES[index]; + } + + public static @Nullable SensorType getSensorType(int sensor) { + if (sensor < 0 || sensor >= GAMEPAD_SENSOR_TYPES.length) { + return null; + } + return GAMEPAD_SENSOR_TYPES[sensor]; + } + + public static SDLControllerEvent.DeviceEvent.@Nullable Type getDeviceEventType(int event) { + return switch (event) { + case SdlEvents.SDL_EVENT_JOYSTICK_ADDED -> SDLControllerEvent.DeviceEvent.Type.ADDED; + case SdlEvents.SDL_EVENT_JOYSTICK_REMOVED -> SDLControllerEvent.DeviceEvent.Type.REMOVED; + case SdlEvents.SDL_EVENT_JOYSTICK_UPDATE_COMPLETE -> SDLControllerEvent.DeviceEvent.Type.UPDATE_COMPLETE; + case SdlEvents.SDL_EVENT_GAMEPAD_REMAPPED -> SDLControllerEvent.DeviceEvent.Type.REMAPPED; + case SdlEvents.SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED -> SDLControllerEvent.DeviceEvent.Type.STEAM_HANDLE_UPDATED; + default -> null; + }; + } + + public static SDLControllerEvent.Battery.@Nullable PowerState getPowerState(int powerState) { + return switch (powerState) { + case SdlGamepad.SDL_POWERSTATE_ERROR -> SDLControllerEvent.Battery.PowerState.ERROR; + case SdlGamepad.SDL_POWERSTATE_UNKNOWN -> SDLControllerEvent.Battery.PowerState.UNKNOWN; + case SdlGamepad.SDL_POWERSTATE_ON_BATTERY -> SDLControllerEvent.Battery.PowerState.ON_BATTERY; + case SdlGamepad.SDL_POWERSTATE_NO_BATTERY -> SDLControllerEvent.Battery.PowerState.NO_BATTERY; + case SdlGamepad.SDL_POWERSTATE_CHARGING -> SDLControllerEvent.Battery.PowerState.CHARGING; + case SdlGamepad.SDL_POWERSTATE_CHARGED -> SDLControllerEvent.Battery.PowerState.CHARGED; + default -> null; + }; + } + + public static SDLControllerEvent.GamepadTouchpad.@Nullable Action getTouchpadAction(int event) { + return switch (event) { + case SdlEvents.SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN -> SDLControllerEvent.GamepadTouchpad.Action.DOWN; + case SdlEvents.SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION -> SDLControllerEvent.GamepadTouchpad.Action.MOTION; + case SdlEvents.SDL_EVENT_GAMEPAD_TOUCHPAD_UP -> SDLControllerEvent.GamepadTouchpad.Action.UP; + default -> null; + }; + } + + private SDLInputConversions() { + } +} diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java new file mode 100644 index 000000000..e43cfa0a0 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java @@ -0,0 +1,92 @@ +package dev.isxander.controlify.driver.sdl; + +import dev.isxander.controlify.controller.input.JoystickInputs; +import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.input.physical.PhysicalInputSignal; +import dev.isxander.controlify.input.physical.PhysicalSensorSignal; +import dev.isxander.controlify.input.physical.PhysicalSignal; +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.EventStage; +import net.minecraft.resources.Identifier; + +import java.util.Arrays; + +public class SDLToPhysicalStage implements EventStage { + private final float[] prevGamepadAxisValues = new float[64]; + private final float[] prevJoystickAxisValues = new float[64]; + + public SDLToPhysicalStage() { + Arrays.fill(this.prevGamepadAxisValues, 0f); + Arrays.fill(this.prevJoystickAxisValues, 0f); + } + + @Override + public void onEvent(SDLControllerEvent event, EventSink downstream) { + switch (event) { + case SDLControllerEvent.JoyAxis(_, long timeNanos, byte axis, short value) -> { + float normalisedValue = normaliseAxis(value); + + float prevNormalisedValue = this.prevJoystickAxisValues[axis]; + this.prevJoystickAxisValues[axis] = normalisedValue; + + boolean positive = normalisedValue > 0; + boolean prevPositive = prevNormalisedValue > 0; + + if (prevPositive != positive) { + // sign changed + Identifier prevInput = JoystickInputs.axis(axis, prevPositive); + downstream.accept(new PhysicalInputSignal.AxisMoved(timeNanos, prevInput, 0f)); + } + + Identifier input = JoystickInputs.axis(axis, positive); + downstream.accept(new PhysicalInputSignal.AxisMoved(timeNanos, input, Math.abs(normalisedValue))); + } + + case SDLControllerEvent.JoyButton(_, long timeNanos, byte button, boolean down) -> + downstream.accept(new PhysicalInputSignal.ButtonChanged(timeNanos, JoystickInputs.button(button), down)); + + case SDLControllerEvent.GamepadAxis(_, long timeNanos, byte axis, short value) -> { + float normalisedValue = normaliseAxis(value); + + float prevNormalisedValue = this.prevGamepadAxisValues[axis]; + this.prevGamepadAxisValues[axis] = normalisedValue; + + boolean positive = normalisedValue > 0; + boolean prevPositive = prevNormalisedValue > 0; + + if (prevPositive != positive) { + // sign changed + Identifier prevInput = SDLInputConversions.getGamepadAxis(axis, prevPositive); + if (prevInput != null) { + downstream.accept(new PhysicalInputSignal.AxisMoved(timeNanos, prevInput, 0f)); + } + } + + Identifier input = SDLInputConversions.getGamepadAxis(axis, positive); + if (input != null) { + downstream.accept(new PhysicalInputSignal.AxisMoved(timeNanos, input, Math.abs(normalisedValue))); + } + } + + case SDLControllerEvent.GamepadButton(_, long timeNanos, byte button, boolean down) -> { + Identifier input = SDLInputConversions.getGamepadButton(button); + if (input != null) { + downstream.accept(new PhysicalInputSignal.ButtonChanged(timeNanos, input, down)); + } + } + + case SDLControllerEvent.GamepadSensor(_, long timeNanos, int sensor, float x, float y, float z, long sensorTimestamp) -> { + SensorType sensorType = SDLInputConversions.getSensorType(sensor); + if (sensorType != null) { + downstream.accept(new PhysicalSensorSignal(timeNanos, sensorTimestamp, sensorType, x, y, z)); + } + } + + default -> {} + } + } + + private static float normaliseAxis(short v) { + return v < 0 ? (v / 32768f) : (v / 32767f); + } +} diff --git a/src/main/java/dev/isxander/controlify/input/InputComponent.java b/src/main/java/dev/isxander/controlify/input/InputComponent.java index 817a9885c..d95475312 100644 --- a/src/main/java/dev/isxander/controlify/input/InputComponent.java +++ b/src/main/java/dev/isxander/controlify/input/InputComponent.java @@ -15,6 +15,7 @@ import dev.isxander.controlify.input.logical.LogicalInput; import dev.isxander.controlify.input.physical.SensorProcessorStage; import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.utils.event.EventSource; import net.minecraft.resources.Identifier; import net.minecraft.util.Util; import org.jspecify.annotations.Nullable; @@ -40,6 +41,8 @@ public class InputComponent extends ECSComponentImpl { private final boolean isGamepad; private final Set supportedSensors; + private EventSource.Subscription actionGraphSub; + public InputComponent( Identifier controllerType, InputPipeline inputPipeline, @@ -74,7 +77,7 @@ public void attach(ControllerEntity controller) { // we need to wait for settings to load before getting current binding this.reloadActions(); - this.inputPipeline.sourceLogicalSignals().subscribe(this.actionGraph); + this.actionGraphSub = this.inputPipeline.sourceLogicalSignals().subscribe(this.actionGraph); this.inputPipeline.stageDeadzone().setDeadzoneSupplier(axis -> { DeadzoneGroup group = this.deadzoneGroups.get(axis); if (group == null) { @@ -150,6 +153,14 @@ public boolean supportsAccelerometer() { return this.supportedSensors.stream().anyMatch(SensorType::isAccelerometer); } + @Override + public void close() { + super.close(); + + this.actionGraphSub.close(); + this.actionGraphSub = null; + } + private ActionImpl createAction(ActionSpec spec) { DefaultBindProvider bindProvider = Controlify.instance().defaultBindManager() .getDefaultBindProvider(this.controllerType); @@ -157,7 +168,8 @@ private ActionImpl createAction(ActionSpec spec) { LogicalInput currentBoundInput = settings().bindings.bindings.get(spec.id()); - ActivatorConfig activatorConfig = Controlify.instance().activatorConfigManager().getConfig(spec.id()); + ActivatorConfig activatorConfig = Controlify.instance().activatorConfigManager() + .getConfig(spec.id()); ActionImpl action = new ActionImpl( spec, diff --git a/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java b/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java index 7f5505da5..587d3418d 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java +++ b/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java @@ -56,7 +56,7 @@ public void onEvent( }); } - case PhysicalSensorSignal(long timeNanos, SensorType sensorType, float x, float y, float z) -> { + case PhysicalSensorSignal(long timeNanos, _, SensorType sensorType, float x, float y, float z) -> { Acc acc = this.accSensorValues.computeIfAbsent(sensorType, _ -> new Acc()); if (acc.lastNs != -1 && timeNanos <= acc.lastNs) { diff --git a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java index 57ef156be..f4af8d8d8 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java +++ b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java @@ -3,8 +3,18 @@ import dev.isxander.controlify.input.SensorType; /// Represents a single IMU sample +/// @param timeNanos timestamp of the event in nanoseconds +/// @param sensorTimeNanos timestamp provided by the sensor firmware in nanoseconds. +/// this may be out of sync with the system clock and therefore {@link timeNanos} +/// @param sensorType the type of sensor this signal is for +/// @param x the first component of the sensor data +/// @param y the second component of the sensor data; +/// may be zero if the sensor data is not at least 2-dimensional +/// @param z the third component of the sensor data; +/// may be zero if the sensor data is not at least 3-dimensional public record PhysicalSensorSignal( long timeNanos, + long sensorTimeNanos, SensorType sensorType, float x, float y, float z ) implements PhysicalSignal { diff --git a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java index f61d23a3c..5657f8dc5 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java +++ b/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java @@ -1,6 +1,7 @@ package dev.isxander.controlify.input.physical; public sealed interface PhysicalSignal permits PhysicalInputSignal, PhysicalSensorSignal, PhysicalSignal.Frame { + /// timestamp of the signal in nanoseconds long timeNanos(); /// Emitted at the end of each polling / every frame. diff --git a/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java b/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java index 6e3e41c4c..2e007424c 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java +++ b/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java @@ -36,16 +36,16 @@ public void setProcessors(Function> processorF @Override public void onEvent(PhysicalSignal event, EventSink downstream) { switch (event) { - case PhysicalSensorSignal(long timeNanos, SensorType sensorType, float x, float y, float z) + case PhysicalSensorSignal(long timeNanos, long sensorTimeNanos, SensorType sensorType, float x, float y, float z) when !this.processors.get(sensorType).isEmpty() -> { var data = new Vector3f(x, y, z); for (SensorProcessor processor : this.processors.get(sensorType)) { - processor.process(data, timeNanos); + processor.process(data, sensorTimeNanos); } - // TODO: port GyroCalibrator here, and do other stuff like low pass - downstream.accept(new PhysicalSensorSignal(timeNanos, sensorType, data.x, data.y, data.z)); + // TODO: port GyroCalibrator here + downstream.accept(new PhysicalSensorSignal(timeNanos, sensorTimeNanos, sensorType, data.x, data.y, data.z)); } default -> downstream.accept(event); } diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventSource.java b/src/main/java/dev/isxander/controlify/utils/event/EventSource.java index 69a1d8416..d96dbfec8 100644 --- a/src/main/java/dev/isxander/controlify/utils/event/EventSource.java +++ b/src/main/java/dev/isxander/controlify/utils/event/EventSource.java @@ -1,8 +1,22 @@ package dev.isxander.controlify.utils.event; +import java.util.function.Predicate; + public interface EventSource { Subscription subscribe(EventSink listener); + default EventSource via(EventStage stage) { + return sink -> this.subscribe(stage.bind(sink)); + } + + default EventSource filter(Predicate predicate) { + return sink -> this.subscribe(event -> { + if (predicate.test(event)) { + sink.accept(event); + } + }); + } + @FunctionalInterface interface Subscription extends AutoCloseable { @Override From dbebcc3a0287db033bcab37f58533109475e924c Mon Sep 17 00:00:00 2001 From: isxander Date: Wed, 14 Oct 2026 13:26:32 +0100 Subject: [PATCH 07/12] rewrite controller manager and start to wire up fixedupdate/update system --- .../dev/isxander/controlify/Controlify.java | 164 +++++------- .../api/event/ControlifyEvents.java | 2 +- .../controller/info/ControllerInfo.java | 3 - .../AbstractControllerManager.java | 157 ------------ .../controllermanager/ControllerBackend.java | 33 +++ .../controllermanager/ControllerManager.java | 100 ++++++-- .../SDLControllerBackend.java} | 63 +++-- .../SDLControllerManager.java | 241 ------------------ .../controllermanager2/ControllerManager.java | 22 -- .../ControllerManagerBackend.java | 12 - .../gui/screen/BindConsumerScreen.java | 2 +- .../screen/ControllerMappingMakerScreen.java | 2 +- .../controlify/ingame/InGameInputHandler.java | 3 +- .../input/action/ActionContext.java | 5 +- .../mixins/core/MinecraftMixin.java | 7 +- .../controlify/screenop/ScreenProcessor.java | 2 +- .../controlify/utils/ControllerUtils.java | 2 +- ...ollerSetupWizard.java => SetupWizard.java} | 2 +- .../controlify/utils/SetupWizardManager.java | 28 ++ .../wireless/LowBatteryNotifier.java | 6 +- 20 files changed, 265 insertions(+), 591 deletions(-) delete mode 100644 src/main/java/dev/isxander/controlify/controllermanager/AbstractControllerManager.java create mode 100644 src/main/java/dev/isxander/controlify/controllermanager/ControllerBackend.java rename src/main/java/dev/isxander/controlify/{controllermanager2/SDLControllerManagerBackend.java => controllermanager/SDLControllerBackend.java} (79%) delete mode 100644 src/main/java/dev/isxander/controlify/controllermanager/SDLControllerManager.java delete mode 100644 src/main/java/dev/isxander/controlify/controllermanager2/ControllerManager.java delete mode 100644 src/main/java/dev/isxander/controlify/controllermanager2/ControllerManagerBackend.java rename src/main/java/dev/isxander/controlify/utils/{ControllerSetupWizard.java => SetupWizard.java} (97%) create mode 100644 src/main/java/dev/isxander/controlify/utils/SetupWizardManager.java diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index dfd09084c..ad4df0da7 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -27,12 +27,11 @@ import dev.isxander.controlify.controller.*; import dev.isxander.controlify.controller.dualsense.TriggerEffectManager; import dev.isxander.controlify.controller.id.ControllerTypeManager; -import dev.isxander.controlify.controller.input.ControllerState; -import dev.isxander.controlify.controller.input.ControllerStateView; import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.controller.rumble.RumbleComponent; +import dev.isxander.controlify.controllermanager.ControllerBackend; import dev.isxander.controlify.controllermanager.ControllerManager; -import dev.isxander.controlify.controllermanager.SDLControllerManager; +import dev.isxander.controlify.controllermanager.SDLControllerBackend; import dev.isxander.controlify.driver.sdl.SDLNativesLoader; import dev.isxander.controlify.driver.steamdeck.SteamDeckMode; import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; @@ -70,7 +69,6 @@ import java.io.IOException; import java.util.*; -import java.util.stream.Collectors; import static dev.isxander.controlify.utils.ControllerUtils.wrapControllerError; @@ -80,10 +78,13 @@ public class Controlify implements ControlifyApi { private Minecraft minecraft = null; private ControllerManager controllerManager; + private ControllerBackend controllerBackend; private ControllerEntity currentController = null; private InputMode currentInputMode = InputMode.KEYBOARD_MOUSE; + private ConfigManager config; + private @Nullable InGameInputHandler inGameInputHandler; public @Nullable InGameButtonGuide inGameButtonGuide; private VirtualMouseHandler virtualMouseHandler; @@ -99,12 +100,8 @@ public class Controlify implements ControlifyApi { private TriggerEffectManager triggerEffectManager; - private Set thisTickContexts; - - private ConfigManager config; + private SetupWizardManager setupWizardManager; - private final Queue setupWizards = new ArrayDeque<>(); - private ControllerSetupWizard currentSetupWizard = null; private boolean hasDiscoveredControllers = false; private int consecutiveInputSwitches = 0; @@ -137,6 +134,8 @@ public void preInitialiseControlify() { this.config.close(); }); + this.setupWizardManager = new SetupWizardManager(); + this.inputFontMapper = new InputFontMapper(); this.defaultBindManager = new DefaultBindManager(); this.defaultConfigManager = new DefaultConfigManager(); @@ -258,15 +257,17 @@ public void initializeControlify() { ScreenProcessorProvider.provide(screen).render(controller, graphics, tickDelta); })); + this.controllerManager = new ControllerManager(); try { Sdl sdl = SDLNativesLoader.load(); - controllerManager = new SDLControllerManager(sdl, CUtil.LOGGER); + this.controllerBackend = new SDLControllerBackend(sdl, this, this.controllerManager); } catch (Throwable throwable) { - CUtil.LOGGER.error("Failed to initialize controller manager", throwable); + CUtil.LOGGER.error("Failed to initialize controller backend", throwable); return; } + this.controllerBackend.setup(); - PlatformClientUtil.registerClientTickStarted(this::tick); + PlatformClientUtil.registerClientTickStarted(this::fixedUpdate); // initialise and compatability modules that controlify implements itself // this does NOT invoke any entrypoints. this is done in the pre-initialisation phase @@ -337,9 +338,9 @@ public void discoverControllers() { DebugLog.log("Discovering and initializing controllers..."); - controllerManager.discoverControllers(); + this.controllerBackend.discoverControllers(); - if (controllerManager.getConnectedControllers().isEmpty()) { + if (this.controllerManager.getAllControllers().isEmpty()) { CUtil.LOGGER.log("No controllers found."); } @@ -364,7 +365,7 @@ public void discoverControllers() { * @param hotplugged if this was a result of hotplugging */ private void onControllerAdded(ControllerEntity controller, boolean hotplugged) { - ControllerSetupWizard wizard = new ControllerSetupWizard(); + SetupWizard wizard = new SetupWizard(); DeviceSettings rememberedDevice = config().getSettings().getOrCreateDeviceSettings(controller.uid()); rememberedDevice.name = controller.name(); rememberedDevice.lastSeen = System.currentTimeMillis(); @@ -378,8 +379,6 @@ private void onControllerAdded(ControllerEntity controller, boolean hotplugged) // wizard.addStage(() -> SubmitUnknownControllerScreen.canSubmit(controller), nextScreen -> new SubmitUnknownControllerScreen(controller, nextScreen)); - // Calibration screen removed - gyro calibration is now automatic via rolling calibration - wizard.addStage( () -> { Optional inputOpt = controller.input(); @@ -410,7 +409,7 @@ private void onControllerAdded(ControllerEntity controller, boolean hotplugged) config().saveIfDirty(); } - setupWizards.add(wizard); + this.setupWizardManager.push(wizard); } /** @@ -434,39 +433,20 @@ private void onControllerRemoved(ControllerEntity controller) { } private void selectFirstConnectedController() { - Optional firstController = controllerManager.getConnectedControllers() + Optional firstController = this.controllerManager.getAllControllers() .stream() .findFirst(); this.setCurrentController(firstController.orElse(null), true); } - /** - * The main loop of Controlify. - * Only the current controller ticks. - */ - public void tick(Minecraft client) { - if (MinecraftUtil.getOverlay() == null) { - if (currentSetupWizard != null && currentSetupWizard.isDone()) { - currentSetupWizard = null; - } - - if (!setupWizards.isEmpty() && !(MinecraftUtil.getScreen() instanceof DontInterruptScreen)) { - currentSetupWizard = setupWizards.poll(); - MinecraftUtil.setScreen(currentSetupWizard.start(MinecraftUtil.getScreen())); - } - } - - boolean outOfFocus = !config().getSettings().globalSettings().outOfFocusInput && !client.isWindowActive(); - - this.thisTickContexts = BindContext.CONTEXTS.values().stream() - .filter(ctx -> ctx.isApplicable().apply(minecraft)) - .collect(Collectors.toUnmodifiableSet()); + /// Called once per frame, just after Minecraft has done its own SDL event polling. + public void update(float tickDelta) { + this.controllerBackend.pollEvents(); - // handles updating state of all controllers - controllerManager.tick(outOfFocus); + this.setupWizardManager.tick(); // handle showing/hiding mouse whilst in mixed input mode - if (minecraft.mouseHandler.isMouseGrabbed()) + if (this.minecraft.mouseHandler.isMouseGrabbed()) showMouseTicks = 0; if (currentInputMode() == InputMode.MIXED && showMouseTicks > 0) { showMouseTicks--; @@ -475,53 +455,42 @@ public void tick(Minecraft client) { } } - LowBatteryNotifier.tick(); + boolean outOfFocus = !config().getSettings().globalSettings().outOfFocusInput + && !this.minecraft.isWindowActive(); - getCurrentController().ifPresent(currentController -> { + this.getCurrentController().ifPresent(currentController -> { wrapControllerError( - () -> tickActiveController(currentController, outOfFocus), - "Ticking current controller", + () -> updateActiveController(currentController, outOfFocus), + "Updating current controller", currentController ); }); - for (ControllerEntity controller : controllerManager.getConnectedControllers()) { - if (controller.equals(getCurrentController().orElse(null))) continue; - - wrapControllerError( - () -> tickInactiveController(controller), - "Ticking inactive controller", - controller - ); - } mouseUsedThisTick = false; } - /** - * Ticks a specific controller. - * - * @param controller controller to tick - * @param outOfFocus if the window is out of focus - */ - private void tickActiveController(ControllerEntity controller, boolean outOfFocus) { - InputComponent input = controller.input().orElseThrow(); - ControllerStateView state = input.stateNow(); - Optional rumbleManager = controller.rumble().map(RumbleComponent::rumbleManager); + /// Called at 20tps + public void fixedUpdate() { + LowBatteryNotifier.tick(); - boolean isPaused = minecraft.isPaused() || MinecraftUtil.getScreen() instanceof PauseScreen; - boolean isConfigScreen = MinecraftUtil.getScreen() instanceof YACLScreen; + boolean outOfFocus = !config().getSettings().globalSettings().outOfFocusInput + && !this.minecraft.isWindowActive(); - rumbleManager.ifPresent(rumble -> rumble.setSilent(outOfFocus || (isPaused && !isConfigScreen) || currentInputMode() == InputMode.KEYBOARD_MOUSE)); - if (outOfFocus) { - state = ControllerState.EMPTY; - } else { - rumbleManager.ifPresent(RumbleManager::tick); - } + this.getCurrentController().ifPresent(currentController -> { + wrapControllerError( + () -> fixedUpdateActiveController(currentController, outOfFocus), + "Fixed-updating current controller", + currentController + ); + }); + } + private void updateActiveController(ControllerEntity controller, boolean outOfFocus) { boolean controllerInputSuppressed = outOfFocus || currentInputMode() == InputMode.KEYBOARD_MOUSE; this.triggerEffectManager().tick(this.minecraft, controller); this.triggerEffectManager().applyTriggerEffects(controller, controllerInputSuppressed); + // TODO: move this to listener based InputPipeline signal approach if (state.isGivingInput()) { minecraft.getFramerateLimitTracker().onInputReceived(); @@ -532,10 +501,6 @@ private void tickActiveController(ControllerEntity controller, boolean outOfFocu } } - if (showMouseTicks > 0 && !mouseUsedThisTick && state.isGivingInput()) { - this.endTemporaryCursor(); - } - if (consecutiveInputSwitches > 100) { CUtil.LOGGER.warn("Controlify detected current controller to be constantly giving input and has been disabled."); MinecraftUtil.sendToast( @@ -548,32 +513,35 @@ private void tickActiveController(ControllerEntity controller, boolean outOfFocu return; } - if (minecraft.level != null) { - this.inGameInputHandler().ifPresent(InGameInputHandler::inputTick); - } - if (this.currentInputMode().isController()) { - if (MinecraftUtil.getScreen() != null) { - ScreenProcessorProvider.provide(MinecraftUtil.getScreen()).onControllerUpdate(controller); - } - ControlifyEvents.ACTIVE_CONTROLLER_TICKED.invoke(new ControlifyEvents.ControllerStateUpdate(controller)); } } - private void tickInactiveController(ControllerEntity controller) { - if (config().getActiveProfile().controllerUid != null) { - return; + private void fixedUpdateActiveController(ControllerEntity controller, boolean outOfFocus) { + Optional rumbleManager = controller.rumble().map(RumbleComponent::rumbleManager); + + boolean isPaused = minecraft.isPaused() || MinecraftUtil.getScreen() instanceof PauseScreen; + boolean isConfigScreen = MinecraftUtil.getScreen() instanceof YACLScreen; + + rumbleManager.ifPresent(rumble -> rumble.setSilent(outOfFocus || (isPaused && !isConfigScreen) || currentInputMode() == InputMode.KEYBOARD_MOUSE)); + if (!outOfFocus) { + rumbleManager.ifPresent(RumbleManager::tick); } - InputComponent input = controller.input().orElseThrow(); - ControllerStateView state = input.stateNow(); + if (showMouseTicks > 0 && !mouseUsedThisTick && state.isGivingInput()) { + // TODO: move this to a InputPipeline listener-based approach + this.endTemporaryCursor(); + } - boolean thisControllerGivingInput = state.isGivingInput(); - boolean activeControllerGivingInput = getCurrentController().map(c -> c.input().orElseThrow().stateNow().isGivingInput()).orElse(false); + if (minecraft.level != null) { + this.inGameInputHandler().ifPresent(InGameInputHandler::fixedUpdate); + } - if (thisControllerGivingInput && !activeControllerGivingInput) { - this.setCurrentController(controller, true); + if (this.currentInputMode().isController()) { + if (MinecraftUtil.getScreen() != null) { + ScreenProcessorProvider.provide(MinecraftUtil.getScreen()).onControllerFixedUpdate(controller); + } } } @@ -581,7 +549,7 @@ public void applyControllerSelection(boolean changeInputMode) { String selectedUid = config().getActiveProfile().controllerUid; Optional selected = controllerManager == null ? Optional.empty() - : controllerManager.getConnectedControllers().stream() + : this.controllerManager.getAllControllers().stream() .filter(controller -> selectedUid == null || selectedUid.equals(controller.uid())) .findFirst(); this.setCurrentController(selected.orElse(null), changeInputMode); @@ -593,8 +561,8 @@ public boolean switchProfile(int profileIndex, boolean remember) throws IOExcept } ProfileSettings profile = config().getActiveProfile(); - if (controllerManager != null) { - controllerManager.getConnectedControllers().forEach(controller -> controller.setSettings(profile)); + if (this.controllerManager != null) { + this.controllerManager.getAllControllers().forEach(controller -> controller.setSettings(profile)); } this.applyControllerSelection(true); this.setupForController(this.currentInputMode.isController() ? this.currentController : null); diff --git a/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java b/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java index 183c6d320..e96f10ff1 100644 --- a/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java +++ b/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java @@ -48,7 +48,7 @@ public final class ControlifyEvents { */ public static final EventHandler LOOK_INPUT_MODIFIER = EventHandler.createPlatformBackedEvent(); - public record ControllerConnected(ControllerEntity controller, boolean hotplugged, @Deprecated boolean newController) { + public record ControllerConnected(ControllerEntity controller, boolean hotplugged) { } public record ControllerDisconnected(ControllerEntity controller) { diff --git a/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java b/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java index 553dd853a..1fc56b074 100644 --- a/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java +++ b/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java @@ -8,10 +8,7 @@ import dev.isxander.controlify.controller.id.ControllerType; import dev.isxander.controlify.controllermanager.UniqueControllerID; -import dev.isxander.controlify.hid.HIDDevice; import dev.isxander.controlify.hid.HIDID; -import java.util.Optional; - public record ControllerInfo(UniqueControllerID ucid, ControllerType type, HIDID hid) { } diff --git a/src/main/java/dev/isxander/controlify/controllermanager/AbstractControllerManager.java b/src/main/java/dev/isxander/controlify/controllermanager/AbstractControllerManager.java deleted file mode 100644 index 3f9c26ffe..000000000 --- a/src/main/java/dev/isxander/controlify/controllermanager/AbstractControllerManager.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controllermanager; - -import com.google.common.collect.ImmutableList; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.event.ControlifyEvents; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; -import dev.isxander.controlify.hid.ControllerHIDInfo; -import dev.isxander.controlify.hid.HIDDevice; -import dev.isxander.controlify.hid.HIDID; -import dev.isxander.controlify.utils.ControllerUtils; -import dev.isxander.controlify.utils.log.ControlifyLogger; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import net.minecraft.CrashReport; -import net.minecraft.CrashReportCategory; -import net.minecraft.client.Minecraft; -import net.minecraft.server.packs.resources.ResourceProvider; - -import java.util.List; -import java.util.Map; -import java.util.Optional; - -public abstract class AbstractControllerManager implements ControllerManager { - protected final Controlify controlify; - protected final Minecraft minecraft; - - protected final Map controllersByJid = new Object2ObjectOpenHashMap<>(); - protected final Map controllersByUid = new Object2ObjectOpenHashMap<>(); - protected final Map hidInfoByUid = new Object2ObjectOpenHashMap<>(); - - protected final ControlifyLogger logger; - - public AbstractControllerManager(ControlifyLogger logger) { - this.controlify = Controlify.instance(); - this.minecraft = Minecraft.getInstance(); - this.logger = logger.createSubLogger("ControllerManager"); - } - - public Optional tryCreate(UniqueControllerID ucid, ControllerHIDInfo hidInfo) { - ControlifyLogger controllerLogger = logger.createSubLogger("Controller #" + ucid); - - try { - if (controllersByJid.containsKey(ucid)) { - controllerLogger.warn("Tried to create controller that already is initialised: {}.", ucid); - return Optional.empty(); - } - - if (hidInfo.type().dontLoad()) { - controllerLogger.debugLog("Preventing load of controller #" + ucid + " because its type prevents loading."); - return Optional.empty(); - } - - if (hidInfo.type().isSteamDeck() - && SteamDeckUtil.DECK_MODE.isDesktopMode() - ) { - controllerLogger.log("Preventing load of controller #{} because Steam Deck is in desktop mode.", ucid); - return Optional.empty(); - } - - return createController(ucid, hidInfo, controllerLogger); - } catch (Throwable e) { - controllerLogger.error("Failed to create controller #{}!", e, ucid); - CrashReport crashReport = CrashReport.forThrowable(e, "Creating controller #" + ucid); - CrashReportCategory category = crashReport.addCategory("Controller Info"); - category.setDetail("Unique controller ID", ucid); - category.setDetail("Controller identification", hidInfo.type()); - category.setDetail("HID path", hidInfo.hidDevice().map(HIDDevice::path).orElse("N/A")); - category.setDetail("System name", Optional.ofNullable(getControllerSystemName(ucid)).orElse("N/A")); - controllerLogger.crashReport(crashReport); - return Optional.empty(); - //throw new ReportedException(crashReport); - } - } - - protected abstract Optional createController(UniqueControllerID ucid, ControllerHIDInfo hidInfo, ControlifyLogger controllerLogger); - - @Override - public void tick(boolean outOfFocus) { - for (ControllerEntity controller : controllersByUid.values()) { - controller.update(outOfFocus); - ControlifyEvents.CONTROLLER_STATE_UPDATE.invoke(new ControlifyEvents.ControllerStateUpdate(controller)); - } - } - - protected void onControllerConnected(ControllerEntity controller, boolean hotplug) { - logger.log("Controller connected: {}", ControllerUtils.createControllerString(controller)); - - ControlifyEvents.CONTROLLER_CONNECTED.invoke(new ControlifyEvents.ControllerConnected(controller, hotplug, false)); - } - - protected void onControllerRemoved(ControllerEntity controller) { - logger.log("Controller disconnected: {}", ControllerUtils.createControllerString(controller)); - - closeController(controller.uid()); - - ControlifyEvents.CONTROLLER_DISCONNECTED.invoke(new ControlifyEvents.ControllerDisconnected(controller)); - } - - @Override - public Optional reinitController(ControllerEntity controller, ControllerHIDInfo hidInfo) { - onControllerRemoved(controller); - - Optional newController = tryCreate(controller.info().ucid(), hidInfo); - newController.ifPresent(c -> { - ControllerUtils.wrapControllerError(() -> onControllerConnected(c, true), "Connecting controller", c); - }); - return newController; - } - - protected void addController(UniqueControllerID ucid, ControllerEntity controller) { - controllersByUid.put(controller.uid(), controller); - controllersByJid.put(ucid, controller); - } - - @Override - public void closeController(String uid) { - ControllerEntity controller = controllersByUid.remove(uid); - - if (controller == null) return; - - controller.close(); - - controllersByJid.remove(controller.info().ucid()); - hidInfoByUid.remove(uid); - } - - @Override - public List getConnectedControllers() { - return ImmutableList.copyOf(controllersByUid.values()); - } - - @Override - public boolean isControllerConnected(String uid) { - return controllersByUid.containsKey(uid); - } - - protected int getControllerCountWithMatchingHID(HIDID hid) { - return (int) controllersByJid.values().stream() - .filter(c -> c.info().hid().isPresent() && c.info().hid().get().hidid().equals(hid)) - .count(); - } - - @Override - public void close() { - controllersByUid.values().forEach(ControllerEntity::close); - } - - protected abstract void loadGamepadMappings(ResourceProvider resourceProvider); - - protected abstract String getControllerSystemName(UniqueControllerID ucid); -} diff --git a/src/main/java/dev/isxander/controlify/controllermanager/ControllerBackend.java b/src/main/java/dev/isxander/controlify/controllermanager/ControllerBackend.java new file mode 100644 index 000000000..75317ffdb --- /dev/null +++ b/src/main/java/dev/isxander/controlify/controllermanager/ControllerBackend.java @@ -0,0 +1,33 @@ +package dev.isxander.controlify.controllermanager; + +import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.controller.id.ControllerType; +import dev.isxander.controlify.hid.HIDID; + +/// A controller backend is responsible for listening to controller events +/// and creating controllers using the referenced {@link ControllerManager controller manager}. +public abstract class ControllerBackend { + protected final Controlify controlify; + protected final ControllerManager controllerManager; + + public ControllerBackend(Controlify controlify, ControllerManager controllerManager) { + this.controlify = controlify; + this.controllerManager = controllerManager; + } + + /// Called once and allows the backend to do any first-time setup + /// before beginning to poll events and discover controllers. + public abstract void setup(); + + /// Called once after {@link setup}, discovers already-connected + /// controllers before ever polling events. + public abstract void discoverControllers(); + + /// Called once per frame, polls events from the backend and processes + /// them, potentially creating controllers and adding them to {@link ControllerManager}. + public abstract void pollEvents(); + + protected ControllerType getControllerType(HIDID hidId) { + return this.controlify.controllerTypeManager().getControllerType(hidId); + } +} diff --git a/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java b/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java index 9f7cb531a..e8f0811cb 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java +++ b/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java @@ -1,33 +1,95 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ package dev.isxander.controlify.controllermanager; +import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.api.event.ControlifyEvents; import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.hid.ControllerHIDInfo; +import dev.isxander.controlify.controller.id.ControllerType; +import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; +import dev.isxander.controlify.hid.HIDID; +import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.utils.ControllerUtils; +import dev.isxander.controlify.utils.log.ControlifyLogger; -import java.util.List; -import java.util.Optional; +import java.io.Closeable; +import java.util.*; -public interface ControllerManager { - void discoverControllers(); +public class ControllerManager implements Closeable { + private final Map controllersByUid; + private final Map controllersByUcid; - void tick(boolean outOfFocus); + public ControllerManager() { + this.controllersByUid = new HashMap<>(); + this.controllersByUcid = new HashMap<>(); + } - boolean probeConnectedControllers(); + public boolean canAddController( + UniqueControllerID ucid, + HIDID hidid, + ControllerType controllerType, + ControlifyLogger controllerLogger + ) { + if (this.controllersByUcid.containsKey(ucid)) { + controllerLogger.warn("Tried to create controller that already is initialised: {}.", ucid); + return false; + } - List getConnectedControllers(); + if (controllerType.dontLoad()) { + controllerLogger.debugLog("Preventing load of controller #" + ucid + " because its type prevents loading."); + return false; + } - boolean isControllerConnected(String uid); + if (controllerType.isSteamDeck() + && SteamDeckUtil.DECK_MODE.isDesktopMode() + ) { + controllerLogger.log("Preventing load of controller #{} because Steam Deck is in desktop mode.", ucid); + return false; + } - boolean isControllerGamepad(UniqueControllerID ucid); + return true; + } - Optional reinitController(ControllerEntity controller, ControllerHIDInfo hidInfo); + public void addController(ControllerEntity controller, boolean hotplugged) { + this.controllersByUcid.put(controller.info().ucid(), controller); + this.controllersByUid.put(controller.uid(), controller); - void closeController(String uid); + CUtil.LOGGER.log("Controller connected: {}", ControllerUtils.createControllerString(controller)); - void close(); + ControllerUtils.wrapControllerError( + () -> ControlifyEvents.CONTROLLER_CONNECTED.invoke(new ControlifyEvents.ControllerConnected(controller, hotplugged)), + "Connecting controller", + controller + ); + } + + public void removeController(UniqueControllerID controllerUcid) { + ControllerEntity controller = this.controllersByUcid.get(controllerUcid); + + ControlifyEvents.CONTROLLER_DISCONNECTED.invoke(new ControlifyEvents.ControllerDisconnected(controller)); + + if (controller == null) { + throw new IllegalArgumentException("The given ucid is not associated with any connected controller"); + } + + this.controllersByUcid.remove(controllerUcid, controller); + this.controllersByUid.remove(controller.uid(), controller); + + controller.close(); + } + + public Optional getControllerByUcid(UniqueControllerID ucid) { + return Optional.ofNullable(this.controllersByUcid.get(ucid)); + } + + public Optional getControllerByUid(String uid) { + return Optional.ofNullable(this.controllersByUid.get(uid)); + } + + public Collection getAllControllers() { + return Collections.unmodifiableCollection(this.controllersByUcid.values()); + } + + @Override + public void close() { + this.controllersByUcid.values().forEach(ControllerEntity::close); + } } diff --git a/src/main/java/dev/isxander/controlify/controllermanager2/SDLControllerManagerBackend.java b/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java similarity index 79% rename from src/main/java/dev/isxander/controlify/controllermanager2/SDLControllerManagerBackend.java rename to src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java index 4d3e8ade4..2b437f4ac 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager2/SDLControllerManagerBackend.java +++ b/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java @@ -1,11 +1,10 @@ -package dev.isxander.controlify.controllermanager2; +package dev.isxander.controlify.controllermanager; import dev.isxander.controlify.Controlify; import dev.isxander.controlify.config.settings.profile.ProfileSettings; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.controller.id.ControllerType; import dev.isxander.controlify.controller.info.ControllerInfo; -import dev.isxander.controlify.controllermanager.SDLUniqueControllerID; import dev.isxander.controlify.debug.DebugProperties; import dev.isxander.controlify.driver.Driver; import dev.isxander.controlify.driver.sdl.*; @@ -22,18 +21,17 @@ import java.nio.ByteBuffer; import java.util.Optional; -public class SDLControllerManagerBackend implements ControllerManagerBackend { +public class SDLControllerBackend extends ControllerBackend { private final Sdl sdl; - private final ControllerManager controllerManager; private final ControlifyLogger logger; private final SDLControllerEventStage controllerEventStage; private final EventTap controllerEventTap; private SdlEvent event; - public SDLControllerManagerBackend(Sdl sdl, ControllerManager controllerManager) { + public SDLControllerBackend(Sdl sdl, Controlify controlify, ControllerManager controllerManager) { + super(controlify, controllerManager); this.sdl = sdl; - this.controllerManager = controllerManager; this.logger = CUtil.LOGGER.createSubLogger("SDLControllerManagerBackend"); this.controllerEventStage = new SDLControllerEventStage(); this.controllerEventTap = new EventTap<>(); @@ -80,6 +78,16 @@ public void setup() { } } + @Override + public void discoverControllers() { + this.logger.debugLog("Discovering controllers..."); + + SdlJoystickId[] joysticks = this.sdl.joystick().SDL_GetJoysticks(); + for (SdlJoystickId jid : joysticks) { + this.tryCreateAndAddController(jid, false); + } + } + @Override public void pollEvents() { if (this.event == null) { @@ -98,17 +106,7 @@ private void onControllerEvent(SDLControllerEvent event) { switch (event) { case SDLControllerEvent.JoyDevice(SdlJoystickId which, _, SDLControllerEvent.DeviceEvent.Type eventType) when eventType == SDLControllerEvent.DeviceEvent.Type.ADDED -> { - var ucid = new SDLUniqueControllerID(which); - - var logger = this.logger.createSubLogger("Controller #" + ucid); - logger.debugLog("New controller detected!"); - - HIDID hidId = this.getJoystickHIDID(which); - ControllerType type = this.controllerManager.getControllerType(hidId); - - if (this.controllerManager.canAddController(ucid, hidId, type, logger)) { - this.createAndAddController(ucid, hidId, type, logger); - } + this.tryCreateAndAddController(which, true); } case SDLControllerEvent.JoyDevice(SdlJoystickId which, _, SDLControllerEvent.DeviceEvent.Type type) @@ -120,7 +118,27 @@ private void onControllerEvent(SDLControllerEvent event) { } } - private void createAndAddController(SDLUniqueControllerID ucid, HIDID hidId, ControllerType type, ControlifyLogger controllerLogger) { + private void tryCreateAndAddController(SdlJoystickId jid, boolean hotplugged) { + var ucid = new SDLUniqueControllerID(jid); + + var logger = this.logger.createSubLogger("Controller #" + ucid); + logger.debugLog("New controller detected!"); + + HIDID hidId = this.getJoystickHIDID(jid); + ControllerType type = this.getControllerType(hidId); + + if (this.controllerManager.canAddController(ucid, hidId, type, logger)) { + this.createAndAddController(ucid, hidId, type, logger, hotplugged); + } + } + + private void createAndAddController( + SDLUniqueControllerID ucid, + HIDID hidId, + ControllerType type, + ControlifyLogger controllerLogger, + boolean hotplugged + ) { SdlJoystickId jid = ucid.jid(); controllerLogger.debugLog("Creating controller: {}", jid.value()); @@ -131,7 +149,6 @@ private void createAndAddController(SDLUniqueControllerID ucid, HIDID hidId, Con .filter(event -> event.which().equals(jid)); Driver driver; - if (isGamepad) { SdlGamepadHandle gamepadHandle = SDLUtil.openGamepad(this.sdl, jid); driver = new SDL3GamepadDriver(this.sdl, gamepadHandle, controllerEventSource, jid, type, controllerLogger); @@ -149,13 +166,7 @@ private void createAndAddController(SDLUniqueControllerID ucid, HIDID hidId, Con controllerLogger ); - this.controllerManager.addController(controller); - - } - - @Override - public void closeController(ControllerEntity controller) { - + this.controllerManager.addController(controller, hotplugged); } private HIDID getJoystickHIDID(SdlJoystickId jid) { diff --git a/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerManager.java b/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerManager.java deleted file mode 100644 index 280f6a224..000000000 --- a/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerManager.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controllermanager; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; -import dev.isxander.controlify.controller.info.ControllerInfo; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.debug.DebugProperties; -import dev.isxander.controlify.driver.CompoundDriver; -import dev.isxander.controlify.driver.Driver; -import dev.isxander.controlify.driver.sdl.SDL3GamepadDriver; -import dev.isxander.controlify.driver.sdl.SDL3JoystickDriver; -import dev.isxander.controlify.driver.sdl.SDLUtil; -import dev.isxander.controlify.driver.steamdeck.SteamDeckDriver; -import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; -import dev.isxander.controlify.hid.ControllerHIDInfo; -import dev.isxander.controlify.hid.HIDDevice; -import dev.isxander.controlify.hid.HIDID; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.ControllerUtils; -import dev.isxander.controlify.utils.log.ControlifyLogger; -import dev.isxander.sdl.*; -import net.minecraft.server.packs.resources.Resource; -import net.minecraft.server.packs.resources.ResourceProvider; - -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.stream.Collectors; - -import static dev.isxander.sdl.SdlEvents.*; - -public class SDLControllerManager extends AbstractControllerManager { - - private final Sdl sdl; - - private SdlEvent event = new SdlEvent(); - - private boolean steamDeckConsumed = false; - - public SDLControllerManager(Sdl sdl, ControlifyLogger logger) { - super(logger); - this.sdl = sdl; - logger.debugLog("Controller manager using SDL3"); - - this.loadGamepadMappings(minecraft.getResourceManager()); - } - - @Override - public void tick(boolean outOfFocus) { - if (event == null) { - logger.warn("SDL_Event has somehow been set to null. Recreating..."); - event = new SdlEvent(); - } - - while (sdl.events().SDL_PollEvent(event)) { - switch (event.type()) { - // On added, `which` refers to the device index - case SDL_EVENT_JOYSTICK_ADDED -> { - var jdevice = (SdlEvent.JoyDevice) event.data(); - SdlJoystickId jid = jdevice.which(); - logger.validateIsTrue(jid != null, "event.jdevice.which was null during SDL_EVENT_JOYSTICK_ADDED event"); - - logger.debugLog("SDL event: Joystick added: {}", jid.value()); - - UniqueControllerID ucid = new SDLUniqueControllerID(jid); - - Optional controllerOpt = tryCreate( - ucid, - fetchTypeFromSDL(sdl, jid) - .orElse(new ControllerHIDInfo(ControllerType.DEFAULT, Optional.empty())) - ); - controllerOpt.ifPresent(controller -> { - ControllerUtils.wrapControllerError(() -> onControllerConnected(controller, true), "Connecting controller", controller); - }); - } - - // On removed, `which` refers to the device instance ID - case SDL_EVENT_JOYSTICK_REMOVED -> { - var jdevice = (SdlEvent.JoyDevice) event.data(); - SdlJoystickId jid = jdevice.which(); - logger.validateIsTrue(jid != null, "event.jdevice.which was null during SDL_EVENT_JOYSTICK_REMOVED event"); - - logger.debugLog("SDL event: Joystick removed: {}", jid.value()); - - getController(new SDLUniqueControllerID(jid)) - .ifPresentOrElse( - this::onControllerRemoved, - () -> CUtil.LOGGER.warn("Controller removed but not found: {}", jid.value()) - ); - } - } - } - - super.tick(outOfFocus); - } - - @Override - public void discoverControllers() { - logger.debugLog("Discovering controllers..."); - - SdlJoystickId[] joysticks = sdl.joystick().SDL_GetJoysticks(); - for (SdlJoystickId jid : joysticks) { - Optional controllerOpt = tryCreate( - new SDLUniqueControllerID(jid), - fetchTypeFromSDL(sdl, jid) - .orElse(new ControllerHIDInfo(ControllerType.DEFAULT, Optional.empty())) - ); - controllerOpt.ifPresent(controller -> onControllerConnected(controller, false)); - } - } - - @Override - protected Optional createController(UniqueControllerID ucid, ControllerHIDInfo hidInfo, ControlifyLogger controllerLogger) { - SdlJoystickId jid = ((SDLUniqueControllerID) ucid).jid(); - controllerLogger.debugLog("Creating controller: {}", jid.value()); - - boolean isGamepad = isControllerGamepad(ucid) && !DebugProperties.FORCE_JOYSTICK; - controllerLogger.debugLog("Controller is gamepad: {}", isGamepad); - - List drivers = new ArrayList<>(); - if ((SteamDeckUtil.DECK_MODE.isGamingMode() || DebugProperties.STEAM_DECK_CUSTOM_CEF_URL != null) - && !steamDeckConsumed - && hidInfo.type().namespace().equals(SteamDeckUtil.STEAM_DECK_NAMESPACE) - ) { - controllerLogger.debugLog("Controller is steam deck candidate"); - Optional steamDeckDriver = SteamDeckDriver.create(controllerLogger); - if (steamDeckDriver.isPresent()) { - drivers.add(steamDeckDriver.get()); - steamDeckConsumed = true; - controllerLogger.debugLog("Adding SteamDeckDriver - this controller has been reserved for Steam Deck"); - } - } - - if (isGamepad) { - SdlGamepadHandle ptrGamepad = SDLUtil.openGamepad(sdl, jid); - drivers.add(new SDL3GamepadDriver(sdl, ptrGamepad, jid, hidInfo.type(), controllerLogger)); - } else { - SdlJoystickHandle ptrJoystick = SDLUtil.openJoystick(sdl, jid); - drivers.add(new SDL3JoystickDriver(sdl, ptrJoystick, jid, hidInfo.type(), controllerLogger)); - } - - controllerLogger.debugLog("Drivers: {}", drivers.stream().map(driver -> driver.getClass().getSimpleName()).collect(Collectors.joining(", "))); - - CompoundDriver compoundDriver = new CompoundDriver(drivers); - - ControllerInfo info = new ControllerInfo(ucid, hidInfo.type(), hidInfo.hidDevice()); - ControllerEntity controller = new ControllerEntity( - info, - compoundDriver, - this.controlify.config().getActiveProfile(), - ProfileSettings.createDefault(), - controllerLogger - ); - - controllerLogger.debugLog("Unique Controller ID: {}", info.ucid()); - - this.addController(ucid, controller); - return Optional.of(controller); - } - - @Override - public boolean probeConnectedControllers() { - return sdl.joystick().SDL_HasJoystick() || sdl.gamepad().SDL_HasGamepad(); - } - - @Override - public boolean isControllerGamepad(UniqueControllerID ucid) { - SdlJoystickId jid = ((SDLUniqueControllerID) ucid).jid; - return sdl.gamepad().SDL_IsGamepad(jid); - } - - @Override - protected String getControllerSystemName(UniqueControllerID ucid) { - SdlJoystickId jid = ((SDLUniqueControllerID) ucid).jid; - return isControllerGamepad(ucid) - ? sdl.gamepad().SDL_GetGamepadNameForID(jid) - : sdl.joystick().SDL_GetJoystickNameForID(jid); - } - - private Optional getController(UniqueControllerID ucid) { - return Optional.ofNullable(controllersByJid.getOrDefault(ucid, null)); - } - - @Override - protected void loadGamepadMappings(ResourceProvider resourceProvider) { - CUtil.LOGGER.debugLog("Loading gamepad mappings..."); - - Optional resourceOpt = resourceProvider - .getResource(CUtil.rl("controllers/gamecontrollerdb-sdl3.txt")); - if (resourceOpt.isEmpty()) { - CUtil.LOGGER.error("Failed to find game controller database."); - return; - } - - try (InputStream is = resourceOpt.get().open()) { - byte[] bytes = is.readAllBytes(); - ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bytes.length); - byteBuffer.put(bytes); - byteBuffer.flip(); - - SdlIoStreamHandle stream = sdl.ioStream().SDL_IOFromConstMem(byteBuffer); - if (stream == null) throw new IllegalStateException("Failed to open stream"); - - int count = sdl.gamepad().SDL_AddGamepadMappingsFromIO(stream, true); - if (count < 0) { - CUtil.LOGGER.error("Failed to load gamepad mappings: {}", sdl.error().SDL_GetError()); - } else if (count == 0) { - CUtil.LOGGER.warn("Successfully applied gamepad mappings but none were found for this OS. Unsupported OS?"); - } else { - CUtil.LOGGER.log("Successfully loaded {} gamepad mapping entries!", count); - } - } catch (Throwable e) { - CUtil.LOGGER.error("Failed to load gamepad mappings", e); - } - } - - private static Optional fetchTypeFromSDL(Sdl sdl, SdlJoystickId jid) { - int vid = sdl.joystick().SDL_GetJoystickVendorForID(jid); - int pid = sdl.joystick().SDL_GetJoystickProductForID(jid); - SdlGuid guid = sdl.joystick().SDL_GetJoystickGUIDForID(jid); - String guidStr = guid.toString(); - - if (vid != 0 && pid != 0) { - CUtil.LOGGER.log("Using SDL to identify controller type."); - return Optional.of(new ControllerHIDInfo( - Controlify.instance().controllerTypeManager().getControllerType(new HIDID(vid, pid)), - Optional.of(new HIDDevice(new HIDID(vid, pid), guidStr)) - )); - } - - return Optional.empty(); - } - -} diff --git a/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManager.java b/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManager.java deleted file mode 100644 index a74a58593..000000000 --- a/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManager.java +++ /dev/null @@ -1,22 +0,0 @@ -package dev.isxander.controlify.controllermanager2; - -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.controllermanager.UniqueControllerID; -import dev.isxander.controlify.hid.HIDID; -import dev.isxander.controlify.utils.log.ControlifyLogger; - -public interface ControllerManager { - boolean canAddController( - UniqueControllerID ucid, - HIDID hidid, - ControllerType controllerType, - ControlifyLogger controllerLogger - ); - - void addController(ControllerEntity controller); - - void removeController(UniqueControllerID controller); - - ControllerType getControllerType(HIDID hidId); -} diff --git a/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManagerBackend.java b/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManagerBackend.java deleted file mode 100644 index 78a77c5be..000000000 --- a/src/main/java/dev/isxander/controlify/controllermanager2/ControllerManagerBackend.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.isxander.controlify.controllermanager2; - -import dev.isxander.controlify.controller.ControllerEntity; - -public interface ControllerManagerBackend { - - void setup(); - - void pollEvents(); - - void closeController(ControllerEntity controller); -} diff --git a/src/main/java/dev/isxander/controlify/gui/screen/BindConsumerScreen.java b/src/main/java/dev/isxander/controlify/gui/screen/BindConsumerScreen.java index b0b2700a5..764eb1ebf 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/BindConsumerScreen.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/BindConsumerScreen.java @@ -150,7 +150,7 @@ public ScreenProcessorImpl(BindConsumerScreen screen) { } @Override - public void onControllerUpdate(ControllerEntity controller) { + public void onControllerFixedUpdate(ControllerEntity controller) { // prevent all other controller input logic } } diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java b/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java index 42c5c4b7d..01dd89c0a 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java @@ -359,7 +359,7 @@ public ScreenProcessorImpl(ControllerMappingMakerScreen screen) { } @Override - public void onControllerUpdate(ControllerEntity controller) { + public void onControllerFixedUpdate(ControllerEntity controller) { } } diff --git a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java b/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java index f62ceecd2..4f8a86587 100644 --- a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java +++ b/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java @@ -41,7 +41,6 @@ import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; import net.minecraft.server.commands.GameModeCommand; import net.minecraft.util.Mth; -import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec2; @@ -83,7 +82,7 @@ public InGameInputHandler(ControllerEntity controller) { this.gyroToggledOn = false; } - public void inputTick() { + public void fixedUpdate() { boolean isController = ControllerPlayerMovement.shouldBeControllerInput(); handlePlayerLookInput(isController); diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionContext.java b/src/main/java/dev/isxander/controlify/input/action/ActionContext.java index 477527a15..6a93fc9d9 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionContext.java +++ b/src/main/java/dev/isxander/controlify/input/action/ActionContext.java @@ -1,9 +1,12 @@ package dev.isxander.controlify.input.action; +import net.minecraft.client.Minecraft; import net.minecraft.resources.Identifier; import org.jspecify.annotations.NonNull; -public record ActionContext(Identifier id) implements Comparable { +import java.util.function.Function; + +public record ActionContext(Identifier id, Function isApplicable) implements Comparable { @Override public int compareTo(@NonNull ActionContext o) { return this.id().compareTo(o.id()); diff --git a/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java index 3eba1f2a2..2a25963d8 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java @@ -39,8 +39,13 @@ private void initControlifyNow(CallbackInfo ci) { } } + @Inject(method = "runTick", at = @At("HEAD")) + private void doPolling(CallbackInfo ci) { + Controlify.instance().update(getTickDelta()); + } + @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MouseHandler;handleAccumulatedMovement()V")) - private void doPlayerLook(boolean advanceGameTime, CallbackInfo ci) { + private void doPlayerLook(CallbackInfo ci) { Controlify.instance().inGameInputHandler().ifPresent(ih -> ih.processPlayerLook(getTickDelta())); } diff --git a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java b/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java index 64eeb95dd..ac04de7df 100644 --- a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java @@ -58,7 +58,7 @@ public ScreenProcessor(T screen) { this.holdRepeatHelper = createHoldRepeatHelper(); } - public void onControllerUpdate(ControllerEntity controller) { + public void onControllerFixedUpdate(ControllerEntity controller) { Controlify.instance().virtualMouseHandler().handleControllerInput(controller); if (!Controlify.instance().virtualMouseHandler().isVirtualMouseEnabled()) { diff --git a/src/main/java/dev/isxander/controlify/utils/ControllerUtils.java b/src/main/java/dev/isxander/controlify/utils/ControllerUtils.java index a43df5f04..3c9b55f70 100644 --- a/src/main/java/dev/isxander/controlify/utils/ControllerUtils.java +++ b/src/main/java/dev/isxander/controlify/utils/ControllerUtils.java @@ -24,7 +24,7 @@ public static String createControllerString(ControllerEntity controller) { return String.format("'%s'#%s-%s (%s)", controller.name(), controller.info().ucid().toString(), - controller.info().hid().map(hid -> hid.hidid().toString()).orElse("hid"), + controller.info().hid().toString(), controller.info().type().friendlyName() ); } diff --git a/src/main/java/dev/isxander/controlify/utils/ControllerSetupWizard.java b/src/main/java/dev/isxander/controlify/utils/SetupWizard.java similarity index 97% rename from src/main/java/dev/isxander/controlify/utils/ControllerSetupWizard.java rename to src/main/java/dev/isxander/controlify/utils/SetupWizard.java index 66c592ea1..224ef4934 100644 --- a/src/main/java/dev/isxander/controlify/utils/ControllerSetupWizard.java +++ b/src/main/java/dev/isxander/controlify/utils/SetupWizard.java @@ -14,7 +14,7 @@ /** * Collection of screens that are in a specific order to set up various aspects of a controller. */ -public class ControllerSetupWizard { +public class SetupWizard { private final Deque stages = new ArrayDeque<>(); private final List screens = new ArrayList<>(); diff --git a/src/main/java/dev/isxander/controlify/utils/SetupWizardManager.java b/src/main/java/dev/isxander/controlify/utils/SetupWizardManager.java new file mode 100644 index 000000000..ca601f2ca --- /dev/null +++ b/src/main/java/dev/isxander/controlify/utils/SetupWizardManager.java @@ -0,0 +1,28 @@ +package dev.isxander.controlify.utils; + +import dev.isxander.controlify.gui.screen.DontInterruptScreen; + +import java.util.ArrayDeque; +import java.util.Queue; + +public class SetupWizardManager { + private final Queue setupWizards = new ArrayDeque<>(); + private SetupWizard currentSetupWizard = null; + + public void push(SetupWizard setupWizard) { + this.setupWizards.add(setupWizard); + } + + public void tick() { + if (MinecraftUtil.getOverlay() == null) { + if (this.currentSetupWizard != null && this.currentSetupWizard.isDone()) { + this.currentSetupWizard = null; + } + + if (!this.setupWizards.isEmpty() && !(MinecraftUtil.getScreen() instanceof DontInterruptScreen)) { + this.currentSetupWizard = this.setupWizards.poll(); + MinecraftUtil.setScreen(this.currentSetupWizard.start(MinecraftUtil.getScreen())); + } + } + } +} diff --git a/src/main/java/dev/isxander/controlify/wireless/LowBatteryNotifier.java b/src/main/java/dev/isxander/controlify/wireless/LowBatteryNotifier.java index 1c89d4ba3..c06014598 100644 --- a/src/main/java/dev/isxander/controlify/wireless/LowBatteryNotifier.java +++ b/src/main/java/dev/isxander/controlify/wireless/LowBatteryNotifier.java @@ -35,18 +35,18 @@ public static void tick() { if (controllerManager == null) return; - for (ControllerEntity controller : controllerManager.getConnectedControllers()) { + for (ControllerEntity controller : controllerManager.getAllControllers()) { PowerState batteryLevel = controller.batteryLevel() .map(BatteryLevelComponent::getBatteryLevel) .orElse(new PowerState.Unknown()); String uid = controller.uid(); - if (batteryLevel instanceof PowerState.Depleting depleting && depleting.percent() <= 10) { + if (batteryLevel instanceof PowerState.Depleting(int percent) && percent <= 10) { if (!notifiedControllers.contains(uid)) { MinecraftUtil.sendToast( Component.translatable("controlify.toast.low_battery.title"), - Component.translatable("controlify.toast.low_battery.message", controller.name(), depleting.percent() + "%"), + Component.translatable("controlify.toast.low_battery.message", controller.name(), percent + "%"), true ); From a1ed3ce68d0f36ab7b890283c2a60f77e1102e1e Mon Sep 17 00:00:00 2001 From: isxander Date: Fri, 16 Oct 2026 12:42:10 +0100 Subject: [PATCH 08/12] extract some of Controlify into ControllerCoordinator; start to reimplement ControllerMapping for pipeline; implement radial deadzones --- gradle/libs.versions.toml | 2 +- .../dev/isxander/controlify/Controlify.java | 245 ++++-------------- .../api/event/ControlifyEvents.java | 10 + .../controller/ControllerEntity.java | 14 + .../controller/gyro/GyroCalibrator.java | 63 ++--- .../controller/gyro/GyroComponent.java | 106 +++++--- .../controller/input/GamepadInputs.java | 1 - .../input/mapping/ControllerMapping.java | 50 ++-- .../controller/input/mapping/MapType.java | 4 +- .../input/mapping/MappingEntry.java | 160 +++--------- .../input/mapping/MappingEntryCodecs.java | 130 ++-------- .../controller/input/mapping/StateMapper.java | 13 - .../ControllerCoordinator.java | 241 +++++++++++++++++ .../SDLControllerBackend.java | 9 +- .../controlify/driver/CompoundDriver.java | 7 + .../isxander/controlify/driver/Driver.java | 4 + .../driver/sdl/SDL3GamepadDriver.java | 58 +++-- .../driver/sdl/SDLCommonDriver.java | 6 +- .../driver/sdl/SDLControllerEvent.java | 20 +- .../driver/sdl/SDLToPhysicalStage.java | 3 + .../screen/ControllerMappingMakerScreen.java | 31 --- .../controlify/input/InputComponent.java | 16 +- .../input/logical/SensorAccumulatorStage.java | 26 +- .../input/physical/DeadzoneStage.java | 105 ++++++-- .../input/physical/SensorProcessorStage.java | 8 +- .../mixins/core/MinecraftMixin.java | 4 +- 26 files changed, 687 insertions(+), 649 deletions(-) delete mode 100644 src/main/java/dev/isxander/controlify/controller/input/mapping/StateMapper.java create mode 100644 src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 56ccb5774..be2e9fc64 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] fabric_loader = "0.19.3" sdl_natives = "release-3.4.12" -sdl_java = "release-3.4.14-7" +sdl_java = "release-3.4.14-8" steamdeck4j = "1.1.7" quilt_parsers = "0.3.0" diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index ad4df0da7..662f62848 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -20,25 +20,21 @@ import dev.isxander.controlify.compatibility.ControlifyCompat; import dev.isxander.controlify.config.ConfigManager; import dev.isxander.controlify.config.dto.profile.defaults.DefaultConfigManager; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; import dev.isxander.controlify.contextual.ContextualDomains; import dev.isxander.controlify.contextual.RuleSetManager; import dev.isxander.controlify.controller.*; import dev.isxander.controlify.controller.dualsense.TriggerEffectManager; import dev.isxander.controlify.controller.id.ControllerTypeManager; -import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.controller.rumble.RumbleComponent; -import dev.isxander.controlify.controllermanager.ControllerBackend; +import dev.isxander.controlify.controllermanager.ControllerCoordinator; import dev.isxander.controlify.controllermanager.ControllerManager; -import dev.isxander.controlify.controllermanager.SDLControllerBackend; -import dev.isxander.controlify.driver.sdl.SDLNativesLoader; import dev.isxander.controlify.driver.steamdeck.SteamDeckMode; import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; import dev.isxander.controlify.font.InputFontMapper; import dev.isxander.controlify.gui.screen.*; import dev.isxander.controlify.debug.DebugProperties; import dev.isxander.controlify.ingame.ControllerPlayerMovement; +import dev.isxander.controlify.input.InputComponent; import dev.isxander.controlify.input.action.activator.ActivatorConfigManager; import dev.isxander.controlify.platform.client.PlatformClientUtil; import dev.isxander.controlify.platform.main.PlatformMainUtil; @@ -56,7 +52,6 @@ import dev.isxander.controlify.utils.*; import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; import dev.isxander.controlify.wireless.LowBatteryNotifier; -import dev.isxander.sdl.Sdl; import dev.isxander.yacl3.gui.YACLScreen; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; @@ -77,10 +72,7 @@ public class Controlify implements ControlifyApi { private Minecraft minecraft = null; - private ControllerManager controllerManager; - private ControllerBackend controllerBackend; - - private ControllerEntity currentController = null; + private ControllerCoordinator controllerCoordinator; private InputMode currentInputMode = InputMode.KEYBOARD_MOUSE; private ConfigManager config; @@ -102,13 +94,11 @@ public class Controlify implements ControlifyApi { private SetupWizardManager setupWizardManager; - private boolean hasDiscoveredControllers = false; - private int consecutiveInputSwitches = 0; private double lastInputSwitchTime = 0; private int showMouseTicks = 0; - private boolean mouseUsedThisTick = false; + private boolean mouseUsedThisFrame = false; /** * Called at usual fabric client entrypoint and in NeoForge mod constructor @@ -131,6 +121,7 @@ public void preInitialiseControlify() { PlatformMainUtil.getConfigDir() ); PlatformClientUtil.registerClientStopping(_ -> { + this.getControllerCoordinator().ifPresent(ControllerCoordinator::close); this.config.close(); }); @@ -245,10 +236,6 @@ public void initializeControlify() { this.virtualMouseHandler = new VirtualMouseHandler(); this.triggerEffectManager = new TriggerEffectManager(); - ControlifyEvents.CONTROLLER_CONNECTED.register(event -> this.onControllerAdded( - event.controller(), event.hotplugged())); - ControlifyEvents.CONTROLLER_DISCONNECTED.register(event -> this.onControllerRemoved(event.controller())); - ControlifyBindings.registerModdedBindings(); PlatformClientUtil.registerPostScreenRender((screen, graphics, mouseX, mouseY, tickDelta) -> @@ -257,15 +244,12 @@ public void initializeControlify() { ScreenProcessorProvider.provide(screen).render(controller, graphics, tickDelta); })); - this.controllerManager = new ControllerManager(); - try { - Sdl sdl = SDLNativesLoader.load(); - this.controllerBackend = new SDLControllerBackend(sdl, this, this.controllerManager); - } catch (Throwable throwable) { - CUtil.LOGGER.error("Failed to initialize controller backend", throwable); + ControlifyEvents.CURRENT_CONTROLLER_CHANGED.register(event -> + this.onCurrentControllerChanged(event.controller(), event.changeInputMode())); + this.controllerCoordinator = new ControllerCoordinator(this, this.setupWizardManager); + if (!this.controllerCoordinator.initialize()) { return; } - this.controllerBackend.setup(); PlatformClientUtil.registerClientTickStarted(this::fixedUpdate); @@ -324,155 +308,49 @@ private void doSteamDeckChecks() { } } - /** - * Loops through every controller slot and initialises it if it is connected. - * This is guaranteed to be called at most once. If no controllers are connected - * in the whole game lifecycle, this is never ran. - */ + /// Discovers already-connected controllers once the backend is initialized. public void discoverControllers() { - if (hasDiscoveredControllers) { - CUtil.LOGGER.warn("Attempted to discover controllers twice!"); - return; - } - hasDiscoveredControllers = true; - - DebugLog.log("Discovering and initializing controllers..."); - - this.controllerBackend.discoverControllers(); - - if (this.controllerManager.getAllControllers().isEmpty()) { - CUtil.LOGGER.log("No controllers found."); - } - - this.applyControllerSelection(false); - - config().saveIfDirty(); - - PlatformMainUtil.applyToControlifyEntrypoint(entrypoint -> { - try { - entrypoint.onControllersDiscovered(this); - } catch (Throwable e) { - CUtil.LOGGER.error("Failed to run `onControllersDiscovered` on Controlify entrypoint: {}", entrypoint.getClass().getName(), e); - } - }); - } - - /** - * Called when a controller is connected. Either from controller - * discovery or hotplugging. - * - * @param controller the new controller - * @param hotplugged if this was a result of hotplugging - */ - private void onControllerAdded(ControllerEntity controller, boolean hotplugged) { - SetupWizard wizard = new SetupWizard(); - DeviceSettings rememberedDevice = config().getSettings().getOrCreateDeviceSettings(controller.uid()); - rememberedDevice.name = controller.name(); - rememberedDevice.lastSeen = System.currentTimeMillis(); - rememberedDevice.controllerType = controller.info().type().namespace(); - config().markDirty(); - - String selectedUid = config().getActiveProfile().controllerUid; - if (selectedUid == null || selectedUid.equals(controller.uid())) { - this.setCurrentController(controller, true); - } - - // wizard.addStage(() -> SubmitUnknownControllerScreen.canSubmit(controller), nextScreen -> new SubmitUnknownControllerScreen(controller, nextScreen)); - - wizard.addStage( - () -> { - Optional inputOpt = controller.input(); - if (inputOpt.isPresent()) { - InputComponent input = inputOpt.get(); - DeviceSettings deviceSettings = config().getSettings().getOrCreateDeviceSettings(controller.uid()); - return !input.isDefinitelyGamepad() && deviceSettings.mapping == null; - } - return false; - }, - nextScreen -> new AskToMapControllerScreen(controller, nextScreen) - ); - wizard.addStage( - () -> controller.dualSense().isPresent() && controller.bluetooth().map(bt -> !bt.settings().dontShowWarning).orElse(false), - nextScreen -> new BluetoothWarningScreen(controller.bluetooth().orElseThrow(), nextScreen) - ); - - if (hotplugged) { - MinecraftUtil.sendToast( - Component.translatable("controlify.toast.controller_connected.title"), - Component.translatable("controlify.toast.controller_connected.description", controller.name()), - false - ); - } - - // saved after discovery - if (hotplugged) { - config().saveIfDirty(); - } - - this.setupWizardManager.push(wizard); - } - - /** - * Called when a controller is disconnected. - * @param controller controller that has been disconnected - */ - private void onControllerRemoved(ControllerEntity controller) { - if (this.getCurrentController().isPresent() && getCurrentController().get().equals(controller)) { - if (config().getActiveProfile().controllerUid == null) { - this.selectFirstConnectedController(); - } else { - this.setCurrentController(null, true); - } - } - - MinecraftUtil.sendToast( - Component.translatable("controlify.toast.controller_disconnected.title"), - Component.translatable("controlify.toast.controller_disconnected.description", controller.name()), - false - ); - } - - private void selectFirstConnectedController() { - Optional firstController = this.controllerManager.getAllControllers() - .stream() - .findFirst(); - this.setCurrentController(firstController.orElse(null), true); + this.getControllerCoordinator().ifPresent(ControllerCoordinator::discoverControllers); } /// Called once per frame, just after Minecraft has done its own SDL event polling. public void update(float tickDelta) { - this.controllerBackend.pollEvents(); + if (this.minecraft == null || this.controllerCoordinator == null || !this.controllerCoordinator.isReady()) { + return; + } + + boolean outOfFocus = !config().getSettings().globalSettings().outOfFocusInput + && !this.minecraft.isWindowActive(); + boolean givingInput = this.controllerCoordinator.update(outOfFocus); this.setupWizardManager.tick(); // handle showing/hiding mouse whilst in mixed input mode - if (this.minecraft.mouseHandler.isMouseGrabbed()) + if (this.minecraft.mouseHandler.isMouseGrabbed()) { showMouseTicks = 0; - if (currentInputMode() == InputMode.MIXED && showMouseTicks > 0) { - showMouseTicks--; - if (showMouseTicks == 0) { - restoreVirtualCursor(); - } } - - boolean outOfFocus = !config().getSettings().globalSettings().outOfFocusInput - && !this.minecraft.isWindowActive(); - this.getCurrentController().ifPresent(currentController -> { wrapControllerError( - () -> updateActiveController(currentController, outOfFocus), + () -> updateActiveController(currentController, givingInput), "Updating current controller", currentController ); }); - mouseUsedThisTick = false; + this.mouseUsedThisFrame = false; } /// Called at 20tps public void fixedUpdate() { LowBatteryNotifier.tick(); + if (currentInputMode() == InputMode.MIXED && showMouseTicks > 0) { + showMouseTicks--; + if (showMouseTicks == 0) { + restoreVirtualCursor(); + } + } + boolean outOfFocus = !config().getSettings().globalSettings().outOfFocusInput && !this.minecraft.isWindowActive(); @@ -485,15 +363,14 @@ public void fixedUpdate() { }); } - private void updateActiveController(ControllerEntity controller, boolean outOfFocus) { - boolean controllerInputSuppressed = outOfFocus || currentInputMode() == InputMode.KEYBOARD_MOUSE; - this.triggerEffectManager().tick(this.minecraft, controller); - this.triggerEffectManager().applyTriggerEffects(controller, controllerInputSuppressed); - - // TODO: move this to listener based InputPipeline signal approach - if (state.isGivingInput()) { + private void updateActiveController(ControllerEntity controller, boolean givingInput) { + if (givingInput) { minecraft.getFramerateLimitTracker().onInputReceived(); + if (showMouseTicks > 0 && !mouseUsedThisFrame) { + this.endTemporaryCursor(); + } + if (!this.currentInputMode().isController()) { this.setInputMode(config().getSettings().globalSettings().mixedInput ? InputMode.MIXED : InputMode.CONTROLLER); @@ -519,21 +396,19 @@ private void updateActiveController(ControllerEntity controller, boolean outOfFo } private void fixedUpdateActiveController(ControllerEntity controller, boolean outOfFocus) { - Optional rumbleManager = controller.rumble().map(RumbleComponent::rumbleManager); + boolean controllerInputSuppressed = outOfFocus || currentInputMode() == InputMode.KEYBOARD_MOUSE; + this.triggerEffectManager().tick(this.minecraft, controller); + this.triggerEffectManager().applyTriggerEffects(controller, controllerInputSuppressed); boolean isPaused = minecraft.isPaused() || MinecraftUtil.getScreen() instanceof PauseScreen; boolean isConfigScreen = MinecraftUtil.getScreen() instanceof YACLScreen; + Optional rumbleManager = controller.rumble().map(RumbleComponent::rumbleManager); rumbleManager.ifPresent(rumble -> rumble.setSilent(outOfFocus || (isPaused && !isConfigScreen) || currentInputMode() == InputMode.KEYBOARD_MOUSE)); if (!outOfFocus) { rumbleManager.ifPresent(RumbleManager::tick); } - if (showMouseTicks > 0 && !mouseUsedThisTick && state.isGivingInput()) { - // TODO: move this to a InputPipeline listener-based approach - this.endTemporaryCursor(); - } - if (minecraft.level != null) { this.inGameInputHandler().ifPresent(InGameInputHandler::fixedUpdate); } @@ -546,13 +421,7 @@ private void fixedUpdateActiveController(ControllerEntity controller, boolean ou } public void applyControllerSelection(boolean changeInputMode) { - String selectedUid = config().getActiveProfile().controllerUid; - Optional selected = controllerManager == null - ? Optional.empty() - : this.controllerManager.getAllControllers().stream() - .filter(controller -> selectedUid == null || selectedUid.equals(controller.uid())) - .findFirst(); - this.setCurrentController(selected.orElse(null), changeInputMode); + this.getControllerCoordinator().ifPresent(coordinator -> coordinator.applyControllerSelection(changeInputMode)); } public boolean switchProfile(int profileIndex, boolean remember) throws IOException { @@ -560,12 +429,8 @@ public boolean switchProfile(int profileIndex, boolean remember) throws IOExcept return false; } - ProfileSettings profile = config().getActiveProfile(); - if (this.controllerManager != null) { - this.controllerManager.getAllControllers().forEach(controller -> controller.setSettings(profile)); - } - this.applyControllerSelection(true); - this.setupForController(this.currentInputMode.isController() ? this.currentController : null); + this.getControllerCoordinator().ifPresent(ControllerCoordinator::applyActiveProfile); + this.setupForController(this.currentInputMode.isController() ? this.getCurrentController().orElse(null) : null); return true; } @@ -575,23 +440,22 @@ public ConfigManager config() { @Override public @NotNull Optional getCurrentController() { - return Optional.ofNullable(currentController); + return this.getControllerCoordinator().flatMap(ControllerCoordinator::currentController); } public void setCurrentController(@Nullable ControllerEntity controller, boolean changeInputMode) { - if (this.currentController == controller) return; - this.currentController = controller; + this.getControllerCoordinator().ifPresent(coordinator -> coordinator.setCurrentController(controller, changeInputMode)); + } + private void onCurrentControllerChanged(@Nullable ControllerEntity controller, boolean changeInputMode) { boolean changedInputMode = false; if (controller == null) { changedInputMode = this.setInputMode(InputMode.KEYBOARD_MOUSE); - DebugLog.log("Cleared current controller."); - } else { + } else if (changeInputMode) { changedInputMode = this.setInputMode(config().getSettings().globalSettings().mixedInput ? InputMode.MIXED : InputMode.CONTROLLER); - DebugLog.log("Updated current controller to {}({})", controller.name(), controller.uid()); } if (!changedInputMode) { - this.setupForController(controller); + this.setupForController(this.currentInputMode.isController() ? controller : null); } } @@ -620,7 +484,7 @@ public boolean setInputMode(@NotNull InputMode newInputMode) { hideMouse(newInputMode.isController(), true); } - this.setupForController(this.currentInputMode.isController() ? this.currentController : null); + this.setupForController(this.currentInputMode.isController() ? this.getCurrentController().orElse(null) : null); KeyMapping.resetToggleKeys(); @@ -655,14 +519,15 @@ private void setupForController(@Nullable ControllerEntity controller) { this.inGameInputHandler = new InGameInputHandler(controller); this.inGameButtonGuide = new InGameButtonGuide(controller, this.minecraft); - controller.input().ifPresent(input -> { - input.rawStateNow().clearState(); - input.rawStateThen().clearState(); - }); + controller.input().ifPresent(InputComponent::resetActions); } public Optional getControllerManager() { - return Optional.ofNullable(controllerManager); + return this.getControllerCoordinator().map(ControllerCoordinator::controllerManager); + } + + public Optional getControllerCoordinator() { + return Optional.ofNullable(this.controllerCoordinator); } public Optional inGameInputHandler() { @@ -697,7 +562,7 @@ public void hideMouse(boolean hide, boolean moveMouse) { public void showCursorTemporarily() { if (currentInputMode() == InputMode.MIXED && !minecraft.mouseHandler.isMouseGrabbed()) { - mouseUsedThisTick = true; + mouseUsedThisFrame = true; if (virtualMouseHandler().isVirtualMouseEnabled()) { moveCursorToVirtualMouse(); virtualMouseHandler().disableVirtualMouse(); diff --git a/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java b/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java index e96f10ff1..34c721b70 100644 --- a/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java +++ b/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java @@ -10,12 +10,19 @@ import dev.isxander.controlify.api.ingameinput.LookInputModifier; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.platform.EventHandler; +import org.jetbrains.annotations.Nullable; public final class ControlifyEvents { public static final EventHandler CONTROLLER_CONNECTED = EventHandler.createPlatformBackedEvent(); public static final EventHandler CONTROLLER_DISCONNECTED = EventHandler.createPlatformBackedEvent(); + /** + * Triggers after the current controller changes and its activation has been updated. + * The controller is null when the current selection is cleared. + */ + public static final EventHandler CURRENT_CONTROLLER_CHANGED = EventHandler.createPlatformBackedEvent(); + /** * Triggers when the input mode is changed from keyboard to controller or vice versa. */ @@ -54,6 +61,9 @@ public record ControllerConnected(ControllerEntity controller, boolean hotplugge public record ControllerDisconnected(ControllerEntity controller) { } + public record CurrentControllerChanged(@Nullable ControllerEntity controller, boolean changeInputMode) { + } + public record InputModeChanged(InputMode mode) { } diff --git a/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java b/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java index 6481592a2..037edbec7 100644 --- a/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java +++ b/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java @@ -37,6 +37,7 @@ public class ControllerEntity extends ECSEntityImpl { private ProfileSettings settings; private final ProfileSettings defaultSettings; private final ControlifyLogger logger; + private boolean active; public ControllerEntity( ControllerInfo info, @@ -151,7 +152,20 @@ public void update(boolean outOfFocus) { this.driver.update(this, outOfFocus); } + public boolean isActive() { + return this.active; + } + + public void setActive(boolean active) { + if (this.active == active) { + return; + } + this.active = active; + this.driver.setActive(active); + } + public void close() { + this.setActive(false); this.getAllComponents().values().forEach(ECSComponent::close); this.driver.close(); } diff --git a/src/main/java/dev/isxander/controlify/controller/gyro/GyroCalibrator.java b/src/main/java/dev/isxander/controlify/controller/gyro/GyroCalibrator.java index 7b7bf3ebc..a626e4fe7 100644 --- a/src/main/java/dev/isxander/controlify/controller/gyro/GyroCalibrator.java +++ b/src/main/java/dev/isxander/controlify/controller/gyro/GyroCalibrator.java @@ -8,9 +8,8 @@ /** * Implements rolling gyro calibration using exponential moving average - * for background bias estimation. The calibrator continuously updates - * during stationary periods (low angular velocity) to track and correct - * for gyro drift over time. + * for background bias estimation during stationary periods (low angular velocity). + * Bias application is handled by the input pipeline using the device settings. */ public class GyroCalibrator { // Exponential moving average (EMA) alpha value - lower = slower adaptation, more stable @@ -30,54 +29,34 @@ public class GyroCalibrator { // Counter for consecutive stationary samples private int stationarySampleCount = 0; - /** - * Update the calibration with a new gyro sample. - * This should be called every time new gyro data arrives. - * - * @param rawGyroState The raw gyro reading from SDL3 - */ - public void update(GyroStateC rawGyroState) { + public void update(float x, float y, float z) { // Check if the gyro appears to be stationary - boolean isStationary = isStationary(rawGyroState); + boolean isStationary = isStationary(x, y, z); if (isStationary) { - stationarySampleCount++; + this.stationarySampleCount++; // Only update bias estimate if we've been stationary long enough - if (stationarySampleCount >= MIN_STATIONARY_SAMPLES) { + if (this.stationarySampleCount >= MIN_STATIONARY_SAMPLES) { // Update bias estimate using exponential moving average // New bias = (1 - alpha) * old_bias + alpha * current_reading - biasEstimate.x = (1 - EMA_ALPHA) * biasEstimate.x + EMA_ALPHA * rawGyroState.pitch(); - biasEstimate.y = (1 - EMA_ALPHA) * biasEstimate.y + EMA_ALPHA * rawGyroState.yaw(); - biasEstimate.z = (1 - EMA_ALPHA) * biasEstimate.z + EMA_ALPHA * rawGyroState.roll(); + this.biasEstimate.x = (1 - EMA_ALPHA) * this.biasEstimate.x + EMA_ALPHA * x; + this.biasEstimate.y = (1 - EMA_ALPHA) * this.biasEstimate.y + EMA_ALPHA * y; + this.biasEstimate.z = (1 - EMA_ALPHA) * this.biasEstimate.z + EMA_ALPHA * z; } } else { // Reset stationary counter when motion is detected - stationarySampleCount = 0; + this.stationarySampleCount = 0; } } - /** - * Apply the current bias correction to a raw gyro reading. - * - * @param rawGyroState The raw gyro reading from SDL3 - * @return Calibrated gyro state with bias removed - */ - public GyroState applyCalibration(GyroStateC rawGyroState) { - return new GyroState( - rawGyroState.pitch() - biasEstimate.pitch(), - rawGyroState.yaw() - biasEstimate.yaw(), - rawGyroState.roll() - biasEstimate.roll() - ); - } - /** * Check if the gyro appears to be stationary based on angular velocity. */ - private boolean isStationary(GyroStateC state) { - return Math.abs(state.pitch()) < STATIONARY_THRESHOLD - && Math.abs(state.yaw()) < STATIONARY_THRESHOLD - && Math.abs(state.roll()) < STATIONARY_THRESHOLD; + private boolean isStationary(float x, float y, float z) { + return Math.abs(x) < STATIONARY_THRESHOLD + && Math.abs(y) < STATIONARY_THRESHOLD + && Math.abs(z) < STATIONARY_THRESHOLD; } /** @@ -87,19 +66,13 @@ public GyroStateC getCurrentBias() { return new GyroState(this.biasEstimate); } - /** - * Set the bias estimate (for loading from config). - */ public void setBias(GyroStateC bias) { - biasEstimate.set(bias.pitch(), bias.yaw(), bias.roll()); - stationarySampleCount = 0; + this.biasEstimate.set(bias.x(), bias.y(), bias.z()); + this.stationarySampleCount = 0; } - /** - * Reset the calibrator to initial state. - */ public void reset() { - biasEstimate.set(0, 0, 0); - stationarySampleCount = 0; + this.biasEstimate.set(0, 0, 0); + this.stationarySampleCount = 0; } } diff --git a/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java b/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java index 3a49a211b..8bfdfb87d 100644 --- a/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java +++ b/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java @@ -11,54 +11,93 @@ import dev.isxander.controlify.config.settings.profile.GyroSettings; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.controller.impl.ECSComponentImpl; +import dev.isxander.controlify.input.InputPipeline; +import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.input.physical.PhysicalSensorSignal; +import dev.isxander.controlify.input.physical.PhysicalSignal; import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.utils.event.EventSource; import net.minecraft.resources.Identifier; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; public class GyroComponent extends ECSComponentImpl { public static final Identifier ID = CUtil.rl("gyro"); + private final InputPipeline inputPipeline; + private @Nullable EventSource.Subscription calibrationSubscription; + private @Nullable EventSource.Subscription sensorSubscription; + private DeviceSettings deviceSettings; private GyroStateC gyroState = GyroStateC.ZERO; + private static final long MAX_SAMPLE_AGE_NANOS = 50_000_000L; + private long lastStateTimeNanos; private final GyroCalibrator calibrator = new GyroCalibrator(); - // Save calibration every 5 seconds (100 ticks) - private static final int CALIBRATION_SAVE_INTERVAL = 100; - private int ticksSinceLastSave = 0; + private static final long CALIBRATION_SAVE_INTERVAL_NANOS = 5_000_000_000L; + private long lastCalibrationSaveTimeNanos; private GyroStateC lastSavedBias = GyroStateC.ZERO; + public GyroComponent(InputPipeline inputPipeline) { + this.inputPipeline = Objects.requireNonNull(inputPipeline); + } + @Override public void attach(ControllerEntity controller) { super.attach(controller); // Load the calibration from device settings - DeviceSettings deviceSettings = Controlify.instance().config().getSettings() + this.deviceSettings = Controlify.instance().config().getSettings() .getOrCreateDeviceSettings(controller.uid()); - GyroStateC savedOffset = deviceSettings.gyroCalibration.offset; + GyroStateC savedOffset = this.deviceSettings.gyroCalibration.offset; // Initialize the calibrator with the saved offset calibrator.setBias(savedOffset); - lastSavedBias = savedOffset; + lastSavedBias = new GyroState(savedOffset); + this.lastCalibrationSaveTimeNanos = System.nanoTime(); + + this.calibrationSubscription = this.inputPipeline.sourceRawPhysicalSignals().subscribe(this::onRawSignal); + this.sensorSubscription = this.inputPipeline.sourceLogicalSignals().subscribe(this::onSignal); } - public GyroStateC getState() { - return this.gyroState; + private void onRawSignal(PhysicalSignal signal) { + if (signal instanceof PhysicalSensorSignal(_, _, SensorType sensorType, float x, float y, float z) + && sensorType == SensorType.GYROSCOPE) { + this.updateCalibration(x, y, z); + } + } + + private void updateCalibration(float x, float y, float z) { + this.calibrator.update(x, y, z); + // The raw tap runs before SensorProcessorStage, so its bias supplier sees this update immediately. + this.deviceSettings.gyroCalibration.offset = this.calibrator.getCurrentBias(); + + long now = System.nanoTime(); + if (now - this.lastCalibrationSaveTimeNanos >= CALIBRATION_SAVE_INTERVAL_NANOS) { + this.lastCalibrationSaveTimeNanos = now; + this.saveCalibrationIfChanged(); + } } - public void setState(GyroStateC state) { - // Update the calibrator with the raw reading - calibrator.update(state); - // Store the calibrated state - this.gyroState = calibrator.applyCalibration(state); - - // Periodically save calibration if it has changed significantly - ticksSinceLastSave++; - if (ticksSinceLastSave >= CALIBRATION_SAVE_INTERVAL) { - ticksSinceLastSave = 0; - saveCalibrationIfChanged(); + private void onSignal(LogicalSignal signal) { + if (signal instanceof LogicalSignal.SensorInterval(_, _, SensorType sensorType, float x, float y, float z) + && sensorType == SensorType.GYROSCOPE) { + // The pipeline has already calibrated, filtered and integrated these values into radians. + this.gyroState = new GyroState(x, y, z); + this.lastStateTimeNanos = System.nanoTime(); } } + /// Returns the latest integrated gyro interval in radians. + /// Missing samples expire naturally, independently of controller selection. + public GyroStateC getState() { + return System.nanoTime() - this.lastStateTimeNanos > MAX_SAMPLE_AGE_NANOS + ? GyroStateC.ZERO : this.gyroState; + } + private void saveCalibrationIfChanged() { - GyroStateC currentBias = calibrator.getCurrentBias(); + GyroStateC currentBias = this.deviceSettings.gyroCalibration.offset; // Check if bias has changed significantly (more than 0.001 rad/s on any axis) float threshold = 0.001f; @@ -66,17 +105,10 @@ private void saveCalibrationIfChanged() { Math.abs(currentBias.yaw() - lastSavedBias.yaw()) > threshold || Math.abs(currentBias.roll() - lastSavedBias.roll()) > threshold) { - // Save to device settings - DeviceSettings deviceSettings = Controlify.instance().config().getSettings() - .getOrCreateDeviceSettings(controller().uid()); - deviceSettings.gyroCalibration.offset = new GyroState(currentBias); - - // Mark config as dirty so it gets saved at some point - // We don't really care if it never gets saved if the user never changes any other config - // that triggers a save, we just recalibrate from last saved on next launch + // Settings update on every sample; persistence is checked at a fixed time interval. Controlify.instance().config().markDirty(); - lastSavedBias = currentBias; + lastSavedBias = new GyroState(currentBias); } } @@ -97,4 +129,20 @@ public Identifier id() { return ID; } + @Override + public void close() { + if (this.calibrationSubscription != null) { + this.calibrationSubscription.close(); + this.calibrationSubscription = null; + } + if (this.sensorSubscription != null) { + this.sensorSubscription.close(); + this.sensorSubscription = null; + } + if (this.deviceSettings != null) { + this.saveCalibrationIfChanged(); + } + super.close(); + } + } diff --git a/src/main/java/dev/isxander/controlify/controller/input/GamepadInputs.java b/src/main/java/dev/isxander/controlify/controller/input/GamepadInputs.java index b663983f6..71bf9c65b 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/GamepadInputs.java +++ b/src/main/java/dev/isxander/controlify/controller/input/GamepadInputs.java @@ -61,7 +61,6 @@ private GamepadInputs() { public static final Identifier MISC_5_BUTTON = button("misc_5"); public static final Identifier MISC_6_BUTTON = button("misc_6"); - public static final Identifier RIGHT_PADDLE_1_BUTTON = button("right_paddle_1"); public static final Identifier RIGHT_PADDLE_2_BUTTON = button("right_paddle_2"); public static final Identifier LEFT_PADDLE_1_BUTTON = button("left_paddle_1"); diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java index bdf7bac7f..4da4e14bf 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java +++ b/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java @@ -7,22 +7,29 @@ package dev.isxander.controlify.controller.input.mapping; import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.input.ControllerState; import dev.isxander.controlify.controller.input.DeadzoneGroup; -import dev.isxander.controlify.controller.input.ModifiableControllerState; -import dev.isxander.controlify.controller.impl.ControllerStateImpl; +import dev.isxander.controlify.controller.input.GamepadInputs; import net.minecraft.resources.Identifier; import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; public record ControllerMapping( List mappings, LinkedHashMap deadzones -) implements StateMapper { +) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( MappingEntry.codec() .listOf() + .validate(entries -> { + if (!validateDistinctMappingSources(entries)) { + return DataResult.error(() -> "Every mapping entry must have a distinct `from` source input"); + } + return DataResult.success(entries); + }) .fieldOf("mappings") .forGetter(ControllerMapping::mappings), Codec.unboundedMap(Identifier.CODEC, DeadzoneGroup.CODEC) @@ -31,22 +38,33 @@ public record ControllerMapping( .forGetter(ControllerMapping::deadzones) ).apply(instance, ControllerMapping::new)); - @Override - public ControllerState mapState(ControllerState state) { - if (mappings.isEmpty()) { - return state; - } - - ModifiableControllerState newState = new ControllerStateImpl(); - - for (MappingEntry mapping : mappings) { - mapping.apply(state, newState); + public ControllerMapping { + if (!validateDistinctMappingSources(mappings)) { + throw new IllegalArgumentException("Every mapping entry must have a distinct source input"); } + } - return newState; + public Map createMappingEntryMap() { + return this.mappings.stream() + .collect(Collectors.toUnmodifiableMap( + MappingEntry::sourceInput, + Function.identity() + )); } public static final ControllerMapping NO_MAPPING = new Builder().build(); + public static final ControllerMapping GAMEPAD_DEADZONES_ONLY_MAPPING = new Builder() + .putDeadzoneGroups(GamepadInputs.DEADZONE_GROUPS) + .build(); + + private static boolean validateDistinctMappingSources(Collection entries) { + long entryCount = entries.size(); + long distinctSourceCount = entries.stream() + .map(MappingEntry::sourceInput) + .distinct() + .count(); + return entryCount == distinctSourceCount; + } public static class Builder { private final List mappings = new ArrayList<>(); @@ -56,7 +74,7 @@ public Builder putMapping(MappingEntry mapping) { if (mapping == null) return this; - mappings.add(mapping); + this.mappings.add(mapping); return this; } diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/MapType.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/MapType.java index 35e83f294..17e82057e 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/MapType.java +++ b/src/main/java/dev/isxander/controlify/controller/input/mapping/MapType.java @@ -12,9 +12,7 @@ public enum MapType implements StringRepresentable { BUTTON, - AXIS, - HAT, - NOTHING; + AXIS; public static final Codec CODEC = StringRepresentable.fromEnum(MapType::values); diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java index 696f62c2f..b834bbebd 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java +++ b/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java @@ -10,11 +10,20 @@ import dev.isxander.controlify.controller.input.ControllerState; import dev.isxander.controlify.controller.input.HatState; import dev.isxander.controlify.controller.input.ModifiableControllerState; +import dev.isxander.controlify.input.physical.PhysicalInputSignal; import dev.isxander.controlify.utils.MthExt; import net.minecraft.resources.Identifier; +import org.jspecify.annotations.Nullable; public sealed interface MappingEntry { - void apply(ControllerState oldState, ModifiableControllerState newState); + /// Transforms an input signal + /// A mapping entry may transform a signal to one with a differing input identifier. + /// This function will only be called when the signal matches {@link sourceInput}. + PhysicalInputSignal apply(PhysicalInputSignal signal); + + /// The physical input identifier this mapping entry transforms. + /// The {@link apply} function will only receive signals whose {@link PhysicalInputSignal#input()} matches. + Identifier sourceInput(); MapType inputType(); @@ -25,146 +34,61 @@ static Codec codec() { } sealed interface FromButton extends MappingEntry { - record ToButton(Identifier from, Identifier to, boolean invert, MapType inputType, MapType outputType) implements FromButton { - public ToButton(Identifier from, Identifier to, boolean invert) { - this(from, to, invert, MapType.BUTTON, MapType.BUTTON); - } - - @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - boolean fromState = oldState.isButtonDown(from); - if (invert()) fromState = !fromState; - newState.setButton(to, fromState); - } - } - - record ToAxis(Identifier from, Identifier to, float offState, float onState, MapType inputType, MapType outputType) implements FromButton { - public ToAxis(Identifier from, Identifier to, float offState, float onState) { - this(from, to, offState, onState, MapType.BUTTON, MapType.AXIS); + record ToButton(Identifier sourceInput, Identifier to, boolean invert, MapType inputType, MapType outputType) implements FromButton { + public ToButton(Identifier sourceInput, Identifier to, boolean invert) { + this(sourceInput, to, invert, MapType.BUTTON, MapType.BUTTON); } @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - newState.setAxis(to, oldState.isButtonDown(from) ? onState : offState); + public PhysicalInputSignal apply(PhysicalInputSignal signal) { + if (signal instanceof PhysicalInputSignal.ButtonChanged(long timeNanos, _, boolean state)) { + return new PhysicalInputSignal.ButtonChanged(timeNanos, to, invert != state); + } + return signal; } } - record ToHat(Identifier from, Identifier to, HatState offState, HatState onState, MapType inputType, MapType outputType) implements FromButton { - public ToHat(Identifier from, Identifier to, HatState offState, HatState onState) { - this(from, to, offState, onState, MapType.BUTTON, MapType.HAT); + record ToAxis(Identifier sourceInput, Identifier to, float offState, float onState, MapType inputType, MapType outputType) implements FromButton { + public ToAxis(Identifier sourceInput, Identifier to, float offState, float onState) { + this(sourceInput, to, offState, onState, MapType.BUTTON, MapType.AXIS); } @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - newState.setHat(to, oldState.isButtonDown(from) ? onState : offState); + public PhysicalInputSignal apply(PhysicalInputSignal signal) { + if (signal instanceof PhysicalInputSignal.ButtonChanged(long timeNanos, _, boolean state)) { + return new PhysicalInputSignal.AxisMoved(timeNanos, this.to, state ? onState : offState); + } + return signal; } } } sealed interface FromAxis extends MappingEntry { - record ToButton(Identifier from, Identifier to, float threshold, MapType inputType, MapType outputType) implements FromAxis { - public ToButton(Identifier from, Identifier to, float threshold) { - this(from, to, threshold, MapType.AXIS, MapType.BUTTON); - } - - @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - newState.setButton(to, oldState.getAxisState(from) >= threshold); - } - } - - record ToAxis(Identifier from, Identifier to, float minIn, float minOut, float maxIn, float maxOut, MapType inputType, MapType outputType) implements FromAxis { - public ToAxis(Identifier from, Identifier to, float minIn, float minOut, float maxIn, float maxOut) { - this(from, to, minIn, minOut, maxIn, maxOut, MapType.AXIS, MapType.AXIS); - } - - @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - float oldVal = oldState.getAxisState(from); - float newVal = MthExt.remap(oldVal, minIn, maxIn, minOut, maxOut); - newState.setAxis(to, newVal); - } - } - - record ToHat(Identifier from, Identifier to, float threshold, HatState targetState, MapType inputType, MapType outputType) implements FromAxis { - public ToHat(Identifier from, Identifier to, float threshold, HatState targetState) { - this(from, to, threshold, targetState, MapType.AXIS, MapType.HAT); - } - - @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - float oldVal = oldState.getAxisState(from); - newState.setHat(to, oldVal >= threshold ? targetState : HatState.CENTERED); - } - } - } - - sealed interface FromHat extends MappingEntry { - record ToButton(Identifier from, Identifier to, HatState targetState, MapType inputType, MapType outputType) implements FromHat { - public ToButton(Identifier from, Identifier to, HatState targetState) { - this(from, to, targetState, MapType.HAT, MapType.BUTTON); - } - - @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - newState.setButton(to, oldState.getHatState(from) == targetState); - } - } - - record ToAxis(Identifier from, Identifier to, HatState targetState, float onState, float offState, MapType inputType, MapType outputType) implements FromHat { - public ToAxis(Identifier from, Identifier to, HatState targetState, float onState, float offState) { - this(from, to, targetState, onState, offState, MapType.HAT, MapType.AXIS); - } - - @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - newState.setAxis(to, oldState.getHatState(from) == targetState ? onState : offState); - } - } - - record ToHat(Identifier from, Identifier to, MapType inputType, MapType outputType) implements FromHat { - public ToHat(Identifier from, Identifier to) { - this(from, to, MapType.HAT, MapType.HAT); - } - - @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - newState.setHat(to, oldState.getHatState(from)); - } - } - } - - sealed interface FromNothing extends MappingEntry { - record ToButton(Identifier to, boolean state, MapType inputType, MapType outputType) implements FromNothing { - public ToButton(Identifier to, boolean state) { - this(to, state, MapType.NOTHING, MapType.BUTTON); - } - - @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - newState.setButton(to, state); - } - } - - record ToAxis(Identifier to, float state, MapType inputType, MapType outputType) implements FromNothing { - public ToAxis(Identifier to, float state) { - this(to, state, MapType.NOTHING, MapType.AXIS); + record ToButton(Identifier sourceInput, Identifier to, float threshold, MapType inputType, MapType outputType) implements FromAxis { + public ToButton(Identifier sourceInput, Identifier to, float threshold) { + this(sourceInput, to, threshold, MapType.AXIS, MapType.BUTTON); } @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - newState.setAxis(to, state); + public PhysicalInputSignal apply(PhysicalInputSignal signal) { + if (signal instanceof PhysicalInputSignal.AxisMoved(long timeNanos, _, float value)) { + return new PhysicalInputSignal.ButtonChanged(timeNanos, to, value >= threshold); + } + return signal; } } - record ToHat(Identifier to, MapType inputType, MapType outputType) implements FromNothing { - public ToHat(Identifier to) { - this(to, MapType.NOTHING, MapType.HAT); + record ToAxis(Identifier sourceInput, Identifier to, float minIn, float minOut, float maxIn, float maxOut, MapType inputType, MapType outputType) implements FromAxis { + public ToAxis(Identifier sourceInput, Identifier to, float minIn, float minOut, float maxIn, float maxOut) { + this(sourceInput, to, minIn, minOut, maxIn, maxOut, MapType.AXIS, MapType.AXIS); } @Override - public void apply(ControllerState oldState, ModifiableControllerState newState) { - newState.setHat(to, HatState.CENTERED); + public PhysicalInputSignal apply(PhysicalInputSignal signal) { + if (signal instanceof PhysicalInputSignal.AxisMoved(long timeNanos, _, float value)) { + return new PhysicalInputSignal.AxisMoved(timeNanos, to, MthExt.remap(value, minIn, maxIn, minOut, maxOut)); + } + return signal; } } } diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java index 2f3c09253..03dced81b 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java +++ b/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java @@ -22,7 +22,7 @@ final class MappingEntryCodecs { ).apply(instance, MappingEntryStub::new)); public static final Codec CODEC_BUTTON_TO_BUTTON = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromButton.ToButton::from), + Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromButton.ToButton::sourceInput), Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromButton.ToButton::to), Codec.BOOL.fieldOf("invert").forGetter(MappingEntry.FromButton.ToButton::invert), MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromButton.ToButton::inputType), @@ -30,7 +30,7 @@ final class MappingEntryCodecs { ).apply(instance, MappingEntry.FromButton.ToButton::new)); public static final Codec CODEC_BUTTON_TO_AXIS = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromButton.ToAxis::from), + Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromButton.ToAxis::sourceInput), Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromButton.ToAxis::to), Codec.FLOAT.fieldOf("off_state").forGetter(MappingEntry.FromButton.ToAxis::offState), Codec.FLOAT.fieldOf("on_state").forGetter(MappingEntry.FromButton.ToAxis::onState), @@ -38,17 +38,8 @@ final class MappingEntryCodecs { MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromButton.ToAxis::outputType) ).apply(instance, MappingEntry.FromButton.ToAxis::new)); - public static final Codec CODEC_BUTTON_TO_HAT = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromButton.ToHat::from), - Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromButton.ToHat::to), - HatState.CODEC.fieldOf("off_state").forGetter(MappingEntry.FromButton.ToHat::offState), - HatState.CODEC.fieldOf("on_state").forGetter(MappingEntry.FromButton.ToHat::onState), - MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromButton.ToHat::inputType), - MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromButton.ToHat::outputType) - ).apply(instance, MappingEntry.FromButton.ToHat::new)); - public static final Codec CODEC_AXIS_TO_BUTTON = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromAxis.ToButton::from), + Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromAxis.ToButton::sourceInput), Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromAxis.ToButton::to), Codec.FLOAT.fieldOf("threshold").forGetter(MappingEntry.FromAxis.ToButton::threshold), MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromAxis.ToButton::inputType), @@ -56,7 +47,7 @@ final class MappingEntryCodecs { ).apply(instance, MappingEntry.FromAxis.ToButton::new)); public static final Codec CODEC_AXIS_TO_AXIS = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromAxis.ToAxis::from), + Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromAxis.ToAxis::sourceInput), Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromAxis.ToAxis::to), Codec.FLOAT.fieldOf("min_in").forGetter(MappingEntry.FromAxis.ToAxis::minIn), Codec.FLOAT.fieldOf("min_out").forGetter(MappingEntry.FromAxis.ToAxis::minOut), @@ -66,120 +57,33 @@ final class MappingEntryCodecs { MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromAxis.ToAxis::outputType) ).apply(instance, MappingEntry.FromAxis.ToAxis::new)); - public static final Codec CODEC_AXIS_TO_HAT = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromAxis.ToHat::from), - Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromAxis.ToHat::to), - Codec.FLOAT.fieldOf("threshold").forGetter(MappingEntry.FromAxis.ToHat::threshold), - HatState.CODEC.fieldOf("target_state").forGetter(MappingEntry.FromAxis.ToHat::targetState), - MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromAxis.ToHat::inputType), - MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromAxis.ToHat::outputType) - ).apply(instance, MappingEntry.FromAxis.ToHat::new)); - - public static final Codec CODEC_HAT_TO_BUTTON = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromHat.ToButton::from), - Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromHat.ToButton::to), - HatState.CODEC.fieldOf("target_state").forGetter(MappingEntry.FromHat.ToButton::targetState), - MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromHat.ToButton::inputType), - MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromHat.ToButton::outputType) - ).apply(instance, MappingEntry.FromHat.ToButton::new)); - - public static final Codec CODEC_HAT_TO_AXIS = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromHat.ToAxis::from), - Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromHat.ToAxis::to), - HatState.CODEC.fieldOf("target_state").forGetter(MappingEntry.FromHat.ToAxis::targetState), - Codec.FLOAT.fieldOf("on_state").forGetter(MappingEntry.FromHat.ToAxis::onState), - Codec.FLOAT.fieldOf("off_state").forGetter(MappingEntry.FromHat.ToAxis::offState), - MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromHat.ToAxis::inputType), - MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromHat.ToAxis::outputType) - ).apply(instance, MappingEntry.FromHat.ToAxis::new)); - - public static final Codec CODEC_HAT_TO_HAT = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("from").forGetter(MappingEntry.FromHat.ToHat::from), - Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromHat.ToHat::to), - MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromHat.ToHat::inputType), - MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromHat.ToHat::outputType) - ).apply(instance, MappingEntry.FromHat.ToHat::new)); - - public static final Codec CODEC_NOTHING_TO_BUTTON = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromNothing.ToButton::to), - Codec.BOOL.fieldOf("state").forGetter(MappingEntry.FromNothing.ToButton::state), - MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromNothing.ToButton::inputType), - MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromNothing.ToButton::outputType) - ).apply(instance, MappingEntry.FromNothing.ToButton::new)); - - public static final Codec CODEC_NOTHING_TO_AXIS = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromNothing.ToAxis::to), - Codec.FLOAT.fieldOf("state").forGetter(MappingEntry.FromNothing.ToAxis::state), - MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromNothing.ToAxis::inputType), - MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromNothing.ToAxis::outputType) - ).apply(instance, MappingEntry.FromNothing.ToAxis::new)); - - public static final Codec CODEC_NOTHING_TO_HAT = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("to").forGetter(MappingEntry.FromNothing.ToHat::to), - MapType.CODEC.fieldOf("input_type").forGetter(MappingEntry.FromNothing.ToHat::inputType), - MapType.CODEC.fieldOf("output_type").forGetter(MappingEntry.FromNothing.ToHat::outputType) - ).apply(instance, MappingEntry.FromNothing.ToHat::new)); - public static final Codec CODEC = new Codec<>() { @Override public DataResult encode(MappingEntry input, DynamicOps ops, T prefix) { return switch (input) { case MappingEntry.FromButton.ToButton e -> CODEC_BUTTON_TO_BUTTON.encode(e, ops, prefix); case MappingEntry.FromButton.ToAxis e -> CODEC_BUTTON_TO_AXIS.encode(e, ops, prefix); - case MappingEntry.FromButton.ToHat e -> CODEC_BUTTON_TO_HAT.encode(e, ops, prefix); case MappingEntry.FromAxis.ToButton e -> CODEC_AXIS_TO_BUTTON.encode(e, ops, prefix); case MappingEntry.FromAxis.ToAxis e -> CODEC_AXIS_TO_AXIS.encode(e, ops, prefix); - case MappingEntry.FromAxis.ToHat e -> CODEC_AXIS_TO_HAT.encode(e, ops, prefix); - case MappingEntry.FromHat.ToButton e -> CODEC_HAT_TO_BUTTON.encode(e, ops, prefix); - case MappingEntry.FromHat.ToAxis e -> CODEC_HAT_TO_AXIS.encode(e, ops, prefix); - case MappingEntry.FromHat.ToHat e -> CODEC_HAT_TO_HAT.encode(e, ops, prefix); - case MappingEntry.FromNothing.ToButton e -> CODEC_NOTHING_TO_BUTTON.encode(e, ops, prefix); - case MappingEntry.FromNothing.ToAxis e -> CODEC_NOTHING_TO_AXIS.encode(e, ops, prefix); - case MappingEntry.FromNothing.ToHat e -> CODEC_NOTHING_TO_HAT.encode(e, ops, prefix); }; } @Override public DataResult> decode(DynamicOps ops, T input) { // First decode the stub to determine types - return CODEC_STUB.parse(ops, input).flatMap(stub -> switch (stub) { - case MappingEntryStub s when s.inputType() == MapType.BUTTON && s.outputType() == MapType.BUTTON -> - CODEC_BUTTON_TO_BUTTON.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.BUTTON && s.outputType() == MapType.AXIS -> - CODEC_BUTTON_TO_AXIS.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.BUTTON && s.outputType() == MapType.HAT -> - CODEC_BUTTON_TO_HAT.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.AXIS && s.outputType() == MapType.BUTTON -> - CODEC_AXIS_TO_BUTTON.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.AXIS && s.outputType() == MapType.AXIS -> - CODEC_AXIS_TO_AXIS.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.AXIS && s.outputType() == MapType.HAT -> - CODEC_AXIS_TO_HAT.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.HAT && s.outputType() == MapType.BUTTON -> - CODEC_HAT_TO_BUTTON.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.HAT && s.outputType() == MapType.AXIS -> - CODEC_HAT_TO_AXIS.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.HAT && s.outputType() == MapType.HAT -> - CODEC_HAT_TO_HAT.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.NOTHING && s.outputType() == MapType.BUTTON -> - CODEC_NOTHING_TO_BUTTON.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.NOTHING && s.outputType() == MapType.AXIS -> - CODEC_NOTHING_TO_AXIS.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - case MappingEntryStub s when s.inputType() == MapType.NOTHING && s.outputType() == MapType.HAT -> - CODEC_NOTHING_TO_HAT.decode(ops, input) - .map(pair -> pair.mapFirst(e -> (MappingEntry) e)); - default -> DataResult.error(() -> "Unknown MappingEntry type for input type " + stub.inputType() + " and output type " + stub.outputType()); + return CODEC_STUB.parse(ops, input).flatMap(stub -> { + Codec codec = switch (stub.inputType()) { + case BUTTON -> switch (stub.outputType()) { + case BUTTON -> CODEC_BUTTON_TO_BUTTON; + case AXIS -> CODEC_BUTTON_TO_AXIS; + }; + case AXIS -> switch (stub.outputType()) { + case BUTTON -> CODEC_AXIS_TO_BUTTON; + case AXIS -> CODEC_AXIS_TO_AXIS; + }; + }; + return codec.decode(ops, input) + .map(pair -> pair.mapFirst(entry -> entry)); }); } }; diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/StateMapper.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/StateMapper.java deleted file mode 100644 index 0ac303ff5..000000000 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/StateMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.input.mapping; - -import dev.isxander.controlify.controller.input.ControllerState; - -public interface StateMapper { -ControllerState mapState(ControllerState state); -} diff --git a/src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java b/src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java new file mode 100644 index 000000000..360e7e03c --- /dev/null +++ b/src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.controllermanager; + +import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.api.event.ControlifyEvents; +import dev.isxander.controlify.config.ConfigManager; +import dev.isxander.controlify.config.settings.device.DeviceSettings; +import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.driver.sdl.SDLNativesLoader; +import dev.isxander.controlify.gui.screen.AskToMapControllerScreen; +import dev.isxander.controlify.gui.screen.BluetoothWarningScreen; +import dev.isxander.controlify.input.physical.PhysicalInputSignal; +import dev.isxander.controlify.platform.main.PlatformMainUtil; +import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.utils.DebugLog; +import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.utils.SetupWizard; +import dev.isxander.controlify.utils.SetupWizardManager; +import dev.isxander.controlify.utils.event.EventSource; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import static dev.isxander.controlify.utils.ControllerUtils.wrapControllerError; + +/// Owns controller discovery, selection, activation and activity subscriptions. +/// Publishes selection changes through {@link ControlifyEvents#CURRENT_CONTROLLER_CHANGED}. +public class ControllerCoordinator implements AutoCloseable { + private final Controlify controlify; + private final ConfigManager config; + private final SetupWizardManager setupWizardManager; + private final ControllerManager controllerManager = new ControllerManager(); + private final Map inputSubscriptions = new HashMap<>(); + private final Set controllersWithInput = new LinkedHashSet<>(); + + private @Nullable ControllerBackend backend; + private @Nullable ControllerEntity currentController; + private boolean hasDiscoveredControllers; + private boolean closed; + + public ControllerCoordinator(Controlify controlify, SetupWizardManager setupWizardManager) { + this.controlify = controlify; + this.config = controlify.config(); + this.setupWizardManager = setupWizardManager; + + ControlifyEvents.CONTROLLER_CONNECTED.register(event -> + this.onControllerAdded(event.controller(), event.hotplugged())); + ControlifyEvents.CONTROLLER_DISCONNECTED.register(event -> + this.onControllerRemoved(event.controller())); + } + + public boolean initialize() { + try { + this.backend = new SDLControllerBackend(SDLNativesLoader.load(), this.controlify, this.controllerManager); + } catch (Throwable throwable) { + CUtil.LOGGER.error("Failed to initialize controller backend", throwable); + return false; + } + this.backend.setup(); + return true; + } + + public boolean isReady() { + return this.backend != null && !this.closed; + } + + public ControllerManager controllerManager() { + return this.controllerManager; + } + + public Optional currentController() { + return Optional.ofNullable(this.currentController); + } + + public void discoverControllers() { + if (!this.isReady()) { + return; + } + if (this.hasDiscoveredControllers) { + CUtil.LOGGER.warn("Attempted to discover controllers twice!"); + return; + } + this.hasDiscoveredControllers = true; + DebugLog.log("Discovering and initializing controllers..."); + this.backend.discoverControllers(); + if (this.controllerManager.getAllControllers().isEmpty()) { + CUtil.LOGGER.log("No controllers found."); + } + this.applyControllerSelection(false); + this.config.saveIfDirty(); + + PlatformMainUtil.applyToControlifyEntrypoint(entrypoint -> { + try { + entrypoint.onControllersDiscovered(this.controlify); + } catch (Throwable e) { + CUtil.LOGGER.error("Failed to run `onControllersDiscovered` on Controlify entrypoint: {}", entrypoint.getClass().getName(), e); + } + }); + } + + /// Polls every controller and resolves selection after all events have been received. + /// @return whether the selected controller received non-sensor input during this poll + public boolean update(boolean outOfFocus) { + this.controllersWithInput.clear(); + + if (!this.isReady()) { + return false; + } + + this.backend.pollEvents(); + + if (!outOfFocus && this.config.getActiveProfile().controllerUid == null + && !this.controllersWithInput.contains(this.currentController)) { + // The active controller wins regardless of the order of events within the poll. + this.controllersWithInput.stream().findFirst().ifPresent(controller -> wrapControllerError( + () -> this.setCurrentController(controller, true), + "Selecting controller from input", controller)); + } + return !outOfFocus && this.controllersWithInput.contains(this.currentController); + } + + public void setCurrentController(@Nullable ControllerEntity controller, boolean changeInputMode) { + if (this.closed || this.currentController == controller) { + return; + } + if (this.currentController != null) { + this.currentController.setActive(false); + } + this.currentController = controller; + if (controller != null) { + controller.setActive(true); + DebugLog.log("Updated current controller to {}({})", controller.name(), controller.uid()); + } else { + DebugLog.log("Cleared current controller."); + } + ControlifyEvents.CURRENT_CONTROLLER_CHANGED.invoke( + new ControlifyEvents.CurrentControllerChanged(controller, changeInputMode)); + } + + public void applyControllerSelection(boolean changeInputMode) { + String selectedUid = this.config.getActiveProfile().controllerUid; + ControllerEntity selected = this.controllerManager.getAllControllers().stream() + .filter(controller -> selectedUid == null || selectedUid.equals(controller.uid())) + .findFirst().orElse(null); + this.setCurrentController(selected, changeInputMode); + } + + public void applyActiveProfile() { + this.controllerManager.getAllControllers().forEach(controller -> + controller.setSettings(this.config.getActiveProfile())); + this.applyControllerSelection(true); + } + + private void onControllerAdded(ControllerEntity controller, boolean hotplugged) { + if (this.closed) { + return; + } + controller.input().ifPresent(input -> { + EventSource.Subscription previous = this.inputSubscriptions.remove(controller); + if (previous != null) { + previous.close(); + } + this.inputSubscriptions.put(controller, input.inputPipeline().sourceProcessedPhysicalSignals() + .filter(signal -> signal instanceof PhysicalInputSignal) + .subscribe(_ -> this.controllersWithInput.add(controller))); + }); + + DeviceSettings rememberedDevice = this.config.getSettings().getOrCreateDeviceSettings(controller.uid()); + rememberedDevice.name = controller.name(); + rememberedDevice.lastSeen = System.currentTimeMillis(); + rememberedDevice.controllerType = controller.info().type().namespace(); + this.config.markDirty(); + + String selectedUid = this.config.getActiveProfile().controllerUid; + if (selectedUid == null || selectedUid.equals(controller.uid())) { + this.setCurrentController(controller, true); + } + + SetupWizard wizard = new SetupWizard(); + wizard.addStage( + () -> controller.input().map(input -> !input.isGamepad() + && this.config.getSettings().getOrCreateDeviceSettings(controller.uid()).mapping == null) + .orElse(false), + nextScreen -> new AskToMapControllerScreen(controller, nextScreen)); + wizard.addStage( + () -> controller.dualSense().isPresent() + && controller.bluetooth().map(bt -> !bt.settings().dontShowWarning).orElse(false), + nextScreen -> new BluetoothWarningScreen(controller.bluetooth().orElseThrow(), nextScreen)); + if (hotplugged) { + MinecraftUtil.sendToast( + Component.translatable("controlify.toast.controller_connected.title"), + Component.translatable("controlify.toast.controller_connected.description", controller.name()), false); + this.config.saveIfDirty(); + } + this.setupWizardManager.push(wizard); + } + + private void onControllerRemoved(ControllerEntity controller) { + if (this.closed) { + return; + } + EventSource.Subscription subscription = this.inputSubscriptions.remove(controller); + if (subscription != null) { + subscription.close(); + } + this.controllersWithInput.remove(controller); + if (this.currentController == controller) { + ControllerEntity fallback = this.config.getActiveProfile().controllerUid == null + ? this.controllerManager.getAllControllers().stream() + .filter(candidate -> candidate != controller).findFirst().orElse(null) + : null; + this.setCurrentController(fallback, true); + } + MinecraftUtil.sendToast( + Component.translatable("controlify.toast.controller_disconnected.title"), + Component.translatable("controlify.toast.controller_disconnected.description", controller.name()), false); + } + + @Override + public void close() { + if (this.closed) { + return; + } + this.closed = true; + this.inputSubscriptions.values().forEach(EventSource.Subscription::close); + this.inputSubscriptions.clear(); + this.controllersWithInput.clear(); + this.currentController = null; + this.controllerManager.close(); + } +} diff --git a/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java b/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java index 2b437f4ac..fc0d497a1 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java +++ b/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java @@ -28,6 +28,7 @@ public class SDLControllerBackend extends ControllerBackend { private final EventTap controllerEventTap; private SdlEvent event; + private long lastFrameTimeNanos = -1; public SDLControllerBackend(Sdl sdl, Controlify controlify, ControllerManager controllerManager) { super(controlify, controllerManager); @@ -98,6 +99,11 @@ public void pollEvents() { while (this.sdl.events().SDL_PollEvent(this.event)) { this.controllerEventStage.onEvent(this.event, this::onControllerEvent); } + + long timeNanos = this.sdl.timer().SDL_GetTicksNS(); + long deltaTimeNanos = this.lastFrameTimeNanos == -1 ? 0 : timeNanos - this.lastFrameTimeNanos; + this.lastFrameTimeNanos = timeNanos; + this.onControllerEvent(new SDLControllerEvent.Frame(timeNanos, deltaTimeNanos)); } private void onControllerEvent(SDLControllerEvent event) { @@ -146,7 +152,8 @@ private void createAndAddController( controllerLogger.debugLog("Controller is gamepad: {}", isGamepad); EventSource controllerEventSource = this.controllerEventTap - .filter(event -> event.which().equals(jid)); + .filter(event -> event instanceof SDLControllerEvent.Frame + || event instanceof SDLControllerEvent.DeviceScopedEvent scoped && scoped.which().equals(jid)); Driver driver; if (isGamepad) { diff --git a/src/main/java/dev/isxander/controlify/driver/CompoundDriver.java b/src/main/java/dev/isxander/controlify/driver/CompoundDriver.java index fa157e05f..5175847a9 100644 --- a/src/main/java/dev/isxander/controlify/driver/CompoundDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/CompoundDriver.java @@ -33,6 +33,13 @@ public void update(ControllerEntity controller, boolean outOfFocus) { } } + @Override + public void setActive(boolean active) { + for (Driver driver : drivers) { + driver.setActive(active); + } + } + @Override public void close() { for (Driver driver : drivers) { diff --git a/src/main/java/dev/isxander/controlify/driver/Driver.java b/src/main/java/dev/isxander/controlify/driver/Driver.java index e258310f3..3f4e0c43f 100644 --- a/src/main/java/dev/isxander/controlify/driver/Driver.java +++ b/src/main/java/dev/isxander/controlify/driver/Driver.java @@ -13,5 +13,9 @@ default void addComponents(ControllerEntity controller) {} default void update(ControllerEntity controller, boolean outOfFocus) {} + /// Enables resources needed only by the active controller, such as sensor sampling. + /// Buttons and axes must remain available while inactive for controller selection. + default void setActive(boolean active) {} + default void close() {} } diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java index f719323c8..48dc387ff 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java @@ -10,12 +10,10 @@ import dev.isxander.controlify.controller.touchpad.TouchpadComponent; import dev.isxander.controlify.controller.gyro.GyroComponent; import dev.isxander.controlify.controller.input.GamepadInputs; -import dev.isxander.controlify.controller.gyro.GyroState; import dev.isxander.controlify.controller.*; import dev.isxander.controlify.controller.touchpad.Touchpads; import dev.isxander.controlify.input.InputComponent; import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.logical.LogicalSignal; import dev.isxander.controlify.utils.event.EventSource; import dev.isxander.controlify.utils.log.ControlifyLogger; import dev.isxander.sdl.*; @@ -32,14 +30,14 @@ public class SDL3GamepadDriver extends SDLCommonDriver { private InputComponent inputComponent; - private GyroComponent gyroComponent; private TouchpadComponent touchpadComponent; private final Set supportedButtons; private final Set supportedAxes; private final Set supportedSensors; - private final boolean isGryoSupported; + private final boolean isGyroSupported; + private boolean active; private final int numTouchpads; @@ -60,10 +58,7 @@ public SDL3GamepadDriver(Sdl sdl, SdlGamepadHandle ptrController, EventSource { - if (sig instanceof LogicalSignal.SensorInterval(long timeNanos, long deltaTimeNanos, SensorType sensorType, float x, float y, float z)) { - if (sensorType == SensorType.GYROSCOPE) { - this.gyroComponent.setState(new GyroState(x, y, z)); - } - } - }); + if (this.isGyroSupported) { + controller.setComponent(new GyroComponent(this.inputPipeline)); } if (this.numTouchpads > 0) { @@ -120,8 +97,27 @@ public void addComponents(ControllerEntity controller) { } } + @Override + public void setActive(boolean active) { + if (this.ptrController == null) { + throw new IllegalStateException("Tried to activate or deactivate a closed controller."); + } + if (this.active == active) { + return; + } + this.active = active; + if (this.isGyroSupported + && !this.sdl.gamepad().SDL_SetGamepadSensorEnabled(this.ptrController, SDL_SENSOR_GYRO, active)) { + this.logger.warn("Failed to {} gyro sensor: {}", active ? "enable" : "disable", this.sdl.error().SDL_GetError()); + } + } + @Override protected void onEvent(SDLControllerEvent event) { + // SDL may still have queued samples after the sensor has been disabled. + if (!this.active && event instanceof SDLControllerEvent.GamepadSensor) { + return; + } super.onEvent(event); switch (event) { @@ -137,6 +133,12 @@ public void update(ControllerEntity controller, boolean outOfFocus) { super.update(controller, outOfFocus); } + @Override + public void close() { + this.setActive(false); + super.close(); + } + private void onTouchpadEvent(SDLControllerEvent.GamepadTouchpad event) { // TODO: touchpad component probably needs redoing, it was designed to receive // complete snapshots of touchpad data, not continuous updates diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java index a4b48168c..0ef26ce5a 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java @@ -52,7 +52,7 @@ public abstract class SDLCommonDriver implements Driver { private static final int AUDIO_STREAM_TIMEOUT_TICKS = 5 * 60 * 60 * 20; // 5 minutes protected final Sdl sdl; - private final ControlifyLogger logger; + protected final ControlifyLogger logger; protected final Arena arena; @@ -186,6 +186,8 @@ public void addComponents(ControllerEntity controller) { if (isBluetooth()) { controller.setComponent(new BluetoothDeviceComponent()); } + + this.eventSubscription = this.sdlEventSource.subscribe(this::onEvent); } protected void onEvent(SDLControllerEvent event) { @@ -426,7 +428,7 @@ protected String createUid() { String nonDuplicateUid = uid; int duplicateCount = (int) Controlify.instance().getControllerManager().orElseThrow() - .getConnectedControllers() + .getAllControllers() .stream() .filter(controller -> controller.uid().startsWith(nonDuplicateUid)) .count(); diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java index 60a8ba551..b1d763393 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java @@ -6,12 +6,18 @@ public sealed interface SDLControllerEvent { long timeNanos(); - SdlJoystickId which(); + /// Emitted once after each backend poll and delivered to every controller. + /// Uses the same SDL clock as native event timestamps; the first frame has a zero delta. + record Frame(long timeNanos, long deltaTimeNanos) implements SDLControllerEvent {} - sealed interface JoystickEvent extends SDLControllerEvent {} - sealed interface GamepadEvent extends SDLControllerEvent {} + sealed interface DeviceScopedEvent extends SDLControllerEvent { + SdlJoystickId which(); + } + + sealed interface JoystickEvent extends DeviceScopedEvent {} + sealed interface GamepadEvent extends DeviceScopedEvent {} - sealed interface DeviceEvent extends SDLControllerEvent { + sealed interface DeviceEvent extends DeviceScopedEvent { Type type(); enum Type { @@ -25,7 +31,7 @@ enum Type { } } - sealed interface AxisEvent extends SDLControllerEvent { + sealed interface AxisEvent extends DeviceScopedEvent { /// The axis. It may be an index or a constant, depending on the event type. byte axis(); @@ -33,7 +39,7 @@ sealed interface AxisEvent extends SDLControllerEvent { short value(); } - sealed interface ButtonEvent extends SDLControllerEvent { + sealed interface ButtonEvent extends DeviceScopedEvent { /// The button. It may be an index or a constant, depending on the event type. byte button(); @@ -85,7 +91,7 @@ record Battery( long timeNanos, PowerState state, int percent - ) implements SDLControllerEvent { + ) implements DeviceScopedEvent { public enum PowerState { ERROR, UNKNOWN, diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java index e43cfa0a0..0b0554298 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java @@ -23,6 +23,9 @@ public SDLToPhysicalStage() { @Override public void onEvent(SDLControllerEvent event, EventSink downstream) { switch (event) { + case SDLControllerEvent.Frame(long timeNanos, long deltaTimeNanos) -> + downstream.accept(new PhysicalSignal.Frame(timeNanos, deltaTimeNanos)); + case SDLControllerEvent.JoyAxis(_, long timeNanos, byte axis, short value) -> { float normalisedValue = normaliseAxis(value); diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java b/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java index 01dd89c0a..facfb4f6f 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java @@ -154,11 +154,6 @@ private void processStage(MappingStage stage, ControllerStateView stateNow, Cont MappingEntry mapping = switch (stage.outputType()) { case BUTTON -> new MappingEntry.FromButton.ToButton(button, stage.originInput(), !now); case AXIS -> new MappingEntry.FromButton.ToAxis(button, stage.originInput(), prev ? 1 : 0, now ? 1 : 0); - case HAT -> { - HatState state = now ? HatState.DOWN : HatState.UP; - yield new MappingEntry.FromButton.ToHat(button, stage.originInput(), HatState.CENTERED, state); - } - case NOTHING -> null; }; mappingBuilder.putMapping(mapping); stage.setSatisfied(true); @@ -174,24 +169,6 @@ private void processStage(MappingStage stage, ControllerStateView stateNow, Cont MappingEntry mapping = switch (stage.outputType()) { case BUTTON -> new MappingEntry.FromAxis.ToButton(axis, stage.originInput(), 0.5f); case AXIS -> new MappingEntry.FromAxis.ToAxis(axis, stage.originInput(), 0, 0, 1, 1); - case HAT -> new MappingEntry.FromAxis.ToHat(axis, stage.originInput(), 0.5f, diff > 0 ? HatState.UP : HatState.DOWN); - case NOTHING -> null; - }; - mappingBuilder.putMapping(mapping); - stage.setSatisfied(true); - return; - } - } - - for (Identifier hat : stateNow.getHats()) { - HatState now = stateNow.getHatState(hat); - HatState prev = stateThen.getHatState(hat); - if (now != prev) { - MappingEntry mapping = switch (stage.outputType()) { - case BUTTON -> new MappingEntry.FromHat.ToButton(hat, stage.originInput(), now); - case AXIS -> new MappingEntry.FromHat.ToAxis(hat, stage.originInput(), now, 0, 1); - case HAT -> new MappingEntry.FromHat.ToHat(hat, stage.originInput()); - case NOTHING -> null; }; mappingBuilder.putMapping(mapping); stage.setSatisfied(true); @@ -205,14 +182,6 @@ private void setStage(MappingStage stage) { } private void mapAsNone() { - MappingEntry mapping = switch (currentStage.outputType()) { - case BUTTON -> new MappingEntry.FromNothing.ToButton(currentStage.originInput(), false); - case AXIS -> new MappingEntry.FromNothing.ToAxis(currentStage.originInput(), 0f); - case HAT -> new MappingEntry.FromNothing.ToHat(currentStage.originInput()); - case NOTHING -> null; - }; - mappingBuilder.putMapping(mapping); - delayTillNextStage = 0; } diff --git a/src/main/java/dev/isxander/controlify/input/InputComponent.java b/src/main/java/dev/isxander/controlify/input/InputComponent.java index d95475312..8f2017480 100644 --- a/src/main/java/dev/isxander/controlify/input/InputComponent.java +++ b/src/main/java/dev/isxander/controlify/input/InputComponent.java @@ -78,13 +78,7 @@ public void attach(ControllerEntity controller) { this.reloadActions(); this.actionGraphSub = this.inputPipeline.sourceLogicalSignals().subscribe(this.actionGraph); - this.inputPipeline.stageDeadzone().setDeadzoneSupplier(axis -> { - DeadzoneGroup group = this.deadzoneGroups.get(axis); - if (group == null) { - return 0f; - } - return settings().sensitivity.getDeadzone(group.name()); - }); + this.inputPipeline.stageDeadzone().setDeadzoneSupplier(axis -> settings().sensitivity.getDeadzone((Identifier) axis)); this.inputPipeline.stageSensorProcessor().setProcessors(sensorType -> { if (sensorType.isGyroscope()) { return List.of( @@ -101,6 +95,14 @@ public void attach(ControllerEntity controller) { return this.actions.get(actionId); } + public InputPipeline inputPipeline() { + return this.inputPipeline; + } + + public void resetActions() { + this.actions.values().forEach(ActionImpl::reset); + } + public void reloadActions() { this.actions.clear(); this.actionGraph.clearActions(); diff --git a/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java b/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java index 587d3418d..6d5ca6083 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java +++ b/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java @@ -22,6 +22,8 @@ public void onEvent( ) { switch (event) { case PhysicalSignal.Frame(long timeNanos, _) -> { + this.accSensorValues.values().removeIf(acc -> + acc.lastSampleNanos != -1 && timeNanos - acc.lastSampleNanos > MAX_SAMPLE_AGE_NANOS); this.accSensorValues.forEach((sensorType, acc) -> { if (acc.lastNs == -1) { return; @@ -102,21 +104,19 @@ public void integrateUntil(long timeNanos) { return; } - // Integrate only while the last sensor reading is considered valid. - long validUntilNanos = lastSampleNanos + MAX_SAMPLE_AGE_NANOS; - long integrationEndNanos = Math.min(timeNanos, validUntilNanos); - - if (integrationEndNanos > lastNs) { - long integrationNanos = integrationEndNanos - lastNs; - float deltaSeconds = integrationNanos * 1e-9f; - - x += velocityX * deltaSeconds; - y += velocityY * deltaSeconds; - z += velocityZ * deltaSeconds; - - accumulatedNanos += integrationNanos; + if (lastSampleNanos == -1 || timeNanos - lastSampleNanos > MAX_SAMPLE_AGE_NANOS) { + // A gap invalidates both the held sample and any motion waiting for a frame. + resetAccumulation(); + lastSampleNanos = -1; + lastNs = timeNanos; + return; } + float deltaSeconds = deltaNanos * 1e-9f; + x += velocityX * deltaSeconds; + y += velocityY * deltaSeconds; + z += velocityZ * deltaSeconds; + accumulatedNanos += deltaNanos; lastNs = timeNanos; } diff --git a/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java b/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java index a1ef784b5..5349465ab 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java +++ b/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java @@ -1,54 +1,107 @@ package dev.isxander.controlify.input.physical; +import dev.isxander.controlify.controller.input.DeadzoneGroup; import dev.isxander.controlify.utils.ControllerUtils; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.UnaryEventStage; +import it.unimi.dsi.fastutil.objects.*; import net.minecraft.resources.Identifier; +import net.minecraft.util.Mth; import java.util.HashSet; +import java.util.Map; import java.util.Set; -import java.util.function.Function; +import java.util.stream.Collectors; -/// Applies deadzones to physical axes. -// TODO: radial deadzones +/// Applies radial deadzones to physical axes. public class DeadzoneStage implements UnaryEventStage { - private Function deadzoneSupplier; - private final Set axisWasZero; + private final Map groupByAxis; + private final Map stateByGroup; - public DeadzoneStage(Function deadzoneSupplier) { - this.deadzoneSupplier = deadzoneSupplier; - this.axisWasZero = new HashSet<>(); - } + private Object2FloatFunction deadzoneByGroupName; - public DeadzoneStage() { - this(_ -> 0f); + public DeadzoneStage(Set deadzoneGroups) { + this.groupByAxis = deadzoneGroups.stream() + .flatMap(g -> g.axes().stream().map(a -> Map.entry(a, g))) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (_, _) -> { + throw new IllegalArgumentException("Axis belongs to multiple deadzone groups"); + }, + Object2ObjectOpenHashMap::new + )); + this.stateByGroup = new Object2ObjectArrayMap<>(); + this.deadzoneByGroupName = _ -> 0f; } @Override public void onEvent(PhysicalSignal event, EventSink downstream) { - if (event instanceof PhysicalInputSignal.AxisMoved(long timeNanos, Identifier input, float value)) { - float deadzone = this.deadzoneSupplier.apply(input); - - if (deadzone > 0) { - float newValue = ControllerUtils.deadzone(value, deadzone); + if (event instanceof PhysicalInputSignal.AxisMoved axisMoved) { + DeadzoneGroup deadzoneGroup = this.groupByAxis.get(axisMoved.input()); - if (newValue != 0 || this.axisWasZero.add(input)) { - downstream.accept(new PhysicalInputSignal.AxisMoved(timeNanos, input, newValue)); - if (newValue != 0) { - this.axisWasZero.remove(input); - } - } + if (deadzoneGroup != null) { + RadialDeadzoneState state = this.stateByGroup.computeIfAbsent(deadzoneGroup, RadialDeadzoneState::new); + state.onEvent(axisMoved, downstream); return; - } else { - this.axisWasZero.remove(input); } } downstream.accept(event); } - public void setDeadzoneSupplier(Function deadzoneSupplier) { - this.deadzoneSupplier = deadzoneSupplier; + public void setDeadzoneSupplier(Object2FloatFunction deadzoneByGroupName) { + this.deadzoneByGroupName = deadzoneByGroupName; + } + + private class RadialDeadzoneState implements UnaryEventStage { + private final DeadzoneGroup deadzoneGroup; + private final Object2FloatMap rawAxes = new Object2FloatArrayMap<>(4); + private final Object2FloatMap outputAxes = new Object2FloatArrayMap<>(4); + + public RadialDeadzoneState(DeadzoneGroup deadzoneGroup) { + this.deadzoneGroup = deadzoneGroup; + + for (Identifier axis : deadzoneGroup.axes()) { + this.rawAxes.put(axis, 0.0f); + this.outputAxes.put(axis, 0.0f); + } + } + + @Override + public void onEvent(PhysicalInputSignal.AxisMoved event, EventSink downstream) { + this.rawAxes.put(event.input(), event.value()); + + float deadzone = DeadzoneStage.this.deadzoneByGroupName.getFloat(this.deadzoneGroup.name()); + + float magnitudeSqr = 0.0f; + for (float value : this.rawAxes.values()) { + magnitudeSqr += value * value; + } + float magnitude = Mth.sqrt(magnitudeSqr); + + float scale; + if (magnitude <= deadzone) { + scale = 0.0f; + } else { + float outputMagnitude = Math.min( + (magnitude - deadzone) / (1.0f - deadzone), + 1.0f + ); + scale = outputMagnitude / magnitude; + } + + for (var entry : Object2FloatMaps.fastIterable(this.rawAxes)) { + Identifier axis = entry.getKey(); + + float newValue = entry.getFloatValue() * scale; + float oldValue = this.outputAxes.put(axis, newValue); + + if (newValue != oldValue) { + downstream.accept(new PhysicalInputSignal.AxisMoved(event.timeNanos(), axis, newValue)); + } + } + } } } diff --git a/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java b/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java index 2e007424c..c90e7c733 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java +++ b/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java @@ -44,7 +44,6 @@ case PhysicalSensorSignal(long timeNanos, long sensorTimeNanos, SensorType senso processor.process(data, sensorTimeNanos); } - // TODO: port GyroCalibrator here downstream.accept(new PhysicalSensorSignal(timeNanos, sensorTimeNanos, sensorType, data.x, data.y, data.z)); } default -> downstream.accept(event); @@ -64,9 +63,11 @@ public void process(Vector3f data, long timeNanos) { /// A first-order low-pass filter with a finite, positive cutoff frequency in Hz. /// Lower frequencies smooth more strongly. The first sample passes through unchanged. + /// History expires after a gap of 50ms or when the sensor clock moves backwards. /// /// If the frequency is set to 0, the filter is bypassed. public static class LowPassFilter implements SensorProcessor { + private static final long MAX_SAMPLE_AGE_NANOS = 50_000_000L; private final DoubleSupplier cutoffHz; private @Nullable Vector3f previous; private long previousTimeNanos; @@ -79,11 +80,12 @@ public LowPassFilter(DoubleSupplier cutoffHz) { public void process(Vector3f data, long timeNanos) { double cutoffHz = this.cutoffHz.getAsDouble(); - if (cutoffHz == 0 || this.previous == null) { + long elapsedNanos = timeNanos - this.previousTimeNanos; + if (cutoffHz == 0 || this.previous == null + || elapsedNanos > MAX_SAMPLE_AGE_NANOS || elapsedNanos < 0) { this.previous = new Vector3f(data); this.previousTimeNanos = timeNanos; } else { - long elapsedNanos = timeNanos - this.previousTimeNanos; if (elapsedNanos > 0) { // Exponential decay keeps the response consistent across sample rates. // expm1 preserves precision for very short sample intervals. diff --git a/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java index 2a25963d8..736a94226 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java @@ -7,7 +7,7 @@ package dev.isxander.controlify.mixins.core; import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controllermanager.ControllerManager; +import dev.isxander.controlify.controllermanager.ControllerCoordinator; import dev.isxander.controlify.utils.animation.impl.Animator; import net.minecraft.CrashReport; import net.minecraft.client.DeltaTracker; @@ -57,7 +57,7 @@ private void doPlayerLook(CallbackInfo ci) { ) ) private void onMinecraftClose(CallbackInfo ci) { - Controlify.instance().getControllerManager().ifPresent(ControllerManager::close); + Controlify.instance().getControllerCoordinator().ifPresent(ControllerCoordinator::close); } @Inject( From 7683b39ee9f0c9f133bd6f39a44a030bbe80121b Mon Sep 17 00:00:00 2001 From: isxander Date: Fri, 16 Oct 2026 16:00:28 +0100 Subject: [PATCH 09/12] wire up controller mapping to pipeline --- .../settings/device/DeviceSettings.java | 1 + .../controller/impl/ControllerStateImpl.java | 106 ---------- .../controller/input/ControllerState.java | 17 -- .../controller/input/ControllerStateView.java | 31 --- .../input/DeadzoneControllerStateView.java | 62 ------ .../controlify/controller/input/HatState.java | 57 ------ .../controller/input/InputComponent.java | 187 ------------------ .../input/ModifiableControllerState.java | 17 -- .../input/mapping/ControllerMapping.java | 10 - .../mapping/ControllerMappingStorage.java | 47 ----- .../input/mapping/MappingEntry.java | 4 - .../input/mapping/MappingEntryCodecs.java | 1 - .../mapping/MappingEntryTypeAdapter.java | 53 ----- .../driver/sdl/SDL3GamepadDriver.java | 10 +- .../driver/sdl/SDL3JoystickDriver.java | 3 +- .../controlify/input/InputComponent.java | 27 +-- .../controlify/input/InputPipeline.java | 8 + .../input/physical/DeadzoneStage.java | 41 ++-- .../input/physical/MappingStage.java | 40 ++++ 19 files changed, 90 insertions(+), 632 deletions(-) delete mode 100644 src/main/java/dev/isxander/controlify/controller/impl/ControllerStateImpl.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/input/ControllerState.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/input/ControllerStateView.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/input/DeadzoneControllerStateView.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/input/HatState.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/input/InputComponent.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/input/ModifiableControllerState.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMappingStorage.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryTypeAdapter.java create mode 100644 src/main/java/dev/isxander/controlify/input/physical/MappingStage.java diff --git a/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java b/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java index 4bd8a88af..c255e2036 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java +++ b/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java @@ -19,6 +19,7 @@ public class DeviceSettings { public long lastSeen; public Identifier controllerType; public final GyroCalibrationSettings gyroCalibration; + /// Controller must be re-initialized for a change in mapping to take effect. public @Nullable ControllerMapping mapping; private DeviceSettings(String uid) { diff --git a/src/main/java/dev/isxander/controlify/controller/impl/ControllerStateImpl.java b/src/main/java/dev/isxander/controlify/controller/impl/ControllerStateImpl.java deleted file mode 100644 index c7f7abdad..000000000 --- a/src/main/java/dev/isxander/controlify/controller/impl/ControllerStateImpl.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.impl; - -import com.google.common.base.Joiner; -import dev.isxander.controlify.controller.input.HatState; -import dev.isxander.controlify.controller.input.ModifiableControllerState; -import it.unimi.dsi.fastutil.objects.Object2BooleanArrayMap; -import it.unimi.dsi.fastutil.objects.Object2FloatArrayMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; -import net.minecraft.resources.Identifier; - -import java.util.Map; -import java.util.Set; - -public class ControllerStateImpl implements ModifiableControllerState { - private final Map buttons; - private final Map axes; - private final Map restingAxes; - private final Map hats; - - public ControllerStateImpl() { - this.buttons = new Object2BooleanArrayMap<>(); - this.axes = new Object2FloatArrayMap<>(); - this.restingAxes = new Object2FloatArrayMap<>(); - this.hats = new Object2ObjectArrayMap<>(); - } - - @Override - public boolean isButtonDown(Identifier button) { - return buttons.getOrDefault(button, false); - } - - @Override - public Set getButtons() { - return buttons.keySet(); - } - - @Override - public float getAxisState(Identifier axis) { - return axes.getOrDefault(axis, 0f); - } - - @Override - public Set getAxes() { - return axes.keySet(); - } - - @Override - public float getAxisResting(Identifier axis) { - return restingAxes.getOrDefault(axis, 0f); - } - - @Override - public HatState getHatState(Identifier hat) { - return hats.getOrDefault(hat, HatState.CENTERED); - } - - @Override - public Set getHats() { - return hats.keySet(); - } - - @Override - public void setButton(Identifier button, boolean value) { - buttons.put(button, value); - } - - @Override - public void setAxis(Identifier axis, float value) { - axes.put(axis, value); - } - - public void setRestingAxis(Identifier axis, float value) { - if (!axes.containsKey(axis)) - throw new IllegalArgumentException("Cannot set resting axis for axis that doesn't exist"); - - restingAxes.put(axis, value); - } - - @Override - public void setHat(Identifier hat, HatState value) { - hats.put(hat, value); - } - - @Override - public void clearState() { - this.buttons.clear(); - this.axes.clear(); - this.restingAxes.clear(); - this.hats.clear(); - } - - public String toDebugString() { - Joiner.MapJoiner joiner = Joiner.on(",").withKeyValueSeparator("="); - return "ControllerState{axes:%s,buttons:%s,hats:%s}".formatted( - joiner.join(axes), - joiner.join(buttons), - joiner.join(hats) - ); - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/input/ControllerState.java b/src/main/java/dev/isxander/controlify/controller/input/ControllerState.java deleted file mode 100644 index fbabdfc10..000000000 --- a/src/main/java/dev/isxander/controlify/controller/input/ControllerState.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.input; - -import dev.isxander.controlify.controller.impl.ControllerStateImpl; - -public interface ControllerState extends ControllerStateView { - ControllerState EMPTY = new ControllerStateImpl(); - - void clearState(); - - default void close() {} -} diff --git a/src/main/java/dev/isxander/controlify/controller/input/ControllerStateView.java b/src/main/java/dev/isxander/controlify/controller/input/ControllerStateView.java deleted file mode 100644 index 46141b247..000000000 --- a/src/main/java/dev/isxander/controlify/controller/input/ControllerStateView.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.input; - -import net.minecraft.resources.Identifier; - -import java.util.Set; - -public interface ControllerStateView { - boolean isButtonDown(Identifier button); - - Set getButtons(); - - float getAxisState(Identifier axis); - Set getAxes(); - - float getAxisResting(Identifier axis); - - HatState getHatState(Identifier hat); - Set getHats(); - - default boolean isGivingInput() { - return getButtons().stream().anyMatch(this::isButtonDown) - || getAxes().stream().map(this::getAxisState).anyMatch(axis -> Math.abs(axis) > 0.5f) - || getHats().stream().map(this::getHatState).anyMatch(hat -> hat != HatState.CENTERED); - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/input/DeadzoneControllerStateView.java b/src/main/java/dev/isxander/controlify/controller/input/DeadzoneControllerStateView.java deleted file mode 100644 index 2a1f62e41..000000000 --- a/src/main/java/dev/isxander/controlify/controller/input/DeadzoneControllerStateView.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.input; - -import dev.isxander.controlify.utils.ControllerUtils; -import net.minecraft.resources.Identifier; - -import java.util.Optional; -import java.util.Set; - -public class DeadzoneControllerStateView implements ControllerStateView { - private final ControllerStateView view; - private final InputComponent input; - - public DeadzoneControllerStateView(ControllerStateView view, InputComponent input) { - this.view = view; - this.input = input; - } - - @Override - public boolean isButtonDown(Identifier button) { - return view.isButtonDown(button); - } - - @Override - public Set getButtons() { - return view.getButtons(); - } - - @Override - public float getAxisState(Identifier axis) { - float rawAxis = view.getAxisState(axis); - Optional deadzoneId = input.getDeadzoneForAxis(axis); - float deadzone = deadzoneId.map(id -> input.settings().sensitivity.getDeadzone(id)).orElse(0f); - - return ControllerUtils.deadzone(rawAxis, deadzone); - } - - @Override - public Set getAxes() { - return view.getAxes(); - } - - @Override - public float getAxisResting(Identifier axis) { - return view.getAxisResting(axis); - } - - @Override - public HatState getHatState(Identifier hat) { - return view.getHatState(hat); - } - - @Override - public Set getHats() { - return view.getHats(); - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/input/HatState.java b/src/main/java/dev/isxander/controlify/controller/input/HatState.java deleted file mode 100644 index bd1068f69..000000000 --- a/src/main/java/dev/isxander/controlify/controller/input/HatState.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.input; - -import com.mojang.serialization.Codec; -import dev.isxander.yacl3.api.NameableEnum; -import net.minecraft.network.chat.Component; -import net.minecraft.util.StringRepresentable; -import org.jetbrains.annotations.NotNull; - -public enum HatState implements NameableEnum, StringRepresentable { - CENTERED, - UP, - RIGHT, - DOWN, - LEFT, - RIGHT_UP, - RIGHT_DOWN, - LEFT_UP, - LEFT_DOWN; - - public static final Codec CODEC = StringRepresentable.fromEnum(HatState::values); - - public boolean isCentered() { - return this == CENTERED; - } - - public boolean isRight() { - return this == RIGHT || this == RIGHT_UP || this == RIGHT_DOWN; - } - - public boolean isUp() { - return this == UP || this == RIGHT_UP || this == LEFT_UP; - } - - public boolean isLeft() { - return this == LEFT || this == LEFT_UP || this == LEFT_DOWN; - } - - public boolean isDown() { - return this == DOWN || this == RIGHT_DOWN || this == LEFT_DOWN; - } - - @Override - public Component getDisplayName() { - return Component.translatable("controlify.hat_state." + this.name().toLowerCase()); - } - - @Override - public @NotNull String getSerializedName() { - return this.name(); - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/input/InputComponent.java b/src/main/java/dev/isxander/controlify/controller/input/InputComponent.java deleted file mode 100644 index 61ae21e19..000000000 --- a/src/main/java/dev/isxander/controlify/controller/input/InputComponent.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.input; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.ControlifyBindApiImpl; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.config.settings.profile.InputSettings; -import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.controller.input.mapping.ControllerMapping; -import dev.isxander.controlify.utils.CUtil; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class InputComponent extends ECSComponentImpl { - public static final Identifier ID = CUtil.rl("input"); - - private final ControllerEntity controller; - private DeviceSettings deviceSettings; // Cached reference - - private ControllerState - stateNow = ControllerState.EMPTY, - stateThen = ControllerState.EMPTY; - private DeadzoneControllerStateView - deadzoneStateNow, - deadzoneStateThen; - - private final int buttonCount, axisCount, hatCount; - private final Map deadzoneAxes; - private final boolean definitelyGamepad; - - private final Map inputBindings; - - public InputComponent( - ControllerEntity controller, - int buttonCount, int axisCount, int hatCount, - boolean definitelyGamepad, - Set deadzoneAxes, - String mappingId - ) { - this.controller = controller; - this.buttonCount = buttonCount; - this.axisCount = axisCount; - this.hatCount = hatCount; - this.definitelyGamepad = definitelyGamepad; - this.deadzoneAxes = deadzoneAxes.stream() - .collect(Collectors.toMap( - DeadzoneGroup::name, - Function.identity(), - (x, y) -> y, - LinkedHashMap::new - )); - this.inputBindings = new LinkedHashMap<>(); - - this.updateDeadzoneView(); - } - - public ControllerStateView stateNow() { - return this.deadzoneStateNow; - } - public ControllerStateView stateThen() { - return this.deadzoneStateThen; - } - - public ControllerState rawStateNow() { - return this.stateNow; - } - - public ControllerState rawStateThen() { - return this.stateThen; - } - - public void pushState(ControllerState state) { - ControllerMapping mapping = getDeviceMapping(); - if (mapping != null) { - state = mapping.mapState(state); - } - - this.stateThen = this.stateNow; - this.stateNow = state; - this.updateDeadzoneView(); - - for (InputBinding binding : this.inputBindings.values()) { - binding.pushState(this.deadzoneStateNow); - } - } - - public @Nullable InputBinding getBinding(Identifier id) { - return this.inputBindings.get(id); - } - - public Collection getAllBindings() { - return this.inputBindings.values(); - } - - public void notifyGuiPressOutputsOfNavigate() { - for (InputBinding binding : this.inputBindings.values()) { - binding.guiPressed().onNavigate(); - } - } - - @Override - public void attach(ControllerEntity controller) { - super.attach(controller); - - // Cache device settings reference - this.deviceSettings = Controlify.instance().config().getSettings() - .getOrCreateDeviceSettings(controller.uid()); - - // Populate bindings - for (InputBinding binding : ControlifyBindApiImpl.INSTANCE.provideBindsForController(controller)) { - this.inputBindings.put(binding.id(), binding); - } - - // Note: No need to copy bound inputs from config here since InputBindingImpl.boundInput() - // now reads directly from the config (via inputComponent.settings().bindings.bindings) - } - - public int buttonCount() { - return this.buttonCount; - } - public int axisCount() { - return this.axisCount; - } - public int hatCount() { - return this.hatCount; - } - - public boolean isDefinitelyGamepad() { - return this.definitelyGamepad; - } - - public Map getDeadzoneGroups() { - ControllerMapping mapping = getDeviceMapping(); - if (mapping != null) { - return mapping.deadzones(); - } else { - return this.deadzoneAxes; - } - } - - private @Nullable ControllerMapping getDeviceMapping() { - // Use cached device settings to avoid repeated lookups - return deviceSettings.mapping; - } - - public ControllerEntity getController() { - return controller(); - } - - public InputSettings settings() { - return this.controller().settings().input; - } - - public InputSettings defaultSettings() { - return this.controller().defaultSettings().input; - } - - @Override - public Identifier id() { - return ID; - } - - private void updateDeadzoneView() { - this.deadzoneStateNow = new DeadzoneControllerStateView(this.stateNow, this); - this.deadzoneStateThen = new DeadzoneControllerStateView(this.stateThen, this); - } - - Optional getDeadzoneForAxis(Identifier axis) { - for (DeadzoneGroup group : this.getDeadzoneGroups().values()) { - if (group.axes().contains(axis)) { - return Optional.of(group.name()); - } - } - return Optional.empty(); - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/input/ModifiableControllerState.java b/src/main/java/dev/isxander/controlify/controller/input/ModifiableControllerState.java deleted file mode 100644 index 2f7b7ee64..000000000 --- a/src/main/java/dev/isxander/controlify/controller/input/ModifiableControllerState.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.input; - -import net.minecraft.resources.Identifier; - -public interface ModifiableControllerState extends ControllerState { - void setButton(Identifier button, boolean pressed); - - void setAxis(Identifier axis, float value); - - void setHat(Identifier hat, HatState state); -} diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java index 4da4e14bf..f5ecff6cd 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java +++ b/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java @@ -14,8 +14,6 @@ import net.minecraft.resources.Identifier; import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; public record ControllerMapping( List mappings, @@ -44,14 +42,6 @@ public record ControllerMapping( } } - public Map createMappingEntryMap() { - return this.mappings.stream() - .collect(Collectors.toUnmodifiableMap( - MappingEntry::sourceInput, - Function.identity() - )); - } - public static final ControllerMapping NO_MAPPING = new Builder().build(); public static final ControllerMapping GAMEPAD_DEADZONES_ONLY_MAPPING = new Builder() .putDeadzoneGroups(GamepadInputs.DEADZONE_GROUPS) diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMappingStorage.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMappingStorage.java deleted file mode 100644 index 144aa49a7..000000000 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMappingStorage.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.input.mapping; - -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.utils.CUtil; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import net.minecraft.client.Minecraft; -import net.minecraft.server.packs.resources.Resource; -import net.minecraft.server.packs.resources.ResourceManager; -import org.jetbrains.annotations.Nullable; - -import java.io.BufferedReader; -import java.io.IOException; -import java.util.Map; - -public class ControllerMappingStorage { - private static final Map MAPPINGS = new Object2ObjectOpenHashMap<>(); - - public static @Nullable ControllerMapping get(String id) { - return MAPPINGS.computeIfAbsent(id, ControllerMappingStorage::resolve); - } - - private static @Nullable ControllerMapping resolve(String id) { - ResourceManager resourceManager = Minecraft.getInstance().getResourceManager(); - Resource resource = resourceManager - .getResource(CUtil.rl("mappings/" + id + ".json")) - .orElse(null); - if (resource == null) - return null; - - try (BufferedReader reader = resource.openAsReader()) { - JsonElement jsonElement = JsonParser.parseReader(reader); - DataResult result = ControllerMapping.CODEC.parse(JsonOps.INSTANCE, jsonElement); - return result.getOrThrow(); - } catch (IOException e) { - throw new IllegalStateException("Failed to load controller mapping!", e); - } - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java index b834bbebd..2338302fe 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java +++ b/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java @@ -7,13 +7,9 @@ package dev.isxander.controlify.controller.input.mapping; import com.mojang.serialization.Codec; -import dev.isxander.controlify.controller.input.ControllerState; -import dev.isxander.controlify.controller.input.HatState; -import dev.isxander.controlify.controller.input.ModifiableControllerState; import dev.isxander.controlify.input.physical.PhysicalInputSignal; import dev.isxander.controlify.utils.MthExt; import net.minecraft.resources.Identifier; -import org.jspecify.annotations.Nullable; public sealed interface MappingEntry { /// Transforms an input signal diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java index 03dced81b..804633966 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java +++ b/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java @@ -11,7 +11,6 @@ import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.input.HatState; import net.minecraft.resources.Identifier; final class MappingEntryCodecs { diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryTypeAdapter.java b/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryTypeAdapter.java deleted file mode 100644 index 92f0f3a0e..000000000 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryTypeAdapter.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.input.mapping; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; - -import java.lang.reflect.Type; - -public class MappingEntryTypeAdapter implements JsonDeserializer { - @Override - public MappingEntry deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - InOutRecord inOut = context.deserialize(json, InOutRecord.class); - - Type type = switch (inOut.inputType()) { - case BUTTON -> switch (inOut.outputType()) { - case BUTTON -> MappingEntry.FromButton.ToButton.class; - case AXIS -> MappingEntry.FromButton.ToAxis.class; - case HAT -> MappingEntry.FromButton.ToHat.class; - case NOTHING -> throw new IllegalStateException(); - }; - case AXIS -> switch (inOut.outputType()) { - case BUTTON -> MappingEntry.FromAxis.ToButton.class; - case AXIS -> MappingEntry.FromAxis.ToAxis.class; - case HAT -> MappingEntry.FromAxis.ToHat.class; - case NOTHING -> throw new IllegalStateException(); - }; - case HAT -> switch (inOut.outputType()) { - case BUTTON -> MappingEntry.FromHat.ToButton.class; - case AXIS -> MappingEntry.FromHat.ToAxis.class; - case HAT -> MappingEntry.FromHat.ToHat.class; - case NOTHING -> throw new IllegalStateException(); - }; - case NOTHING -> switch (inOut.outputType()) { - case BUTTON -> MappingEntry.FromNothing.ToButton.class; - case AXIS -> MappingEntry.FromNothing.ToAxis.class; - case HAT -> MappingEntry.FromNothing.ToHat.class; - case NOTHING -> throw new IllegalStateException(); - }; - }; - - return context.deserialize(json, type); - } - - private record InOutRecord(MapType inputType, MapType outputType) { - } -} diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java index 48dc387ff..f9b1f2f44 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java @@ -9,7 +9,6 @@ import dev.isxander.controlify.controller.id.ControllerType; import dev.isxander.controlify.controller.touchpad.TouchpadComponent; import dev.isxander.controlify.controller.gyro.GyroComponent; -import dev.isxander.controlify.controller.input.GamepadInputs; import dev.isxander.controlify.controller.*; import dev.isxander.controlify.controller.touchpad.Touchpads; import dev.isxander.controlify.input.InputComponent; @@ -73,9 +72,8 @@ public void addComponents(ControllerEntity controller) { this.inputPipeline, this.supportedButtons, this.supportedAxes, - GamepadInputs.DEADZONE_GROUPS, - true, - this.supportedSensors + this.supportedSensors, + true ) ); @@ -114,10 +112,6 @@ public void setActive(boolean active) { @Override protected void onEvent(SDLControllerEvent event) { - // SDL may still have queued samples after the sensor has been disabled. - if (!this.active && event instanceof SDLControllerEvent.GamepadSensor) { - return; - } super.onEvent(event); switch (event) { diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java index 8165911a3..4e77ffd9d 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java @@ -54,8 +54,7 @@ public void addComponents(ControllerEntity controller) { this.supportedButtons, this.supportedAxes, Set.of(), - false, - Set.of() + false )); } diff --git a/src/main/java/dev/isxander/controlify/input/InputComponent.java b/src/main/java/dev/isxander/controlify/input/InputComponent.java index 8f2017480..6ec17e595 100644 --- a/src/main/java/dev/isxander/controlify/input/InputComponent.java +++ b/src/main/java/dev/isxander/controlify/input/InputComponent.java @@ -6,7 +6,7 @@ import dev.isxander.controlify.config.settings.profile.InputSettings; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.controller.input.DeadzoneGroup; +import dev.isxander.controlify.controller.input.mapping.ControllerMapping; import dev.isxander.controlify.input.action.ActionGraph; import dev.isxander.controlify.input.action.ActionImpl; import dev.isxander.controlify.input.action.ActionSpec; @@ -37,7 +37,6 @@ public class InputComponent extends ECSComponentImpl { private final Map actions; private final Set physicalButtons, physicalAxes; - private final Map deadzoneGroups; private final boolean isGamepad; private final Set supportedSensors; @@ -48,20 +47,16 @@ public InputComponent( InputPipeline inputPipeline, Set physicalButtons, Set physicalAxes, - Set deadzoneGroups, - boolean isGamepad, - Set supportedSensors + Set supportedSensors, + boolean isGamepad ) { this.controllerType = controllerType; this.inputPipeline = inputPipeline; this.physicalButtons = Set.copyOf(physicalButtons); this.physicalAxes = Set.copyOf(physicalAxes); - this.deadzoneGroups = deadzoneGroups.stream() - .flatMap(g -> g.axes().stream().map(a -> Map.entry(a, g))) - .collect(Util.toMap()); - this.isGamepad = isGamepad; this.supportedSensors = Set.copyOf(supportedSensors); + this.isGamepad = isGamepad; this.actionGraph = new ActionGraph(); this.actions = new LinkedHashMap<>(); @@ -74,10 +69,15 @@ public void attach(ControllerEntity controller) { this.deviceSettings = Controlify.instance().config().getSettings() .getOrCreateDeviceSettings(controller.uid()); - // we need to wait for settings to load before getting current binding - this.reloadActions(); + ControllerMapping controllerMapping = this.deviceSettings.mapping; + if (controllerMapping == null) { + controllerMapping = this.isGamepad + ? ControllerMapping.GAMEPAD_DEADZONES_ONLY_MAPPING + : ControllerMapping.NO_MAPPING; + } - this.actionGraphSub = this.inputPipeline.sourceLogicalSignals().subscribe(this.actionGraph); + this.inputPipeline.stageMapping().setControllerMapping(controllerMapping); + this.inputPipeline.stageDeadzone().setDeadzoneGroups(controllerMapping.deadzones().values()); this.inputPipeline.stageDeadzone().setDeadzoneSupplier(axis -> settings().sensitivity.getDeadzone((Identifier) axis)); this.inputPipeline.stageSensorProcessor().setProcessors(sensorType -> { if (sensorType.isGyroscope()) { @@ -89,6 +89,9 @@ public void attach(ControllerEntity controller) { return List.of(); } }); + + this.reloadActions(); + this.actionGraphSub = this.inputPipeline.sourceLogicalSignals().subscribe(this.actionGraph); } public @Nullable ActionImpl getAction(Identifier actionId) { diff --git a/src/main/java/dev/isxander/controlify/input/InputPipeline.java b/src/main/java/dev/isxander/controlify/input/InputPipeline.java index faf952ab7..252f1ed78 100644 --- a/src/main/java/dev/isxander/controlify/input/InputPipeline.java +++ b/src/main/java/dev/isxander/controlify/input/InputPipeline.java @@ -1,5 +1,6 @@ package dev.isxander.controlify.input; +import dev.isxander.controlify.controller.input.mapping.ControllerMapping; import dev.isxander.controlify.input.logical.LogicalSignal; import dev.isxander.controlify.input.logical.PhysicalToLogicalStage; import dev.isxander.controlify.input.logical.SensorAccumulatorStage; @@ -11,6 +12,7 @@ public class InputPipeline implements EventSink { private final EventTap tapRawPhysicalSignals; private final SensorProcessorStage stageSensorProcessor; + private final MappingStage stageMapping; private final DeadzoneStage stageDeadzone; private final GestureRecogniserStage stageGestureRecogniser; private final InputDomainExpansionStage stageInputDomainExpansion; @@ -25,6 +27,7 @@ public class InputPipeline implements EventSink { public InputPipeline() { this.tapRawPhysicalSignals = new EventTap<>(); this.stageSensorProcessor = new SensorProcessorStage(); + this.stageMapping = new MappingStage(ControllerMapping.NO_MAPPING); this.stageDeadzone = new DeadzoneStage(); this.stageGestureRecogniser = new GestureRecogniserStage(); this.stageInputDomainExpansion = new InputDomainExpansionStage(0.5f, 0.49f, 1f, 0f); @@ -35,6 +38,7 @@ public InputPipeline() { this.fullPipeline = this.tapRawPhysicalSignals .andThen(this.stageSensorProcessor) + .andThen(this.stageMapping) .andThen(this.stageDeadzone) .andThen(this.stageGestureRecogniser) .andThen(this.stageInputDomainExpansion) @@ -57,6 +61,10 @@ public SensorProcessorStage stageSensorProcessor() { return this.stageSensorProcessor; } + public MappingStage stageMapping() { + return this.stageMapping; + } + public DeadzoneStage stageDeadzone() { return this.stageDeadzone; } diff --git a/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java b/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java index 5349465ab..23bce96cb 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java +++ b/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java @@ -8,7 +8,7 @@ import net.minecraft.resources.Identifier; import net.minecraft.util.Mth; -import java.util.HashSet; +import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -16,33 +16,24 @@ /// Applies radial deadzones to physical axes. public class DeadzoneStage implements UnaryEventStage { - private final Map groupByAxis; - private final Map stateByGroup; - + private Map stateByAxis; private Object2FloatFunction deadzoneByGroupName; public DeadzoneStage(Set deadzoneGroups) { - this.groupByAxis = deadzoneGroups.stream() - .flatMap(g -> g.axes().stream().map(a -> Map.entry(a, g))) - .collect(Collectors.toMap( - Map.Entry::getKey, - Map.Entry::getValue, - (_, _) -> { - throw new IllegalArgumentException("Axis belongs to multiple deadzone groups"); - }, - Object2ObjectOpenHashMap::new - )); - this.stateByGroup = new Object2ObjectArrayMap<>(); + this.setDeadzoneGroups(deadzoneGroups); this.deadzoneByGroupName = _ -> 0f; } + public DeadzoneStage() { + this(Set.of()); + } + @Override public void onEvent(PhysicalSignal event, EventSink downstream) { if (event instanceof PhysicalInputSignal.AxisMoved axisMoved) { - DeadzoneGroup deadzoneGroup = this.groupByAxis.get(axisMoved.input()); + RadialDeadzoneState state = this.stateByAxis.get(axisMoved.input()); - if (deadzoneGroup != null) { - RadialDeadzoneState state = this.stateByGroup.computeIfAbsent(deadzoneGroup, RadialDeadzoneState::new); + if (state != null) { state.onEvent(axisMoved, downstream); return; } @@ -51,6 +42,20 @@ public void onEvent(PhysicalSignal event, EventSink down downstream.accept(event); } + public void setDeadzoneGroups(Collection deadzoneGroups) { + this.stateByAxis = deadzoneGroups.stream() + .map(RadialDeadzoneState::new) + .flatMap(state -> state.deadzoneGroup.axes().stream().map(axis -> Map.entry(axis, state))) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (_, _) -> { + throw new IllegalArgumentException("Axis belongs to multiple deadzone groups"); + }, + Object2ObjectOpenHashMap::new + )); + } + public void setDeadzoneSupplier(Object2FloatFunction deadzoneByGroupName) { this.deadzoneByGroupName = deadzoneByGroupName; } diff --git a/src/main/java/dev/isxander/controlify/input/physical/MappingStage.java b/src/main/java/dev/isxander/controlify/input/physical/MappingStage.java new file mode 100644 index 000000000..b929ec49e --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/physical/MappingStage.java @@ -0,0 +1,40 @@ +package dev.isxander.controlify.input.physical; + +import dev.isxander.controlify.controller.input.mapping.ControllerMapping; +import dev.isxander.controlify.controller.input.mapping.MappingEntry; +import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.utils.event.UnaryEventStage; +import net.minecraft.resources.Identifier; + +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class MappingStage implements UnaryEventStage { + private Map mappingByInput; + + public MappingStage(ControllerMapping mapping) { + this.setControllerMapping(mapping); + } + + @Override + public void onEvent(PhysicalSignal event, EventSink downstream) { + if (event instanceof PhysicalInputSignal inputSignal) { + MappingEntry mapping = this.mappingByInput.get(inputSignal.input()); + + if (mapping != null) { + downstream.accept(mapping.apply(inputSignal)); + return; + } + } + downstream.accept(event); + } + + public void setControllerMapping(ControllerMapping mapping) { + this.mappingByInput = mapping.mappings().stream() + .collect(Collectors.toUnmodifiableMap( + MappingEntry::sourceInput, + Function.identity() + )); + } +} From b7813fb2a176d8eb7c65fcb4d34ec141b74afacd Mon Sep 17 00:00:00 2001 From: isxander Date: Fri, 16 Oct 2026 17:18:24 +0100 Subject: [PATCH 10/12] implement data-driven controller mappings; bit of reorganisation --- .../tests/VirtualControllerInputTests.java | 2 +- .../dev/isxander/controlify/Controlify.java | 21 +- .../{input => }/action/Accumulator.java | 2 +- .../controlify/{input => }/action/Action.java | 4 +- .../{input => }/action/ActionAccessor.java | 4 +- .../action/ActionAccessorImpl.java | 4 +- .../{input => }/action/ActionContext.java | 2 +- .../{input => }/action/ActionGraph.java | 6 +- .../{input => }/action/ActionImpl.java | 8 +- .../{input => }/action/ActionSpec.java | 2 +- .../{input => }/action/ActionSpecBuilder.java | 2 +- .../action/ActionSpecBuilderImpl.java | 2 +- .../action/ActionSpecRegistry.java | 2 +- .../action/ActionSpecRegistryImpl.java | 2 +- .../{input => }/action/ActionState.java | 2 +- .../{input => }/action/Activator.java | 6 +- .../{input => }/action/Channel.java | 2 +- .../action/activator/ActivatorConfig.java | 6 +- .../activator/ActivatorConfigManager.java | 4 +- .../action/activator/ActivatorConfigType.java | 4 +- .../action/activator/CompoundActivator.java | 10 +- .../action/activator/ContinuousActivator.java | 11 +- .../activator/DoubleTapPulseActivator.java | 11 +- .../activator/GuiPressPulseActivator.java | 11 +- .../action/activator/HoldLatchActivator.java | 11 +- .../action/activator/HoldPulseActivator.java | 11 +- .../action/activator/NoopActivator.java | 23 ++ .../action/activator/PressPulseActivator.java | 11 +- .../activator/ReleasePulseActivator.java | 11 +- .../activator/RepeatLatchPulseActivator.java | 10 +- .../action/activator/TapPulseActivator.java | 11 +- .../activator/ToggleLatchActivator.java | 10 +- .../defaults/DefaultBindManager.java | 2 +- .../defaults/DefaultBindProvider.java | 4 +- .../defaults/LayeredDefaultBindProvider.java | 4 +- .../MapBackedDefaultBindProvider.java | 4 +- .../controlify/action/radial/RadialIcon.java | 102 +++++ .../radial}/RadialIconExtractor.java | 18 +- .../radial}/RadialIconManager.java | 20 +- .../api/bind/ControlifyBindApi.java | 83 ----- .../controlify/api/bind/InputBinding.java | 243 ------------ .../api/bind/InputBindingBuilder.java | 155 -------- .../api/bind/InputBindingSupplier.java | 65 ---- .../controlify/api/bind/RadialIcon.java | 74 ---- .../api/buttonguide/ButtonGuideApi.java | 11 +- .../bindings/ControlifyBindApiImpl.java | 126 ------- .../bindings/InputBindingBuilderImpl.java | 211 ----------- .../controlify/bindings/InputBindingImpl.java | 351 ------------------ .../bindings/InputBindingSupplierImpl.java | 27 -- .../controlify/bindings/RadialIcons.java | 32 -- .../controlify/bindings/StateAccess.java | 19 - .../controlify/bindings/input/AxisInput.java | 37 -- .../bindings/input/ButtonInput.java | 37 -- .../controlify/bindings/input/EmptyInput.java | 39 -- .../controlify/bindings/input/HatInput.java | 39 -- .../controlify/bindings/input/Input.java | 25 -- .../controlify/bindings/input/InputType.java | 64 ---- .../bindings/output/AnalogueOutput.java | 11 - .../bindings/output/BindingOutput.java | 10 - .../bindings/output/DigitalOutput.java | 15 - .../bindings/output/GuiPressOutput.java | 67 ---- .../bindings/output/JustPressedOutput.java | 26 -- .../bindings/output/JustReleasedOutput.java | 26 -- .../bindings/output/JustTappedOutput.java | 46 --- .../output/KeyMappingEmulationOutput.java | 56 --- .../bindings/output/SimpleAnalogueOutput.java | 28 -- .../bindings/output/SimpleDigitalOutput.java | 28 -- .../config/dto/device/DeviceConfig.java | 2 +- .../config/dto/profile/InputConfig.java | 2 +- .../settings/device/DeviceSettings.java | 2 +- .../settings/profile/InputSettings.java | 2 +- .../controller/ControllerEntity.java | 2 +- .../dualsense/TriggerEffectInstanceImpl.java | 2 +- .../controller/gyro/GyroComponent.java | 8 +- .../controller/id/ControllerType.java | 17 +- .../input/InputComponent.java | 37 +- .../ControllerCoordinator.java | 2 +- .../controllermanager/ControllerManager.java | 3 +- .../driver/sdl/SDL3GamepadDriver.java | 2 +- .../driver/sdl/SDL3JoystickDriver.java | 4 +- .../driver/sdl/SDLCommonDriver.java | 2 +- .../driver/sdl/SDLInputConversions.java | 2 +- .../driver/sdl/SDLToPhysicalStage.java | 8 +- .../driver/steamdeck/SteamDeckDriver.java | 2 +- .../controlify/gui/ButtonGuideRenderer.java | 24 +- .../controllers/Deadzone2DImageRenderer.java | 2 +- .../screen/ControllerConfigScreenFactory.java | 4 +- .../screen/ControllerMappingMakerScreen.java | 6 +- .../controlify/gui/screen/RadialItems.java | 4 +- .../gui/screen/RadialMenuEditScreen.java | 5 +- .../gui/screen/RadialMenuScreen.java | 4 +- .../input/{logical => }/LogicalInput.java | 4 +- .../input/action/activator/NoopActivator.java | 23 -- .../input/mapping/ControllerMapping.java | 4 +- .../mapping/ControllerMappingManager.java | 70 ++++ .../mapping}/DeadzoneGroup.java | 2 +- .../mapping}/GamepadInputs.java | 14 +- .../{physical => mapping}/GestureInputs.java | 2 +- .../input => input/mapping}/Inputs.java | 2 +- .../mapping}/JoystickInputs.java | 2 +- .../input/mapping/MapType.java | 2 +- .../input/mapping/MappingEntry.java | 4 +- .../input/mapping/MappingEntryCodecs.java | 2 +- .../{physical => pipeline}/DeadzoneStage.java | 7 +- .../GestureRecogniserStage.java | 7 +- .../InputDomainExpansionStage.java | 4 +- .../input/{ => pipeline}/InputPipeline.java | 10 +- .../{physical => pipeline}/MappingStage.java | 8 +- .../PhysicalToLogicalStage.java | 10 +- .../SensorAccumulatorStage.java | 7 +- .../SensorProcessorStage.java | 4 +- .../{logical => signal}/LogicalSignal.java | 4 +- .../PhysicalInputSignal.java | 2 +- .../PhysicalSensorSignal.java | 2 +- .../{physical => signal}/PhysicalSignal.java | 2 +- .../controlify/screenop/ScreenProcessor.java | 2 +- .../virtualmouse/VirtualMouseHandler.java | 2 +- 117 files changed, 458 insertions(+), 2225 deletions(-) rename src/main/java/dev/isxander/controlify/{input => }/action/Accumulator.java (81%) rename src/main/java/dev/isxander/controlify/{input => }/action/Action.java (81%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionAccessor.java (88%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionAccessorImpl.java (74%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionContext.java (89%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionGraph.java (95%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionImpl.java (88%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionSpec.java (96%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionSpecBuilder.java (92%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionSpecBuilderImpl.java (97%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionSpecRegistry.java (66%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionSpecRegistryImpl.java (95%) rename src/main/java/dev/isxander/controlify/{input => }/action/ActionState.java (95%) rename src/main/java/dev/isxander/controlify/{input => }/action/Activator.java (70%) rename src/main/java/dev/isxander/controlify/{input => }/action/Channel.java (93%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/ActivatorConfig.java (88%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/ActivatorConfigManager.java (96%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/ActivatorConfigType.java (96%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/CompoundActivator.java (82%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/ContinuousActivator.java (71%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/DoubleTapPulseActivator.java (73%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/GuiPressPulseActivator.java (73%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/HoldLatchActivator.java (76%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/HoldPulseActivator.java (72%) create mode 100644 src/main/java/dev/isxander/controlify/action/activator/NoopActivator.java rename src/main/java/dev/isxander/controlify/{input => }/action/activator/PressPulseActivator.java (72%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/ReleasePulseActivator.java (73%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/RepeatLatchPulseActivator.java (91%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/TapPulseActivator.java (72%) rename src/main/java/dev/isxander/controlify/{input => }/action/activator/ToggleLatchActivator.java (85%) rename src/main/java/dev/isxander/controlify/{bindings => action}/defaults/DefaultBindManager.java (99%) rename src/main/java/dev/isxander/controlify/{bindings => action}/defaults/DefaultBindProvider.java (76%) rename src/main/java/dev/isxander/controlify/{bindings => action}/defaults/LayeredDefaultBindProvider.java (92%) rename src/main/java/dev/isxander/controlify/{bindings => action}/defaults/MapBackedDefaultBindProvider.java (89%) create mode 100644 src/main/java/dev/isxander/controlify/action/radial/RadialIcon.java rename src/main/java/dev/isxander/controlify/{bindings => action/radial}/RadialIconExtractor.java (75%) rename src/main/java/dev/isxander/controlify/{bindings => action/radial}/RadialIconManager.java (79%) delete mode 100644 src/main/java/dev/isxander/controlify/api/bind/ControlifyBindApi.java delete mode 100644 src/main/java/dev/isxander/controlify/api/bind/InputBinding.java delete mode 100644 src/main/java/dev/isxander/controlify/api/bind/InputBindingBuilder.java delete mode 100644 src/main/java/dev/isxander/controlify/api/bind/InputBindingSupplier.java delete mode 100644 src/main/java/dev/isxander/controlify/api/bind/RadialIcon.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/ControlifyBindApiImpl.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/InputBindingBuilderImpl.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/InputBindingImpl.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/InputBindingSupplierImpl.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/RadialIcons.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/StateAccess.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/input/AxisInput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/input/ButtonInput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/input/EmptyInput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/input/HatInput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/input/Input.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/input/InputType.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/AnalogueOutput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/BindingOutput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/DigitalOutput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/GuiPressOutput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/JustPressedOutput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/JustReleasedOutput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/JustTappedOutput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/KeyMappingEmulationOutput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/SimpleAnalogueOutput.java delete mode 100644 src/main/java/dev/isxander/controlify/bindings/output/SimpleDigitalOutput.java rename src/main/java/dev/isxander/controlify/{ => controller}/input/InputComponent.java (82%) rename src/main/java/dev/isxander/controlify/input/{logical => }/LogicalInput.java (94%) delete mode 100644 src/main/java/dev/isxander/controlify/input/action/activator/NoopActivator.java rename src/main/java/dev/isxander/controlify/{controller => }/input/mapping/ControllerMapping.java (93%) create mode 100644 src/main/java/dev/isxander/controlify/input/mapping/ControllerMappingManager.java rename src/main/java/dev/isxander/controlify/{controller/input => input/mapping}/DeadzoneGroup.java (92%) rename src/main/java/dev/isxander/controlify/{controller/input => input/mapping}/GamepadInputs.java (87%) rename src/main/java/dev/isxander/controlify/input/{physical => mapping}/GestureInputs.java (82%) rename src/main/java/dev/isxander/controlify/{controller/input => input/mapping}/Inputs.java (94%) rename src/main/java/dev/isxander/controlify/{controller/input => input/mapping}/JoystickInputs.java (95%) rename src/main/java/dev/isxander/controlify/{controller => }/input/mapping/MapType.java (89%) rename src/main/java/dev/isxander/controlify/{controller => }/input/mapping/MappingEntry.java (96%) rename src/main/java/dev/isxander/controlify/{controller => }/input/mapping/MappingEntryCodecs.java (98%) rename src/main/java/dev/isxander/controlify/input/{physical => pipeline}/DeadzoneStage.java (93%) rename src/main/java/dev/isxander/controlify/input/{physical => pipeline}/GestureRecogniserStage.java (63%) rename src/main/java/dev/isxander/controlify/input/{physical => pipeline}/InputDomainExpansionStage.java (90%) rename src/main/java/dev/isxander/controlify/input/{ => pipeline}/InputPipeline.java (89%) rename src/main/java/dev/isxander/controlify/input/{physical => pipeline}/MappingStage.java (78%) rename src/main/java/dev/isxander/controlify/input/{logical => pipeline}/PhysicalToLogicalStage.java (95%) rename src/main/java/dev/isxander/controlify/input/{logical => pipeline}/SensorAccumulatorStage.java (92%) rename src/main/java/dev/isxander/controlify/input/{physical => pipeline}/SensorProcessorStage.java (95%) rename src/main/java/dev/isxander/controlify/input/{logical => signal}/LogicalSignal.java (91%) rename src/main/java/dev/isxander/controlify/input/{physical => signal}/PhysicalInputSignal.java (94%) rename src/main/java/dev/isxander/controlify/input/{physical => signal}/PhysicalSensorSignal.java (94%) rename src/main/java/dev/isxander/controlify/input/{physical => signal}/PhysicalSignal.java (86%) diff --git a/src/gametest/java/dev/isxander/controlify/gametest/tests/VirtualControllerInputTests.java b/src/gametest/java/dev/isxander/controlify/gametest/tests/VirtualControllerInputTests.java index 044a1655e..d66c54502 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/tests/VirtualControllerInputTests.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/tests/VirtualControllerInputTests.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.gametest.tests; -import dev.isxander.controlify.controller.input.GamepadInputs; +import dev.isxander.controlify.input.mapping.GamepadInputs; import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.gametest.framework.CTestUtil; import dev.isxander.controlify.gametest.framework.controller.ControlifyGameTestContext; diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index 662f62848..0be77c533 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -12,11 +12,10 @@ import dev.isxander.controlify.api.contextual.ContextualDomainRegistry; import dev.isxander.controlify.api.entrypoint.InitContext; import dev.isxander.controlify.api.entrypoint.PreInitContext; -import dev.isxander.controlify.bindings.BindContext; import dev.isxander.controlify.bindings.ControlifyBindApiImpl; import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.bindings.RadialIconManager; -import dev.isxander.controlify.bindings.defaults.DefaultBindManager; +import dev.isxander.controlify.action.radial.RadialIconManager; +import dev.isxander.controlify.action.defaults.DefaultBindManager; import dev.isxander.controlify.compatibility.ControlifyCompat; import dev.isxander.controlify.config.ConfigManager; import dev.isxander.controlify.config.dto.profile.defaults.DefaultConfigManager; @@ -25,6 +24,7 @@ import dev.isxander.controlify.controller.*; import dev.isxander.controlify.controller.dualsense.TriggerEffectManager; import dev.isxander.controlify.controller.id.ControllerTypeManager; +import dev.isxander.controlify.input.mapping.ControllerMappingManager; import dev.isxander.controlify.controller.rumble.RumbleComponent; import dev.isxander.controlify.controllermanager.ControllerCoordinator; import dev.isxander.controlify.controllermanager.ControllerManager; @@ -34,8 +34,8 @@ import dev.isxander.controlify.gui.screen.*; import dev.isxander.controlify.debug.DebugProperties; import dev.isxander.controlify.ingame.ControllerPlayerMovement; -import dev.isxander.controlify.input.InputComponent; -import dev.isxander.controlify.input.action.activator.ActivatorConfigManager; +import dev.isxander.controlify.controller.input.InputComponent; +import dev.isxander.controlify.action.activator.ActivatorConfigManager; import dev.isxander.controlify.platform.client.PlatformClientUtil; import dev.isxander.controlify.platform.main.PlatformMainUtil; import dev.isxander.controlify.platform.network.SidedNetworkApi; @@ -89,6 +89,7 @@ public class Controlify implements ControlifyApi { private KeyboardLayoutManager keyboardLayoutManager; private RadialIconManager radialIconManager; private ActivatorConfigManager activatorConfigManager; + private ControllerMappingManager controllerMappingManager; private TriggerEffectManager triggerEffectManager; @@ -134,6 +135,7 @@ public void preInitialiseControlify() { this.keyboardLayoutManager = new KeyboardLayoutManager(); this.radialIconManager = new RadialIconManager(); this.activatorConfigManager = new ActivatorConfigManager(); + this.controllerMappingManager = new ControllerMappingManager(); PlatformClientUtil.registerAssetReloadListener(this.inputFontMapper); PlatformClientUtil.registerAssetReloadListener(this.defaultBindManager); @@ -142,6 +144,7 @@ public void preInitialiseControlify() { PlatformClientUtil.registerAssetReloadListener(this.keyboardLayoutManager); PlatformClientUtil.registerAssetReloadListener(this.radialIconManager); PlatformClientUtil.registerAssetReloadListener(this.activatorConfigManager); + PlatformClientUtil.registerAssetReloadListener(this.controllerMappingManager); PlatformClientUtil.registerAssetReloadListener(RuleSetManager.GUIDE_RULES); PlatformClientUtil.registerAssetReloadListener(RuleSetManager.TRIGGER_EFFECT_RULES); ContextualDomains.touch(); @@ -622,12 +625,12 @@ public ActivatorConfigManager activatorConfigManager() { return this.activatorConfigManager; } - public TriggerEffectManager triggerEffectManager() { - return this.triggerEffectManager; + public ControllerMappingManager controllerMappingManager() { + return this.controllerMappingManager; } - public Set thisTickBindContexts() { - return this.thisTickContexts; + public TriggerEffectManager triggerEffectManager() { + return this.triggerEffectManager; } public void notifyNewServer(ServerData data) { diff --git a/src/main/java/dev/isxander/controlify/input/action/Accumulator.java b/src/main/java/dev/isxander/controlify/action/Accumulator.java similarity index 81% rename from src/main/java/dev/isxander/controlify/input/action/Accumulator.java rename to src/main/java/dev/isxander/controlify/action/Accumulator.java index 00470df98..fb9e37d17 100644 --- a/src/main/java/dev/isxander/controlify/input/action/Accumulator.java +++ b/src/main/java/dev/isxander/controlify/action/Accumulator.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; /// Accepts action state. public interface Accumulator { diff --git a/src/main/java/dev/isxander/controlify/input/action/Action.java b/src/main/java/dev/isxander/controlify/action/Action.java similarity index 81% rename from src/main/java/dev/isxander/controlify/input/action/Action.java rename to src/main/java/dev/isxander/controlify/action/Action.java index fb6ec58af..39de6c9fe 100644 --- a/src/main/java/dev/isxander/controlify/input/action/Action.java +++ b/src/main/java/dev/isxander/controlify/action/Action.java @@ -1,6 +1,6 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; -import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.LogicalInput; import org.jspecify.annotations.Nullable; /// An action is bound to a logical input and has one or more activators diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java b/src/main/java/dev/isxander/controlify/action/ActionAccessor.java similarity index 88% rename from src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java rename to src/main/java/dev/isxander/controlify/action/ActionAccessor.java index 366a6575c..7fd0ed51a 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionAccessor.java +++ b/src/main/java/dev/isxander/controlify/action/ActionAccessor.java @@ -1,7 +1,7 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.input.InputComponent; +import dev.isxander.controlify.controller.input.InputComponent; import net.minecraft.resources.Identifier; import org.jspecify.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionAccessorImpl.java b/src/main/java/dev/isxander/controlify/action/ActionAccessorImpl.java similarity index 74% rename from src/main/java/dev/isxander/controlify/input/action/ActionAccessorImpl.java rename to src/main/java/dev/isxander/controlify/action/ActionAccessorImpl.java index db1419c9a..6ee6f2a3f 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionAccessorImpl.java +++ b/src/main/java/dev/isxander/controlify/action/ActionAccessorImpl.java @@ -1,6 +1,6 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; -import dev.isxander.controlify.input.InputComponent; +import dev.isxander.controlify.controller.input.InputComponent; import net.minecraft.resources.Identifier; import org.jspecify.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionContext.java b/src/main/java/dev/isxander/controlify/action/ActionContext.java similarity index 89% rename from src/main/java/dev/isxander/controlify/input/action/ActionContext.java rename to src/main/java/dev/isxander/controlify/action/ActionContext.java index 6a93fc9d9..ccaaf4763 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionContext.java +++ b/src/main/java/dev/isxander/controlify/action/ActionContext.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; import net.minecraft.client.Minecraft; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionGraph.java b/src/main/java/dev/isxander/controlify/action/ActionGraph.java similarity index 95% rename from src/main/java/dev/isxander/controlify/input/action/ActionGraph.java rename to src/main/java/dev/isxander/controlify/action/ActionGraph.java index 4c76b1161..71be9fc45 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionGraph.java +++ b/src/main/java/dev/isxander/controlify/action/ActionGraph.java @@ -1,7 +1,7 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; import dev.isxander.controlify.utils.event.EventSink; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionImpl.java b/src/main/java/dev/isxander/controlify/action/ActionImpl.java similarity index 88% rename from src/main/java/dev/isxander/controlify/input/action/ActionImpl.java rename to src/main/java/dev/isxander/controlify/action/ActionImpl.java index 317369bc1..6e2847cf3 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionImpl.java +++ b/src/main/java/dev/isxander/controlify/action/ActionImpl.java @@ -1,8 +1,8 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; -import dev.isxander.controlify.input.action.activator.ActivatorConfig; -import dev.isxander.controlify.input.action.activator.NoopActivator; -import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.action.activator.ActivatorConfig; +import dev.isxander.controlify.action.activator.NoopActivator; +import dev.isxander.controlify.input.LogicalInput; import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java b/src/main/java/dev/isxander/controlify/action/ActionSpec.java similarity index 96% rename from src/main/java/dev/isxander/controlify/input/action/ActionSpec.java rename to src/main/java/dev/isxander/controlify/action/ActionSpec.java index 44b31a138..c39361cb5 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionSpec.java +++ b/src/main/java/dev/isxander/controlify/action/ActionSpec.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; import dev.isxander.controlify.controller.ControllerEntity; import net.minecraft.network.chat.Component; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java b/src/main/java/dev/isxander/controlify/action/ActionSpecBuilder.java similarity index 92% rename from src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java rename to src/main/java/dev/isxander/controlify/action/ActionSpecBuilder.java index 631bf5290..d30c52e96 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilder.java +++ b/src/main/java/dev/isxander/controlify/action/ActionSpecBuilder.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; import dev.isxander.controlify.controller.ControllerEntity; import net.minecraft.network.chat.Component; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilderImpl.java b/src/main/java/dev/isxander/controlify/action/ActionSpecBuilderImpl.java similarity index 97% rename from src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilderImpl.java rename to src/main/java/dev/isxander/controlify/action/ActionSpecBuilderImpl.java index e653e1ecb..c6a3d10d7 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionSpecBuilderImpl.java +++ b/src/main/java/dev/isxander/controlify/action/ActionSpecBuilderImpl.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; import dev.isxander.controlify.controller.ControllerEntity; import net.minecraft.network.chat.Component; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java b/src/main/java/dev/isxander/controlify/action/ActionSpecRegistry.java similarity index 66% rename from src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java rename to src/main/java/dev/isxander/controlify/action/ActionSpecRegistry.java index 26101ca60..1fc2a2ca5 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistry.java +++ b/src/main/java/dev/isxander/controlify/action/ActionSpecRegistry.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; public interface ActionSpecRegistry { ActionAccessor register(ActionSpec actionSpec); diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistryImpl.java b/src/main/java/dev/isxander/controlify/action/ActionSpecRegistryImpl.java similarity index 95% rename from src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistryImpl.java rename to src/main/java/dev/isxander/controlify/action/ActionSpecRegistryImpl.java index ec5104397..ae391579f 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionSpecRegistryImpl.java +++ b/src/main/java/dev/isxander/controlify/action/ActionSpecRegistryImpl.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/dev/isxander/controlify/input/action/ActionState.java b/src/main/java/dev/isxander/controlify/action/ActionState.java similarity index 95% rename from src/main/java/dev/isxander/controlify/input/action/ActionState.java rename to src/main/java/dev/isxander/controlify/action/ActionState.java index 159457849..17838159e 100644 --- a/src/main/java/dev/isxander/controlify/input/action/ActionState.java +++ b/src/main/java/dev/isxander/controlify/action/ActionState.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; public final class ActionState implements Accumulator, Channel.Continuous, Channel.Latch, Channel.Pulse { private int pulses = 0; diff --git a/src/main/java/dev/isxander/controlify/input/action/Activator.java b/src/main/java/dev/isxander/controlify/action/Activator.java similarity index 70% rename from src/main/java/dev/isxander/controlify/input/action/Activator.java rename to src/main/java/dev/isxander/controlify/action/Activator.java index 7e5b0db02..4e87f8f5a 100644 --- a/src/main/java/dev/isxander/controlify/input/action/Activator.java +++ b/src/main/java/dev/isxander/controlify/action/Activator.java @@ -1,7 +1,7 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Processes signals and activates an {@link Action}. public interface Activator { diff --git a/src/main/java/dev/isxander/controlify/input/action/Channel.java b/src/main/java/dev/isxander/controlify/action/Channel.java similarity index 93% rename from src/main/java/dev/isxander/controlify/input/action/Channel.java rename to src/main/java/dev/isxander/controlify/action/Channel.java index 064d29c4c..dfa89cfbc 100644 --- a/src/main/java/dev/isxander/controlify/input/action/Channel.java +++ b/src/main/java/dev/isxander/controlify/action/Channel.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.action; +package dev.isxander.controlify.action; /// A channel is a way of interpreting the output state of a given {@link Action}. /// An {@link Action action's} bindings sends output to any of these channels. diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java b/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfig.java similarity index 88% rename from src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java rename to src/main/java/dev/isxander/controlify/action/activator/ActivatorConfig.java index 189aa34a8..908c6556c 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfig.java +++ b/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfig.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; import net.minecraft.util.StringRepresentable; /// An immutable structure typically containing the configuration diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigManager.java b/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigManager.java similarity index 96% rename from src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigManager.java rename to src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigManager.java index d19a8dee2..34aeecf18 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigManager.java +++ b/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigManager.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.input.InputComponent; +import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; import dev.isxander.controlify.utils.CUtil; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java b/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigType.java similarity index 96% rename from src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java rename to src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigType.java index 4f2bd4809..5c8f2cb97 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ActivatorConfigType.java +++ b/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigType.java @@ -1,7 +1,7 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Activator; +import dev.isxander.controlify.action.Activator; import net.minecraft.util.StringRepresentable; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/CompoundActivator.java b/src/main/java/dev/isxander/controlify/action/activator/CompoundActivator.java similarity index 82% rename from src/main/java/dev/isxander/controlify/input/action/activator/CompoundActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/CompoundActivator.java index 916a1beb0..b39c7b18e 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/CompoundActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/CompoundActivator.java @@ -1,11 +1,11 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java b/src/main/java/dev/isxander/controlify/action/activator/ContinuousActivator.java similarity index 71% rename from src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/ContinuousActivator.java index 503e71b17..552d00840 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ContinuousActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/ContinuousActivator.java @@ -1,10 +1,9 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; public record ContinuousActivator(LogicalInput boundInput) implements Activator { @Override diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java b/src/main/java/dev/isxander/controlify/action/activator/DoubleTapPulseActivator.java similarity index 73% rename from src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/DoubleTapPulseActivator.java index 6ca8373c0..dfd6a6c84 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/DoubleTapPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/DoubleTapPulseActivator.java @@ -1,10 +1,9 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Produces a pulse when the input is double tapped. public record DoubleTapPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java b/src/main/java/dev/isxander/controlify/action/activator/GuiPressPulseActivator.java similarity index 73% rename from src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/GuiPressPulseActivator.java index 2760ea5e4..d66ec387e 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/GuiPressPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/GuiPressPulseActivator.java @@ -1,10 +1,9 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Produces a pulse on release when no GUI navigation consumed the press. public record GuiPressPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java b/src/main/java/dev/isxander/controlify/action/activator/HoldLatchActivator.java similarity index 76% rename from src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/HoldLatchActivator.java index 3a0954e38..35eb00978 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/HoldLatchActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/HoldLatchActivator.java @@ -1,10 +1,9 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Keeps the latch active from button press until release, without a hold delay. public record HoldLatchActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java b/src/main/java/dev/isxander/controlify/action/activator/HoldPulseActivator.java similarity index 72% rename from src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/HoldPulseActivator.java index abeb8a984..004e83593 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/HoldPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/HoldPulseActivator.java @@ -1,10 +1,9 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Produces a pulse once the input reaches the hold duration. public record HoldPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/action/activator/NoopActivator.java b/src/main/java/dev/isxander/controlify/action/activator/NoopActivator.java new file mode 100644 index 000000000..d4d4e3632 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/action/activator/NoopActivator.java @@ -0,0 +1,23 @@ +package dev.isxander.controlify.action.activator; + +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; + +public class NoopActivator implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + + } + + @Override + public LogicalInput boundInput() { + return null; + } + + @Override + public String describe() { + return "Noop"; + } +} diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java b/src/main/java/dev/isxander/controlify/action/activator/PressPulseActivator.java similarity index 72% rename from src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/PressPulseActivator.java index 4f7d6ad03..812a5616b 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/PressPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/PressPulseActivator.java @@ -1,10 +1,9 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Produces a pulse when the input is pressed. public record PressPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java b/src/main/java/dev/isxander/controlify/action/activator/ReleasePulseActivator.java similarity index 73% rename from src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/ReleasePulseActivator.java index 9e065ab52..c74e9bae4 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ReleasePulseActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/ReleasePulseActivator.java @@ -1,10 +1,9 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Produces a pulse when the input is released. public record ReleasePulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java b/src/main/java/dev/isxander/controlify/action/activator/RepeatLatchPulseActivator.java similarity index 91% rename from src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/RepeatLatchPulseActivator.java index 35a6523c5..b87ab051e 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/RepeatLatchPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/RepeatLatchPulseActivator.java @@ -1,12 +1,12 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Accepts another latch binding, and sends repeat pulses out while the latch is active. public class RepeatLatchPulseActivator implements Activator { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java b/src/main/java/dev/isxander/controlify/action/activator/TapPulseActivator.java similarity index 72% rename from src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/TapPulseActivator.java index ba7c4d377..fc8f5dd63 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/TapPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/TapPulseActivator.java @@ -1,10 +1,9 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Produces a pulse when the input is tapped. public record TapPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java b/src/main/java/dev/isxander/controlify/action/activator/ToggleLatchActivator.java similarity index 85% rename from src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java rename to src/main/java/dev/isxander/controlify/action/activator/ToggleLatchActivator.java index 3c8df2b38..691ea2282 100644 --- a/src/main/java/dev/isxander/controlify/input/action/activator/ToggleLatchActivator.java +++ b/src/main/java/dev/isxander/controlify/action/activator/ToggleLatchActivator.java @@ -1,11 +1,11 @@ -package dev.isxander.controlify.input.action.activator; +package dev.isxander.controlify.action.activator; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; +import dev.isxander.controlify.action.Accumulator; +import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; /// Accepts another pulse binding, and converts pulses into toggling a latch. public class ToggleLatchActivator implements Activator { diff --git a/src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindManager.java b/src/main/java/dev/isxander/controlify/action/defaults/DefaultBindManager.java similarity index 99% rename from src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindManager.java rename to src/main/java/dev/isxander/controlify/action/defaults/DefaultBindManager.java index 38af1cf98..bc7e14d9f 100644 --- a/src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindManager.java +++ b/src/main/java/dev/isxander/controlify/action/defaults/DefaultBindManager.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.bindings.defaults; +package dev.isxander.controlify.action.defaults; import com.google.gson.JsonElement; import com.google.gson.JsonParser; diff --git a/src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindProvider.java b/src/main/java/dev/isxander/controlify/action/defaults/DefaultBindProvider.java similarity index 76% rename from src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindProvider.java rename to src/main/java/dev/isxander/controlify/action/defaults/DefaultBindProvider.java index dfcb82a0a..f18f820be 100644 --- a/src/main/java/dev/isxander/controlify/bindings/defaults/DefaultBindProvider.java +++ b/src/main/java/dev/isxander/controlify/action/defaults/DefaultBindProvider.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.bindings.defaults; +package dev.isxander.controlify.action.defaults; -import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.LogicalInput; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/bindings/defaults/LayeredDefaultBindProvider.java b/src/main/java/dev/isxander/controlify/action/defaults/LayeredDefaultBindProvider.java similarity index 92% rename from src/main/java/dev/isxander/controlify/bindings/defaults/LayeredDefaultBindProvider.java rename to src/main/java/dev/isxander/controlify/action/defaults/LayeredDefaultBindProvider.java index 3ee8345f1..e469b92ca 100644 --- a/src/main/java/dev/isxander/controlify/bindings/defaults/LayeredDefaultBindProvider.java +++ b/src/main/java/dev/isxander/controlify/action/defaults/LayeredDefaultBindProvider.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.bindings.defaults; +package dev.isxander.controlify.action.defaults; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.LogicalInput; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/bindings/defaults/MapBackedDefaultBindProvider.java b/src/main/java/dev/isxander/controlify/action/defaults/MapBackedDefaultBindProvider.java similarity index 89% rename from src/main/java/dev/isxander/controlify/bindings/defaults/MapBackedDefaultBindProvider.java rename to src/main/java/dev/isxander/controlify/action/defaults/MapBackedDefaultBindProvider.java index 238aff79d..46d4c1824 100644 --- a/src/main/java/dev/isxander/controlify/bindings/defaults/MapBackedDefaultBindProvider.java +++ b/src/main/java/dev/isxander/controlify/action/defaults/MapBackedDefaultBindProvider.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.bindings.defaults; +package dev.isxander.controlify.action.defaults; import com.mojang.serialization.Codec; import com.mojang.serialization.Keyable; import com.mojang.serialization.MapCodec; import dev.isxander.controlify.api.bind.ControlifyBindApi; -import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.LogicalInput; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/action/radial/RadialIcon.java b/src/main/java/dev/isxander/controlify/action/radial/RadialIcon.java new file mode 100644 index 000000000..21112c3ff --- /dev/null +++ b/src/main/java/dev/isxander/controlify/action/radial/RadialIcon.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.action.radial; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.resources.Identifier; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public record RadialIcon(Content content, @Nullable Component overlay) { + public static final RadialIcon EMPTY = new RadialIcon(new Empty(), null); + + public static final Codec CODEC = Definition.CODEC.flatXmap( + Definition::toRadialIcon, + RadialIcon::toDefinition + ); + + public static RadialIcon model(Identifier model, boolean enchantGlint) { + return new RadialIcon(new Model(model, enchantGlint), null); + } + + public static RadialIcon model(Identifier model) { + return model(model, false); + } + + public static RadialIcon texture(Identifier texture) { + return new RadialIcon(new Texture(texture), null); + } + + public RadialIcon withOverlay(Component overlay) { + return new RadialIcon(content, overlay); + } + + private static DataResult toDefinition(RadialIcon icon) { + return switch (icon.content()) { + case Model model -> DataResult.success(new Definition( + Optional.of(model), + Optional.empty(), + Optional.ofNullable(icon.overlay()) + )); + case Texture texture -> DataResult.success(new Definition( + Optional.empty(), + Optional.of(texture), + Optional.ofNullable(icon.overlay()) + )); + default -> DataResult.error(() -> "Only model and texture radial icons can be serialized"); + }; + } + + public sealed interface Content permits Empty, Model, Texture { + } + + public record Empty() implements Content { + } + + public record Model(Identifier id, boolean enchantGlint) implements Content { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Identifier.CODEC.fieldOf("id").forGetter(Model::id), + Codec.BOOL.optionalFieldOf("enchant_glint", false).forGetter(Model::enchantGlint) + ).apply(instance, Model::new)) + .withAlternative(Identifier.CODEC.xmap(id -> new Model(id, false), Model::id)); + } + + public record Texture(Identifier id) implements Content { + public static final Codec CODEC = Identifier.CODEC.xmap(Texture::new, Texture::id); + } + + private record Definition(Optional model, Optional texture, Optional overlay) { + private static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Model.CODEC.optionalFieldOf("model").forGetter(Definition::model), + Texture.CODEC.optionalFieldOf("texture").forGetter(Definition::texture), + ComponentSerialization.CODEC.optionalFieldOf("overlay").forGetter(Definition::overlay) + ).apply(instance, Definition::new)) + .validate(def -> { + if (def.model.isPresent() == def.texture.isPresent()) { + return DataResult.error(() -> "Radial icon must define exactly one of 'model' or 'texture'"); + } + return DataResult.success(def); + }); + + private DataResult toRadialIcon() { + if (this.model.isPresent() == this.texture.isPresent()) { + return DataResult.error(() -> "Radial icon must define exactly one of 'model' or 'texture'"); + } + + Content content = this.model.isPresent() + ? this.model.get() + : this.texture.get(); + + return DataResult.success(new RadialIcon(content, this.overlay.orElse(null))); + } + } +} diff --git a/src/main/java/dev/isxander/controlify/bindings/RadialIconExtractor.java b/src/main/java/dev/isxander/controlify/action/radial/RadialIconExtractor.java similarity index 75% rename from src/main/java/dev/isxander/controlify/bindings/RadialIconExtractor.java rename to src/main/java/dev/isxander/controlify/action/radial/RadialIconExtractor.java index 5c47b22bb..d2714c87a 100644 --- a/src/main/java/dev/isxander/controlify/bindings/RadialIconExtractor.java +++ b/src/main/java/dev/isxander/controlify/action/radial/RadialIconExtractor.java @@ -4,9 +4,8 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.bindings; +package dev.isxander.controlify.action.radial; -import dev.isxander.controlify.api.bind.RadialIcon; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.renderer.RenderPipelines; @@ -22,7 +21,7 @@ public final class RadialIconExtractor { public static void extract(GuiGraphicsExtractor graphics, RadialIcon icon, int x, int y) { switch (icon.content()) { case RadialIcon.Empty _ -> {} - case RadialIcon.Model(Identifier model) -> extractModel(graphics, model, x, y); + case RadialIcon.Model(Identifier model, boolean enchantGlint) -> extractModel(graphics, model, enchantGlint, x, y); case RadialIcon.Texture(Identifier texture) -> extractTexture(graphics, texture, x, y); } @@ -31,15 +30,16 @@ public static void extract(GuiGraphicsExtractor graphics, RadialIcon icon, int x } } - private static void extractModel(GuiGraphicsExtractor graphics, Identifier model, int x, int y) { + private static void extractModel(GuiGraphicsExtractor graphics, Identifier model, boolean enchantGlint, int x, int y) { ItemStack stack = new ItemStack(Holder.direct( Items.STICK, DataComponentMap.builder() - .set(DataComponents.MAX_STACK_SIZE, 1) - .set(DataComponents.MAX_DAMAGE, 2) - .set(DataComponents.DAMAGE, 0) - .set(DataComponents.ITEM_MODEL, model) - .build() + .set(DataComponents.MAX_STACK_SIZE, 1) + .set(DataComponents.MAX_DAMAGE, 2) + .set(DataComponents.DAMAGE, 0) + .set(DataComponents.ITEM_MODEL, model) + .set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, enchantGlint) + .build() )); graphics.item(stack, x, y); diff --git a/src/main/java/dev/isxander/controlify/bindings/RadialIconManager.java b/src/main/java/dev/isxander/controlify/action/radial/RadialIconManager.java similarity index 79% rename from src/main/java/dev/isxander/controlify/bindings/RadialIconManager.java rename to src/main/java/dev/isxander/controlify/action/radial/RadialIconManager.java index d6e86dda1..ea7dbd269 100644 --- a/src/main/java/dev/isxander/controlify/bindings/RadialIconManager.java +++ b/src/main/java/dev/isxander/controlify/action/radial/RadialIconManager.java @@ -4,14 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.bindings; +package dev.isxander.controlify.action.radial; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.api.bind.RadialIcon; +import dev.isxander.controlify.bindings.ControlifyBindings; import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; import dev.isxander.controlify.utils.CUtil; import net.minecraft.resources.Identifier; @@ -32,17 +31,16 @@ public class RadialIconManager implements SimpleControlifyReloadListener> CODEC = Codec.unboundedMap(Identifier.CODEC, RadialIcon.CODEC); private static final RadialIcon FALLBACK = RadialIcon.model(Identifier.withDefaultNamespace("book")); - private volatile Map iconsByBinding = Map.of(); + private volatile Map iconsByActionId = Map.of(); - public boolean isRadialCandidate(InputBinding binding) { + public boolean isRadialCandidate(Identifier actionId) { // noinspection removal - return iconsByBinding.containsKey(binding.id()) - || binding.id().getNamespace().equals(ControlifyBindings.MODDED_BIND_NAMESPACE) - || binding.isRadialCandidate(); + return this.iconsByActionId.containsKey(actionId) + || actionId.getNamespace().equals(ControlifyBindings.MODDED_BIND_NAMESPACE); } - public RadialIcon getIcon(InputBinding binding) { - return iconsByBinding.getOrDefault(binding.id(), FALLBACK); + public RadialIcon getIcon(Identifier actionId) { + return iconsByActionId.getOrDefault(actionId, FALLBACK); } @Override @@ -74,7 +72,7 @@ public CompletableFuture> load(ResourceManager manag @Override public CompletableFuture apply(Map data, ResourceManager manager, Executor executor) { - return CompletableFuture.runAsync(() -> iconsByBinding = data, executor); + return CompletableFuture.runAsync(() -> iconsByActionId = data, executor); } @Override diff --git a/src/main/java/dev/isxander/controlify/api/bind/ControlifyBindApi.java b/src/main/java/dev/isxander/controlify/api/bind/ControlifyBindApi.java deleted file mode 100644 index 5fc639f63..000000000 --- a/src/main/java/dev/isxander/controlify/api/bind/ControlifyBindApi.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.api.bind; - -import dev.isxander.controlify.bindings.BindContext; -import dev.isxander.controlify.bindings.ControlifyBindApiImpl; -import dev.isxander.controlify.controller.ControllerEntity; -import net.minecraft.client.KeyMapping; -import net.minecraft.resources.Identifier; - -import java.util.List; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import java.util.stream.Stream; - -/** - * The API for registering and managing bindings. - */ -public interface ControlifyBindApi { - static ControlifyBindApi get() { - return ControlifyBindApiImpl.INSTANCE; - } - - /** - * Registers a new binding that will be created on all controllers. - * - * @param callback the callback that populates the binding builder. will only be called once - * @return the supplier for the binding - */ - InputBindingSupplier registerBinding(RegistryCallback callback); - - /** - * Registers a new binding that will be created on only the controllers that pass the filter. - * - * @param callback the callback that populates the binding builder. will only be called once - * @param filter the filter that determines if the binding should be created for the controller - * @return the supplier for the binding - */ - InputBindingSupplier registerBinding(RegistryCallback callback, Predicate filter); - - /** - * Creates a supplier for an input binding with the given bind ID. - * Useful when fetching bindings by ID, rather than by java reference, such is needed - * in cases of data-driven systems. - * {@link InputBindingSupplier#on(ControllerEntity)} may throw an exception if the binding does not exist, - * when it is attempted to be resolved. - * @param bindId the ID of the binding to create a supplier for - * @return the supplier for the binding - */ - InputBindingSupplier createSupplier(Identifier bindId); - - /** - * Get all the controller bindings for a vanilla key mapping. - * This is populated using {@link InputBindingBuilder#addKeyCorrelation(KeyMapping)} - * or {@link InputBindingBuilder#keyEmulation(KeyMapping)}. - * - * @param key the key mapping to get the correlations for - * @return the list of the suppliers for the binding - */ - List getKeyCorrelation(KeyMapping key); - - /** - * Registers a new bind context that can be used to determine when a binding is active. - * - * @param context the bind context - */ - void registerBindContext(BindContext context); - - /** - * Gets all registered bind contexts. - * - * @return the stream of bind contexts - */ - Stream getAllBindIds(); - - @FunctionalInterface - interface RegistryCallback extends UnaryOperator { - } -} diff --git a/src/main/java/dev/isxander/controlify/api/bind/InputBinding.java b/src/main/java/dev/isxander/controlify/api/bind/InputBinding.java deleted file mode 100644 index 1d86013dd..000000000 --- a/src/main/java/dev/isxander/controlify/api/bind/InputBinding.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.api.bind; - -import dev.isxander.controlify.bindings.BindContext; -import dev.isxander.controlify.bindings.StateAccess; -import dev.isxander.controlify.bindings.input.EmptyInput; -import dev.isxander.controlify.bindings.input.Input; -import dev.isxander.controlify.bindings.output.AnalogueOutput; -import dev.isxander.controlify.bindings.output.DigitalOutput; -import dev.isxander.controlify.bindings.output.GuiPressOutput; -import dev.isxander.controlify.controller.input.ControllerStateView; -import dev.isxander.controlify.utils.CUtil; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.ApiStatus; - -import java.util.Set; -import java.util.function.Consumer; - -/** - * An input binding is a single action that can be performed in Minecraft, e.g. punching. - * It is bound to a controller {@link Input}, e.g. the A button. - * Every tick, the input binding will update its state based on the controller input and then propagate to its outputs, - * e.g. {@link #justTapped()}. The outputs are then used to perform the action in the game. - */ -public interface InputBinding { - /** - * The ID of the binding, set from {@link InputBindingBuilder#id(Identifier)}. - * @return the ID - */ - Identifier id(); - - /** - * The name of the binding. - * @return the name - */ - Component name(); - - /** - * The description of the binding. - * @return the description - */ - Component description(); - - /** - * The category of the binding. - * @return the category - */ - Component category(); - - /** - * The icon glyph of the input - * @return the icon component - */ - Component inputGlyph(); - - /** - * The icon glyph of the input - * @return the icon component - */ - @Deprecated - default Component inputIcon() { - return this.inputGlyph(); - } - - @Deprecated(forRemoval = true) - boolean isRadialCandidate(); - - /** - * Create a new state access with the given history required. - * Please use the minimum amount of history required. - * - * @param historyRequired the amount of ticks of history required. - * @return the state access - */ - StateAccess createStateAccess(int historyRequired); - - /** - * Create a new state access with the given history required and push event. - * Please use the minimum amount of history required. - * - * @param historyRequired the amount of ticks of history required. - * @param pushEvent the event to call when a new state is pushed. - * @return the state access - */ - StateAccess createStateAccess(int historyRequired, Consumer pushEvent); - - /** - * Returns the state access created with {@link #createStateAccess(int)}. - * This renders it unusable forever. - * This frees up history if possible. - * - * @param stateAccess the state access to return - */ - void returnStateAccess(StateAccess stateAccess); - - @ApiStatus.Internal - void pushState(ControllerStateView state); - - /** - * Emulates a tap of this binding. - * This is used by the radial menu. - */ - void fakePress(); - - /** - * Set the input that this binding is bound to. - * - * @param input input to bind - */ - void setBoundInput(Input input); - - /** - * Get the input that this binding is bound to. - * - * @return currently bound input - */ - Input boundInput(); - - /** - * Get the default input for this binding. - * This can change if the user reloads resources and the default changes - * (since it's data-driven). - * - * @return default input - */ - Input defaultInput(); - - /** - * @return true if the binding is equal to {@link EmptyInput} - */ - default boolean isUnbound() { - return EmptyInput.equals(this.boundInput()); - } - - /** - * Gets all contexts associated with this binding, - * not just the currently applicable ones. - * This is set from {@link InputBindingBuilder#allowedContexts(BindContext...)}. - * - * @return the contexts - */ - Set contexts(); - - /** - * Equivalent to calling - *

-	 *     StateAccess stateAccess = binding.createStateAccess(0);
-	 *     float analogueNow = stateAccess.analogue(0);
-	 * 
- * - * @return the current analogue state (0-1, never negative), - * this tick. - */ - float analogueNow(); - - /** - * Equivalent to calling - *

-	 *     StateAccess stateAccess = binding.createStateAccess(1);
-	 *     float analoguePrev = stateAccess.analogue(1);
-	 * 
- * - * @return the previous analogue state (0-1, never negative), 1 tick ago - */ - float analoguePrev(); - - /** - * Equivalent to calling - *

-	 *     StateAccess stateAccess = binding.createStateAccess(0);
-	 *     boolean digitalNow = stateAccess.digital(0);
-	 * 
- * - * @return the current digital state (true or false), this tick - */ - boolean digitalNow(); - - /** - * Equivalent to calling - *

-	 *     StateAccess stateAccess = binding.createStateAccess(1);
-	 *     boolean digitalPrev = stateAccess.digital(1);
-	 * 
- * - * @return the previous digital state (true or false), 1 tick ago - */ - boolean digitalPrev(); - - /** - * Equivalent to calling - *

-	 *     binding.digitalNow() && !binding.digitalPrev()
-	 * 
- * - * @return true if the binding is pressed this tick and not pressed the previous tick - */ - boolean justPressed(); - - /** - * Equivalent to calling - *

-	 *     !binding.digitalNow() && binding.digitalPrev()
-	 * 
- * - * @return true if the binding is not pressed this tick and pressed the previous tick - */ - boolean justReleased(); - - /** - * @return true if the binding got pressed, and then released - */ - boolean justTapped(); - - /** - * A more advanced output that returns true after the input was released, - * but only if the player has not navigated away from the button where the input was initially pressed. - * - * @return the output - */ - GuiPressOutput guiPressed(); - - Identifier ANALOGUE_NOW = CUtil.rl("analogue_now"); - Identifier ANALOGUE_PREV = CUtil.rl("analogue_prev"); - Identifier DIGITAL_NOW = CUtil.rl("digital_now"); - Identifier DIGITAL_PREV = CUtil.rl("digital_prev"); - Identifier JUST_PRESSED = CUtil.rl("just_pressed"); - Identifier JUST_RELEASED = CUtil.rl("just_released"); - Identifier JUST_TAPPED = CUtil.rl("just_tapped"); - Identifier GUI_PRESSED = CUtil.rl("gui_pressed"); - Identifier KEY_EMULATION = CUtil.rl("key_emulation"); - - T getDigitalOutput(Identifier id); - T addDigitalOutput(Identifier id, T output); - - T getAnalogueOutput(Identifier id); - T addAnalogueOutput(Identifier id, T output); -} diff --git a/src/main/java/dev/isxander/controlify/api/bind/InputBindingBuilder.java b/src/main/java/dev/isxander/controlify/api/bind/InputBindingBuilder.java deleted file mode 100644 index e0671897d..000000000 --- a/src/main/java/dev/isxander/controlify/api/bind/InputBindingBuilder.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.api.bind; - -import dev.isxander.controlify.bindings.BindContext; -import dev.isxander.controlify.bindings.input.Input; -import dev.isxander.controlify.controller.ControllerEntity; -import net.minecraft.client.KeyMapping; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.function.Function; - -/** - * A builder for creating an {@link InputBinding}. - * This is used to populate the fields of the binding. - * The builder is provided through a callback in - * {@link ControlifyBindApi#registerBinding(ControlifyBindApi.RegistryCallback)} - * and should not be created or built manually. - */ -public interface InputBindingBuilder { - /** - * Sets the unique identifier for the binding. - * This is a required field. The namespace should be your mod's ID. - *

- * The id is used to automatically generate the translation keys for the name and description. - *

    - *
  • Name: controlify.binding.(namespace).(path)
  • - *
  • Desc: controlify.binding.(namespace).(path).desc, optional
  • - *
- * This is the ID referred to in {@link InputBindingSupplier#bindId()}. - * - * @param rl the binding's id - * @return this builder - */ - InputBindingBuilder id(@NotNull Identifier rl); - - /** - * Sets the unique identifier for the binding. - * This is a required field. The namespace should be your mod's ID. - *

- * The id is used to automatically generate the translation keys for the name and description. - *

    - *
  • Name: controlify.binding.(namespace).(path)
  • - *
  • Desc: controlify.binding.(namespace).(path).desc, optional
  • - *
- * This is the ID referred to in {@link InputBindingSupplier#bindId()}. - * - * @param namespace namespace of {@link Identifier} - * @param path path of {@link Identifier} - * @return this builder - */ - InputBindingBuilder id(@NotNull String namespace, @NotNull String path); - - /** - * Sets a custom name component for the binding. Optional field. - * If not set, the name will be automatically generated from {@link #id(Identifier)}, - * controlify.binding.(namespace).(path) - *

- * Useful for re-using language keys from regular key mappings. - * - * @param text the name component - * @return this builder - */ - InputBindingBuilder name(@NotNull Component text); - - /** - * Sets a custom description component for the binding. Optional field. - * If not set, the description will be automatically generated from {@link #id(Identifier)}, - * controlify.binding.(namespace).(path).desc - * The description will be empty if the translation key does not exist. - *

- * Useful for re-using language keys from regular key mappings. - * - * @param text the name component - * @return this builder - */ - InputBindingBuilder description(@NotNull Component text); - - /** - * Sets the category for the binding. Required field. - * This is used to group the binding in the option menu. - * It's recommended that you use a single category for all of your mod's bindings. - * - * @param text the category component - * @return this builder - */ - InputBindingBuilder category(@NotNull Component text); - - /** - * Sets the contexts that the binding is allowed to be active in. - * If the binding's predicate {@link BindContext#isApplicable()} returns false, all outputs will be disabled. - * - * @param contexts all applicable contexts - * @return this builder - */ - InputBindingBuilder allowedContexts(@NotNull BindContext @Nullable... contexts); - - /** - * Adds a correlation between a vanilla key mapping and this binding. - * A correlation means that an auto-generated binding for this vanilla key mapping will not be created. - * - * @param keyMapping the key mapping to correlate with - * @return this builder - */ - InputBindingBuilder addKeyCorrelation(@NotNull KeyMapping keyMapping); - - /** - * Makes the binding emulate a vanilla key mapping. - * If the bound input is pressed, so will the key mapping. - * - * @param keyMapping the key mapping to emulate - * @return this builder - */ - InputBindingBuilder keyEmulation(@NotNull KeyMapping keyMapping); - - InputBindingBuilder keyEmulation(@NotNull KeyMapping keyMapping, @Nullable Function toggleCondition); - - /** - * Sets the default input for the binding. - * It is not recommended to use this method. Default inputs should be data-driven. - * If specified, the default will be bottom-most layered with data-driven defaults. - * To set the default input from data, specify it in: - *

assets/controlify/controllers/default_bind/default.json
- *

-	 *     {
-	 *         "defaults": {
-	 *             "your_binding_id": {
-	 *                 "button": "controlify:button/south"
-	 *             }
-	 *         }
-	 *     }
-	 * 
- * @param input the default input - * @return this builder - */ - @Deprecated - InputBindingBuilder defaultInput(@Nullable Input input); - - /// @deprecated Radial Menu candidates are now data driven. - /// [Check out the wiki](https://moddedmc.wiki/en/project/controlify/latest/docs/resource-packs/radial-icons) - @Deprecated(forRemoval = true) - default InputBindingBuilder radialCandidate(@Nullable Identifier icon) { - return radialCandidate(icon != null); - } - - @Deprecated(forRemoval = true) - InputBindingBuilder radialCandidate(boolean isCandidate); -} diff --git a/src/main/java/dev/isxander/controlify/api/bind/InputBindingSupplier.java b/src/main/java/dev/isxander/controlify/api/bind/InputBindingSupplier.java deleted file mode 100644 index 50cc4fdd5..000000000 --- a/src/main/java/dev/isxander/controlify/api/bind/InputBindingSupplier.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.api.bind; - -import com.mojang.serialization.Codec; -import dev.isxander.controlify.controller.ControllerEntity; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Objects; - -/** - * A supplier that retrieves an {@link InputBinding} for a controller. - */ -public interface InputBindingSupplier { - /** - * Retrieves the input binding for the controller, throwing an exception if it does not exist. - * - * @param controller the controller to fetch the binding from - * @throws NullPointerException if the binding does not exist - * @return the input binding - */ - default InputBinding on(@NotNull ControllerEntity controller) { - return Objects.requireNonNull( - onOrNull(controller), - () -> "Attempted to fetch " + bindId() + " for controller " + controller.uid() + " but it did not exist." + - "The binding registry callback may have a filter that did not pass for this controller."); - } - - /** - * Retrieves the input binding for the controller, or null if it does not exist. - * - * @param controller controller to fetch binding from - * @return the input binding, or null if it does not exist - */ - @Nullable InputBinding onOrNull(ControllerEntity controller); - - /** - * @return id of the binding. - */ - Identifier bindId(); - - /** - * Returns a text component with the currently bound input glyph - * for the currently selected controller. - *

- * Be careful, as this component will be rendered differently - * depending on the active controller, so make sure to deal with - * width caching and other issues that may arise. - * @see InputBinding#inputGlyph() for a deterministic version on a specific controller - * @return a component representing the input glyph - */ - Component inputGlyph(); - - Codec CODEC = Identifier.CODEC.xmap( - bindId -> ControlifyBindApi.get().createSupplier(bindId), - InputBindingSupplier::bindId - ); -} diff --git a/src/main/java/dev/isxander/controlify/api/bind/RadialIcon.java b/src/main/java/dev/isxander/controlify/api/bind/RadialIcon.java deleted file mode 100644 index 101c41f9a..000000000 --- a/src/main/java/dev/isxander/controlify/api/bind/RadialIcon.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.api.bind; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; - -public record RadialIcon(Content content, @Nullable Component overlay) { - public static final RadialIcon EMPTY = new RadialIcon(new Empty(), null); - - public static final Codec CODEC = Definition.CODEC.flatXmap( - Definition::toRadialIcon, - RadialIcon::toDefinition - ); - - public static RadialIcon model(Identifier model) { - return new RadialIcon(new Model(model), null); - } - - public static RadialIcon texture(Identifier texture) { - return new RadialIcon(new Texture(texture), null); - } - - public RadialIcon withOverlay(Component overlay) { - return new RadialIcon(content, overlay); - } - - private static DataResult toDefinition(RadialIcon icon) { - return switch (icon.content()) { - case Model(Identifier model) -> DataResult.success(new Definition(Optional.of(model), Optional.empty())); - case Texture(Identifier texture) -> DataResult.success(new Definition(Optional.empty(), Optional.of(texture))); - default -> DataResult.error(() -> "Only model and texture radial icons can be serialized"); - }; - } - - public sealed interface Content permits Empty, Model, Texture { - } - - public record Empty() implements Content { - } - - public record Model(Identifier id) implements Content { - } - - public record Texture(Identifier id) implements Content { - } - - private record Definition(Optional model, Optional texture) { - private static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.optionalFieldOf("model").forGetter(Definition::model), - Identifier.CODEC.optionalFieldOf("texture").forGetter(Definition::texture) - ).apply(instance, Definition::new)); - - private DataResult toRadialIcon() { - if (model.isPresent() == texture.isPresent()) { - return DataResult.error(() -> "Radial icon must define exactly one of 'model' or 'texture'"); - } - - return DataResult.success(model - .map(RadialIcon::model) - .orElseGet(() -> RadialIcon.texture(texture.orElseThrow()))); - } - } -} diff --git a/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuideApi.java b/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuideApi.java index ab2bca95c..bf64bc3d3 100644 --- a/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuideApi.java +++ b/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuideApi.java @@ -6,6 +6,7 @@ */ package dev.isxander.controlify.api.buttonguide; +import dev.isxander.controlify.action.ActionAccessor; import dev.isxander.controlify.api.bind.InputBindingSupplier; import dev.isxander.controlify.gui.ButtonGuideRenderer; import net.minecraft.client.gui.screens.Screen; @@ -28,20 +29,20 @@ private ButtonGuideApi() { * Custom behaviour should be handled inside a {@link dev.isxander.controlify.screenop.ScreenProcessor} or {@link dev.isxander.controlify.screenop.ComponentProcessor} * * @param button button to render the guide for - * @param binding the custom binding to render + * @param action the action binding to render * @param renderPredicate whether the guide should be rendered */ public static void addGuideToButton( @NotNull T button, - @NotNull InputBindingSupplier binding, + @NotNull ActionAccessor action, @NotNull ButtonGuidePredicate renderPredicate) { - ButtonGuideRenderer.registerBindingForButton(button, () -> binding, renderPredicate); + ButtonGuideRenderer.registerBindingForButton(button, () -> action, renderPredicate); } public static void addGuideToButton( @NotNull T button, - @NotNull Supplier binding, + @NotNull Supplier action, @NotNull ButtonGuidePredicate renderPredicate) { - ButtonGuideRenderer.registerBindingForButton(button, binding, renderPredicate); + ButtonGuideRenderer.registerBindingForButton(button, action, renderPredicate); } } diff --git a/src/main/java/dev/isxander/controlify/bindings/ControlifyBindApiImpl.java b/src/main/java/dev/isxander/controlify/bindings/ControlifyBindApiImpl.java deleted file mode 100644 index 111686670..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/ControlifyBindApiImpl.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings; - -import dev.isxander.controlify.api.bind.ControlifyBindApi; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.bindings.output.KeyMappingEmulationOutput; -import dev.isxander.controlify.controller.ControllerEntity; -import net.minecraft.client.KeyMapping; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.function.BooleanSupplier; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Stream; - -public class ControlifyBindApiImpl implements ControlifyBindApi { - public static final ControlifyBindApiImpl INSTANCE = new ControlifyBindApiImpl(); - - private final List bindEntries = new ArrayList<>(); - private final Map> keyMappingCorrelations = new HashMap<>(); - - private boolean locked; - - @Override - public InputBindingSupplier registerBinding(RegistryCallback callback) { - return registerBinding(callback, c -> true); - } - - @Override - public InputBindingSupplier registerBinding(RegistryCallback callback, Predicate filter) { - checkLocked(); - - var builder = new InputBindingBuilderImpl(); - - callback.apply(builder); - - Function finaliser = builder::build; - - Identifier bindId = builder.getIdAndLock(); - - this.bindEntries.add(new RegistryEntry(filter, finaliser, builder.getKeyEmulation(), builder.getKeyEmulationToggle(), bindId)); - - for (KeyMapping key : builder.getKeyCorrelations()) { - keyMappingCorrelations.computeIfAbsent(key, k -> new ArrayList<>()).add(createSupplier(bindId)); - } - - return createSupplier(bindId); - } - - @Override - public List getKeyCorrelation(KeyMapping key) { - return Optional.ofNullable(this.keyMappingCorrelations.get(key)).orElse(List.of()); - } - - @Override - public void registerBindContext(BindContext context) { - BindContext.CONTEXTS.put(context.id(), context); - } - - private void checkLocked() { - if (locked) - throw new IllegalStateException("Registry is locked. Cannot add bind now."); - } - - /** - * Provides all bindings for a given controller. - * @param controller The controller to provide bindings for. Can be null to get a list of all bindings. - * @return A list of input bindings. - */ - public List provideBindsForController(@Nullable ControllerEntity controller) { - List bindings = new ArrayList<>(); - - for (RegistryEntry entry : bindEntries) { - if (controller != null && !entry.filter().test(controller)) - continue; - - InputBindingImpl binding = entry.builder().apply(controller); - - if (controller != null && entry.emulation() != null) { - BooleanSupplier emulationToggle = null; - if (entry.emulationToggle() != null) { - emulationToggle = () -> entry.emulationToggle().apply(controller); - } - - binding.addDigitalOutput( - InputBinding.KEY_EMULATION, - new KeyMappingEmulationOutput(controller, binding, entry.emulation(), emulationToggle) - ); - } - - bindings.add(binding); - } - - return bindings; - } - - @Override - public InputBindingSupplier createSupplier(Identifier bindingId) { - return new InputBindingSupplierImpl(bindingId); - } - - public void lock() { - this.locked = true; - } - - @Override - public Stream getAllBindIds() { - return this.bindEntries.stream().map(RegistryEntry::id); - } - - private record RegistryEntry( - Predicate filter, - Function<@Nullable ControllerEntity, InputBindingImpl> builder, - KeyMapping emulation, - Function emulationToggle, - Identifier id - ) {} -} diff --git a/src/main/java/dev/isxander/controlify/bindings/InputBindingBuilderImpl.java b/src/main/java/dev/isxander/controlify/bindings/InputBindingBuilderImpl.java deleted file mode 100644 index 063f68487..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/InputBindingBuilderImpl.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.bind.InputBindingBuilder; -import dev.isxander.controlify.bindings.defaults.DefaultBindProvider; -import dev.isxander.controlify.bindings.input.EmptyInput; -import dev.isxander.controlify.bindings.input.Input; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.id.ControllerType; -import net.minecraft.client.KeyMapping; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.Identifier; -import org.apache.commons.lang3.Validate; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.function.Function; -import java.util.function.Supplier; - -public class InputBindingBuilderImpl implements InputBindingBuilder { - private @Nullable Identifier id; - private @Nullable Component category; - private @Nullable Component customName, customDescription; - private @Nullable Input defaultInput; - private final Set allowedContexts = new HashSet<>(); - private final Set keyCorrelations = new HashSet<>(); - private KeyMapping keyEmulation = null; - private Function keyEmulationToggle = null; - - @Deprecated(forRemoval = true) - private boolean isRadialCandidate = false; - - private boolean locked; - - @Override - public InputBindingBuilder id(@NotNull Identifier rl) { - checkLocked(); - - this.id = rl; - return this; - } - - @Override - public InputBindingBuilder id(@NotNull String namespace, @NotNull String path) { - return this.id(Identifier.fromNamespaceAndPath(namespace, path)); - } - - @Override - public InputBindingBuilder category(@NotNull Component text) { - checkLocked(); - - this.category = text; - return this; - } - - @Override - public InputBindingBuilder name(@NotNull Component text) { - checkLocked(); - - this.customName = text; - return this; - } - - @Override - public InputBindingBuilder description(@NotNull Component text) { - checkLocked(); - - this.customDescription = text; - return this; - } - - @Override - public InputBindingBuilder defaultInput(@Nullable Input input) { - checkLocked(); - - this.defaultInput = input; - return this; - } - - @Override - public InputBindingBuilder allowedContexts(@NotNull BindContext @Nullable ... contexts) { - checkLocked(); - - if (contexts != null) - this.allowedContexts.addAll(List.of(contexts)); - return this; - } - - @Override - public InputBindingBuilder addKeyCorrelation(@NotNull KeyMapping keyMapping) { - checkLocked(); - - this.keyCorrelations.add(keyMapping); - return this; - } - - @Override - public InputBindingBuilder keyEmulation(@NotNull KeyMapping keyMapping, @Nullable Function toggleCondition) { - checkLocked(); - - this.keyEmulation = keyMapping; - this.keyEmulationToggle = toggleCondition; - this.addKeyCorrelation(keyMapping); - return this; - } - - @Override - public InputBindingBuilder keyEmulation(@NotNull KeyMapping keyMapping) { - return keyEmulation(keyMapping, null); - } - - @Override - @Deprecated(forRemoval = true) - @SuppressWarnings("removal") - public InputBindingBuilder radialCandidate(boolean isCandidate) { - this.isRadialCandidate = isCandidate; - return this; - } - - public InputBindingImpl build(@Nullable ControllerEntity controller) { - Validate.isTrue(locked, "Tried to build builder before it was locked."); - - Identifier controllerType = controller != null - ? controller.info().type().namespace() - : ControllerType.DEFAULT.namespace(); - - Component name = createDefaultString(controllerType, null, false); - if (customName != null) name = customName; - - Component description = createDefaultString(controllerType, "desc", true); - if (customDescription != null) description = customDescription; - if (description == null) description = Component.empty(); - - Supplier defaultSupplier = () -> { - // retrieve every tick so the bind provider isn't cached after a resource reload - DefaultBindProvider provider = Controlify.instance().defaultBindManager().getDefaultBindProvider( - controllerType - ); - - Input input = provider.getDefaultInput(id); - if (input == null) input = defaultInput; - if (input == null) input = EmptyInput.INSTANCE; - - return input; - }; - - return new InputBindingImpl( - controller != null ? controller.input().orElse(null) : null, - controllerType, - id, - name, - description, - category, - defaultSupplier, - allowedContexts, - isRadialCandidate - ); - } - - @NotNull public Identifier getIdAndLock() { - checkLocked(); - - locked = true; - Validate.notNull(this.id, "Must call `.id(Identifier)` on builder!"); - Validate.notNull(this.category, "Must call `.category(Component)` on builder %s!".formatted(this.id)); - - return this.id; - } - - public Set getKeyCorrelations() { - return this.keyCorrelations; - } - - public @Nullable KeyMapping getKeyEmulation() { - return this.keyEmulation; - } - - public @Nullable Function getKeyEmulationToggle() { - return this.keyEmulationToggle; - } - - private void checkLocked() { - Validate.isTrue(!locked, "Tried to modify binding builder after is has been locked!"); - } - - private Component createDefaultString(Identifier controllerType, @Nullable String suffix, boolean notExistToNull) { - Objects.requireNonNull(id); - - String typeSpecificKey = controllerType.toLanguageKey("controlify.binding", id.toLanguageKey()); - if (suffix != null) typeSpecificKey += "." + suffix; - if (Language.getInstance().has(typeSpecificKey)) { - return Component.translatable(typeSpecificKey); - } - - String genericKey = id.toLanguageKey("controlify.binding"); - if (suffix != null) genericKey += "." + suffix; - - if (notExistToNull && !Language.getInstance().has(genericKey)) - return null; - - return Component.translatable(genericKey); - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/InputBindingImpl.java b/src/main/java/dev/isxander/controlify/bindings/InputBindingImpl.java deleted file mode 100644 index 58b9be40e..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/InputBindingImpl.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.input.Input; -import dev.isxander.controlify.bindings.output.*; -import dev.isxander.controlify.controller.input.ControllerStateView; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.utils.ResizableRingBuffer; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class InputBindingImpl implements InputBinding { - private final Identifier id; - private final Component name, description, category; - private final boolean isRadialCandidate; - /** - * Fallback bound input used only when inputComponent is null (i.e., bindings not attached to a controller). - * When inputComponent is present, the bound input is read/written directly from the config. - */ - private Input fallbackBoundInput; - private final Supplier defaultBindSupplier; - private final Set contexts; - private final @Nullable InputComponent inputComponent; - private final Identifier controllerType; - - private final ResizableRingBuffer stateHistory; - private final Set borrowedAccesses; - - private boolean suppressed; - - private final AnalogueOutput analogueNow; - private final AnalogueOutput analoguePrev; - private final DigitalOutput digitalNow; - private final DigitalOutput digitalThen; - private final DigitalOutput justPressed; - private final DigitalOutput justReleased; - private final DigitalOutput justTapped; - private final GuiPressOutput guiPressOutput; - - private final Map digitalOutputs; - private final Map analogueOutputs; - - private int fakePressState = -1; - - public InputBindingImpl( - @Nullable InputComponent inputComponent, - Identifier controllerType, - Identifier id, - Component name, - Component description, - Component category, - Supplier defaultBindSupplier, - Set contexts, - boolean isRadialCandidate - ) { - this.inputComponent = inputComponent; - this.controllerType = controllerType; - this.id = id; - this.name = name; - this.description = description; - this.category = category; - this.isRadialCandidate = isRadialCandidate; - this.stateHistory = new ResizableRingBuffer<>(2, () -> 0f); - this.fallbackBoundInput = defaultBindSupplier.get(); - this.defaultBindSupplier = defaultBindSupplier; - this.contexts = contexts; - this.borrowedAccesses = new HashSet<>(); - - this.digitalOutputs = new HashMap<>(); - this.analogueOutputs = new HashMap<>(); - - this.analogueNow = addAnalogueOutput(ANALOGUE_NOW, new SimpleAnalogueOutput(this, 0)); - this.analoguePrev = addAnalogueOutput(ANALOGUE_PREV, new SimpleAnalogueOutput(this, 1)); - this.digitalNow = addDigitalOutput(DIGITAL_NOW, new SimpleDigitalOutput(this, 0)); - this.digitalThen = addDigitalOutput(DIGITAL_PREV, new SimpleDigitalOutput(this, 1)); - this.justPressed = addDigitalOutput(JUST_PRESSED, new JustPressedOutput(this)); - this.justReleased = addDigitalOutput(JUST_RELEASED, new JustReleasedOutput(this)); - this.justTapped = addDigitalOutput(JUST_TAPPED, new JustTappedOutput(this)); - this.guiPressOutput = addDigitalOutput(GUI_PRESSED, new GuiPressOutput(this)); - } - - @Override - public Identifier id() { - return this.id; - } - - @Override - public Component name() { - return this.name; - } - - @Override - public Component description() { - return this.description; - } - - @Override - public Component category() { - return this.category; - } - - @Override - public Component inputGlyph() { - return Controlify.instance().inputFontMapper().getComponentFromInputs( - controllerType, - boundInput().getRelevantInputs() - ); - } - - @Deprecated(forRemoval = true) - @SuppressWarnings("removal") - @Override - public boolean isRadialCandidate() { - return isRadialCandidate; - } - - @Override - public StateAccess createStateAccess(int historyRequired) { - return createStateAccess(historyRequired, null); - } - - @Override - public StateAccess createStateAccess(int historyRequired, Consumer pushEvent) { - if (historyRequired > this.stateHistory.size()) { - this.stateHistory.setSize(historyRequired); - } - - StateAccessImpl access = new StateAccessImpl(historyRequired, pushEvent); - borrowedAccesses.add(access); - - return access; - } - - @Override - public void returnStateAccess(StateAccess stateAccess) { - if (stateAccess instanceof StateAccessImpl accessImpl) { - boolean removed = this.borrowedAccesses.remove(accessImpl); - accessImpl.retire(); - - if (removed) { - OptionalInt newMaxSize = this.borrowedAccesses.stream().mapToInt(StateAccessImpl::maxHistory).max(); - newMaxSize.ifPresent(this.stateHistory::setSize); - } - } else { - throw new IllegalStateException("Unknown implementation of state access"); - } - } - - @Override - public void pushState(ControllerStateView state) { - if (!this.contexts.isEmpty()) { - Set thisTickContexts = Controlify.instance().thisTickBindContexts(); - this.suppressed = this.contexts.stream().noneMatch(thisTickContexts::contains); - } else { - this.suppressed = false; - } - - float analogue = this.boundInput().state(state); - - switch (fakePressState) { - case 0 -> analogue = 0; - case 1,2 -> analogue = 1; - case 3 -> analogue = 0; - } - if (fakePressState >= 0) { - if (fakePressState == 3) - fakePressState = -1; - else - fakePressState++; - } - - this.stateHistory.push(analogue); - borrowedAccesses.forEach(StateAccessImpl::onPush); - } - - @Override - public void fakePress() { - fakePressState = 0; - } - - @Override - public void setBoundInput(Input input) { - if (inputComponent != null) { - var settings = inputComponent.settings(); - // If keepDefaultBindings is false and the input equals the default, - // remove from config so it won't be serialized (allowing future default changes to take effect) - if (!settings.keepDefaultBindings && input.equals(defaultInput())) { - settings.bindings.bindings.remove(id); - } else { - // Write directly to the config - all bindings sharing the same config will see this change - settings.bindings.bindings.put(id, input); - } - } else { - // No inputComponent means this binding isn't attached to a controller, use fallback - this.fallbackBoundInput = input; - } - Controlify.instance().config().markDirty(); - } - - @Override - public Input boundInput() { - if (inputComponent != null) { - // Read directly from the config - ensures all bindings sharing the same config see the same value - Input configInput = inputComponent.settings().bindings.bindings.get(id); - if (configInput != null) { - return configInput; - } - // Not in config means it's at the default (require keepDefaultBindings is false) - // Return the dynamic default so all controllers stay in sync - return defaultInput(); - } - // Fallback: use local value for bindings without inputComponent - return this.fallbackBoundInput; - } - - @Override - public Input defaultInput() { - return this.defaultBindSupplier.get(); - } - - @Override - public Set contexts() { - return this.contexts; - } - - @Override - public float analogueNow() { - return this.analogueNow.get(); - } - - @Override - public float analoguePrev() { - return this.analoguePrev.get(); - } - - @Override - public boolean digitalNow() { - return this.digitalNow.get(); - } - - @Override - public boolean digitalPrev() { - return this.digitalThen.get(); - } - - @Override - public boolean justPressed() { - return this.justPressed.get(); - } - - @Override - public boolean justReleased() { - return this.justReleased.get(); - } - - @Override - public boolean justTapped() { - return this.justTapped.get(); - } - - @Override - public GuiPressOutput guiPressed() { - return this.guiPressOutput; - } - - @Override - public T addDigitalOutput(Identifier id, T output) { - this.digitalOutputs.put(id, output); - return output; - } - - @Override - public T getDigitalOutput(Identifier id) { - return (T) this.digitalOutputs.get(id); - } - - @Override - public T addAnalogueOutput(Identifier id, T output) { - this.analogueOutputs.put(id, output); - return output; - } - - @Override - public T getAnalogueOutput(Identifier id) { - return (T) this.analogueOutputs.get(id); - } - - private class StateAccessImpl implements StateAccess { - private final int maxHistory; - private boolean valid; - private final @Nullable Consumer pushListener; - - public StateAccessImpl(int maxHistory, @Nullable Consumer pushListener) { - this.maxHistory = maxHistory; - this.valid = true; - this.pushListener = pushListener; - } - - @Override - public float analogue(int history) { - if (!valid) throw new IllegalStateException("Tried to access state from returned access!"); - if (history > maxHistory) throw new IllegalStateException("Overflowing history!"); - - return InputBindingImpl.this.stateHistory.tail(history); - } - - @Override - public boolean digital(int history) { - float threshold = inputComponent != null - ? inputComponent.settings().buttonActivationThreshold - : 0.5f; - return analogue(history) > threshold; - } - - @Override - public boolean isSuppressed() { - return suppressed; - } - - @Override - public boolean isValid() { - return valid; - } - - @Override - public int maxHistory() { - return this.maxHistory; - } - - public void onPush() { - if (this.pushListener != null) - this.pushListener.accept(this); - } - - public void retire() { - this.valid = false; - } - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/InputBindingSupplierImpl.java b/src/main/java/dev/isxander/controlify/bindings/InputBindingSupplierImpl.java deleted file mode 100644 index baa7d638c..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/InputBindingSupplierImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings; - -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.font.BindingFontHelper; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.Nullable; - -public record InputBindingSupplierImpl(Identifier bindId) implements InputBindingSupplier { - @Override - public @Nullable InputBinding onOrNull(ControllerEntity controller) { - return controller.input().map(c -> c.getBinding(bindId)).orElse(null); - } - - @Override - public Component inputGlyph() { - return BindingFontHelper.binding(this.bindId()); - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/RadialIcons.java b/src/main/java/dev/isxander/controlify/bindings/RadialIcons.java deleted file mode 100644 index 3124ff4d5..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/RadialIcons.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings; - -import dev.isxander.controlify.utils.CUtil; -import net.minecraft.core.Holder; -import net.minecraft.resources.Identifier; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.item.Item; - -/// @deprecated Radial icons are now data driven. -/// [Check out the wiki](https://moddedmc.wiki/en/project/controlify/latest/docs/resource-packs/radial-icons) -@Deprecated(forRemoval = true) -public final class RadialIcons { - - private RadialIcons() { - } - - @Deprecated(forRemoval = true) - public static Identifier getItem(Item item) { - return CUtil.rl("radial_icons_are_data_driven"); - } - - @Deprecated(forRemoval = true) - public static Identifier getEffect(Holder effect) { - return CUtil.rl("radial_icons_are_data_driven"); - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/StateAccess.java b/src/main/java/dev/isxander/controlify/bindings/StateAccess.java deleted file mode 100644 index df2b7bfc6..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/StateAccess.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings; - -public interface StateAccess { - float analogue(int history); - - boolean digital(int history); - - boolean isSuppressed(); - - boolean isValid(); - - int maxHistory(); -} diff --git a/src/main/java/dev/isxander/controlify/bindings/input/AxisInput.java b/src/main/java/dev/isxander/controlify/bindings/input/AxisInput.java deleted file mode 100644 index 3045090e1..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/input/AxisInput.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.input; - -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.input.ControllerStateView; -import net.minecraft.resources.Identifier; - -import java.util.List; - -public record AxisInput(Identifier axis) implements Input { - public static final String INPUT_ID = "axis"; - - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Identifier.CODEC.fieldOf(INPUT_ID).forGetter(AxisInput::axis) - ).apply(instance, AxisInput::new)); - - @Override - public float state(ControllerStateView state) { - return state.getAxisState(axis); - } - - @Override - public List getRelevantInputs() { - return List.of(axis); - } - - @Override - public InputType type() { - return InputType.AXIS; - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/input/ButtonInput.java b/src/main/java/dev/isxander/controlify/bindings/input/ButtonInput.java deleted file mode 100644 index eac6b4434..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/input/ButtonInput.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.input; - -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.input.ControllerStateView; -import net.minecraft.resources.Identifier; - -import java.util.List; - -public record ButtonInput(Identifier button) implements Input { - public static final String INPUT_ID = "button"; - - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Identifier.CODEC.fieldOf(INPUT_ID).forGetter(ButtonInput::button) - ).apply(instance, ButtonInput::new)); - - @Override - public float state(ControllerStateView state) { - return state.isButtonDown(button) ? 1 : 0; - } - - @Override - public List getRelevantInputs() { - return List.of(button); - } - - @Override - public InputType type() { - return InputType.BUTTON; - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/input/EmptyInput.java b/src/main/java/dev/isxander/controlify/bindings/input/EmptyInput.java deleted file mode 100644 index 619cd46df..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/input/EmptyInput.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.input; - -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.controller.input.ControllerStateView; -import net.minecraft.resources.Identifier; - -import java.util.List; - -public record EmptyInput() implements Input { - public static final EmptyInput INSTANCE = new EmptyInput(); - - public static final String INPUT_ID = "empty"; - public static final MapCodec CODEC = MapCodec.unit(() -> INSTANCE); - - @Override - public float state(ControllerStateView state) { - return 0; - } - - @Override - public List getRelevantInputs() { - return List.of(); - } - - @Override - public InputType type() { - return InputType.EMPTY; - } - - public static boolean equals(Input input) { - return input instanceof EmptyInput; - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/input/HatInput.java b/src/main/java/dev/isxander/controlify/bindings/input/HatInput.java deleted file mode 100644 index 7d221d6c2..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/input/HatInput.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.input; - -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.input.ControllerStateView; -import dev.isxander.controlify.controller.input.HatState; -import net.minecraft.resources.Identifier; - -import java.util.List; - -public record HatInput(Identifier hat, HatState targetState) implements Input { - public static final String INPUT_ID = "hat"; - - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Identifier.CODEC.fieldOf(INPUT_ID).forGetter(HatInput::hat), - HatState.CODEC.fieldOf("target_state").forGetter(HatInput::targetState) - ).apply(instance, HatInput::new)); - - @Override - public float state(ControllerStateView state) { - return state.getHatState(hat) == targetState ? 1 : 0; - } - - @Override - public List getRelevantInputs() { - return List.of(hat); - } - - @Override - public InputType type() { - return InputType.HAT; - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/input/Input.java b/src/main/java/dev/isxander/controlify/bindings/input/Input.java deleted file mode 100644 index a86b55f14..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/input/Input.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.input; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.controller.input.ControllerStateView; -import net.minecraft.resources.Identifier; - -import java.util.List; - -public interface Input { - MapCodec MAP_CODEC = InputType.createCodec(InputType.TYPES, InputType::codec, Input::type, "type"); - Codec CODEC = MAP_CODEC.codec(); - - float state(ControllerStateView state); - - List getRelevantInputs(); - - InputType type(); -} diff --git a/src/main/java/dev/isxander/controlify/bindings/input/InputType.java b/src/main/java/dev/isxander/controlify/bindings/input/InputType.java deleted file mode 100644 index 5a0b56851..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/input/InputType.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.input; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.codec.CExtraCodecs; -import dev.isxander.controlify.utils.codec.StrictEitherMapCodec; -import net.minecraft.util.Util; -import net.minecraft.util.ExtraCodecs; -import net.minecraft.util.StringRepresentable; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.function.Function; -import java.util.stream.Stream; - -public record InputType(String id, MapCodec codec) implements StringRepresentable { - public static final InputType BUTTON = new InputType<>(ButtonInput.INPUT_ID, ButtonInput.CODEC); - public static final InputType AXIS = new InputType<>(AxisInput.INPUT_ID, AxisInput.CODEC); - public static final InputType HAT = new InputType<>(HatInput.INPUT_ID, HatInput.CODEC); - public static final InputType EMPTY = new InputType<>(EmptyInput.INPUT_ID, EmptyInput.CODEC); - - public static final InputType[] TYPES = { - InputType.BUTTON, InputType.AXIS, InputType.HAT, InputType.EMPTY - }; - - public static MapCodec createCodec( - T[] types, Function> codecGetter, Function typeGetter, String typeFieldName - ) { - MapCodec fuzzyCodec = CExtraCodecs.fuzzyMap( - Stream.of(types).map(codecGetter).toList(), - obj -> codecGetter.apply(typeGetter.apply(obj)) - ); - - - Codec typeCodec = ExtraCodecs.orCompressed( - CExtraCodecs.stringResolver( - StringRepresentable::getSerializedName, - CUtil.createNameLookup(types, Function.identity()) - ), - ExtraCodecs.idResolverCodec( - Util.createIndexLookup(Arrays.asList(types)), - i -> i >= 0 && i < types.length ? types[i] : null, - -1 - ) - ); - - MapCodec typedCodec = typeCodec.dispatchMap(typeFieldName, typeGetter, codecGetter); - MapCodec eitherCodec = new StrictEitherMapCodec<>(typeFieldName, typedCodec, fuzzyCodec, false); - - return CExtraCodecs.orCompressed(eitherCodec, typedCodec); - } - - @Override - public @NotNull String getSerializedName() { - return this.id(); - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/AnalogueOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/AnalogueOutput.java deleted file mode 100644 index fc796b3a2..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/AnalogueOutput.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -public interface AnalogueOutput extends BindingOutput { - float get(); -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/BindingOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/BindingOutput.java deleted file mode 100644 index 86ef48c1f..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/BindingOutput.java +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -public interface BindingOutput { -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/DigitalOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/DigitalOutput.java deleted file mode 100644 index 62aa2607c..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/DigitalOutput.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -/** - * An interface that is responsible for consuming a binding's raw - * state and outputting a relevant value from that. - */ -public interface DigitalOutput extends BindingOutput { - boolean get(); -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/GuiPressOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/GuiPressOutput.java deleted file mode 100644 index f1d4b523f..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/GuiPressOutput.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.StateAccess; - -public class GuiPressOutput implements DigitalOutput { - private final StateAccess stateAccess; - - private PressState pressState = PressState.OFF; - - public GuiPressOutput(InputBinding binding) { - this.stateAccess = binding.createStateAccess(2, state -> push()); - } - - @Override - public boolean get() { - return pressState == PressState.JUST_RELEASED; - } - - public PressState getPressState() { - return this.pressState; - } - - private void push() { - boolean held = stateAccess.digital(0); - boolean prevHeld = stateAccess.digital(1); - - // if just pressed, set state to could press in future - // if just released: - // if it could press in future, set to just released - this is the state where get() == true - // if the state is anything else, set the state to off - - if (held) { - if (!prevHeld) { // just started pressing - pressState = PressState.COULD_PRESS_IN_FUTURE; - } - } else { - if (prevHeld && pressState == PressState.COULD_PRESS_IN_FUTURE) { // just released - pressState = PressState.JUST_RELEASED; - } else { - pressState = PressState.OFF; - } - } - - if (stateAccess.isSuppressed()) - pressState = PressState.OFF; - } - - public void onNavigate() { - this.pressState = PressState.OFF; - } - - public enum PressState { - /** Not pressed or navigated since held */ - OFF, - /** This is the state where the action takes place */ - JUST_RELEASED, - /** Currently held down with no navigations since it was pressed */ - COULD_PRESS_IN_FUTURE, - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/JustPressedOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/JustPressedOutput.java deleted file mode 100644 index 852d7e5e2..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/JustPressedOutput.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.StateAccess; - -public class JustPressedOutput implements DigitalOutput { - private final StateAccess stateAccess; - - public JustPressedOutput(InputBinding binding) { - this.stateAccess = binding.createStateAccess(2); - } - - @Override - public boolean get() { - if (stateAccess.isSuppressed()) - return false; - - return stateAccess.digital(0) && !stateAccess.digital(1); - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/JustReleasedOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/JustReleasedOutput.java deleted file mode 100644 index 18545b432..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/JustReleasedOutput.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.StateAccess; - -public class JustReleasedOutput implements DigitalOutput { - private final StateAccess stateAccess; - - public JustReleasedOutput(InputBinding binding) { - this.stateAccess = binding.createStateAccess(2); - } - - @Override - public boolean get() { - if (stateAccess.isSuppressed()) - return false; - - return !stateAccess.digital(0) && stateAccess.digital(1); - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/JustTappedOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/JustTappedOutput.java deleted file mode 100644 index 060c25276..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/JustTappedOutput.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.StateAccess; - -public class JustTappedOutput implements DigitalOutput { - public static final int DEFAULT_MAX_HOLD_TIME_TICKS = 2; - - private final StateAccess stateAccess; - private final int maxHoldTime; - - public JustTappedOutput(InputBinding binding, int maxHoldTimeTicks) { - this.stateAccess = binding.createStateAccess(maxHoldTimeTicks + 2); - this.maxHoldTime = maxHoldTimeTicks; - } - - public JustTappedOutput(InputBinding binding) { - this(binding, DEFAULT_MAX_HOLD_TIME_TICKS); - } - - @Override - public boolean get() { - if (stateAccess.isSuppressed()) - return false; - - boolean justReleased = stateAccess.digital(0); - if (!justReleased) return false; // still holding or just started to hold, not just tapped - - for (int i = 1; i < maxHoldTime + 2; i++) { // loop through remaining history - boolean state = stateAccess.digital(i); - if (!state) { // if we find one that isn't pressed, we know immediately a tap has taken place - return true; - } - } - - // if we reached the end of the loop without return, - // we know that the maxHoldTime has been exceeded and we did not just tap - return false; - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/KeyMappingEmulationOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/KeyMappingEmulationOutput.java deleted file mode 100644 index c8e6b3c84..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/KeyMappingEmulationOutput.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.KeyMappingHandle; -import dev.isxander.controlify.bindings.StateAccess; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.utils.MinecraftUtil; -import net.minecraft.client.KeyMapping; - -import java.util.function.BooleanSupplier; - -public class KeyMappingEmulationOutput implements DigitalOutput { - private final ControllerEntity controller; - private final StateAccess stateAccess; - private final KeyMapping keyMapping; - - public KeyMappingEmulationOutput(ControllerEntity controller, InputBinding binding, KeyMapping keyMapping, BooleanSupplier toggleCondition) { - this.controller = controller; - this.stateAccess = binding.createStateAccess(2, state -> push()); - this.keyMapping = keyMapping; - - if (toggleCondition != null) { - ((KeyMappingHandle) keyMapping).controlify$addToggleCondition(controller, toggleCondition); - } - } - - @Override - public boolean get() { - throw new IllegalStateException("Should never retrieve output of key mapping emulation!"); - } - - private void push() { - boolean now = stateAccess.digital(0); - boolean prev = stateAccess.digital(1); - - if (ControlifyApi.get().getCurrentController().orElse(null) != controller) - return; // only emulate current controller - - if (MinecraftUtil.getScreen() != null) - return; // minecraft keybinds don't work in gui screens it conflicts - - KeyMappingHandle handle = (KeyMappingHandle) keyMapping; - if (now && !prev) { - handle.controlify$setPressed(true); - } else if (prev && !now) { - handle.controlify$setPressed(false); - } - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/SimpleAnalogueOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/SimpleAnalogueOutput.java deleted file mode 100644 index 9a2d409ad..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/SimpleAnalogueOutput.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.StateAccess; - -public class SimpleAnalogueOutput implements AnalogueOutput { - private final StateAccess stateAccess; - private final int history; - - public SimpleAnalogueOutput(InputBinding binding, int history) { - this.stateAccess = binding.createStateAccess(history + 1); - this.history = history; - } - - @Override - public float get() { - if (stateAccess.isSuppressed()) - return 0f; - - return stateAccess.analogue(history); - } -} diff --git a/src/main/java/dev/isxander/controlify/bindings/output/SimpleDigitalOutput.java b/src/main/java/dev/isxander/controlify/bindings/output/SimpleDigitalOutput.java deleted file mode 100644 index 1eafa83df..000000000 --- a/src/main/java/dev/isxander/controlify/bindings/output/SimpleDigitalOutput.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.bindings.output; - -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.StateAccess; - -public class SimpleDigitalOutput implements DigitalOutput { - private final StateAccess stateAccess; - private final int history; - - public SimpleDigitalOutput(InputBinding binding, int history) { - this.stateAccess = binding.createStateAccess(history + 1); - this.history = history; - } - - @Override - public boolean get() { - if (stateAccess.isSuppressed()) - return false; - - return stateAccess.digital(history); - } -} diff --git a/src/main/java/dev/isxander/controlify/config/dto/device/DeviceConfig.java b/src/main/java/dev/isxander/controlify/config/dto/device/DeviceConfig.java index f0c7bb87f..56b92a71f 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/device/DeviceConfig.java +++ b/src/main/java/dev/isxander/controlify/config/dto/device/DeviceConfig.java @@ -9,7 +9,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.controller.input.mapping.ControllerMapping; +import dev.isxander.controlify.input.mapping.ControllerMapping; import net.minecraft.resources.Identifier; import java.util.Optional; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java b/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java index fb5fd7e32..9ec34705a 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java +++ b/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java @@ -9,7 +9,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.isxander.controlify.ingame.InputCurves; -import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.LogicalInput; import net.minecraft.resources.Identifier; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java b/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java index c255e2036..130f749d6 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java +++ b/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java @@ -8,7 +8,7 @@ import dev.isxander.controlify.config.dto.device.DeviceConfig; import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.controller.input.mapping.ControllerMapping; +import dev.isxander.controlify.input.mapping.ControllerMapping; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java b/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java index c113f89ea..359ada37d 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java +++ b/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java @@ -8,7 +8,7 @@ import dev.isxander.controlify.config.dto.profile.InputConfig; import dev.isxander.controlify.ingame.InputCurves; -import dev.isxander.controlify.input.logical.LogicalInput; +import dev.isxander.controlify.input.LogicalInput; import net.minecraft.resources.Identifier; import java.util.HashMap; diff --git a/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java b/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java index 037edbec7..becb50736 100644 --- a/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java +++ b/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java @@ -22,7 +22,7 @@ import dev.isxander.controlify.controller.rumble.TriggerRumbleComponent; import dev.isxander.controlify.controller.touchpad.TouchpadComponent; import dev.isxander.controlify.driver.Driver; -import dev.isxander.controlify.input.InputComponent; +import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.utils.log.ControlifyLogger; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Contract; diff --git a/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectInstanceImpl.java b/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectInstanceImpl.java index fe6bdbbef..735a5f09e 100644 --- a/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectInstanceImpl.java +++ b/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectInstanceImpl.java @@ -14,7 +14,7 @@ import dev.isxander.controlify.contextual.RuleEngine; import dev.isxander.controlify.contextual.TriggerEffectRule; import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.input.GamepadInputs; +import dev.isxander.controlify.input.mapping.GamepadInputs; import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java b/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java index 8bfdfb87d..c8409deb9 100644 --- a/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java +++ b/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java @@ -11,11 +11,11 @@ import dev.isxander.controlify.config.settings.profile.GyroSettings; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.input.InputPipeline; +import dev.isxander.controlify.input.pipeline.InputPipeline; import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.logical.LogicalSignal; -import dev.isxander.controlify.input.physical.PhysicalSensorSignal; -import dev.isxander.controlify.input.physical.PhysicalSignal; +import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.input.signal.PhysicalSignal; import dev.isxander.controlify.utils.CUtil; import dev.isxander.controlify.utils.event.EventSource; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/controller/id/ControllerType.java b/src/main/java/dev/isxander/controlify/controller/id/ControllerType.java index 13ee74c1d..4b0d01146 100644 --- a/src/main/java/dev/isxander/controlify/controller/id/ControllerType.java +++ b/src/main/java/dev/isxander/controlify/controller/id/ControllerType.java @@ -11,18 +11,25 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.utils.codec.CExtraCodecs; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; -public record ControllerType(@Nullable String friendlyName, String mappingId, Identifier namespace, boolean forceJoystick, boolean dontLoad) { - public static final ControllerType DEFAULT = new ControllerType(null, "default", CUtil.rl("default"), false, false); +public record ControllerType( + Identifier namespace, + @Nullable String friendlyName, + @Nullable Identifier mappingId, + boolean forceJoystick, + boolean preventLoading +) { + public static final ControllerType DEFAULT = new ControllerType(CUtil.rl("default"), null, null, false, false); public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Codec.STRING.optionalFieldOf("name", null).forGetter(ControllerType::friendlyName), - Codec.STRING.optionalFieldOf("mapping", DEFAULT.mappingId()).forGetter(ControllerType::mappingId), Identifier.CODEC.optionalFieldOf("namespace", DEFAULT.namespace()).forGetter(ControllerType::namespace), + CExtraCodecs.nullableField(Codec.STRING, "name").forGetter(ControllerType::friendlyName), + CExtraCodecs.nullableField(Identifier.CODEC, "mapping").forGetter(ControllerType::mappingId), Codec.BOOL.optionalFieldOf("force_joystick", false).forGetter(ControllerType::forceJoystick), - Codec.BOOL.optionalFieldOf("dont_load", false).forGetter(ControllerType::dontLoad) + Codec.BOOL.optionalFieldOf("prevent_loading", false).forGetter(ControllerType::preventLoading) ).apply(instance, ControllerType::new)); public Identifier getIconSprite() { diff --git a/src/main/java/dev/isxander/controlify/input/InputComponent.java b/src/main/java/dev/isxander/controlify/controller/input/InputComponent.java similarity index 82% rename from src/main/java/dev/isxander/controlify/input/InputComponent.java rename to src/main/java/dev/isxander/controlify/controller/input/InputComponent.java index 6ec17e595..2a93f7b71 100644 --- a/src/main/java/dev/isxander/controlify/input/InputComponent.java +++ b/src/main/java/dev/isxander/controlify/controller/input/InputComponent.java @@ -1,29 +1,28 @@ -package dev.isxander.controlify.input; +package dev.isxander.controlify.controller.input; import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.defaults.DefaultBindProvider; +import dev.isxander.controlify.action.defaults.DefaultBindProvider; import dev.isxander.controlify.config.settings.device.DeviceSettings; import dev.isxander.controlify.config.settings.profile.InputSettings; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.controller.input.mapping.ControllerMapping; -import dev.isxander.controlify.input.action.ActionGraph; -import dev.isxander.controlify.input.action.ActionImpl; -import dev.isxander.controlify.input.action.ActionSpec; -import dev.isxander.controlify.input.action.ActionSpecRegistryImpl; -import dev.isxander.controlify.input.action.activator.ActivatorConfig; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.physical.SensorProcessorStage; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.input.mapping.ControllerMapping; +import dev.isxander.controlify.input.mapping.ControllerMappingManager; +import dev.isxander.controlify.action.ActionGraph; +import dev.isxander.controlify.action.ActionImpl; +import dev.isxander.controlify.action.ActionSpec; +import dev.isxander.controlify.action.ActionSpecRegistryImpl; +import dev.isxander.controlify.action.activator.ActivatorConfig; +import dev.isxander.controlify.input.pipeline.InputPipeline; +import dev.isxander.controlify.input.pipeline.SensorProcessorStage; import dev.isxander.controlify.utils.CUtil; import dev.isxander.controlify.utils.event.EventSource; import net.minecraft.resources.Identifier; -import net.minecraft.util.Util; import org.jspecify.annotations.Nullable; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class InputComponent extends ECSComponentImpl { public static final Identifier ID = CUtil.rl("input"); @@ -70,6 +69,12 @@ public void attach(ControllerEntity controller) { .getOrCreateDeviceSettings(controller.uid()); ControllerMapping controllerMapping = this.deviceSettings.mapping; + if (controllerMapping == null) { + ControllerMappingManager controllerMappingManager = Controlify.instance().controllerMappingManager(); + controllerMapping = controllerMappingManager + .getMappingById(controller.info().type().mappingId()) + .orElse(null); + } if (controllerMapping == null) { controllerMapping = this.isGamepad ? ControllerMapping.GAMEPAD_DEADZONES_ONLY_MAPPING @@ -80,7 +85,7 @@ public void attach(ControllerEntity controller) { this.inputPipeline.stageDeadzone().setDeadzoneGroups(controllerMapping.deadzones().values()); this.inputPipeline.stageDeadzone().setDeadzoneSupplier(axis -> settings().sensitivity.getDeadzone((Identifier) axis)); this.inputPipeline.stageSensorProcessor().setProcessors(sensorType -> { - if (sensorType.isGyroscope()) { + if (sensorType == SensorType.GYROSCOPE) { return List.of( new SensorProcessorStage.BiasCorrection(() -> this.deviceSettings.gyroCalibration.offset), new SensorProcessorStage.LowPassFilter(() -> this.controller().settings().gyro.lowPassCutoffHz) diff --git a/src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java b/src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java index 360e7e03c..54c2fe21e 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java +++ b/src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java @@ -14,7 +14,7 @@ import dev.isxander.controlify.driver.sdl.SDLNativesLoader; import dev.isxander.controlify.gui.screen.AskToMapControllerScreen; import dev.isxander.controlify.gui.screen.BluetoothWarningScreen; -import dev.isxander.controlify.input.physical.PhysicalInputSignal; +import dev.isxander.controlify.input.signal.PhysicalInputSignal; import dev.isxander.controlify.platform.main.PlatformMainUtil; import dev.isxander.controlify.utils.CUtil; import dev.isxander.controlify.utils.DebugLog; diff --git a/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java b/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java index e8f0811cb..46b6e8161 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java +++ b/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java @@ -1,6 +1,5 @@ package dev.isxander.controlify.controllermanager; -import dev.isxander.controlify.Controlify; import dev.isxander.controlify.api.event.ControlifyEvents; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.controller.id.ControllerType; @@ -33,7 +32,7 @@ public boolean canAddController( return false; } - if (controllerType.dontLoad()) { + if (controllerType.preventLoading()) { controllerLogger.debugLog("Preventing load of controller #" + ucid + " because its type prevents loading."); return false; } diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java index f9b1f2f44..7f2ae3f30 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java @@ -11,7 +11,7 @@ import dev.isxander.controlify.controller.gyro.GyroComponent; import dev.isxander.controlify.controller.*; import dev.isxander.controlify.controller.touchpad.Touchpads; -import dev.isxander.controlify.input.InputComponent; +import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.input.SensorType; import dev.isxander.controlify.utils.event.EventSource; import dev.isxander.controlify.utils.log.ControlifyLogger; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java index 4e77ffd9d..b508cac32 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDL3JoystickDriver.java @@ -7,9 +7,9 @@ package dev.isxander.controlify.driver.sdl; import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.controller.input.JoystickInputs; +import dev.isxander.controlify.input.mapping.JoystickInputs; import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.input.InputComponent; +import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.utils.event.EventSource; import dev.isxander.controlify.utils.log.ControlifyLogger; import dev.isxander.sdl.*; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java index 0ef26ce5a..5c0120d5d 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLCommonDriver.java @@ -24,7 +24,7 @@ import dev.isxander.controlify.driver.Driver; import dev.isxander.controlify.driver.dualsense.DualsenseEffectsState; import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; -import dev.isxander.controlify.input.InputPipeline; +import dev.isxander.controlify.input.pipeline.InputPipeline; import dev.isxander.controlify.rumble.RumbleState; import dev.isxander.controlify.rumble.TriggerRumbleState; import dev.isxander.controlify.utils.CUtil; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java index 92b36ae82..dda85452f 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java @@ -1,6 +1,6 @@ package dev.isxander.controlify.driver.sdl; -import dev.isxander.controlify.controller.input.GamepadInputs; +import dev.isxander.controlify.input.mapping.GamepadInputs; import dev.isxander.controlify.input.SensorType; import dev.isxander.sdl.SdlEvents; import dev.isxander.sdl.SdlGamepad; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java b/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java index 0b0554298..bf22dcbe5 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java +++ b/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java @@ -1,10 +1,10 @@ package dev.isxander.controlify.driver.sdl; -import dev.isxander.controlify.controller.input.JoystickInputs; +import dev.isxander.controlify.input.mapping.JoystickInputs; import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.physical.PhysicalInputSignal; -import dev.isxander.controlify.input.physical.PhysicalSensorSignal; -import dev.isxander.controlify.input.physical.PhysicalSignal; +import dev.isxander.controlify.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.input.signal.PhysicalSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.EventStage; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckDriver.java b/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckDriver.java index 2c11f8cf6..021e6fc3b 100644 --- a/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckDriver.java +++ b/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckDriver.java @@ -16,7 +16,7 @@ import dev.isxander.controlify.controller.info.DriverNameComponent; import dev.isxander.controlify.controller.info.GUIDComponent; import dev.isxander.controlify.controller.info.UIDComponent; -import dev.isxander.controlify.controller.input.GamepadInputs; +import dev.isxander.controlify.input.mapping.GamepadInputs; import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.controller.steamdeck.SteamDeckComponent; import dev.isxander.controlify.controller.touchpad.TouchpadComponent; diff --git a/src/main/java/dev/isxander/controlify/gui/ButtonGuideRenderer.java b/src/main/java/dev/isxander/controlify/gui/ButtonGuideRenderer.java index 071db5fad..ac55002a1 100644 --- a/src/main/java/dev/isxander/controlify/gui/ButtonGuideRenderer.java +++ b/src/main/java/dev/isxander/controlify/gui/ButtonGuideRenderer.java @@ -7,9 +7,9 @@ package dev.isxander.controlify.gui; import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.bind.InputBinding; +import dev.isxander.controlify.action.Action; +import dev.isxander.controlify.action.ActionAccessor; import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.api.bind.InputBindingSupplier; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; @@ -23,36 +23,36 @@ public interface ButtonGuideRenderer { void controlify$setButtonGuide(RenderData renderData); - static void registerBindingForButton(T button, Supplier binding, ButtonGuidePredicate renderPredicate) { - ((ButtonGuideRenderer) button).controlify$setButtonGuide(new RenderData<>(binding, renderPredicate)); + static void registerBindingForButton(T button, Supplier action, ButtonGuidePredicate renderPredicate) { + ((ButtonGuideRenderer) button).controlify$setButtonGuide(new RenderData<>(action, renderPredicate)); } - record RenderData(Supplier binding, ButtonGuidePredicate renderPredicate) { - public Component getControllerMessage(InputBinding bind, Component actualLabel) { + record RenderData(Supplier action, ButtonGuidePredicate renderPredicate) { + public Component getControllerMessage(Action action, Component actualLabel) { var component = Component.empty(); if (!Minecraft.getInstance().font.isBidirectional()) { - component.append(bind.inputGlyph()); + component.append(action.inputGlyph()); component.append(CommonComponents.SPACE); } component.append(actualLabel); if (Minecraft.getInstance().font.isBidirectional()) { component.append(CommonComponents.SPACE); - component.append(bind.inputGlyph()); + component.append(action.inputGlyph()); } return component; } public boolean shouldRender(T renderable) { - Optional binding = getBind(); + Optional binding = getAction(); return binding.isPresent() && Controlify.instance().currentInputMode().isController() && Controlify.instance().getCurrentController().map(c -> c.settings().generic.guide.showScreenGuides).orElse(false) - && !binding.get().isUnbound() + && binding.get().boundInput() != null && renderPredicate().shouldDisplay(renderable); } - public Optional getBind() { - return Controlify.instance().getCurrentController().map(c -> binding().get().on(c)); + public Optional getAction() { + return Controlify.instance().getCurrentController().map(c -> action().get().on(c)); } } } diff --git a/src/main/java/dev/isxander/controlify/gui/controllers/Deadzone2DImageRenderer.java b/src/main/java/dev/isxander/controlify/gui/controllers/Deadzone2DImageRenderer.java index 450b28ae8..30c7eace6 100644 --- a/src/main/java/dev/isxander/controlify/gui/controllers/Deadzone2DImageRenderer.java +++ b/src/main/java/dev/isxander/controlify/gui/controllers/Deadzone2DImageRenderer.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.gui.controllers; -import dev.isxander.controlify.controller.input.DeadzoneGroup; +import dev.isxander.controlify.input.mapping.DeadzoneGroup; import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.utils.render.elements.CircleElementRenderState; import dev.isxander.yacl3.api.Option; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java b/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java index 26a31aaff..3473aa7d5 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java @@ -21,9 +21,9 @@ import dev.isxander.controlify.controller.*; import dev.isxander.controlify.controller.gyro.GyroButtonMode; import dev.isxander.controlify.controller.gyro.GyroYawMode; -import dev.isxander.controlify.controller.input.DeadzoneGroup; +import dev.isxander.controlify.input.mapping.DeadzoneGroup; import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.controller.input.Inputs; +import dev.isxander.controlify.input.mapping.Inputs; import dev.isxander.controlify.controller.rumble.RumbleComponent; import dev.isxander.controlify.gui.controllers.BindController; import dev.isxander.controlify.gui.controllers.Deadzone2DImageRenderer; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java b/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java index facfb4f6f..8e080af83 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java @@ -9,10 +9,8 @@ import dev.isxander.controlify.Controlify; import dev.isxander.controlify.config.settings.device.DeviceSettings; import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.input.*; -import dev.isxander.controlify.controller.input.mapping.MapType; -import dev.isxander.controlify.controller.input.mapping.MappingEntry; -import dev.isxander.controlify.controller.input.mapping.ControllerMapping; +import dev.isxander.controlify.controller.input.mapping.*; +import dev.isxander.controlify.input.mapping.*; import dev.isxander.controlify.screenop.ScreenControllerEventListener; import dev.isxander.controlify.screenop.ScreenProcessor; import dev.isxander.controlify.screenop.ScreenProcessorProvider; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java b/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java index 477c5d82b..f910ed596 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java @@ -9,9 +9,9 @@ import dev.isxander.controlify.Controlify; import dev.isxander.controlify.api.bind.InputBinding; import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.api.bind.RadialIcon; +import dev.isxander.controlify.action.radial.RadialIcon; import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.bindings.RadialIconManager; +import dev.isxander.controlify.action.radial.RadialIconManager; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.utils.CUtil; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java b/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java index ab306dfcc..1ce96d25a 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java @@ -9,12 +9,11 @@ import com.mojang.blaze3d.platform.InputConstants; import dev.isxander.controlify.Controlify; import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.api.bind.RadialIcon; +import dev.isxander.controlify.action.radial.RadialIcon; import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.bindings.RadialIconExtractor; -import dev.isxander.controlify.bindings.RadialIconManager; +import dev.isxander.controlify.action.radial.RadialIconExtractor; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.controller.haptic.HapticEffects; import dev.isxander.controlify.screenop.ScreenProcessor; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuScreen.java b/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuScreen.java index 838ce9814..0e07e4b47 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuScreen.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuScreen.java @@ -7,9 +7,9 @@ package dev.isxander.controlify.gui.screen; import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.api.bind.RadialIcon; +import dev.isxander.controlify.action.radial.RadialIcon; import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.bindings.RadialIconExtractor; +import dev.isxander.controlify.action.radial.RadialIconExtractor; import dev.isxander.controlify.controller.ControllerEntity; import dev.isxander.controlify.controller.haptic.HapticEffects; import dev.isxander.controlify.gui.screen.RadialItems.RadialPage; diff --git a/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java b/src/main/java/dev/isxander/controlify/input/LogicalInput.java similarity index 94% rename from src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java rename to src/main/java/dev/isxander/controlify/input/LogicalInput.java index 7b17ff27b..bdc48e56a 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/LogicalInput.java +++ b/src/main/java/dev/isxander/controlify/input/LogicalInput.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.logical; +package dev.isxander.controlify.input; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -8,7 +8,7 @@ import java.util.List; import java.util.Set; -/// A reference to a logical button, axis, or sensor. +/// A reference to a logical button or axis. /// /// A logical input's domain is the type of input, meaning that /// a logical input that refers to the same physical inputs can be diff --git a/src/main/java/dev/isxander/controlify/input/action/activator/NoopActivator.java b/src/main/java/dev/isxander/controlify/input/action/activator/NoopActivator.java deleted file mode 100644 index dde0bf7e6..000000000 --- a/src/main/java/dev/isxander/controlify/input/action/activator/NoopActivator.java +++ /dev/null @@ -1,23 +0,0 @@ -package dev.isxander.controlify.input.action.activator; - -import dev.isxander.controlify.input.action.Accumulator; -import dev.isxander.controlify.input.action.Activator; -import dev.isxander.controlify.input.logical.LogicalInput; -import dev.isxander.controlify.input.logical.LogicalSignal; - -public class NoopActivator implements Activator { - @Override - public void onSignal(LogicalSignal signal, Accumulator acc) { - - } - - @Override - public LogicalInput boundInput() { - return null; - } - - @Override - public String describe() { - return "Noop"; - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java b/src/main/java/dev/isxander/controlify/input/mapping/ControllerMapping.java similarity index 93% rename from src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java rename to src/main/java/dev/isxander/controlify/input/mapping/ControllerMapping.java index f5ecff6cd..8559df0c9 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/ControllerMapping.java +++ b/src/main/java/dev/isxander/controlify/input/mapping/ControllerMapping.java @@ -4,13 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.input.mapping; +package dev.isxander.controlify.input.mapping; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.input.DeadzoneGroup; -import dev.isxander.controlify.controller.input.GamepadInputs; import net.minecraft.resources.Identifier; import java.util.*; diff --git a/src/main/java/dev/isxander/controlify/input/mapping/ControllerMappingManager.java b/src/main/java/dev/isxander/controlify/input/mapping/ControllerMappingManager.java new file mode 100644 index 000000000..6224bdd7b --- /dev/null +++ b/src/main/java/dev/isxander/controlify/input/mapping/ControllerMappingManager.java @@ -0,0 +1,70 @@ +package dev.isxander.controlify.input.mapping; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.JsonOps; +import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.utils.CUtil; +import net.minecraft.resources.FileToIdConverter; +import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.util.Util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +public class ControllerMappingManager implements SimpleControlifyReloadListener { + + private static final FileToIdConverter converter = FileToIdConverter.json("controller/mapping"); + + private final Map mappingById = new HashMap<>(); + + public Optional getMappingById(Identifier id) { + return Optional.ofNullable(this.mappingById.get(id)); + } + + @Override + public CompletableFuture load(ResourceManager manager, Executor executor) { + return CompletableFuture.supplyAsync(() -> { + Map resources = converter.listMatchingResources(manager); + Map mappingById = resources.entrySet().stream() + .map(entry -> Map.entry(entry.getKey(), parseFile(entry.getValue()))) + .collect(Util.toMap()); + + return new Preparations(mappingById); + }, executor); + } + + private static ControllerMapping parseFile(Resource resource) { + try (BufferedReader reader = resource.openAsReader()) { + JsonElement json = JsonParser.parseReader(reader); + DataResult mappingResult = ControllerMapping.CODEC.parse(JsonOps.INSTANCE, json); + return mappingResult.getOrThrow(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public CompletableFuture apply(Preparations data, ResourceManager manager, Executor executor) { + return CompletableFuture.runAsync(() -> { + this.mappingById.clear(); + this.mappingById.putAll(data.mappingById); + }, executor); + } + + @Override + public Identifier getReloadId() { + return CUtil.rl("controller_mapping"); + } + + public record Preparations(Map mappingById) { + } +} diff --git a/src/main/java/dev/isxander/controlify/controller/input/DeadzoneGroup.java b/src/main/java/dev/isxander/controlify/input/mapping/DeadzoneGroup.java similarity index 92% rename from src/main/java/dev/isxander/controlify/controller/input/DeadzoneGroup.java rename to src/main/java/dev/isxander/controlify/input/mapping/DeadzoneGroup.java index 773aef561..7cbbb3cb1 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/DeadzoneGroup.java +++ b/src/main/java/dev/isxander/controlify/input/mapping/DeadzoneGroup.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.input; +package dev.isxander.controlify.input.mapping; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/controller/input/GamepadInputs.java b/src/main/java/dev/isxander/controlify/input/mapping/GamepadInputs.java similarity index 87% rename from src/main/java/dev/isxander/controlify/controller/input/GamepadInputs.java rename to src/main/java/dev/isxander/controlify/input/mapping/GamepadInputs.java index 71bf9c65b..bd654e24d 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/GamepadInputs.java +++ b/src/main/java/dev/isxander/controlify/input/mapping/GamepadInputs.java @@ -4,12 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.input; +package dev.isxander.controlify.input.mapping; import com.google.common.collect.Sets; -import dev.isxander.controlify.bindings.input.AxisInput; -import dev.isxander.controlify.bindings.input.ButtonInput; -import dev.isxander.controlify.bindings.input.Input; import dev.isxander.controlify.utils.CUtil; import net.minecraft.resources.Identifier; @@ -84,15 +81,6 @@ private GamepadInputs() { )) )); - public static Input getBind(Identifier id) { - return switch (id.getPath().split("/")[0]) { - case "button" -> new ButtonInput(id); - case "axis" -> new AxisInput(id); - case "hat" -> throw new IllegalArgumentException("Gamepad does not have hat inputs."); - default -> throw new IllegalArgumentException("Unknown bind type: " + id); - }; - } - private static Identifier button(String id) { return CUtil.rl("button/" + id); } diff --git a/src/main/java/dev/isxander/controlify/input/physical/GestureInputs.java b/src/main/java/dev/isxander/controlify/input/mapping/GestureInputs.java similarity index 82% rename from src/main/java/dev/isxander/controlify/input/physical/GestureInputs.java rename to src/main/java/dev/isxander/controlify/input/mapping/GestureInputs.java index 939cb4ba0..66fcfb7cf 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/GestureInputs.java +++ b/src/main/java/dev/isxander/controlify/input/mapping/GestureInputs.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.physical; +package dev.isxander.controlify.input.mapping; import dev.isxander.controlify.utils.CUtil; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/controller/input/Inputs.java b/src/main/java/dev/isxander/controlify/input/mapping/Inputs.java similarity index 94% rename from src/main/java/dev/isxander/controlify/controller/input/Inputs.java rename to src/main/java/dev/isxander/controlify/input/mapping/Inputs.java index 344672c9b..beccfc754 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/Inputs.java +++ b/src/main/java/dev/isxander/controlify/input/mapping/Inputs.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.input; +package dev.isxander.controlify.input.mapping; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; diff --git a/src/main/java/dev/isxander/controlify/controller/input/JoystickInputs.java b/src/main/java/dev/isxander/controlify/input/mapping/JoystickInputs.java similarity index 95% rename from src/main/java/dev/isxander/controlify/controller/input/JoystickInputs.java rename to src/main/java/dev/isxander/controlify/input/mapping/JoystickInputs.java index a39990162..8fbf51cb8 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/JoystickInputs.java +++ b/src/main/java/dev/isxander/controlify/input/mapping/JoystickInputs.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.input; +package dev.isxander.controlify.input.mapping; import dev.isxander.controlify.utils.CUtil; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/MapType.java b/src/main/java/dev/isxander/controlify/input/mapping/MapType.java similarity index 89% rename from src/main/java/dev/isxander/controlify/controller/input/mapping/MapType.java rename to src/main/java/dev/isxander/controlify/input/mapping/MapType.java index 17e82057e..f5fbbddcd 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/MapType.java +++ b/src/main/java/dev/isxander/controlify/input/mapping/MapType.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.input.mapping; +package dev.isxander.controlify.input.mapping; import com.mojang.serialization.Codec; import net.minecraft.util.StringRepresentable; diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java b/src/main/java/dev/isxander/controlify/input/mapping/MappingEntry.java similarity index 96% rename from src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java rename to src/main/java/dev/isxander/controlify/input/mapping/MappingEntry.java index 2338302fe..845b81f6b 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntry.java +++ b/src/main/java/dev/isxander/controlify/input/mapping/MappingEntry.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.input.mapping; +package dev.isxander.controlify.input.mapping; import com.mojang.serialization.Codec; -import dev.isxander.controlify.input.physical.PhysicalInputSignal; +import dev.isxander.controlify.input.signal.PhysicalInputSignal; import dev.isxander.controlify.utils.MthExt; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java b/src/main/java/dev/isxander/controlify/input/mapping/MappingEntryCodecs.java similarity index 98% rename from src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java rename to src/main/java/dev/isxander/controlify/input/mapping/MappingEntryCodecs.java index 804633966..94c6ca3f2 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/mapping/MappingEntryCodecs.java +++ b/src/main/java/dev/isxander/controlify/input/mapping/MappingEntryCodecs.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.input.mapping; +package dev.isxander.controlify.input.mapping; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; diff --git a/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java b/src/main/java/dev/isxander/controlify/input/pipeline/DeadzoneStage.java similarity index 93% rename from src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java rename to src/main/java/dev/isxander/controlify/input/pipeline/DeadzoneStage.java index 23bce96cb..26020acb4 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/DeadzoneStage.java +++ b/src/main/java/dev/isxander/controlify/input/pipeline/DeadzoneStage.java @@ -1,7 +1,8 @@ -package dev.isxander.controlify.input.physical; +package dev.isxander.controlify.input.pipeline; -import dev.isxander.controlify.controller.input.DeadzoneGroup; -import dev.isxander.controlify.utils.ControllerUtils; +import dev.isxander.controlify.input.mapping.DeadzoneGroup; +import dev.isxander.controlify.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.input.signal.PhysicalSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.UnaryEventStage; import it.unimi.dsi.fastutil.objects.*; diff --git a/src/main/java/dev/isxander/controlify/input/physical/GestureRecogniserStage.java b/src/main/java/dev/isxander/controlify/input/pipeline/GestureRecogniserStage.java similarity index 63% rename from src/main/java/dev/isxander/controlify/input/physical/GestureRecogniserStage.java rename to src/main/java/dev/isxander/controlify/input/pipeline/GestureRecogniserStage.java index 36b9c320f..ec478d8f7 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/GestureRecogniserStage.java +++ b/src/main/java/dev/isxander/controlify/input/pipeline/GestureRecogniserStage.java @@ -1,10 +1,13 @@ -package dev.isxander.controlify.input.physical; +package dev.isxander.controlify.input.pipeline; +import dev.isxander.controlify.input.mapping.GestureInputs; +import dev.isxander.controlify.input.signal.PhysicalSignal; +import dev.isxander.controlify.input.signal.PhysicalInputSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.UnaryEventStage; /// Processes sensor data and recognizes distinct gestures such as shaking of the controller. -/// This stage then emits {@link dev.isxander.controlify.input.physical.PhysicalInputSignal.ButtonChanged} events +/// This stage then emits {@link PhysicalInputSignal.ButtonChanged} events /// for when the gesture begins and ends using input identifiers from {@link GestureInputs}. public class GestureRecogniserStage implements UnaryEventStage { @Override diff --git a/src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java b/src/main/java/dev/isxander/controlify/input/pipeline/InputDomainExpansionStage.java similarity index 90% rename from src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java rename to src/main/java/dev/isxander/controlify/input/pipeline/InputDomainExpansionStage.java index d41e478d9..4b94ca556 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/InputDomainExpansionStage.java +++ b/src/main/java/dev/isxander/controlify/input/pipeline/InputDomainExpansionStage.java @@ -1,5 +1,7 @@ -package dev.isxander.controlify.input.physical; +package dev.isxander.controlify.input.pipeline; +import dev.isxander.controlify.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.input.signal.PhysicalSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.UnaryEventStage; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/input/InputPipeline.java b/src/main/java/dev/isxander/controlify/input/pipeline/InputPipeline.java similarity index 89% rename from src/main/java/dev/isxander/controlify/input/InputPipeline.java rename to src/main/java/dev/isxander/controlify/input/pipeline/InputPipeline.java index 252f1ed78..764b924d3 100644 --- a/src/main/java/dev/isxander/controlify/input/InputPipeline.java +++ b/src/main/java/dev/isxander/controlify/input/pipeline/InputPipeline.java @@ -1,10 +1,8 @@ -package dev.isxander.controlify.input; +package dev.isxander.controlify.input.pipeline; -import dev.isxander.controlify.controller.input.mapping.ControllerMapping; -import dev.isxander.controlify.input.logical.LogicalSignal; -import dev.isxander.controlify.input.logical.PhysicalToLogicalStage; -import dev.isxander.controlify.input.logical.SensorAccumulatorStage; -import dev.isxander.controlify.input.physical.*; +import dev.isxander.controlify.input.mapping.ControllerMapping; +import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.input.signal.PhysicalSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.EventSource; import dev.isxander.controlify.utils.event.EventTap; diff --git a/src/main/java/dev/isxander/controlify/input/physical/MappingStage.java b/src/main/java/dev/isxander/controlify/input/pipeline/MappingStage.java similarity index 78% rename from src/main/java/dev/isxander/controlify/input/physical/MappingStage.java rename to src/main/java/dev/isxander/controlify/input/pipeline/MappingStage.java index b929ec49e..38d83fcba 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/MappingStage.java +++ b/src/main/java/dev/isxander/controlify/input/pipeline/MappingStage.java @@ -1,7 +1,9 @@ -package dev.isxander.controlify.input.physical; +package dev.isxander.controlify.input.pipeline; -import dev.isxander.controlify.controller.input.mapping.ControllerMapping; -import dev.isxander.controlify.controller.input.mapping.MappingEntry; +import dev.isxander.controlify.input.mapping.ControllerMapping; +import dev.isxander.controlify.input.mapping.MappingEntry; +import dev.isxander.controlify.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.input.signal.PhysicalSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.UnaryEventStage; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java b/src/main/java/dev/isxander/controlify/input/pipeline/PhysicalToLogicalStage.java similarity index 95% rename from src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java rename to src/main/java/dev/isxander/controlify/input/pipeline/PhysicalToLogicalStage.java index b83e7ee0f..385d2d0bd 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/PhysicalToLogicalStage.java +++ b/src/main/java/dev/isxander/controlify/input/pipeline/PhysicalToLogicalStage.java @@ -1,8 +1,10 @@ -package dev.isxander.controlify.input.logical; +package dev.isxander.controlify.input.pipeline; -import dev.isxander.controlify.input.physical.PhysicalInputSignal; -import dev.isxander.controlify.input.physical.PhysicalSensorSignal; -import dev.isxander.controlify.input.physical.PhysicalSignal; +import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.input.signal.PhysicalSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.EventStage; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java b/src/main/java/dev/isxander/controlify/input/pipeline/SensorAccumulatorStage.java similarity index 92% rename from src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java rename to src/main/java/dev/isxander/controlify/input/pipeline/SensorAccumulatorStage.java index 6d5ca6083..24fb9310f 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/SensorAccumulatorStage.java +++ b/src/main/java/dev/isxander/controlify/input/pipeline/SensorAccumulatorStage.java @@ -1,8 +1,9 @@ -package dev.isxander.controlify.input.logical; +package dev.isxander.controlify.input.pipeline; import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.physical.PhysicalSensorSignal; -import dev.isxander.controlify.input.physical.PhysicalSignal; +import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.input.signal.PhysicalSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.EventStage; diff --git a/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java b/src/main/java/dev/isxander/controlify/input/pipeline/SensorProcessorStage.java similarity index 95% rename from src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java rename to src/main/java/dev/isxander/controlify/input/pipeline/SensorProcessorStage.java index c90e7c733..4ec21c7d5 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/SensorProcessorStage.java +++ b/src/main/java/dev/isxander/controlify/input/pipeline/SensorProcessorStage.java @@ -1,6 +1,8 @@ -package dev.isxander.controlify.input.physical; +package dev.isxander.controlify.input.pipeline; import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.input.signal.PhysicalSignal; import dev.isxander.controlify.utils.event.EventSink; import dev.isxander.controlify.utils.event.UnaryEventStage; import org.joml.Vector3f; diff --git a/src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java b/src/main/java/dev/isxander/controlify/input/signal/LogicalSignal.java similarity index 91% rename from src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java rename to src/main/java/dev/isxander/controlify/input/signal/LogicalSignal.java index 8c3a4e871..233d4c1a4 100644 --- a/src/main/java/dev/isxander/controlify/input/logical/LogicalSignal.java +++ b/src/main/java/dev/isxander/controlify/input/signal/LogicalSignal.java @@ -1,6 +1,8 @@ -package dev.isxander.controlify.input.logical; +package dev.isxander.controlify.input.signal; +import dev.isxander.controlify.input.LogicalInput; import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.input.pipeline.SensorAccumulatorStage; public sealed interface LogicalSignal { /// The time this signal occurred. diff --git a/src/main/java/dev/isxander/controlify/input/physical/PhysicalInputSignal.java b/src/main/java/dev/isxander/controlify/input/signal/PhysicalInputSignal.java similarity index 94% rename from src/main/java/dev/isxander/controlify/input/physical/PhysicalInputSignal.java rename to src/main/java/dev/isxander/controlify/input/signal/PhysicalInputSignal.java index aa6b8d064..aaf72386d 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/PhysicalInputSignal.java +++ b/src/main/java/dev/isxander/controlify/input/signal/PhysicalInputSignal.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.physical; +package dev.isxander.controlify.input.signal; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java b/src/main/java/dev/isxander/controlify/input/signal/PhysicalSensorSignal.java similarity index 94% rename from src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java rename to src/main/java/dev/isxander/controlify/input/signal/PhysicalSensorSignal.java index f4af8d8d8..69367f56f 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSensorSignal.java +++ b/src/main/java/dev/isxander/controlify/input/signal/PhysicalSensorSignal.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.physical; +package dev.isxander.controlify.input.signal; import dev.isxander.controlify.input.SensorType; diff --git a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java b/src/main/java/dev/isxander/controlify/input/signal/PhysicalSignal.java similarity index 86% rename from src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java rename to src/main/java/dev/isxander/controlify/input/signal/PhysicalSignal.java index 5657f8dc5..10ec1a5cc 100644 --- a/src/main/java/dev/isxander/controlify/input/physical/PhysicalSignal.java +++ b/src/main/java/dev/isxander/controlify/input/signal/PhysicalSignal.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.physical; +package dev.isxander.controlify.input.signal; public sealed interface PhysicalSignal permits PhysicalInputSignal, PhysicalSensorSignal, PhysicalSignal.Frame { /// timestamp of the signal in nanoseconds diff --git a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java b/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java index ac04de7df..330fc61e0 100644 --- a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java @@ -14,7 +14,7 @@ import dev.isxander.controlify.controller.*; import dev.isxander.controlify.controller.haptic.HapticEffects; import dev.isxander.controlify.controller.input.ControllerStateView; -import dev.isxander.controlify.controller.input.GamepadInputs; +import dev.isxander.controlify.input.mapping.GamepadInputs; import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.mixins.feature.screenop.ScreenAccessor; import dev.isxander.controlify.mixins.feature.screenop.impl.outofgame.TabNavigationBarAccessor; diff --git a/src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseHandler.java b/src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseHandler.java index 65b58dc37..b5409039c 100644 --- a/src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseHandler.java +++ b/src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseHandler.java @@ -15,7 +15,7 @@ import dev.isxander.controlify.bindings.ControlifyBindings; import dev.isxander.controlify.api.bind.InputBinding; import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.controller.input.GamepadInputs; +import dev.isxander.controlify.input.mapping.GamepadInputs; import dev.isxander.controlify.controller.input.InputComponent; import dev.isxander.controlify.controller.touchpad.TouchpadComponent; import dev.isxander.controlify.debug.DebugProperties; From 92928d660a2b41b14e8a4a1a87c478a1dc9a0657 Mon Sep 17 00:00:00 2001 From: isxander Date: Mon, 19 Oct 2026 16:38:26 +0100 Subject: [PATCH 11/12] repackage everything into api and impl packages; rewrite rumble api --- .../fabric/ControlifyBootstrap.java | 8 +- .../FabricCompatMixinPlatform.java | 2 +- .../compatibility/ModMenuIntegration.java | 2 +- .../platform/FabricBackedEventHandler.java | 2 +- .../platform/FabricPlatformMainImpl.java | 16 +- .../client/FAPIApiCreativeTabHelper.java | 2 +- .../client/FabricPlatformClientImpl.java | 16 +- .../platform/network/C2SNetworkApiFabric.java | 2 +- .../platform/network/S2CNetworkApiFabric.java | 2 +- .../gametest/framework/CTestUtil.java | 11 +- .../controller/ControlifyGameTestContext.java | 23 +- .../controller/DualsenseEffectDriver.java | 2 +- .../controller/TestControllerContext.java | 12 +- .../controller/VirtualControllerBuilder.java | 2 +- .../mixin/ControlifySettingsAccessor.java | 8 +- .../mixin/SDLControllerManagerAccessor.java | 2 +- .../mixin/SDLControllerManagerMixin.java | 16 +- .../gametest/tests/AdaptiveTriggerTests.java | 10 +- .../gametest/tests/ButtonGuideTests.java | 10 +- .../gametest/tests/KeyboardLayoutTests.java | 4 +- .../gametest/tests/ManyHotplugTests.java | 2 +- .../tests/RecipeBookNavigationTests.java | 10 +- .../tests/ResetControlifySettingsTests.java | 16 +- .../gametest/tests/ServerPolicyTests.java | 7 +- .../tests/VirtualControllerInputTests.java | 12 +- .../controlify/action/ActionSpecRegistry.java | 5 - .../action/activator/NoopActivator.java | 23 - .../controlify/api/ControlifyApi.java | 27 +- .../api/{event => }/ControlifyEvents.java | 17 +- .../controlify/{ => api}/InputMode.java | 2 +- .../controlify/{ => api}/action/Action.java | 7 +- .../{ => api}/action/ActionSpec.java | 11 +- .../controlify/{ => api}/action/Channel.java | 2 +- .../controlify/api/action/package-info.java | 4 + .../api/contextual/ContainerContext.java | 4 +- .../controlify/api/contextual/Context.java | 4 +- .../ContextualStateContributor.java | 2 +- .../api/contextual/InGameContext.java | 9 +- .../api/contextual/TriggerEffectInstance.java | 2 +- .../api/contextual/package-info.java | 4 + .../controlify/api/controller/Controller.java | 40 + .../api/controller/package-info.java | 4 + .../rumble/ContinuousRumbleEffect.java | 34 + .../controller/rumble/FiniteRumbleEffect.java | 27 + .../controller/rumble/RumbleComponent.java | 11 + .../api/controller/rumble/RumbleEffect.java | 28 + .../rumble/RumbleEffectInstance.java | 26 + .../controller}/rumble/RumbleState.java | 2 +- .../rumble/TriggerRumbleState.java | 2 +- .../api/controller/rumble/package-info.java | 4 + .../{buttonguide => gui}/ButtonGuideApi.java | 22 +- .../ButtonGuidePredicate.java | 11 +- .../controlify/api/gui/package-info.java | 4 + .../{ => api}/input/LogicalInput.java | 4 +- .../controlify/api/input/package-info.java | 4 + .../isxander/controlify/api/package-info.java | 4 + .../controller/ControllerEntity.java | 176 --- .../controlify/controller/ECSComponent.java | 21 - .../controlify/controller/ECSEntity.java | 22 - .../controller/SingleValueComponent.java | 28 - .../controlify/controller/gyro/GyroState.java | 59 - .../controller/gyro/GyroStateC.java | 36 - .../controller/impl/ECSComponentImpl.java | 23 - .../controller/impl/ECSEntityImpl.java | 45 - .../controller/info/ControllerInfo.java | 14 - .../controller/info/DriverNameComponent.java | 19 - .../controller/info/UIDComponent.java | 19 - .../controller/rumble/RumbleComponent.java | 57 - .../steamdeck/SteamDeckComponent.java | 20 - .../controlify/{ => impl}/Controlify.java | 124 +- .../{ => impl}/action/Accumulator.java | 2 +- .../{ => impl}/action/ActionAccessor.java | 11 +- .../{ => impl}/action/ActionAccessorImpl.java | 5 +- .../{ => impl}/action/ActionContext.java | 2 +- .../{ => impl}/action/ActionGraph.java | 8 +- .../{ => impl}/action/ActionImpl.java | 11 +- .../{ => impl}/action/ActionSpecBuilder.java | 7 +- .../action/ActionSpecBuilderImpl.java | 9 +- .../impl/action/ActionSpecRegistry.java | 7 + .../action/ActionSpecRegistryImpl.java | 4 +- .../{ => impl}/action/ActionState.java | 4 +- .../{ => impl}/action/Activator.java | 7 +- .../action/activator/ActivatorConfig.java | 6 +- .../activator/ActivatorConfigManager.java | 12 +- .../action/activator/ActivatorConfigType.java | 4 +- .../action/activator/CompoundActivator.java | 10 +- .../action/activator/ContinuousActivator.java | 10 +- .../activator/DoubleTapPulseActivator.java | 10 +- .../activator/GuiPressPulseActivator.java | 10 +- .../action/activator/HoldLatchActivator.java | 10 +- .../action/activator/HoldPulseActivator.java | 10 +- .../impl/action/activator/NoopActivator.java | 23 + .../action/activator/PressPulseActivator.java | 10 +- .../activator/ReleasePulseActivator.java | 10 +- .../activator/RepeatLatchPulseActivator.java | 10 +- .../action/activator/TapPulseActivator.java | 10 +- .../activator/ToggleLatchActivator.java | 10 +- .../action/defaults/DefaultBindManager.java | 20 +- .../action/defaults/DefaultBindProvider.java | 4 +- .../defaults/LayeredDefaultBindProvider.java | 4 +- .../MapBackedDefaultBindProvider.java | 6 +- .../{ => impl}/action/radial/RadialIcon.java | 2 +- .../action/radial/RadialIconExtractor.java | 2 +- .../action/radial/RadialIconManager.java | 10 +- .../api/entrypoint/ControlifyEntrypoint.java | 2 +- .../api/entrypoint/InitContext.java | 2 +- .../api/entrypoint/PreInitContext.java | 4 +- .../api/ingameinput/LookInputModifier.java | 12 +- .../api/vmousesnapping/ISnapBehaviour.java | 2 +- .../api/vmousesnapping/SnapPoint.java | 2 +- .../{ => impl}/bindings/BindContext.java | 14 +- .../bindings/ControlifyBindings.java | 10 +- .../{ => impl}/bindings/KeyMappingHandle.java | 6 +- .../boatfix/AnalogBoatInput.java | 2 +- .../compatibility/CompatMixinPlatform.java | 2 +- .../compatibility/CompatMixinPlugin.java | 2 +- .../compatibility/ControlifyCompat.java | 10 +- .../fancymenu/FancyMenuCompat.java | 2 +- .../OpenControlifySettingsAction.java | 6 +- .../compatibility/iris/IrisMixinPlugin.java | 4 +- .../mixins/BaseOptionElementWidgetMixin.java | 8 +- .../BaseOptionElementComponentProcessor.java | 4 +- .../compatibility/rrls/RrlsMixinPlugin.java | 4 +- .../rrls/mixins/HideTypeMixin.java | 4 +- .../compatibility/rso/RSOMixinPlugin.java | 4 +- .../rso/mixins/AbstractFrameAccessor.java | 2 +- .../mixins/SodiumVideoOptionsScreenMixin.java | 2 +- .../rso/mixins/TabFrameAccessor.java | 2 +- .../simplevoicechat/SVCMixinPlugin.java | 4 +- .../SimpleVoiceChatCompat.java | 16 +- .../mixins/KeyEventsAccessor.java | 2 +- .../mixins/PTTKeyHandlerMixin.java | 4 +- .../sodium/SodiumMixinPlugin.java | 4 +- .../sodium/mixins/AbstractWidgetMixin.java | 4 +- .../mixins/CycleControlElementMixin.java | 8 +- .../mixins/FlatButtonWidgetAccessor.java | 2 +- .../sodium/mixins/FlatButtonWidgetMixin.java | 6 +- .../mixins/SliderControlElementMixin.java | 8 +- .../mixins/TickBoxControlElementMixin.java | 8 +- .../mixins/VideoSettingsScreenMixin.java | 10 +- .../screenop/CycleControlProcessor.java | 12 +- .../screenop/SliderControlProcessor.java | 4 +- .../screenop/SodiumGuiScreenProcessor.java | 18 +- .../screenop/SodiumScreenOperations.java | 2 +- .../screenop/TickBoxControlProcessor.java | 12 +- .../compatibility/yacl/YACLMixinPlugin.java | 4 +- .../yacl/mixins/ControllerWidgetAccessor.java | 2 +- .../mixins/CyclingControllerElementMixin.java | 8 +- .../mixins/GroupSeparatorEntryAccessor.java | 2 +- .../yacl/mixins/OptionListWidgetMixin.java | 8 +- .../mixins/SliderControllerElementMixin.java | 8 +- .../StringControllerElementAccessor.java | 2 +- .../mixins/StringControllerElementMixin.java | 8 +- .../mixins/YACLScreenCategoryTabAccessor.java | 2 +- .../mixins/YACLScreenCategoryTabMixin.java | 8 +- .../yacl/mixins/YACLScreenMixin.java | 8 +- ...ngControllerElementComponentProcessor.java | 14 +- .../OptionListWidgetComponentProcessor.java | 14 +- ...erControllerElementComponentProcessor.java | 18 +- ...ngControllerElementComponentProcessor.java | 20 +- .../yacl/screenop/YACLScreenProcessor.java | 14 +- .../{ => impl}/config/ConfigManager.java | 14 +- .../{ => impl}/config/ConfigMigrator.java | 16 +- .../{ => impl}/config/dto/GlobalConfig.java | 4 +- .../{ => impl}/config/dto/SharedConfig.java | 4 +- .../config/dto/device/DeviceConfig.java | 8 +- .../dto/device/GyroCalibrationConfig.java | 10 +- .../config/dto/dfu/ControlifyDataFixer.java | 8 +- .../config/dto/dfu/ControlifySchemas.java | 2 +- .../dto/dfu/ControlifyTypeReferences.java | 2 +- .../fixes/AnalogueMovementWhitelistFix.java | 4 +- .../dto/dfu/fixes/DualsenseConfigFix.java | 6 +- .../dto/dfu/fixes/GeneratedBindingIdsFix.java | 4 +- .../dto/dfu/fixes/GuideGuiScaleFix.java | 6 +- .../config/dto/dfu/fixes/GyroLowPassFix.java | 6 +- .../dfu/fixes/HorizontalLookInvertFix.java | 4 +- .../dto/dfu/fixes/RadialMenuActionsFix.java | 4 +- .../dto/dfu/fixes/TheHolyMigrationFix.java | 8 +- .../dto/profile/BluetoothDeviceConfig.java | 2 +- .../config/dto/profile/DualsenseConfig.java | 2 +- .../dto/profile/GenericControllerConfig.java | 2 +- .../config/dto/profile/GyroConfig.java | 6 +- .../config/dto/profile/HDHapticConfig.java | 2 +- .../config/dto/profile/InputConfig.java | 6 +- .../config/dto/profile/ProfileConfig.java | 2 +- .../config/dto/profile/RumbleConfig.java | 2 +- .../defaults/DefaultConfigManager.java | 8 +- .../defaults/DefaultConfigProvider.java | 4 +- .../config/settings/ControlifySettings.java | 8 +- .../config/settings/GlobalSettings.java | 8 +- .../settings/device/DeviceSettings.java | 10 +- .../device/GyroCalibrationSettings.java | 14 +- .../profile/BluetoothDeviceSettings.java | 4 +- .../settings/profile/DualsenseSettings.java | 4 +- .../profile/GenericControllerSettings.java | 4 +- .../config/settings/profile/GyroSettings.java | 8 +- .../settings/profile/HDHapticSettings.java | 4 +- .../settings/profile/InputSettings.java | 8 +- .../settings/profile/ProfileSettings.java | 6 +- .../settings/profile/RumbleSettings.java | 8 +- .../contextual/ContextualDebug.java | 6 +- .../contextual/ContextualDomainImpl.java | 15 +- .../contextual/ContextualDomains.java | 6 +- .../contextual/ContextualPredicate.java | 8 +- .../contextual/ContextualState.java | 2 +- .../ContextualStateAccumulator.java | 12 +- .../ContextualStateContributors.java | 9 +- .../CyclicFactDependencyException.java | 2 +- .../{ => impl}/contextual/FactDefinition.java | 2 +- .../contextual/FactDependencyGraph.java | 2 +- .../contextual/GuideLocation.java | 2 +- .../{ => impl}/contextual/GuideRule.java | 5 +- .../{ => impl}/contextual/Rule.java | 2 +- .../{ => impl}/contextual/RuleEngine.java | 2 +- .../{ => impl}/contextual/RuleSet.java | 2 +- .../{ => impl}/contextual/RuleSetManager.java | 8 +- .../contextual/TriggerEffectRule.java | 8 +- .../impl/controller/ControllerComponent.java | 27 + .../impl/controller/ControllerImpl.java | 194 +++ .../impl/controller/ControllerInfo.java | 14 + .../SingleValueControllerComponent.java | 16 + .../battery/BatteryLevelComponent.java | 17 +- .../controller/battery/PowerState.java | 2 +- .../dualsense/DualsenseComponent.java | 21 +- .../dualsense/TriggerEffectCodecs.java | 6 +- .../dualsense/TriggerEffectInstanceImpl.java | 20 +- .../dualsense/TriggerEffectManager.java | 20 +- .../controller/gyro/GyroButtonMode.java | 2 +- .../controller/gyro/GyroCalibrator.java | 13 +- .../controller/gyro/GyroComponent.java | 64 +- .../controller/gyro/GyroYawMode.java | 2 +- .../controller/haptic/CompleteSoundData.java | 2 +- .../controller/haptic/HDHapticComponent.java | 16 +- .../controller/haptic/HapticEffects.java | 4 +- .../controller/input/InputComponent.java | 54 +- .../controller/led/LEDComponent.java | 16 +- .../misc/BluetoothDeviceComponent.java | 20 +- .../controller/misc/DriverNameComponent.java | 19 + .../controller/misc}/GUIDComponent.java | 6 +- .../impl/controller/misc/UIDComponent.java | 19 + .../rumble/ContinuousRumbleEffectImpl.java | 122 ++ .../rumble/FiniteRumbleEffectImpl.java | 97 ++ .../rumble/RumbleComponentImpl.java | 61 + .../rumble/RumbleEffectInstanceImpl.java | 98 ++ .../impl/controller/rumble/RumbleManager.java | 97 ++ .../impl/controller/rumble/RumbleSource.java | 27 + .../rumble/RumbleSourceManager.java | 82 ++ .../rumble/TriggerRumbleComponent.java | 19 +- .../rumble/effects/UseItemEffectHolder.java | 6 +- .../steamdeck/SteamDeckComponent.java | 19 + .../touchpad/TouchpadComponent.java | 14 +- .../controller/touchpad/Touchpads.java | 2 +- .../controllermanager/ControllerBackend.java | 7 +- .../ControllerCoordinator.java | 58 +- .../controllermanager/ControllerManager.java | 33 +- .../controllermanager}/ControllerType.java | 16 +- .../ControllerTypeManager.java | 23 +- .../SDLControllerBackend.java | 31 +- .../SDLUniqueControllerID.java | 2 +- .../controllermanager/UniqueControllerID.java | 2 +- .../{ => impl}/debug/DebugProperties.java | 6 +- .../driver/ComponentAdderDriver.java | 10 +- .../{ => impl}/driver/CompoundDriver.java | 10 +- .../controlify/{ => impl}/driver/Driver.java | 8 +- .../dualsense/DualsenseEffectsState.java | 2 +- .../dualsense/DualsenseTriggerEffect.java | 2 +- .../DualsenseTriggerEffectTypes.java | 2 +- .../{ => impl}/driver/sdl/DecodedGUID.java | 2 +- .../driver/sdl/SDL3GamepadDriver.java | 27 +- .../driver/sdl/SDL3JoystickDriver.java | 21 +- .../driver/sdl/SDLCommonDriver.java | 62 +- .../driver/sdl/SDLControllerEvent.java | 2 +- .../driver/sdl/SDLControllerEventStage.java | 6 +- .../{ => impl}/driver/sdl/SDLException.java | 2 +- .../driver/sdl/SDLGamepadInputMapping.java | 6 +- .../driver/sdl/SDLInputConversions.java | 6 +- .../sdl/SDLJoystickConnectionState.java | 2 +- .../driver/sdl/SDLNativesLoader.java | 10 +- .../driver/sdl/SDLToPhysicalStage.java | 18 +- .../{ => impl}/driver/sdl/SDLUtil.java | 2 +- .../steamdeck/CEFDebuggerFileResult.java | 2 +- .../driver/steamdeck/SteamDeckDriver.java | 46 +- .../driver/steamdeck/SteamDeckMode.java | 2 +- .../driver/steamdeck/SteamDeckUtil.java | 8 +- .../{ => impl}/font/BindingFontHelper.java | 6 +- .../{ => impl}/font/InputFontMapper.java | 18 +- .../{ => impl}/gui/ButtonGuideRenderer.java | 10 +- .../FakePositionPlainTextButton.java | 2 +- .../gui/components/PlainTextWidget.java | 2 +- .../gui/controllers/BindController.java | 33 +- .../controllers/Deadzone2DImageRenderer.java | 8 +- .../gui/guide/GuideInstanceImpl.java | 23 +- .../{ => impl}/gui/guide/GuideRenderer.java | 2 +- .../gui/guide/InGameButtonGuide.java | 15 +- .../gui/guide/PrecomputedLines.java | 2 +- .../gui/layout/AbstractLayoutComponent.java | 2 +- .../{ => impl}/gui/layout/AnchorPoint.java | 2 +- .../gui/layout/ColumnLayoutComponent.java | 2 +- .../gui/layout/PositionedComponent.java | 2 +- .../gui/layout/RenderComponent.java | 2 +- .../gui/layout/RowLayoutComponent.java | 2 +- .../gui/screen/AskToMapControllerScreen.java | 8 +- .../gui/screen/BindConsumerScreen.java | 18 +- .../gui/screen/BluetoothWarningScreen.java | 8 +- .../gui/screen/ControlifySettingsScreen.java | 35 +- .../screen/ControllerConfigScreenFactory.java | 126 +- .../screen/ControllerMappingMakerScreen.java | 30 +- .../gui/screen/DontInterruptScreen.java | 2 +- .../screen/GlobalSettingsScreenFactory.java | 22 +- .../gui/screen/ProfileSelectionScreen.java | 30 +- .../{ => impl}/gui/screen/RadialItems.java | 28 +- .../gui/screen/RadialMenuEditModel.java | 2 +- .../gui/screen/RadialMenuEditScreen.java | 36 +- .../gui/screen/RadialMenuPages.java | 2 +- .../gui/screen/RadialMenuScreen.java | 48 +- .../gui/screen/SteamDeckAlerts.java | 2 +- .../{ => impl}/hid/ControllerHIDInfo.java | 10 +- .../controlify/{ => impl}/hid/HIDDevice.java | 2 +- .../controlify/{ => impl}/hid/HIDID.java | 4 +- .../ingame/ControllerPlayerMovement.java | 16 +- .../{ => impl}/ingame/DualInput.java | 2 +- .../{ => impl}/ingame/InGameInputHandler.java | 52 +- .../{ => impl}/ingame/InputCurve.java | 2 +- .../{ => impl}/ingame/InputCurves.java | 2 +- .../{ => impl}/ingame/PickBlockAccessor.java | 2 +- .../{ => impl}/input/SensorType.java | 2 +- .../input/mapping/ControllerMapping.java | 2 +- .../mapping/ControllerMappingManager.java | 6 +- .../input/mapping/DeadzoneGroup.java | 2 +- .../input/mapping/GamepadInputs.java | 4 +- .../input/mapping/GestureInputs.java | 4 +- .../{ => impl}/input/mapping/Inputs.java | 2 +- .../input/mapping/JoystickInputs.java | 4 +- .../{ => impl}/input/mapping/MapType.java | 2 +- .../input/mapping/MappingEntry.java | 6 +- .../input/mapping/MappingEntryCodecs.java | 2 +- .../input/pipeline/DeadzoneStage.java | 12 +- .../pipeline/GestureRecogniserStage.java | 12 +- .../pipeline/InputDomainExpansionStage.java | 10 +- .../input/pipeline/InputPipeline.java | 16 +- .../input/pipeline/MappingStage.java | 14 +- .../pipeline/PhysicalToLogicalStage.java | 18 +- .../pipeline/SensorAccumulatorStage.java | 16 +- .../input/pipeline/SensorProcessorStage.java | 12 +- .../input/signal/LogicalSignal.java | 8 +- .../input/signal/PhysicalInputSignal.java | 2 +- .../input/signal/PhysicalSensorSignal.java | 4 +- .../input/signal/PhysicalSignal.java | 2 +- .../platform/ArrayBackedEventHandler.java | 2 +- .../{ => impl}/platform/Environment.java | 2 +- .../controlify/{ => impl}/platform/Event.java | 2 +- .../{ => impl}/platform/EventHandler.java | 2 +- .../platform/client/CreativeTabHelper.java | 2 +- .../platform/client/HudRenderLayer.java | 2 +- .../platform/client/PlatformClientUtil.java | 12 +- .../client/PlatformClientUtilImpl.java | 6 +- .../client/events/DisconnectedEvent.java | 2 +- .../client/events/LifecycleEvent.java | 2 +- .../client/events/ScreenRenderEvent.java | 2 +- .../platform/client/events/TickEvent.java | 2 +- .../resource/ControlifyReloadListener.java | 2 +- .../SimpleControlifyReloadListener.java | 2 +- .../platform/main/PlatformMainUtil.java | 18 +- .../platform/main/PlatformMainUtilImpl.java | 18 +- .../CommandRegistrationCallbackEvent.java | 2 +- .../main/events/HandshakeCompletionEvent.java | 2 +- .../main/events/PlayerJoinedEvent.java | 2 +- .../platform/network/C2SNetworkApi.java | 2 +- .../platform/network/S2CNetworkApi.java | 2 +- .../platform/network/SidedNetworkApi.java | 4 +- .../reacharound/ReachAroundHandler.java | 6 +- .../reacharound/ReachAroundMode.java | 4 +- .../screenop/ComponentProcessor.java | 14 +- .../screenop/ComponentProcessorProvider.java | 2 +- .../{ => impl}/screenop/CustomFocus.java | 2 +- .../{ => impl}/screenop/Registry.java | 2 +- .../ScreenControllerEventListener.java | 6 +- .../{ => impl}/screenop/ScreenProcessor.java | 53 +- .../screenop/ScreenProcessorFactory.java | 2 +- .../screenop/ScreenProcessorProvider.java | 2 +- .../AbstractSliderComponentProcessor.java | 16 +- .../AbstractButtonComponentProcessor.java | 14 +- .../AbstractContainerScreenProcessor.java | 28 +- .../AbstractSignEditScreenProcessor.java | 32 +- .../vanilla/AddServerLikeScreenProcessor.java | 18 +- .../BundleItemSlotControllerAction.java | 10 +- .../compat/vanilla/ChatScreenProcessor.java | 32 +- .../vanilla/CreateWorldScreenProcessor.java | 10 +- .../CreativeModeInventoryScreenProcessor.java | 18 +- .../vanilla/EditBoxComponentProcessor.java | 12 +- .../vanilla/ItemSlotControllerAction.java | 6 +- .../JoinMultiplayerScreenProcessor.java | 14 +- ...nguageSelectionListComponentProcessor.java | 14 +- .../vanilla/OptionsScreenProcessor.java | 10 +- .../vanilla/OptionsSubScreenProcessor.java | 10 +- .../compat/vanilla/PauseScreenProcessor.java | 16 +- .../vanilla/RecipeBookScreenProcessor.java | 12 +- .../vanilla/SelectWorldScreenProcessor.java | 12 +- ...rSelectionListEntryComponentProcessor.java | 12 +- .../vanilla/SliderComponentProcessor.java | 16 +- .../compat/vanilla/TitleScreenProcessor.java | 16 +- .../WorldListEntryComponentProcessor.java | 12 +- .../screenop/keyboard/ChatKeyboardDucky.java | 2 +- .../keyboard/CommonKeyboardHints.java | 6 +- .../keyboard/ComponentKeyboardBehaviour.java | 4 +- .../keyboard/FallbackKeyboardLayout.java | 12 +- .../screenop/keyboard/InputTarget.java | 2 +- .../screenop/keyboard/KeyWidget.java | 26 +- .../screenop/keyboard/KeyboardLayout.java | 6 +- .../keyboard/KeyboardLayoutManager.java | 10 +- .../keyboard/KeyboardLayoutWithId.java | 2 +- .../screenop/keyboard/KeyboardLayouts.java | 6 +- .../keyboard/KeyboardOverlayScreen.java | 6 +- .../screenop/keyboard/KeyboardWidget.java | 16 +- .../screenop/keyboard/MixinInputTarget.java | 2 +- .../server/ControlifyHandshake.java | 8 +- .../{ => impl}/server/ControlifyServer.java | 10 +- .../server/ControlifyServerConfig.java | 6 +- .../{ => impl}/server/ServerPolicies.java | 2 +- .../{ => impl}/server/ServerPolicy.java | 2 +- .../{ => impl}/server/VibrateCommand.java | 28 +- .../server/packets/EntityVibrationPacket.java | 22 +- .../server/packets/OriginVibrationPacket.java | 22 +- .../server/packets/ServerPolicyPacket.java | 4 +- .../server/packets/VibrationPacket.java | 15 +- .../sound/ControlifyClientSounds.java | 4 +- .../controlify/{ => impl}/utils/CUtil.java | 7 +- .../{ => impl}/utils/ColorUtils.java | 2 +- .../{ => impl}/utils/ControllerUtils.java | 10 +- .../{ => impl}/utils/CursorUtils.java | 2 +- .../{ => impl}/utils/DebugDump.java | 14 +- .../controlify/{ => impl}/utils/DebugLog.java | 4 +- .../{ => impl}/utils/DebugOverlayHelper.java | 2 +- .../{ => impl}/utils/DummyMixinTarget.java | 2 +- .../controlify/{ => impl}/utils/Easings.java | 2 +- .../{ => impl}/utils/HoldRepeatHelper.java | 4 +- .../utils/InitialScreenRegistryDuck.java | 2 +- .../{ => impl}/utils/JsonTreeParser.java | 2 +- .../{ => impl}/utils/LazyComponentDims.java | 12 +- .../{ => impl}/utils/MinecraftUtil.java | 2 +- .../utils/MouseMinecraftCallNotifier.java | 2 +- .../controlify/{ => impl}/utils/MthExt.java | 2 +- .../controlify/{ => impl}/utils/Platform.java | 2 +- .../utils/PrecomputedComponentDims.java | 4 +- .../{ => impl}/utils/ResizableRingBuffer.java | 2 +- .../{ => impl}/utils/SetupWizard.java | 2 +- .../{ => impl}/utils/SetupWizardManager.java | 4 +- .../utils/TrackingBodySubscriber.java | 2 +- .../{ => impl}/utils/TrackingConsumer.java | 2 +- .../utils/UnhandledCompletableFutures.java | 2 +- .../utils/animation/api/Animatable.java | 2 +- .../utils/animation/api/Animation.java | 4 +- .../utils/animation/api/AnimationGroup.java | 4 +- .../animation/api/AnimationSequence.java | 4 +- .../utils/animation/api/EasingFunction.java | 2 +- .../animation/impl/AnimationGroupImpl.java | 6 +- .../utils/animation/impl/AnimationImpl.java | 6 +- .../animation/impl/AnimationSequenceImpl.java | 6 +- .../utils/animation/impl/Animator.java | 4 +- .../{ => impl}/utils/codec/CExtraCodecs.java | 2 +- .../{ => impl}/utils/codec/FuzzyCodec.java | 2 +- .../{ => impl}/utils/codec/FuzzyMapCodec.java | 2 +- .../{ => impl}/utils/codec/SetCodec.java | 2 +- .../utils/codec/StrictEitherMapCodec.java | 2 +- .../{ => impl}/utils/event/EventSink.java | 2 +- .../{ => impl}/utils/event/EventSource.java | 2 +- .../{ => impl}/utils/event/EventStage.java | 2 +- .../{ => impl}/utils/event/EventTap.java | 2 +- .../utils/event/UnaryEventStage.java | 2 +- .../utils/log/AbstractControlifyLogger.java | 2 +- .../utils/log/ControlifyLogger.java | 2 +- .../utils/log/ControlifyMasterLogger.java | 4 +- .../utils/log/ControlifySubLogger.java | 2 +- .../utils/log/ControlifySubLoggerImpl.java | 2 +- .../{ => impl}/utils/log/LogLevel.java | 2 +- .../{ => impl}/utils/log/LogMessage.java | 2 +- .../predicates/ClientEntityPredicate.java | 2 +- .../predicates/ClientPredicateUtils.java | 4 +- .../predicates/EntityEquipmentPredicate.java | 2 +- .../utils/render/BaseRenderState.java | 4 +- .../utils/render/CGuiElementRenderState.java | 4 +- .../{ => impl}/utils/render/RenderUtils.java | 2 +- .../elements/CircleElementRenderState.java | 6 +- .../{ => impl}/virtualmouse/SnapUtils.java | 4 +- .../virtualmouse/VirtualMouseBehaviour.java | 2 +- .../virtualmouse/VirtualMouseHandler.java | 37 +- .../wireless/LowBatteryNotifier.java | 18 +- .../core/ClientPacketListenerMixin.java | 2 +- .../controlify/mixins/core/GuiMixin.java | 8 +- .../controlify/mixins/core/HudMixin.java | 4 +- .../mixins/core/KeyboardHandlerMixin.java | 2 +- .../mixins/core/MinecraftMixin.java | 6 +- .../mixins/core/MouseHandlerMixin.java | 8 +- .../mixins/core/SDLEventHandlerMixin.java | 4 +- .../mixins/feature/bind/GuiMixin.java | 6 +- .../mixins/feature/bind/HudMixin.java | 4 +- .../mixins/feature/bind/KeyMappingMixin.java | 6 +- .../feature/bind/ToggleKeyMappingMixin.java | 8 +- .../feature/font/KeybindContentsMixin.java | 6 +- .../font/TranslatableContentsMixin.java | 2 +- .../ingame/ClientPacketListenerMixin.java | 4 +- .../mixins/feature/guide/ingame/HudMixin.java | 4 +- .../guide/screen/AbstractButtonMixin.java | 4 +- .../guide/screen/TabNavigationBarMixin.java | 8 +- .../mixins/feature/input/MinecraftMixin.java | 2 +- .../feature/oofinput/MinecraftMixin.java | 2 +- .../analogueboat/AbstractBoatMixin.java | 2 +- .../analogueboat/LocalPlayerMixin.java | 8 +- .../ClientPacketListenerMixin.java | 6 +- .../MovementTutorialStepInstanceMixin.java | 4 +- .../OpenInventoryTutorialStepMixin.java | 4 +- .../PunchTreeTutorialStepInstanceMixin.java | 4 +- .../patches/sprintfix/LocalPlayerMixin.java | 2 +- .../feature/reacharound/MinecraftMixin.java | 2 +- .../mixins/feature/rumble/MinecraftMixin.java | 4 +- .../blockbreak/MultiPlayerGameModeMixin.java | 25 +- .../damage/ClientPacketListenerMixin.java | 16 +- .../explosion/ClientPacketListenerMixin.java | 16 +- .../rumble/explosion/LightningBoltMixin.java | 14 +- .../rumble/fishing/FishingHookMixin.java | 14 +- .../rumble/itembreak/LocalPlayerMixin.java | 10 +- .../levelevents/LevelEventHandlerMixin.java | 38 +- .../rumble/slowblock/LocalPlayerMixin.java | 22 +- .../useitem/ClientPacketListenerMixin.java | 6 +- .../rumble/useitem/LocalPlayerMixin.java | 47 +- .../rumble/waterland/LocalPlayerMixin.java | 19 +- .../screenop/ContainerEventHandlerMixin.java | 2 +- .../mixins/feature/screenop/GuiMixin.java | 4 +- .../mixins/feature/screenop/ScreenMixin.java | 8 +- .../impl/bundle/BundleMouseActionsMixin.java | 8 +- .../impl/chat/ChatComponentMixin.java | 4 +- .../screenop/impl/chat/ChatScreenMixin.java | 6 +- .../impl/chat/CommandSuggestionsMixin.java | 6 +- .../AbstractContainerScreenMixin.java | 14 +- .../AbstractRecipeBookScreenMixin.java | 6 +- .../CreativeModeInventoryScreenMixin.java | 12 +- .../impl/elements/AbstractButtonMixin.java | 6 +- .../AbstractContainerEventHandlerMixin.java | 2 +- .../elements/AbstractSliderButtonMixin.java | 8 +- .../impl/elements/AbstractWidgetMixin.java | 10 +- ...ontainerObjectSelectionListEntryMixin.java | 2 +- .../screenop/impl/elements/EditBoxMixin.java | 16 +- .../outofgame/CreateWorldScreenMixin.java | 12 +- .../DirectJoinServerScreenMixin.java | 6 +- .../outofgame/JoinMultiplayerScreenMixin.java | 6 +- .../LanguageSelectionListEntryMixin.java | 6 +- .../outofgame/ManageServerScreenMixin.java | 6 +- .../impl/outofgame/OptionsScreenMixin.java | 6 +- .../impl/outofgame/OptionsSubScreenMixin.java | 6 +- .../impl/outofgame/PauseScreenMixin.java | 6 +- .../outofgame/SelectWorldScreenMixin.java | 12 +- .../ServerSelectionListEntryMixin.java | 6 +- .../impl/outofgame/TitleScreenMixin.java | 6 +- .../WorldSelectionListEntryMixin.java | 6 +- .../sign/AbstractSignEditScreenMixin.java | 12 +- .../settingsbutton/ControlsScreenMixin.java | 4 +- .../feature/util/ConnectScreenMixin.java | 2 +- .../mixins/feature/virtualmouse/GuiMixin.java | 4 +- .../virtualmouse/InputConstantsMixin.java | 8 +- .../feature/virtualmouse/MinecraftMixin.java | 4 +- .../virtualmouse/MouseHandlerMixin.java | 4 +- .../AbstractContainerScreenMixin.java | 4 +- .../AbstractRecipeBookScreenMixin.java | 4 +- .../CreativeModeInventoryScreenMixin.java | 2 +- .../snapping/EnchantmentScreenMixin.java | 4 +- .../snapping/LoomScreenMixin.java | 4 +- .../virtualmouse/snapping/ScreenMixin.java | 4 +- .../snapping/StonecutterScreenMixin.java | 4 +- .../controlify/rumble/BasicRumbleEffect.java | 162 --- .../rumble/ContinuousRumbleEffect.java | 161 --- .../controlify/rumble/RumbleCapable.java | 15 - .../controlify/rumble/RumbleEffect.java | 24 - .../controlify/rumble/RumbleManager.java | 92 -- .../controlify/rumble/RumbleSource.java | 74 - .../controlify/controller/activators.json | 3 + .../contextual/facts/container.json | 0 .../contextual/facts/in_game.json | 0 .../contextual/guide/container.json | 0 .../contextual/guide/in_game.json | 0 .../contextual/trigger_effect/in_game.json | 0 .../controller_identification.json5 | 0 .../default_bind/default.json | 0 .../default_bind/dualsense.json | 0 .../default_bind/switch.json | 0 .../default_config.json | 0 .../font_mapping}/default.json | 0 .../font_mapping}/dualsense.json | 0 .../font_mapping}/dualshock3.json | 0 .../font_mapping}/dualshock4.json | 0 .../font_mapping}/steam_controller.json | 0 .../font_mapping}/steam_deck.json | 0 .../font_mapping}/switch.json | 0 .../font_mapping}/xbox_one.json | 0 .../gamecontrollerdb-sdl2.txt | 0 .../gamecontrollerdb-sdl3.txt | 0 .../{ => controller}/haptics/navigate.ogg | Bin .../keyboard_layout/full/en_us.json | 0 .../keyboard_layout/server_ip/en_us.json | 0 .../keyboard_layout/simple/en_us.json | 0 .../{ => controller}/radial_icons.json | 0 .../controlify/controller/rumble_sources.json | 16 + .../controlify-compat.iris.mixins.json | 4 +- ...y-compat.reeses-sodium-options.mixins.json | 4 +- .../controlify-compat.rrls.mixins.json | 4 +- ...olify-compat.simple-voice-chat.mixins.json | 4 +- .../controlify-compat.sodium.mixins.json | 4 +- .../controlify-compat.yacl.mixins.json | 4 +- .../controlify/contextual/guide/in_game.json | 1194 ----------------- .../neoforge/ControlifyBootstrap.java | 12 +- .../NeoforgeCompatMixinPlatform.java | 2 +- .../platform/NeoforgePlatformMainImpl.java | 16 +- .../client/NeoforgeCreativeTabHelper.java | 2 +- .../client/NeoforgePlatformClientImpl.java | 16 +- .../network/C2SNetworkApiNeoforge.java | 2 +- .../network/S2CNetworkApiNeoforge.java | 7 +- .../config/ConfigMigrationTestHelper.java | 4 +- .../contextual/FactDependencyGraphTest.java | 2 +- 617 files changed, 3428 insertions(+), 4644 deletions(-) delete mode 100644 src/main/java/dev/isxander/controlify/action/ActionSpecRegistry.java delete mode 100644 src/main/java/dev/isxander/controlify/action/activator/NoopActivator.java rename src/main/java/dev/isxander/controlify/api/{event => }/ControlifyEvents.java (79%) rename src/main/java/dev/isxander/controlify/{ => api}/InputMode.java (89%) rename src/main/java/dev/isxander/controlify/{ => api}/action/Action.java (65%) rename src/main/java/dev/isxander/controlify/{ => api}/action/ActionSpec.java (76%) rename src/main/java/dev/isxander/controlify/{ => api}/action/Channel.java (94%) create mode 100644 src/main/java/dev/isxander/controlify/api/action/package-info.java create mode 100644 src/main/java/dev/isxander/controlify/api/contextual/package-info.java create mode 100644 src/main/java/dev/isxander/controlify/api/controller/Controller.java create mode 100644 src/main/java/dev/isxander/controlify/api/controller/package-info.java create mode 100644 src/main/java/dev/isxander/controlify/api/controller/rumble/ContinuousRumbleEffect.java create mode 100644 src/main/java/dev/isxander/controlify/api/controller/rumble/FiniteRumbleEffect.java create mode 100644 src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleComponent.java create mode 100644 src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleEffect.java create mode 100644 src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleEffectInstance.java rename src/main/java/dev/isxander/controlify/{ => api/controller}/rumble/RumbleState.java (94%) rename src/main/java/dev/isxander/controlify/{ => api/controller}/rumble/TriggerRumbleState.java (89%) create mode 100644 src/main/java/dev/isxander/controlify/api/controller/rumble/package-info.java rename src/main/java/dev/isxander/controlify/api/{buttonguide => gui}/ButtonGuideApi.java (65%) rename src/main/java/dev/isxander/controlify/api/{buttonguide => gui}/ButtonGuidePredicate.java (57%) create mode 100644 src/main/java/dev/isxander/controlify/api/gui/package-info.java rename src/main/java/dev/isxander/controlify/{ => api}/input/LogicalInput.java (93%) create mode 100644 src/main/java/dev/isxander/controlify/api/input/package-info.java create mode 100644 src/main/java/dev/isxander/controlify/api/package-info.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/ControllerEntity.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/ECSComponent.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/ECSEntity.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/SingleValueComponent.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/gyro/GyroState.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/gyro/GyroStateC.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/impl/ECSComponentImpl.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/impl/ECSEntityImpl.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/info/DriverNameComponent.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/info/UIDComponent.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/rumble/RumbleComponent.java delete mode 100644 src/main/java/dev/isxander/controlify/controller/steamdeck/SteamDeckComponent.java rename src/main/java/dev/isxander/controlify/{ => impl}/Controlify.java (82%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/Accumulator.java (82%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/ActionAccessor.java (64%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/ActionAccessorImpl.java (64%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/ActionContext.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/ActionGraph.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/ActionImpl.java (82%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/ActionSpecBuilder.java (64%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/ActionSpecBuilderImpl.java (86%) create mode 100644 src/main/java/dev/isxander/controlify/impl/action/ActionSpecRegistry.java rename src/main/java/dev/isxander/controlify/{ => impl}/action/ActionSpecRegistryImpl.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/ActionState.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/Activator.java (64%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/ActivatorConfig.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/ActivatorConfigManager.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/ActivatorConfigType.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/CompoundActivator.java (82%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/ContinuousActivator.java (74%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/DoubleTapPulseActivator.java (76%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/GuiPressPulseActivator.java (76%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/HoldLatchActivator.java (79%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/HoldPulseActivator.java (75%) create mode 100644 src/main/java/dev/isxander/controlify/impl/action/activator/NoopActivator.java rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/PressPulseActivator.java (75%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/ReleasePulseActivator.java (75%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/RepeatLatchPulseActivator.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/TapPulseActivator.java (75%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/activator/ToggleLatchActivator.java (85%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/defaults/DefaultBindManager.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/defaults/DefaultBindProvider.java (76%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/defaults/LayeredDefaultBindProvider.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/defaults/MapBackedDefaultBindProvider.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/radial/RadialIcon.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/radial/RadialIconExtractor.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/action/radial/RadialIconManager.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/api/entrypoint/ControlifyEntrypoint.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/api/entrypoint/InitContext.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/api/entrypoint/PreInitContext.java (72%) rename src/main/java/dev/isxander/controlify/{ => impl}/api/ingameinput/LookInputModifier.java (76%) rename src/main/java/dev/isxander/controlify/{ => impl}/api/vmousesnapping/ISnapBehaviour.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/api/vmousesnapping/SnapPoint.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/bindings/BindContext.java (84%) rename src/main/java/dev/isxander/controlify/{ => impl}/bindings/ControlifyBindings.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/bindings/KeyMappingHandle.java (55%) rename src/main/java/dev/isxander/controlify/{fixes => impl}/boatfix/AnalogBoatInput.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/CompatMixinPlatform.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/CompatMixinPlugin.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/ControlifyCompat.java (80%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/fancymenu/FancyMenuCompat.java (85%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/fancymenu/OpenControlifySettingsAction.java (84%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/iris/IrisMixinPlugin.java (66%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/iris/mixins/BaseOptionElementWidgetMixin.java (78%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/iris/screenop/BaseOptionElementComponentProcessor.java (78%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/rrls/RrlsMixinPlugin.java (66%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/rrls/mixins/HideTypeMixin.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/rso/RSOMixinPlugin.java (67%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/rso/mixins/AbstractFrameAccessor.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/rso/mixins/SodiumVideoOptionsScreenMixin.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/rso/mixins/TabFrameAccessor.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/simplevoicechat/SVCMixinPlugin.java (64%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/simplevoicechat/SimpleVoiceChatCompat.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/simplevoicechat/mixins/KeyEventsAccessor.java (84%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/simplevoicechat/mixins/PTTKeyHandlerMixin.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/SodiumMixinPlugin.java (66%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/mixins/AbstractWidgetMixin.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/mixins/CycleControlElementMixin.java (72%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/mixins/FlatButtonWidgetAccessor.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/mixins/FlatButtonWidgetMixin.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/mixins/SliderControlElementMixin.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/mixins/TickBoxControlElementMixin.java (72%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/mixins/VideoSettingsScreenMixin.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/screenop/CycleControlProcessor.java (69%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/screenop/SliderControlProcessor.java (76%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/screenop/SodiumGuiScreenProcessor.java (73%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/screenop/SodiumScreenOperations.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/sodium/screenop/TickBoxControlProcessor.java (67%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/YACLMixinPlugin.java (67%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/ControllerWidgetAccessor.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/CyclingControllerElementMixin.java (68%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/GroupSeparatorEntryAccessor.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/OptionListWidgetMixin.java (67%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/SliderControllerElementMixin.java (68%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/StringControllerElementAccessor.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/StringControllerElementMixin.java (68%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/YACLScreenCategoryTabAccessor.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/YACLScreenCategoryTabMixin.java (78%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/mixins/YACLScreenMixin.java (66%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/screenop/CyclingControllerElementComponentProcessor.java (73%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/screenop/OptionListWidgetComponentProcessor.java (82%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/screenop/SliderControllerElementComponentProcessor.java (74%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/screenop/StringControllerElementComponentProcessor.java (74%) rename src/main/java/dev/isxander/controlify/{ => impl}/compatibility/yacl/screenop/YACLScreenProcessor.java (75%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/ConfigManager.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/ConfigMigrator.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/GlobalConfig.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/SharedConfig.java (85%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/device/DeviceConfig.java (79%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/device/GyroCalibrationConfig.java (60%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/ControlifyDataFixer.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/ControlifySchemas.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/ControlifyTypeReferences.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/fixes/AnalogueMovementWhitelistFix.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/fixes/DualsenseConfigFix.java (85%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/fixes/GeneratedBindingIdsFix.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/fixes/GuideGuiScaleFix.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/fixes/GyroLowPassFix.java (82%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/fixes/HorizontalLookInvertFix.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/fixes/RadialMenuActionsFix.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/dfu/fixes/TheHolyMigrationFix.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/BluetoothDeviceConfig.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/DualsenseConfig.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/GenericControllerConfig.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/GyroConfig.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/HDHapticConfig.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/InputConfig.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/ProfileConfig.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/RumbleConfig.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/defaults/DefaultConfigManager.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/dto/profile/defaults/DefaultConfigProvider.java (61%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/ControlifySettings.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/GlobalSettings.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/device/DeviceSettings.java (82%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/device/GyroCalibrationSettings.java (64%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/profile/BluetoothDeviceSettings.java (79%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/profile/DualsenseSettings.java (78%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/profile/GenericControllerSettings.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/profile/GyroSettings.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/profile/HDHapticSettings.java (76%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/profile/InputSettings.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/profile/ProfileSettings.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/config/settings/profile/RumbleSettings.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/ContextualDebug.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/ContextualDomainImpl.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/ContextualDomains.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/ContextualPredicate.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/ContextualState.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/ContextualStateAccumulator.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/ContextualStateContributors.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/CyclicFactDependencyException.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/FactDefinition.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/FactDependencyGraph.java (99%) rename src/main/java/dev/isxander/controlify/{api => impl}/contextual/GuideLocation.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/GuideRule.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/Rule.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/RuleEngine.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/RuleSet.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/RuleSetManager.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/contextual/TriggerEffectRule.java (79%) create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/ControllerComponent.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/ControllerImpl.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/ControllerInfo.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/SingleValueControllerComponent.java rename src/main/java/dev/isxander/controlify/{ => impl}/controller/battery/BatteryLevelComponent.java (62%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/battery/PowerState.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/dualsense/DualsenseComponent.java (77%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/dualsense/TriggerEffectCodecs.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/dualsense/TriggerEffectInstanceImpl.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/dualsense/TriggerEffectManager.java (73%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/gyro/GyroButtonMode.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/gyro/GyroCalibrator.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/gyro/GyroComponent.java (69%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/gyro/GyroYawMode.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/haptic/CompleteSoundData.java (80%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/haptic/HDHapticComponent.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/haptic/HapticEffects.java (72%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/input/InputComponent.java (75%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/led/LEDComponent.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/misc/BluetoothDeviceComponent.java (50%) create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/misc/DriverNameComponent.java rename src/main/java/dev/isxander/controlify/{controller/info => impl/controller/misc}/GUIDComponent.java (67%) create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/misc/UIDComponent.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/rumble/ContinuousRumbleEffectImpl.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/rumble/FiniteRumbleEffectImpl.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleComponentImpl.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleEffectInstanceImpl.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleManager.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleSource.java create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleSourceManager.java rename src/main/java/dev/isxander/controlify/{ => impl}/controller/rumble/TriggerRumbleComponent.java (62%) rename src/main/java/dev/isxander/controlify/{ => impl/controller}/rumble/effects/UseItemEffectHolder.java (50%) create mode 100644 src/main/java/dev/isxander/controlify/impl/controller/steamdeck/SteamDeckComponent.java rename src/main/java/dev/isxander/controlify/{ => impl}/controller/touchpad/TouchpadComponent.java (60%) rename src/main/java/dev/isxander/controlify/{ => impl}/controller/touchpad/Touchpads.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/controllermanager/ControllerBackend.java (85%) rename src/main/java/dev/isxander/controlify/{ => impl}/controllermanager/ControllerCoordinator.java (79%) rename src/main/java/dev/isxander/controlify/{ => impl}/controllermanager/ControllerManager.java (66%) rename src/main/java/dev/isxander/controlify/{controller/id => impl/controllermanager}/ControllerType.java (73%) rename src/main/java/dev/isxander/controlify/{controller/id => impl/controllermanager}/ControllerTypeManager.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/controllermanager/SDLControllerBackend.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/controllermanager/SDLUniqueControllerID.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/controllermanager/UniqueControllerID.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/debug/DebugProperties.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/ComponentAdderDriver.java (51%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/CompoundDriver.java (77%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/Driver.java (62%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/dualsense/DualsenseEffectsState.java (99%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/dualsense/DualsenseTriggerEffect.java (99%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/dualsense/DualsenseTriggerEffectTypes.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/DecodedGUID.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDL3GamepadDriver.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDL3JoystickDriver.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLCommonDriver.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLControllerEvent.java (99%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLControllerEventStage.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLException.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLGamepadInputMapping.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLInputConversions.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLJoystickConnectionState.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLNativesLoader.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLToPhysicalStage.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/sdl/SDLUtil.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/steamdeck/CEFDebuggerFileResult.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/steamdeck/SteamDeckDriver.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/steamdeck/SteamDeckMode.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/driver/steamdeck/SteamDeckUtil.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/font/BindingFontHelper.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/font/InputFontMapper.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/ButtonGuideRenderer.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/components/FakePositionPlainTextButton.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/components/PlainTextWidget.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/controllers/BindController.java (82%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/controllers/Deadzone2DImageRenderer.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/guide/GuideInstanceImpl.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/guide/GuideRenderer.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/guide/InGameButtonGuide.java (75%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/guide/PrecomputedLines.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/layout/AbstractLayoutComponent.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/layout/AnchorPoint.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/layout/ColumnLayoutComponent.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/layout/PositionedComponent.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/layout/RenderComponent.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/layout/RowLayoutComponent.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/AskToMapControllerScreen.java (77%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/BindConsumerScreen.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/BluetoothWarningScreen.java (79%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/ControlifySettingsScreen.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/ControllerConfigScreenFactory.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/ControllerMappingMakerScreen.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/DontInterruptScreen.java (77%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/GlobalSettingsScreenFactory.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/ProfileSelectionScreen.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/RadialItems.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/RadialMenuEditModel.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/RadialMenuEditScreen.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/RadialMenuPages.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/RadialMenuScreen.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/gui/screen/SteamDeckAlerts.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/hid/ControllerHIDInfo.java (78%) rename src/main/java/dev/isxander/controlify/{ => impl}/hid/HIDDevice.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/hid/HIDID.java (85%) rename src/main/java/dev/isxander/controlify/{ => impl}/ingame/ControllerPlayerMovement.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/ingame/DualInput.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/ingame/InGameInputHandler.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/ingame/InputCurve.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/ingame/InputCurves.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/ingame/PickBlockAccessor.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/SensorType.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/ControllerMapping.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/ControllerMappingManager.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/DeadzoneGroup.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/GamepadInputs.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/GestureInputs.java (64%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/Inputs.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/JoystickInputs.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/MapType.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/MappingEntry.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/mapping/MappingEntryCodecs.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/pipeline/DeadzoneStage.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/pipeline/GestureRecogniserStage.java (56%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/pipeline/InputDomainExpansionStage.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/pipeline/InputPipeline.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/pipeline/MappingStage.java (68%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/pipeline/PhysicalToLogicalStage.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/pipeline/SensorAccumulatorStage.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/pipeline/SensorProcessorStage.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/signal/LogicalSignal.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/signal/PhysicalInputSignal.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/signal/PhysicalSensorSignal.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/input/signal/PhysicalSignal.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/ArrayBackedEventHandler.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/Environment.java (78%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/Event.java (76%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/EventHandler.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/CreativeTabHelper.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/HudRenderLayer.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/PlatformClientUtil.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/PlatformClientUtilImpl.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/events/DisconnectedEvent.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/events/LifecycleEvent.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/events/ScreenRenderEvent.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/events/TickEvent.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/resource/ControlifyReloadListener.java (84%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/client/resource/SimpleControlifyReloadListener.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/main/PlatformMainUtil.java (80%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/main/PlatformMainUtilImpl.java (71%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/main/events/CommandRegistrationCallbackEvent.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/main/events/HandshakeCompletionEvent.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/main/events/PlayerJoinedEvent.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/network/C2SNetworkApi.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/network/S2CNetworkApi.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/platform/network/SidedNetworkApi.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/reacharound/ReachAroundHandler.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/reacharound/ReachAroundMode.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/ComponentProcessor.java (70%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/ComponentProcessorProvider.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/CustomFocus.java (84%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/Registry.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/ScreenControllerEventListener.java (50%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/ScreenProcessor.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/ScreenProcessorFactory.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/ScreenProcessorProvider.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/AbstractSliderComponentProcessor.java (67%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/AbstractButtonComponentProcessor.java (68%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/AbstractContainerScreenProcessor.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/AbstractSignEditScreenProcessor.java (80%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/AddServerLikeScreenProcessor.java (77%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/BundleItemSlotControllerAction.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/ChatScreenProcessor.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/CreateWorldScreenProcessor.java (67%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/CreativeModeInventoryScreenProcessor.java (77%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/EditBoxComponentProcessor.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/ItemSlotControllerAction.java (71%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/JoinMultiplayerScreenProcessor.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/LanguageSelectionListComponentProcessor.java (72%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/OptionsScreenProcessor.java (73%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/OptionsSubScreenProcessor.java (73%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/PauseScreenProcessor.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/RecipeBookScreenProcessor.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/SelectWorldScreenProcessor.java (76%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/ServerSelectionListEntryComponentProcessor.java (63%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/SliderComponentProcessor.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/TitleScreenProcessor.java (75%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/compat/vanilla/WorldListEntryComponentProcessor.java (67%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/ChatKeyboardDucky.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/CommonKeyboardHints.java (79%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/ComponentKeyboardBehaviour.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/FallbackKeyboardLayout.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/InputTarget.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/KeyWidget.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/KeyboardLayout.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/KeyboardLayoutManager.java (93%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/KeyboardLayoutWithId.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/KeyboardLayouts.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/KeyboardOverlayScreen.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/KeyboardWidget.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/screenop/keyboard/MixinInputTarget.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/ControlifyHandshake.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/ControlifyServer.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/ControlifyServerConfig.java (84%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/ServerPolicies.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/ServerPolicy.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/VibrateCommand.java (87%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/packets/EntityVibrationPacket.java (70%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/packets/OriginVibrationPacket.java (70%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/packets/ServerPolicyPacket.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/server/packets/VibrationPacket.java (67%) rename src/main/java/dev/isxander/controlify/{ => impl}/sound/ControlifyClientSounds.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/CUtil.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/ColorUtils.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/ControllerUtils.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/CursorUtils.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/DebugDump.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/DebugLog.java (74%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/DebugOverlayHelper.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/DummyMixinTarget.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/Easings.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/HoldRepeatHelper.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/InitialScreenRegistryDuck.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/JsonTreeParser.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/LazyComponentDims.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/MinecraftUtil.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/MouseMinecraftCallNotifier.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/MthExt.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/Platform.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/PrecomputedComponentDims.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/ResizableRingBuffer.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/SetupWizard.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/SetupWizardManager.java (86%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/TrackingBodySubscriber.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/TrackingConsumer.java (89%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/UnhandledCompletableFutures.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/animation/api/Animatable.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/animation/api/Animation.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/animation/api/AnimationGroup.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/animation/api/AnimationSequence.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/animation/api/EasingFunction.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/animation/impl/AnimationGroupImpl.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/animation/impl/AnimationImpl.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/animation/impl/AnimationSequenceImpl.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/animation/impl/Animator.java (83%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/codec/CExtraCodecs.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/codec/FuzzyCodec.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/codec/FuzzyMapCodec.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/codec/SetCodec.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/codec/StrictEitherMapCodec.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/event/EventSink.java (61%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/event/EventSource.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/event/EventStage.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/event/EventTap.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/event/UnaryEventStage.java (63%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/log/AbstractControlifyLogger.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/log/ControlifyLogger.java (97%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/log/ControlifyMasterLogger.java (91%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/log/ControlifySubLogger.java (81%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/log/ControlifySubLoggerImpl.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/log/LogLevel.java (78%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/log/LogMessage.java (96%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/predicates/ClientEntityPredicate.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/predicates/ClientPredicateUtils.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/predicates/EntityEquipmentPredicate.java (98%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/render/BaseRenderState.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/render/CGuiElementRenderState.java (90%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/render/RenderUtils.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/utils/render/elements/CircleElementRenderState.java (92%) rename src/main/java/dev/isxander/controlify/{ => impl}/virtualmouse/SnapUtils.java (95%) rename src/main/java/dev/isxander/controlify/{ => impl}/virtualmouse/VirtualMouseBehaviour.java (88%) rename src/main/java/dev/isxander/controlify/{ => impl}/virtualmouse/VirtualMouseHandler.java (94%) rename src/main/java/dev/isxander/controlify/{ => impl}/wireless/LowBatteryNotifier.java (72%) delete mode 100644 src/main/java/dev/isxander/controlify/rumble/BasicRumbleEffect.java delete mode 100644 src/main/java/dev/isxander/controlify/rumble/ContinuousRumbleEffect.java delete mode 100644 src/main/java/dev/isxander/controlify/rumble/RumbleCapable.java delete mode 100644 src/main/java/dev/isxander/controlify/rumble/RumbleEffect.java delete mode 100644 src/main/java/dev/isxander/controlify/rumble/RumbleManager.java delete mode 100644 src/main/java/dev/isxander/controlify/rumble/RumbleSource.java create mode 100644 src/main/resources/assets/controlify/controller/activators.json rename src/main/resources/assets/controlify/{ => controller}/contextual/facts/container.json (100%) rename src/main/resources/assets/controlify/{ => controller}/contextual/facts/in_game.json (100%) rename src/main/resources/assets/controlify/{ => controller}/contextual/guide/container.json (100%) rename src/main/resources/assets/controlify/{ => controller}/contextual/guide/in_game.json (100%) rename src/main/resources/assets/controlify/{ => controller}/contextual/trigger_effect/in_game.json (100%) rename src/main/resources/assets/controlify/{controllers => controller}/controller_identification.json5 (100%) rename src/main/resources/assets/controlify/{controllers => controller}/default_bind/default.json (100%) rename src/main/resources/assets/controlify/{controllers => controller}/default_bind/dualsense.json (100%) rename src/main/resources/assets/controlify/{controllers => controller}/default_bind/switch.json (100%) rename src/main/resources/assets/controlify/{controllers => controller}/default_config.json (100%) rename src/main/resources/assets/controlify/{controllers/font_mappings => controller/font_mapping}/default.json (100%) rename src/main/resources/assets/controlify/{controllers/font_mappings => controller/font_mapping}/dualsense.json (100%) rename src/main/resources/assets/controlify/{controllers/font_mappings => controller/font_mapping}/dualshock3.json (100%) rename src/main/resources/assets/controlify/{controllers/font_mappings => controller/font_mapping}/dualshock4.json (100%) rename src/main/resources/assets/controlify/{controllers/font_mappings => controller/font_mapping}/steam_controller.json (100%) rename src/main/resources/assets/controlify/{controllers/font_mappings => controller/font_mapping}/steam_deck.json (100%) rename src/main/resources/assets/controlify/{controllers/font_mappings => controller/font_mapping}/switch.json (100%) rename src/main/resources/assets/controlify/{controllers/font_mappings => controller/font_mapping}/xbox_one.json (100%) rename src/main/resources/assets/controlify/{controllers => controller}/gamecontrollerdb-sdl2.txt (100%) rename src/main/resources/assets/controlify/{controllers => controller}/gamecontrollerdb-sdl3.txt (100%) rename src/main/resources/assets/controlify/{ => controller}/haptics/navigate.ogg (100%) rename src/main/resources/assets/controlify/{ => controller}/keyboard_layout/full/en_us.json (100%) rename src/main/resources/assets/controlify/{ => controller}/keyboard_layout/server_ip/en_us.json (100%) rename src/main/resources/assets/controlify/{ => controller}/keyboard_layout/simple/en_us.json (100%) rename src/main/resources/assets/controlify/{ => controller}/radial_icons.json (100%) create mode 100644 src/main/resources/assets/controlify/controller/rumble_sources.json delete mode 100644 src/main/resources/resourcepacks/legacy_console/assets/controlify/contextual/guide/in_game.json rename src/test/java/dev/isxander/controlify/{ => impl}/config/ConfigMigrationTestHelper.java (95%) rename src/test/java/dev/isxander/controlify/{ => impl}/contextual/FactDependencyGraphTest.java (98%) diff --git a/src/fabric/java/dev/isxander/controlify/fabric/ControlifyBootstrap.java b/src/fabric/java/dev/isxander/controlify/fabric/ControlifyBootstrap.java index 896effd42..e719426ad 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/ControlifyBootstrap.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/ControlifyBootstrap.java @@ -6,12 +6,12 @@ */ package dev.isxander.controlify.fabric; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import dev.isxander.controlify.fabric.platform.client.FabricPlatformClientImpl; import dev.isxander.controlify.fabric.platform.FabricPlatformMainImpl; -import dev.isxander.controlify.platform.client.PlatformClientUtil; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.server.ControlifyServer; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.server.ControlifyServer; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.DedicatedServerModInitializer; import net.fabricmc.api.ModInitializer; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/compatibility/FabricCompatMixinPlatform.java b/src/fabric/java/dev/isxander/controlify/fabric/compatibility/FabricCompatMixinPlatform.java index 9a7096abf..b025c8736 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/compatibility/FabricCompatMixinPlatform.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/compatibility/FabricCompatMixinPlatform.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.fabric.compatibility; -import dev.isxander.controlify.compatibility.CompatMixinPlatform; +import dev.isxander.controlify.impl.compatibility.CompatMixinPlatform; import net.fabricmc.loader.api.FabricLoader; public final class FabricCompatMixinPlatform implements CompatMixinPlatform { diff --git a/src/fabric/java/dev/isxander/controlify/fabric/compatibility/ModMenuIntegration.java b/src/fabric/java/dev/isxander/controlify/fabric/compatibility/ModMenuIntegration.java index 634aba6e3..28cb8a801 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/compatibility/ModMenuIntegration.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/compatibility/ModMenuIntegration.java @@ -10,7 +10,7 @@ import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; -import dev.isxander.controlify.gui.screen.ControlifySettingsScreen; +import dev.isxander.controlify.impl.gui.screen.ControlifySettingsScreen; public class ModMenuIntegration implements ModMenuApi { @Override diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricBackedEventHandler.java b/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricBackedEventHandler.java index a90f48a7e..eeb2d14ad 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricBackedEventHandler.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricBackedEventHandler.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.fabric.platform; -import dev.isxander.controlify.platform.EventHandler; +import dev.isxander.controlify.impl.platform.EventHandler; import net.fabricmc.fabric.api.event.EventFactory; public class FabricBackedEventHandler implements EventHandler { diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricPlatformMainImpl.java b/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricPlatformMainImpl.java index 3b20c45cc..7f650640d 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricPlatformMainImpl.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricPlatformMainImpl.java @@ -6,16 +6,16 @@ */ package dev.isxander.controlify.fabric.platform; -import dev.isxander.controlify.api.entrypoint.ControlifyEntrypoint; +import dev.isxander.controlify.impl.api.entrypoint.ControlifyEntrypoint; import dev.isxander.controlify.fabric.platform.network.C2SNetworkApiFabric; import dev.isxander.controlify.fabric.platform.network.S2CNetworkApiFabric; -import dev.isxander.controlify.platform.Environment; -import dev.isxander.controlify.platform.main.PlatformMainUtilImpl; -import dev.isxander.controlify.platform.main.events.CommandRegistrationCallbackEvent; -import dev.isxander.controlify.platform.main.events.HandshakeCompletionEvent; -import dev.isxander.controlify.platform.main.events.PlayerJoinedEvent; -import dev.isxander.controlify.platform.network.C2SNetworkApi; -import dev.isxander.controlify.platform.network.S2CNetworkApi; +import dev.isxander.controlify.impl.platform.Environment; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtilImpl; +import dev.isxander.controlify.impl.platform.main.events.CommandRegistrationCallbackEvent; +import dev.isxander.controlify.impl.platform.main.events.HandshakeCompletionEvent; +import dev.isxander.controlify.impl.platform.main.events.PlayerJoinedEvent; +import dev.isxander.controlify.impl.platform.network.C2SNetworkApi; +import dev.isxander.controlify.impl.platform.network.S2CNetworkApi; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.networking.v1.FriendlyByteBufs; import net.fabricmc.fabric.api.networking.v1.ServerLoginConnectionEvents; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FAPIApiCreativeTabHelper.java b/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FAPIApiCreativeTabHelper.java index 498c09a5e..dfbc9e63c 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FAPIApiCreativeTabHelper.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FAPIApiCreativeTabHelper.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.fabric.platform.client; -import dev.isxander.controlify.platform.client.CreativeTabHelper; +import dev.isxander.controlify.impl.platform.client.CreativeTabHelper; import net.fabricmc.fabric.api.client.creativetab.v1.FabricCreativeModeInventoryScreen; import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; import net.minecraft.world.item.CreativeModeTab; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FabricPlatformClientImpl.java b/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FabricPlatformClientImpl.java index abe5b8a50..90971484d 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FabricPlatformClientImpl.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FabricPlatformClientImpl.java @@ -6,14 +6,14 @@ */ package dev.isxander.controlify.fabric.platform.client; -import dev.isxander.controlify.platform.client.CreativeTabHelper; -import dev.isxander.controlify.platform.client.HudRenderLayer; -import dev.isxander.controlify.platform.client.PlatformClientUtilImpl; -import dev.isxander.controlify.platform.client.events.DisconnectedEvent; -import dev.isxander.controlify.platform.client.events.LifecycleEvent; -import dev.isxander.controlify.platform.client.events.ScreenRenderEvent; -import dev.isxander.controlify.platform.client.events.TickEvent; -import dev.isxander.controlify.platform.client.resource.ControlifyReloadListener; +import dev.isxander.controlify.impl.platform.client.CreativeTabHelper; +import dev.isxander.controlify.impl.platform.client.HudRenderLayer; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtilImpl; +import dev.isxander.controlify.impl.platform.client.events.DisconnectedEvent; +import dev.isxander.controlify.impl.platform.client.events.LifecycleEvent; +import dev.isxander.controlify.impl.platform.client.events.ScreenRenderEvent; +import dev.isxander.controlify.impl.platform.client.events.TickEvent; +import dev.isxander.controlify.impl.platform.client.resource.ControlifyReloadListener; import dev.isxander.controlify.fabric.mixins.KeyBindingRegistryImplAccessor; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/C2SNetworkApiFabric.java b/src/fabric/java/dev/isxander/controlify/fabric/platform/network/C2SNetworkApiFabric.java index 9faf70398..6de311d99 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/C2SNetworkApiFabric.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/platform/network/C2SNetworkApiFabric.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.fabric.platform.network; -import dev.isxander.controlify.platform.network.C2SNetworkApi; +import dev.isxander.controlify.impl.platform.network.C2SNetworkApi; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/S2CNetworkApiFabric.java b/src/fabric/java/dev/isxander/controlify/fabric/platform/network/S2CNetworkApiFabric.java index 7c4f16cb9..cfa43b0fe 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/S2CNetworkApiFabric.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/platform/network/S2CNetworkApiFabric.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.fabric.platform.network; -import dev.isxander.controlify.platform.network.S2CNetworkApi; +import dev.isxander.controlify.impl.platform.network.S2CNetworkApi; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; diff --git a/src/gametest/java/dev/isxander/controlify/gametest/framework/CTestUtil.java b/src/gametest/java/dev/isxander/controlify/gametest/framework/CTestUtil.java index aacae76ae..2ef684ac9 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/framework/CTestUtil.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/framework/CTestUtil.java @@ -6,16 +6,9 @@ */ package dev.isxander.controlify.gametest.framework; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.config.settings.GlobalSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.gyro.GyroState; -import dev.isxander.controlify.controllermanager.ControllerManager; -import dev.isxander.controlify.gametest.mixin.ControlifySettingsAccessor; import dev.isxander.controlify.gametest.mixin.ToastInstanceAccessor; import dev.isxander.controlify.gametest.mixin.ToastManagerAccessor; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.fabricmc.fabric.api.client.gametest.v1.context.ClientGameTestContext; import net.fabricmc.fabric.api.resource.v1.ResourceLoader; import net.fabricmc.fabric.api.resource.v1.pack.PackActivationType; @@ -36,10 +29,8 @@ import net.minecraft.world.entity.EntityType; import org.jetbrains.annotations.Nullable; -import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; -import java.util.stream.Collectors; import java.util.stream.Stream; @SuppressWarnings("UnstableApiUsage") diff --git a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/ControlifyGameTestContext.java b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/ControlifyGameTestContext.java index d748d7e31..e9f14ca2b 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/ControlifyGameTestContext.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/ControlifyGameTestContext.java @@ -6,17 +6,18 @@ */ package dev.isxander.controlify.gametest.framework.controller; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; -import dev.isxander.controlify.config.settings.GlobalSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.gyro.GyroState; -import dev.isxander.controlify.controllermanager.ControllerManager; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.InputMode; +import dev.isxander.controlify.impl.config.settings.GlobalSettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.gyro.GyroState; +import dev.isxander.controlify.impl.controllermanager.ControllerManager; import dev.isxander.controlify.gametest.mixin.ControlifySettingsAccessor; import dev.isxander.controlify.gametest.mixin.SDLControllerManagerAccessor; import dev.isxander.sdl.Sdl; import net.fabricmc.fabric.api.client.gametest.v1.context.ClientGameTestContext; +import org.joml.Vector3f; import java.util.List; import java.util.stream.Collectors; @@ -66,19 +67,19 @@ public void resetSettings() { .map(ControllerManager::getConnectedControllers) .orElseGet(List::of); var connectedUids = connectedControllers.stream() - .map(ControllerEntity::uid) + .map(ControllerImpl::uid) .collect(Collectors.toSet()); // Keep the existing objects for connected devices because input // components cache their DeviceSettings reference when attached. var deviceSettings = settingsAccessor.controlify_test$getDeviceSettings(); deviceSettings.keySet().retainAll(connectedUids); - for (ControllerEntity controller : connectedControllers) { + for (ControllerImpl controller : connectedControllers) { var device = settings.getOrCreateDeviceSettings(controller.uid()); device.name = controller.name(); device.lastSeen = System.currentTimeMillis(); - device.controllerType = controller.info().type().namespace(); - device.gyroCalibration.offset = new GyroState(); + device.controllerType = controller.info().type().id(); + device.gyroCalibration.offset = new Vector3f(); device.mapping = null; controller.setSettings(profileDefaults); diff --git a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/DualsenseEffectDriver.java b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/DualsenseEffectDriver.java index b50254d74..7101957e3 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/DualsenseEffectDriver.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/DualsenseEffectDriver.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.gametest.framework.controller; -import dev.isxander.controlify.driver.dualsense.DualsenseEffectsState; +import dev.isxander.controlify.impl.driver.dualsense.DualsenseEffectsState; import java.lang.foreign.MemorySegment; import java.nio.ByteBuffer; diff --git a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/TestControllerContext.java b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/TestControllerContext.java index b4a958cfe..df83e1073 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/TestControllerContext.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/TestControllerContext.java @@ -6,11 +6,11 @@ */ package dev.isxander.controlify.gametest.framework.controller; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controllermanager.SDLUniqueControllerID; -import dev.isxander.controlify.driver.sdl.SDLException; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controllermanager.SDLUniqueControllerID; +import dev.isxander.controlify.impl.driver.sdl.SDLException; +import dev.isxander.controlify.impl.utils.CUtil; import dev.isxander.sdl.Sdl; import dev.isxander.sdl.SdlGamepad; import dev.isxander.sdl.SdlJoystickHandle; @@ -45,7 +45,7 @@ public TestControllerContext( this.state = state; } - public ControllerEntity getControllerEntity() { + public ControllerImpl getControllerImpl() { return Controlify.instance().getControllerManager().orElseThrow() .getConnectedControllers().stream() .filter(c -> c.info().ucid().equals(new SDLUniqueControllerID(this.joystickId))) diff --git a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/VirtualControllerBuilder.java b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/VirtualControllerBuilder.java index c62a96d10..b5f2fb1e6 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/VirtualControllerBuilder.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/framework/controller/VirtualControllerBuilder.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.gametest.framework.controller; -import dev.isxander.controlify.driver.sdl.SDLException; +import dev.isxander.controlify.impl.driver.sdl.SDLException; import dev.isxander.controlify.test.framework.SdlVirtualJoystickDescBuilder; import dev.isxander.sdl.*; import net.fabricmc.fabric.api.client.gametest.v1.context.ClientGameTestContext; diff --git a/src/gametest/java/dev/isxander/controlify/gametest/mixin/ControlifySettingsAccessor.java b/src/gametest/java/dev/isxander/controlify/gametest/mixin/ControlifySettingsAccessor.java index 9b627f2ab..ed2a902c3 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/mixin/ControlifySettingsAccessor.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/mixin/ControlifySettingsAccessor.java @@ -6,10 +6,10 @@ */ package dev.isxander.controlify.gametest.mixin; -import dev.isxander.controlify.config.settings.ControlifySettings; -import dev.isxander.controlify.config.settings.GlobalSettings; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.config.settings.ControlifySettings; +import dev.isxander.controlify.impl.config.settings.GlobalSettings; +import dev.isxander.controlify.impl.config.settings.device.DeviceSettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; diff --git a/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerAccessor.java b/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerAccessor.java index bd8a23aa6..0451fdda8 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerAccessor.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerAccessor.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.gametest.mixin; -import dev.isxander.controlify.controllermanager.SDLControllerManager; +import dev.isxander.controlify.impl.controllermanager.SDLControllerManager; import dev.isxander.sdl.Sdl; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; diff --git a/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerMixin.java b/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerMixin.java index e06af92b4..461803a2c 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerMixin.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/mixin/SDLControllerManagerMixin.java @@ -8,12 +8,12 @@ import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controllermanager.SDLControllerManager; -import dev.isxander.controlify.controllermanager.SDLUniqueControllerID; -import dev.isxander.controlify.controllermanager.UniqueControllerID; -import dev.isxander.controlify.hid.ControllerHIDInfo; -import dev.isxander.controlify.utils.log.ControlifyLogger; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controllermanager.SDLControllerManager; +import dev.isxander.controlify.impl.controllermanager.SDLUniqueControllerID; +import dev.isxander.controlify.impl.controllermanager.UniqueControllerID; +import dev.isxander.controlify.impl.hid.ControllerHIDInfo; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; import dev.isxander.sdl.Sdl; import dev.isxander.sdl.SdlJoystickId; import org.spongepowered.asm.mixin.Final; @@ -30,11 +30,11 @@ public class SDLControllerManagerMixin { /// Only load virtual joysticks in test environments @WrapMethod(method = "createController") - private Optional preventNonVirtual( + private Optional preventNonVirtual( UniqueControllerID ucid, ControllerHIDInfo hidInfo, ControlifyLogger controllerLogger, - Operation> original + Operation> original ) { SdlJoystickId jid = ((SDLUniqueControllerID) ucid).jid(); diff --git a/src/gametest/java/dev/isxander/controlify/gametest/tests/AdaptiveTriggerTests.java b/src/gametest/java/dev/isxander/controlify/gametest/tests/AdaptiveTriggerTests.java index 6d1bbbb1e..c7de9a886 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/tests/AdaptiveTriggerTests.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/tests/AdaptiveTriggerTests.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.gametest.tests; -import dev.isxander.controlify.driver.dualsense.DualsenseEffectsState; -import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; +import dev.isxander.controlify.impl.driver.dualsense.DualsenseEffectsState; +import dev.isxander.controlify.impl.driver.dualsense.DualsenseTriggerEffect; import dev.isxander.controlify.gametest.framework.CTestUtil; import dev.isxander.controlify.gametest.framework.controller.ControlifyGameTestContext; import dev.isxander.controlify.gametest.framework.controller.DualsenseEffectDriver; @@ -64,7 +64,7 @@ public void runTest(ClientGameTestContext context) { testTriggerEffectsDisabled(context, controller); - controller.getControllerEntity().settings().dualsense.triggerEffects = true; + controller.getControllerImpl().settings().dualsense.triggerEffects = true; context.waitTick(); @@ -76,7 +76,7 @@ public void runTest(ClientGameTestContext context) { testResourcePackPriority(context, world, controller); testServerTagRule(context, world, controller); - controller.getControllerEntity().settings().dualsense.triggerEffects = false; + controller.getControllerImpl().settings().dualsense.triggerEffects = false; context.waitTick(); waitForEffects(context, controller, new DualsenseEffectsState()); } @@ -91,7 +91,7 @@ private static void testTriggerEffectsDisabled( ClientGameTestContext context, TestControllerContext controller ) { - controller.getControllerEntity().settings().dualsense.triggerEffects = false; + controller.getControllerImpl().settings().dualsense.triggerEffects = false; context.waitTick(); waitForEffects(context, controller, new DualsenseEffectsState()); } diff --git a/src/gametest/java/dev/isxander/controlify/gametest/tests/ButtonGuideTests.java b/src/gametest/java/dev/isxander/controlify/gametest/tests/ButtonGuideTests.java index 8dbdbf306..04b87b985 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/tests/ButtonGuideTests.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/tests/ButtonGuideTests.java @@ -7,14 +7,14 @@ package dev.isxander.controlify.gametest.tests; import dev.isxander.controlify.api.contextual.InGameContext; -import dev.isxander.controlify.api.contextual.GuideLocation; -import dev.isxander.controlify.contextual.*; +import dev.isxander.controlify.impl.contextual.GuideLocation; +import dev.isxander.controlify.impl.contextual.*; import dev.isxander.controlify.gametest.framework.CEntityTypes; import dev.isxander.controlify.gametest.framework.CTestUtil; import dev.isxander.controlify.gametest.framework.TestUnitWorldContext; import dev.isxander.controlify.gametest.framework.controller.ControlifyGameTestContext; -import dev.isxander.controlify.gui.guide.GuideInstanceImpl; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.gui.guide.GuideInstanceImpl; +import dev.isxander.controlify.impl.utils.CUtil; import net.fabricmc.fabric.api.client.gametest.v1.FabricClientGameTest; import net.fabricmc.fabric.api.client.gametest.v1.context.ClientGameTestContext; import net.minecraft.commands.arguments.EntityAnchorArgument; @@ -52,7 +52,7 @@ public void runTest(ClientGameTestContext context) { .orElseThrow(); assertRuleLocation(ruleEngine, "inventory", GuideLocation.LEFT); assertRuleLocation(ruleEngine, "radial_menu", GuideLocation.LEFT); - var inGameContext = InGameContext.create(minecraft, controller.getControllerEntity()); + var inGameContext = InGameContext.create(minecraft, controller.getControllerImpl()); var state = domain.calculateState(inGameContext, ruleEngine.factDependencies()); assertFact(state, "looking_at_entity"); assertFact(state, "looking_at_merchant"); diff --git a/src/gametest/java/dev/isxander/controlify/gametest/tests/KeyboardLayoutTests.java b/src/gametest/java/dev/isxander/controlify/gametest/tests/KeyboardLayoutTests.java index 3754daea7..623dda7ee 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/tests/KeyboardLayoutTests.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/tests/KeyboardLayoutTests.java @@ -8,8 +8,8 @@ import dev.isxander.controlify.gametest.framework.CTestUtil; import dev.isxander.controlify.gametest.framework.controller.ControlifyGameTestContext; -import dev.isxander.controlify.screenop.keyboard.KeyboardWidget; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardWidget; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import dev.isxander.sdl.SdlGamepad; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.gametest.v1.FabricClientGameTest; diff --git a/src/gametest/java/dev/isxander/controlify/gametest/tests/ManyHotplugTests.java b/src/gametest/java/dev/isxander/controlify/gametest/tests/ManyHotplugTests.java index f640319b7..d63eaa856 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/tests/ManyHotplugTests.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/tests/ManyHotplugTests.java @@ -29,7 +29,7 @@ public void runTest(ClientGameTestContext context) { context.waitTicks(3); // finds within ControllerManager if it exists - controller.getControllerEntity(); + controller.getControllerImpl(); } CTestUtil.clearToasts(context); } diff --git a/src/gametest/java/dev/isxander/controlify/gametest/tests/RecipeBookNavigationTests.java b/src/gametest/java/dev/isxander/controlify/gametest/tests/RecipeBookNavigationTests.java index 4cc635bef..df6b882fc 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/tests/RecipeBookNavigationTests.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/tests/RecipeBookNavigationTests.java @@ -6,14 +6,14 @@ */ package dev.isxander.controlify.gametest.tests; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.InputMode; import dev.isxander.controlify.gametest.framework.TestUnitWorldContext; import dev.isxander.controlify.gametest.framework.controller.ControlifyGameTestContext; import dev.isxander.controlify.gametest.mixin.RecipeBookPageAccessor; import dev.isxander.controlify.mixins.feature.virtualmouse.snapping.RecipeBookComponentAccessor; -import dev.isxander.controlify.screenop.compat.vanilla.RecipeBookScreenProcessor; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.screenop.compat.vanilla.RecipeBookScreenProcessor; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import dev.isxander.sdl.SdlGamepad; import net.fabricmc.fabric.api.client.gametest.v1.FabricClientGameTest; import net.fabricmc.fabric.api.client.gametest.v1.context.ClientGameTestContext; @@ -46,7 +46,7 @@ public void runTest(ClientGameTestContext context) { context.runOnClient(client -> { client.player.getRecipeBook().setOpen(RecipeBookType.CRAFTING, true); client.player.getRecipeBook().setFiltering(RecipeBookType.CRAFTING, false); - Controlify.instance().setCurrentController(controller.getControllerEntity(), true); + Controlify.instance().setCurrentController(controller.getControllerImpl(), true); Controlify.instance().setInputMode(InputMode.CONTROLLER); }); region.runOnServer((level, player) -> { diff --git a/src/gametest/java/dev/isxander/controlify/gametest/tests/ResetControlifySettingsTests.java b/src/gametest/java/dev/isxander/controlify/gametest/tests/ResetControlifySettingsTests.java index b5628ff39..e420f23dc 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/tests/ResetControlifySettingsTests.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/tests/ResetControlifySettingsTests.java @@ -6,12 +6,12 @@ */ package dev.isxander.controlify.gametest.tests; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.gyro.GyroState; -import dev.isxander.controlify.gametest.framework.CTestUtil; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.gyro.GyroState; import dev.isxander.controlify.gametest.framework.controller.ControlifyGameTestContext; import net.fabricmc.fabric.api.client.gametest.v1.FabricClientGameTest; import net.fabricmc.fabric.api.client.gametest.v1.context.ClientGameTestContext; +import org.joml.Vector3f; /// Ensures that {@link ControlifyGameTestContext#resetSettings()} /// works appropriately, not leaving behind any stale references. @@ -25,11 +25,11 @@ public void runTest(ClientGameTestContext context) { .withXbox() .attach()) { var controlify = Controlify.instance(); - var controllerEntity = controller.getControllerEntity(); + var ControllerImpl = controller.getControllerImpl(); var settings = controlify.config().getSettings(); - var cachedDeviceSettings = settings.getOrCreateDeviceSettings(controllerEntity.uid()); + var cachedDeviceSettings = settings.getOrCreateDeviceSettings(ControllerImpl.uid()); - cachedDeviceSettings.gyroCalibration.offset = new GyroState(1f, 2f, 3f); + cachedDeviceSettings.gyroCalibration.offset = new Vector3f(1f, 2f, 3f); settings.globalSettings().mixedInput = true; controlifyContext.resetSettings(); @@ -37,13 +37,13 @@ public void runTest(ClientGameTestContext context) { if (settings.globalSettings().mixedInput) { throw new AssertionError("Global settings were not reset"); } - if (cachedDeviceSettings != settings.getOrCreateDeviceSettings(controllerEntity.uid())) { + if (cachedDeviceSettings != settings.getOrCreateDeviceSettings(ControllerImpl.uid())) { throw new AssertionError("Connected controller device settings reference was replaced"); } if (!cachedDeviceSettings.gyroCalibration.offset.equals(new GyroState())) { throw new AssertionError("Device settings were not reset"); } - if (controllerEntity.settings() != controlify.config().getActiveProfile()) { + if (ControllerImpl.settings() != controlify.config().getActiveProfile()) { throw new AssertionError("Controller was not rebound to the default active profile"); } } diff --git a/src/gametest/java/dev/isxander/controlify/gametest/tests/ServerPolicyTests.java b/src/gametest/java/dev/isxander/controlify/gametest/tests/ServerPolicyTests.java index 231263390..05fd3785b 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/tests/ServerPolicyTests.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/tests/ServerPolicyTests.java @@ -6,12 +6,11 @@ */ package dev.isxander.controlify.gametest.tests; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import dev.isxander.controlify.gametest.framework.CTestUtil; import dev.isxander.controlify.gametest.framework.controller.ControlifyGameTestContext; -import dev.isxander.controlify.server.ControlifyServer; -import dev.isxander.controlify.server.ControlifyServerConfig; -import dev.isxander.controlify.server.ServerPolicies; +import dev.isxander.controlify.impl.server.ControlifyServer; +import dev.isxander.controlify.impl.server.ControlifyServerConfig; import net.fabricmc.fabric.api.client.gametest.v1.FabricClientGameTest; import net.fabricmc.fabric.api.client.gametest.v1.context.ClientGameTestContext; import net.minecraft.server.MinecraftServer; diff --git a/src/gametest/java/dev/isxander/controlify/gametest/tests/VirtualControllerInputTests.java b/src/gametest/java/dev/isxander/controlify/gametest/tests/VirtualControllerInputTests.java index d66c54502..b6dcfde3d 100644 --- a/src/gametest/java/dev/isxander/controlify/gametest/tests/VirtualControllerInputTests.java +++ b/src/gametest/java/dev/isxander/controlify/gametest/tests/VirtualControllerInputTests.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.gametest.tests; -import dev.isxander.controlify.input.mapping.GamepadInputs; -import dev.isxander.controlify.controller.input.InputComponent; +import dev.isxander.controlify.impl.input.mapping.GamepadInputs; +import dev.isxander.controlify.impl.controller.input.InputComponent; import dev.isxander.controlify.gametest.framework.CTestUtil; import dev.isxander.controlify.gametest.framework.controller.ControlifyGameTestContext; import dev.isxander.controlify.gametest.framework.controller.TestControllerContext; @@ -21,8 +21,8 @@ //? if >=26.3 { import com.mojang.blaze3d.platform.SDLEventHandler; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.InputMode; import dev.isxander.controlify.gametest.mixin.SDLEventHandlerAccessor; import org.lwjgl.sdl.SDL_Event; //?} @@ -58,8 +58,8 @@ public void runTest(ClientGameTestContext context) { try (var controller = controlify.virtualControllerBuilder() .withXbox() .attach()) { - var controllerEntity = controller.getControllerEntity(); - var input = controllerEntity.input().orElseThrow(); + var ControllerImpl = controller.getControllerImpl(); + var input = ControllerImpl.input().orElseThrow(); // Fabric cancels real mouse input during tests. Controlify must not // change input mode before that cancellation takes effect. diff --git a/src/main/java/dev/isxander/controlify/action/ActionSpecRegistry.java b/src/main/java/dev/isxander/controlify/action/ActionSpecRegistry.java deleted file mode 100644 index 1fc2a2ca5..000000000 --- a/src/main/java/dev/isxander/controlify/action/ActionSpecRegistry.java +++ /dev/null @@ -1,5 +0,0 @@ -package dev.isxander.controlify.action; - -public interface ActionSpecRegistry { - ActionAccessor register(ActionSpec actionSpec); -} diff --git a/src/main/java/dev/isxander/controlify/action/activator/NoopActivator.java b/src/main/java/dev/isxander/controlify/action/activator/NoopActivator.java deleted file mode 100644 index d4d4e3632..000000000 --- a/src/main/java/dev/isxander/controlify/action/activator/NoopActivator.java +++ /dev/null @@ -1,23 +0,0 @@ -package dev.isxander.controlify.action.activator; - -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; - -public class NoopActivator implements Activator { - @Override - public void onSignal(LogicalSignal signal, Accumulator acc) { - - } - - @Override - public LogicalInput boundInput() { - return null; - } - - @Override - public String describe() { - return "Noop"; - } -} diff --git a/src/main/java/dev/isxander/controlify/api/ControlifyApi.java b/src/main/java/dev/isxander/controlify/api/ControlifyApi.java index 0a169145f..260cc610e 100644 --- a/src/main/java/dev/isxander/controlify/api/ControlifyApi.java +++ b/src/main/java/dev/isxander/controlify/api/ControlifyApi.java @@ -6,12 +6,11 @@ */ package dev.isxander.controlify.api; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.rumble.RumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import org.jetbrains.annotations.NotNull; +import dev.isxander.controlify.api.controller.Controller; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; +import net.minecraft.resources.Identifier; import java.util.Optional; @@ -28,20 +27,20 @@ public interface ControlifyApi { /** * The controller that is currently enabled and in use. * If there is no controller disconnected or disabled, this will return {@link Optional#empty()}. - * This is the controller that is used for {@link dev.isxander.controlify.api.event.ControlifyEvents#ACTIVE_CONTROLLER_TICKED} + * This is the controller that is used for {@link ControlifyEvents#ACTIVE_CONTROLLER_TICKED} */ - @NotNull Optional getCurrentController(); + Optional getCurrentController(); /** * The last input received: a controller or keyboard/mouse. */ - @NotNull InputMode currentInputMode(); - boolean setInputMode(@NotNull InputMode mode); + InputMode currentInputMode(); + boolean setInputMode(InputMode mode); - default void playRumbleEffect(@NotNull RumbleSource rumbleSource, @NotNull RumbleEffect rumbleEffect) { - getCurrentController() - .flatMap(ControllerEntity::rumble) - .ifPresent(r -> r.rumbleManager().play(rumbleSource, rumbleEffect)); + default Optional playRumbleEffect(Identifier effectId, RumbleEffect rumbleEffect) { + return getCurrentController() + .flatMap(Controller::rumble) + .map(r -> r.playEffect(effectId, rumbleEffect)); } static ControlifyApi get() { diff --git a/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java b/src/main/java/dev/isxander/controlify/api/ControlifyEvents.java similarity index 79% rename from src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java rename to src/main/java/dev/isxander/controlify/api/ControlifyEvents.java index 34c721b70..87b980f47 100644 --- a/src/main/java/dev/isxander/controlify/api/event/ControlifyEvents.java +++ b/src/main/java/dev/isxander/controlify/api/ControlifyEvents.java @@ -4,12 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.event; +package dev.isxander.controlify.api; -import dev.isxander.controlify.InputMode; -import dev.isxander.controlify.api.ingameinput.LookInputModifier; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.platform.EventHandler; +import dev.isxander.controlify.impl.api.ingameinput.LookInputModifier; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.platform.EventHandler; import org.jetbrains.annotations.Nullable; public final class ControlifyEvents { @@ -55,19 +54,19 @@ public final class ControlifyEvents { */ public static final EventHandler LOOK_INPUT_MODIFIER = EventHandler.createPlatformBackedEvent(); - public record ControllerConnected(ControllerEntity controller, boolean hotplugged) { + public record ControllerConnected(ControllerImpl controller, boolean hotplugged) { } - public record ControllerDisconnected(ControllerEntity controller) { + public record ControllerDisconnected(ControllerImpl controller) { } - public record CurrentControllerChanged(@Nullable ControllerEntity controller, boolean changeInputMode) { + public record CurrentControllerChanged(@Nullable ControllerImpl controller, boolean changeInputMode) { } public record InputModeChanged(InputMode mode) { } - public record ControllerStateUpdate(ControllerEntity controller) { + public record ControllerStateUpdate(ControllerImpl controller) { } public record VirtualMouseToggled(boolean enabled) { diff --git a/src/main/java/dev/isxander/controlify/InputMode.java b/src/main/java/dev/isxander/controlify/api/InputMode.java similarity index 89% rename from src/main/java/dev/isxander/controlify/InputMode.java rename to src/main/java/dev/isxander/controlify/api/InputMode.java index 3bedace21..fb6162b8e 100644 --- a/src/main/java/dev/isxander/controlify/InputMode.java +++ b/src/main/java/dev/isxander/controlify/api/InputMode.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify; +package dev.isxander.controlify.api; public enum InputMode { KEYBOARD_MOUSE, diff --git a/src/main/java/dev/isxander/controlify/action/Action.java b/src/main/java/dev/isxander/controlify/api/action/Action.java similarity index 65% rename from src/main/java/dev/isxander/controlify/action/Action.java rename to src/main/java/dev/isxander/controlify/api/action/Action.java index 39de6c9fe..05046ecd4 100644 --- a/src/main/java/dev/isxander/controlify/action/Action.java +++ b/src/main/java/dev/isxander/controlify/api/action/Action.java @@ -1,6 +1,6 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.api.action; -import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.api.input.LogicalInput; import org.jspecify.annotations.Nullable; /// An action is bound to a logical input and has one or more activators @@ -12,9 +12,12 @@ public interface Action { Channel.Latch latch(); Channel.Continuous continuous(); + /// When set to null, it is unbound. void setBoundInput(@Nullable LogicalInput input); + /// When set to null, it is currently unbound. @Nullable LogicalInput boundInput(); + /// When set to null, it is by default unbound. @Nullable LogicalInput defaultInput(); } diff --git a/src/main/java/dev/isxander/controlify/action/ActionSpec.java b/src/main/java/dev/isxander/controlify/api/action/ActionSpec.java similarity index 76% rename from src/main/java/dev/isxander/controlify/action/ActionSpec.java rename to src/main/java/dev/isxander/controlify/api/action/ActionSpec.java index c39361cb5..2d08312f6 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionSpec.java +++ b/src/main/java/dev/isxander/controlify/api/action/ActionSpec.java @@ -1,9 +1,10 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.api.action; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.action.ActionSpecBuilder; +import dev.isxander.controlify.impl.action.ActionSpecBuilderImpl; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; -import org.jspecify.annotations.NonNull; import java.util.Comparator; import java.util.Set; @@ -23,10 +24,10 @@ public record ActionSpec( Component description, Component category, Set contexts, - Predicate shouldExpose + Predicate shouldExpose ) implements Comparable { @Override - public int compareTo(@NonNull ActionSpec o) { + public int compareTo(ActionSpec o) { return Comparator.comparing(ActionSpec::id) .compare(this, o); } diff --git a/src/main/java/dev/isxander/controlify/action/Channel.java b/src/main/java/dev/isxander/controlify/api/action/Channel.java similarity index 94% rename from src/main/java/dev/isxander/controlify/action/Channel.java rename to src/main/java/dev/isxander/controlify/api/action/Channel.java index dfa89cfbc..120106d3f 100644 --- a/src/main/java/dev/isxander/controlify/action/Channel.java +++ b/src/main/java/dev/isxander/controlify/api/action/Channel.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.api.action; /// A channel is a way of interpreting the output state of a given {@link Action}. /// An {@link Action action's} bindings sends output to any of these channels. diff --git a/src/main/java/dev/isxander/controlify/api/action/package-info.java b/src/main/java/dev/isxander/controlify/api/action/package-info.java new file mode 100644 index 000000000..cbccfc406 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/action/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package dev.isxander.controlify.api.action; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/dev/isxander/controlify/api/contextual/ContainerContext.java b/src/main/java/dev/isxander/controlify/api/contextual/ContainerContext.java index 7f6aba855..a997271b9 100644 --- a/src/main/java/dev/isxander/controlify/api/contextual/ContainerContext.java +++ b/src/main/java/dev/isxander/controlify/api/contextual/ContainerContext.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.api.contextual; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; @@ -17,7 +17,7 @@ public record ContainerContext( @Nullable Slot hoveredSlot, ItemStack holdingItem, boolean cursorOutsideContainer, - ControllerEntity controller, + ControllerImpl controller, GuideVerbosity verbosity ) implements Context { } diff --git a/src/main/java/dev/isxander/controlify/api/contextual/Context.java b/src/main/java/dev/isxander/controlify/api/contextual/Context.java index e77d7598f..c25b54667 100644 --- a/src/main/java/dev/isxander/controlify/api/contextual/Context.java +++ b/src/main/java/dev/isxander/controlify/api/contextual/Context.java @@ -6,10 +6,10 @@ */ package dev.isxander.controlify.api.contextual; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.api.controller.Controller; public interface Context { - ControllerEntity controller(); + Controller controller(); GuideVerbosity verbosity(); } diff --git a/src/main/java/dev/isxander/controlify/api/contextual/ContextualStateContributor.java b/src/main/java/dev/isxander/controlify/api/contextual/ContextualStateContributor.java index 5b0df668b..6ef0b994a 100644 --- a/src/main/java/dev/isxander/controlify/api/contextual/ContextualStateContributor.java +++ b/src/main/java/dev/isxander/controlify/api/contextual/ContextualStateContributor.java @@ -14,7 +14,7 @@ default ContextualStateContributor andThen(ContextualStateContributor ContextualStateContributor noop() { - return (context, sink) -> {}; + return (_, _) -> {}; } @SafeVarargs diff --git a/src/main/java/dev/isxander/controlify/api/contextual/InGameContext.java b/src/main/java/dev/isxander/controlify/api/contextual/InGameContext.java index bfcf9a0d4..e809c7692 100644 --- a/src/main/java/dev/isxander/controlify/api/contextual/InGameContext.java +++ b/src/main/java/dev/isxander/controlify/api/contextual/InGameContext.java @@ -6,7 +6,8 @@ */ package dev.isxander.controlify.api.contextual; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.api.controller.Controller; +import dev.isxander.controlify.impl.controller.ControllerImpl; import dev.isxander.controlify.mixins.feature.guide.ingame.MinecraftAccessor; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; @@ -21,11 +22,11 @@ public record InGameContext( LocalPlayer player, ClientLevel level, HitResult hitResult, - ControllerEntity controller, + Controller controller, GuideVerbosity verbosity ) implements Context { @ApiStatus.Internal - public static InGameContext create(Minecraft minecraft, ControllerEntity controller) { + public static InGameContext create(Minecraft minecraft, Controller controller) { var hitResult = minecraft.hitResult; if (hitResult == null) { ((MinecraftAccessor) minecraft).controlify$invokePick(1f); @@ -38,7 +39,7 @@ public static InGameContext create(Minecraft minecraft, ControllerEntity control Objects.requireNonNull(minecraft.level, "level"), hitResult, controller, - controller.settings().generic.guide.verbosity + ((ControllerImpl) controller).settings().generic.guide.verbosity ); } } diff --git a/src/main/java/dev/isxander/controlify/api/contextual/TriggerEffectInstance.java b/src/main/java/dev/isxander/controlify/api/contextual/TriggerEffectInstance.java index 52551b404..673af410d 100644 --- a/src/main/java/dev/isxander/controlify/api/contextual/TriggerEffectInstance.java +++ b/src/main/java/dev/isxander/controlify/api/contextual/TriggerEffectInstance.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.api.contextual; -import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; +import dev.isxander.controlify.impl.driver.dualsense.DualsenseTriggerEffect; import org.jetbrains.annotations.ApiStatus; public interface TriggerEffectInstance extends ContextualInstance { diff --git a/src/main/java/dev/isxander/controlify/api/contextual/package-info.java b/src/main/java/dev/isxander/controlify/api/contextual/package-info.java new file mode 100644 index 000000000..ea2ec8aa8 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/contextual/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package dev.isxander.controlify.api.contextual; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/dev/isxander/controlify/api/controller/Controller.java b/src/main/java/dev/isxander/controlify/api/controller/Controller.java new file mode 100644 index 000000000..734b6b287 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/controller/Controller.java @@ -0,0 +1,40 @@ +package dev.isxander.controlify.api.controller; + +import dev.isxander.controlify.api.controller.rumble.RumbleComponent; +import net.minecraft.resources.Identifier; + +import java.util.Optional; + +/// The API-safe controller instance. +public interface Controller { + /// The unique identifier of this controller. + /// The same physical controller should have the same + /// identifier after being unplugged and replugged. + String uid(); + + /// The friendly name of this controller. + /// + /// This may use {@link driverReportedName}, but the + /// controller's type may override it, or the user may override + /// it. + /// + /// Because the user may override this, it is not a + /// guarantee that this name is constant for the lifetime + /// of this controller object. + String name(); + + /// The friendly name of this controller reported by + /// the underlying controller driver. + /// + /// To get the display name of this controller, you + /// should use {@link name}. + String driverReportedName(); + + /// The identifier of this controller's type. + /// This is the same ID defined by `controller_identification.json5`. + Identifier typeId(); + + /// Get the rumble component that may be attached to this controller. + /// If the returned optional is empty, then the controller is not capable of rumble. + Optional rumble(); +} diff --git a/src/main/java/dev/isxander/controlify/api/controller/package-info.java b/src/main/java/dev/isxander/controlify/api/controller/package-info.java new file mode 100644 index 000000000..a6310cc72 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/controller/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package dev.isxander.controlify.api.controller; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/dev/isxander/controlify/api/controller/rumble/ContinuousRumbleEffect.java b/src/main/java/dev/isxander/controlify/api/controller/rumble/ContinuousRumbleEffect.java new file mode 100644 index 000000000..71a6e0972 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/controller/rumble/ContinuousRumbleEffect.java @@ -0,0 +1,34 @@ +package dev.isxander.controlify.api.controller.rumble; + +import net.minecraft.world.phys.Vec3; +import java.util.function.BooleanSupplier; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.Supplier; + +/// An immutable effect definition with independent timing for every playback. +public non-sealed interface ContinuousRumbleEffect extends RumbleEffect { + @Override ContinuousRumbleEffect stopCondition(BooleanSupplier condition); + + ContinuousRumbleEffect byTick(IntFunction state); + + ContinuousRumbleEffect constant(float strong, float weak); + + /// Sets the inactivity timeout. Zero disables it; keepAlive resets its clock. + ContinuousRumbleEffect timeout(int ticks); + int timeoutTicks(); + + /// Sets the minimum duration before timeout or a stop condition can finish playback. + /// Explicitly stopping the playback handle always takes effect immediately. + ContinuousRumbleEffect minTime(int ticks); + int minimumTicks(); + + /// Applies distance attenuation relative to the camera, using squared distance / range². + /// Playback ends when no camera is available (subject to the minimum duration). + ContinuousRumbleEffect inWorld( + Supplier location, + float minMagnitude, float maxMagnitude, + float range, + Function falloff + ); +} diff --git a/src/main/java/dev/isxander/controlify/api/controller/rumble/FiniteRumbleEffect.java b/src/main/java/dev/isxander/controlify/api/controller/rumble/FiniteRumbleEffect.java new file mode 100644 index 000000000..11a2b75a4 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/controller/rumble/FiniteRumbleEffect.java @@ -0,0 +1,27 @@ +package dev.isxander.controlify.api.controller.rumble; + +import java.util.Objects; +import java.util.function.BooleanSupplier; +import java.util.function.Function; +import java.util.function.IntFunction; + +/// An immutable, finite effect definition. Each configuration method returns a copy. +public non-sealed interface FiniteRumbleEffect extends RumbleEffect { + @Override + FiniteRumbleEffect stopCondition(BooleanSupplier condition); + + int durationTicks(); + + /// Replaces the waveform with one sample for each zero-based tick. + FiniteRumbleEffect byTick(IntFunction state, int durationTicks); + + /// Replaces the waveform, sampling time in [0, 1), as tick / duration. + FiniteRumbleEffect byTime(Function state, int durationTicks); + + FiniteRumbleEffect constant(float strong, float weak, int durationTicks); + + /// Appends another waveform, retaining this effect's stop conditions. + FiniteRumbleEffect then(FiniteRumbleEffect next); + + FiniteRumbleEffect repeat(int count); +} diff --git a/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleComponent.java b/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleComponent.java new file mode 100644 index 000000000..11a514bb9 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleComponent.java @@ -0,0 +1,11 @@ +package dev.isxander.controlify.api.controller.rumble; + +import net.minecraft.resources.Identifier; + +public interface RumbleComponent { + /// Queues independent playback of a reusable effect definition for the next rumble tick. + /// Stopping the returned handle affects only this playback. + /// The effect ID identifies the event causing the rumble, allowing resource packs + /// to assign its rumble source independently of the waveform. + RumbleEffectInstance playEffect(Identifier effectId, RumbleEffect effect); +} diff --git a/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleEffect.java b/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleEffect.java new file mode 100644 index 000000000..1b71b55a1 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleEffect.java @@ -0,0 +1,28 @@ +package dev.isxander.controlify.api.controller.rumble; + +import dev.isxander.controlify.impl.controller.rumble.FiniteRumbleEffectImpl; +import dev.isxander.controlify.impl.controller.rumble.ContinuousRumbleEffectImpl; + +import java.util.function.BooleanSupplier; + +/// A reusable effect definition. Configuration methods return new definitions; +/// playback state is held by the instance returned from RumbleComponent.playEffect. +/// Callbacks may be shared by multiple playbacks and are invoked on the client thread. +public sealed interface RumbleEffect permits FiniteRumbleEffect, ContinuousRumbleEffect { + /// Samples this definition at a zero-based playback tick. + RumbleState stateAt(int tick); + + /// Returns whether playback should end before its next sample. + boolean shouldStop(); + + /// Returns a copy with an additional stop condition. Conditions are ORed. + RumbleEffect stopCondition(BooleanSupplier condition); + + static FiniteRumbleEffect finite() { + return new FiniteRumbleEffectImpl(); + } + + static ContinuousRumbleEffect continuous() { + return new ContinuousRumbleEffectImpl(); + } +} diff --git a/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleEffectInstance.java b/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleEffectInstance.java new file mode 100644 index 000000000..5a0a7f4cc --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleEffectInstance.java @@ -0,0 +1,26 @@ +package dev.isxander.controlify.api.controller.rumble; + +/// A handle on a specific instance of a queued, playing, or played rumble +/// effect. +public interface RumbleEffectInstance { + /// @return true if the queued rumble effect is playing, or has finished playing + boolean hasStarted(); + + /// @return true if queued rumble effect has finished playing. + boolean hasFinished(); + + /// Stops the effect before it has finished. + /// + /// @return true if the effect was stopped as a result of this method invocation. + boolean stop(); + + /// Resets the age of this effect instance. + /// Only applicable for continuous effects, it prevents + /// them from timing out. This should be called frequently in the + /// context that the effect should stay viable. + /// If the effect has already finished playing, the effect cannot be kept + /// alive as it is already dead. + /// + /// @return true if the effect was successfully kept alive + boolean keepAlive(); +} diff --git a/src/main/java/dev/isxander/controlify/rumble/RumbleState.java b/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleState.java similarity index 94% rename from src/main/java/dev/isxander/controlify/rumble/RumbleState.java rename to src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleState.java index a9e2d7672..8268caabc 100644 --- a/src/main/java/dev/isxander/controlify/rumble/RumbleState.java +++ b/src/main/java/dev/isxander/controlify/api/controller/rumble/RumbleState.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.rumble; +package dev.isxander.controlify.api.controller.rumble; import com.mojang.serialization.Codec; diff --git a/src/main/java/dev/isxander/controlify/rumble/TriggerRumbleState.java b/src/main/java/dev/isxander/controlify/api/controller/rumble/TriggerRumbleState.java similarity index 89% rename from src/main/java/dev/isxander/controlify/rumble/TriggerRumbleState.java rename to src/main/java/dev/isxander/controlify/api/controller/rumble/TriggerRumbleState.java index d09650f78..236db1ad5 100644 --- a/src/main/java/dev/isxander/controlify/rumble/TriggerRumbleState.java +++ b/src/main/java/dev/isxander/controlify/api/controller/rumble/TriggerRumbleState.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.rumble; +package dev.isxander.controlify.api.controller.rumble; public record TriggerRumbleState(float left, float right) { public static final TriggerRumbleState NONE = new TriggerRumbleState(0.0F, 0.0F); diff --git a/src/main/java/dev/isxander/controlify/api/controller/rumble/package-info.java b/src/main/java/dev/isxander/controlify/api/controller/rumble/package-info.java new file mode 100644 index 000000000..db9e76381 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/controller/rumble/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package dev.isxander.controlify.api.controller.rumble; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuideApi.java b/src/main/java/dev/isxander/controlify/api/gui/ButtonGuideApi.java similarity index 65% rename from src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuideApi.java rename to src/main/java/dev/isxander/controlify/api/gui/ButtonGuideApi.java index bf64bc3d3..22f299964 100644 --- a/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuideApi.java +++ b/src/main/java/dev/isxander/controlify/api/gui/ButtonGuideApi.java @@ -4,13 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.buttonguide; +package dev.isxander.controlify.api.gui; -import dev.isxander.controlify.action.ActionAccessor; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.gui.ButtonGuideRenderer; +import dev.isxander.controlify.impl.action.ActionAccessor; +import dev.isxander.controlify.impl.gui.ButtonGuideRenderer; import net.minecraft.client.gui.screens.Screen; -import org.jetbrains.annotations.NotNull; import java.util.function.Supplier; @@ -26,23 +24,23 @@ private 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. - * Custom behaviour should be handled inside a {@link dev.isxander.controlify.screenop.ScreenProcessor} or {@link dev.isxander.controlify.screenop.ComponentProcessor} + * Custom behaviour should be handled inside a {@link dev.isxander.controlify.impl.screenop.ScreenProcessor} or {@link dev.isxander.controlify.impl.screenop.ComponentProcessor} * * @param button button to render the guide for * @param action the action binding to render * @param renderPredicate whether the guide should be rendered */ public static void addGuideToButton( - @NotNull T button, - @NotNull ActionAccessor action, - @NotNull ButtonGuidePredicate renderPredicate) { + T button, + ActionAccessor action, + ButtonGuidePredicate renderPredicate) { ButtonGuideRenderer.registerBindingForButton(button, () -> action, renderPredicate); } public static void addGuideToButton( - @NotNull T button, - @NotNull Supplier action, - @NotNull ButtonGuidePredicate renderPredicate) { + T button, + Supplier action, + ButtonGuidePredicate renderPredicate) { ButtonGuideRenderer.registerBindingForButton(button, action, renderPredicate); } } diff --git a/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuidePredicate.java b/src/main/java/dev/isxander/controlify/api/gui/ButtonGuidePredicate.java similarity index 57% rename from src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuidePredicate.java rename to src/main/java/dev/isxander/controlify/api/gui/ButtonGuidePredicate.java index 7fcd6bf2e..4b18006ed 100644 --- a/src/main/java/dev/isxander/controlify/api/buttonguide/ButtonGuidePredicate.java +++ b/src/main/java/dev/isxander/controlify/api/gui/ButtonGuidePredicate.java @@ -4,9 +4,8 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.buttonguide; +package dev.isxander.controlify.api.gui; -import net.minecraft.client.gui.components.AbstractButton; import net.minecraft.client.gui.components.AbstractWidget; @FunctionalInterface @@ -21,12 +20,4 @@ static ButtonGuidePredicate focusOnly() { static ButtonGuidePredicate always() { return btn -> true; } - - /** Always display the button guide. */ - @Deprecated - ButtonGuidePredicate ALWAYS = btn -> true; - - /** Only display the button guide when the button is focused. */ - @Deprecated - ButtonGuidePredicate FOCUS_ONLY = AbstractWidget::isFocused; } diff --git a/src/main/java/dev/isxander/controlify/api/gui/package-info.java b/src/main/java/dev/isxander/controlify/api/gui/package-info.java new file mode 100644 index 000000000..a9610dd28 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/gui/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package dev.isxander.controlify.api.gui; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/dev/isxander/controlify/input/LogicalInput.java b/src/main/java/dev/isxander/controlify/api/input/LogicalInput.java similarity index 93% rename from src/main/java/dev/isxander/controlify/input/LogicalInput.java rename to src/main/java/dev/isxander/controlify/api/input/LogicalInput.java index bdc48e56a..da729428b 100644 --- a/src/main/java/dev/isxander/controlify/input/LogicalInput.java +++ b/src/main/java/dev/isxander/controlify/api/input/LogicalInput.java @@ -1,8 +1,8 @@ -package dev.isxander.controlify.input; +package dev.isxander.controlify.api.input; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.utils.codec.CExtraCodecs; +import dev.isxander.controlify.impl.utils.codec.CExtraCodecs; import net.minecraft.resources.Identifier; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/api/input/package-info.java b/src/main/java/dev/isxander/controlify/api/input/package-info.java new file mode 100644 index 000000000..efd120283 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/input/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package dev.isxander.controlify.api.input; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/dev/isxander/controlify/api/package-info.java b/src/main/java/dev/isxander/controlify/api/package-info.java new file mode 100644 index 000000000..1e9f2de6c --- /dev/null +++ b/src/main/java/dev/isxander/controlify/api/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package dev.isxander.controlify.api; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java b/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java deleted file mode 100644 index becb50736..000000000 --- a/src/main/java/dev/isxander/controlify/controller/ControllerEntity.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller; - -import dev.isxander.controlify.config.settings.profile.ProfileSettings; -import dev.isxander.controlify.controller.battery.BatteryLevelComponent; -import dev.isxander.controlify.controller.dualsense.DualsenseComponent; -import dev.isxander.controlify.controller.haptic.HDHapticComponent; -import dev.isxander.controlify.controller.info.ControllerInfo; -import dev.isxander.controlify.controller.info.DriverNameComponent; -import dev.isxander.controlify.controller.info.GUIDComponent; -import dev.isxander.controlify.controller.info.UIDComponent; -import dev.isxander.controlify.controller.led.LEDComponent; -import dev.isxander.controlify.controller.gyro.GyroComponent; -import dev.isxander.controlify.controller.impl.ECSEntityImpl; -import dev.isxander.controlify.controller.misc.BluetoothDeviceComponent; -import dev.isxander.controlify.controller.rumble.RumbleComponent; -import dev.isxander.controlify.controller.rumble.TriggerRumbleComponent; -import dev.isxander.controlify.controller.touchpad.TouchpadComponent; -import dev.isxander.controlify.driver.Driver; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.utils.log.ControlifyLogger; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; -import java.util.stream.Collectors; - -public class ControllerEntity extends ECSEntityImpl { - private final ControllerInfo info; - private final Driver driver; - private ProfileSettings settings; - private final ProfileSettings defaultSettings; - private final ControlifyLogger logger; - private boolean active; - - public ControllerEntity( - ControllerInfo info, - Driver driver, - ProfileSettings settings, - ProfileSettings defaultSettings, - ControlifyLogger logger - ) { - this.info = info; - this.driver = driver; - this.settings = settings; - this.defaultSettings = defaultSettings; - this.logger = logger; - - driver.addComponents(this); - this.getAllComponents().values().forEach(c -> c.attach(this)); - - logger.debugLog("Components: {}", this.getAllComponents().keySet().stream().map(Identifier::toString).collect(Collectors.joining(", "))); - } - - public String uid() { - return this.getComponent(UIDComponent.ID).orElseThrow().value(); - } - - @NotNull public String driverName() { - return this.getComponent(DriverNameComponent.ID).orElseThrow().value(); - } - - @NotNull public String guid() { - return this.getComponent(GUIDComponent.ID).orElseThrow().value(); - } - - public ControllerInfo info() { - return this.info; - } - - @NotNull public String name() { - String friendlyName = info().type().friendlyName(); - if (friendlyName != null) - return friendlyName; - - return driverName(); - } - - public Driver drivers() { - return driver; - } - - public ProfileSettings settings() { - return settings; - } - - public void setSettings(ProfileSettings settings) { - this.settings = settings; - } - - public ProfileSettings defaultSettings() { - return defaultSettings; - } - - @Contract(pure = true) - public Optional input() { - return this.getComponent(InputComponent.ID); - } - - @Contract(pure = true) - public Optional rumble() { - return this.getComponent(RumbleComponent.ID); - } - - @Contract(pure = true) - public Optional triggerRumble() { - return this.getComponent(TriggerRumbleComponent.ID); - } - - @Contract(pure = true) - public Optional gyro() { - return this.getComponent(GyroComponent.ID); - } - - @Contract(pure = true) - public Optional touchpad() { - return this.getComponent(TouchpadComponent.ID); - } - - @Contract(pure = true) - public Optional batteryLevel() { - return this.getComponent(BatteryLevelComponent.ID); - } - - @Contract(pure = true) - public Optional hdHaptics() { - return this.getComponent(HDHapticComponent.ID); - } - - @Contract(pure = true) - public Optional dualSense() { - return this.getComponent(DualsenseComponent.ID); - } - - @Contract(pure = true) - public Optional led() { - return this.getComponent(LEDComponent.ID); - } - - @Contract(pure = true) - public Optional bluetooth() { - return this.getComponent(BluetoothDeviceComponent.ID); - } - - public void update(boolean outOfFocus) { - this.driver.update(this, outOfFocus); - } - - public boolean isActive() { - return this.active; - } - - public void setActive(boolean active) { - if (this.active == active) { - return; - } - this.active = active; - this.driver.setActive(active); - } - - public void close() { - this.setActive(false); - this.getAllComponents().values().forEach(ECSComponent::close); - this.driver.close(); - } - - public ControlifyLogger getLogger() { - return logger; - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/ECSComponent.java b/src/main/java/dev/isxander/controlify/controller/ECSComponent.java deleted file mode 100644 index dd0ee1a4c..000000000 --- a/src/main/java/dev/isxander/controlify/controller/ECSComponent.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller; - -import net.minecraft.resources.Identifier; - -public interface ECSComponent { - Identifier id(); - - default void attach(ControllerEntity controller) { - - } - - default void close() { - - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/ECSEntity.java b/src/main/java/dev/isxander/controlify/controller/ECSEntity.java deleted file mode 100644 index e418b2487..000000000 --- a/src/main/java/dev/isxander/controlify/controller/ECSEntity.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller; - -import net.minecraft.resources.Identifier; - -import java.util.Map; -import java.util.Optional; - -public interface ECSEntity { - Map getAllComponents(); - - boolean setComponent(T component); - - boolean removeComponent(Identifier id); - - Optional getComponent(Identifier id); -} diff --git a/src/main/java/dev/isxander/controlify/controller/SingleValueComponent.java b/src/main/java/dev/isxander/controlify/controller/SingleValueComponent.java deleted file mode 100644 index 042da6abe..000000000 --- a/src/main/java/dev/isxander/controlify/controller/SingleValueComponent.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller; - -import net.minecraft.resources.Identifier; - -public class SingleValueComponent implements ECSComponent { - private final T value; - private final Identifier id; - - public SingleValueComponent(T value, Identifier id) { - this.value = value; - this.id = id; - } - - public T value() { - return this.value; - } - - @Override - public Identifier id() { - return this.id; - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/gyro/GyroState.java b/src/main/java/dev/isxander/controlify/controller/gyro/GyroState.java deleted file mode 100644 index 8d687dd04..000000000 --- a/src/main/java/dev/isxander/controlify/controller/gyro/GyroState.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.gyro; - -import org.joml.Vector3f; -import org.joml.Vector3fc; - -public class GyroState extends Vector3f implements GyroStateC { - public GyroState(float pitch, float yaw, float roll) { - super(pitch, yaw, roll); - } - - public GyroState(GyroStateC vec) { - super(vec); - } - - public GyroState() { - } - - @Override - public GyroState mul(Vector3fc v) { - super.mul(v); - return this; - } - - @Override - public GyroState mul(float scalar) { - super.mul(scalar); - return this; - } - - @Override - public GyroState div(Vector3fc v) { - super.div(v); - return this; - } - - @Override - public GyroState div(float scalar) { - super.div(scalar); - return this; - } - - @Override - public GyroState sub(Vector3fc v) { - super.sub(v); - return this; - } - - @Override - public GyroState sub(float x, float y, float z) { - super.sub(x, y, z); - return this; - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/gyro/GyroStateC.java b/src/main/java/dev/isxander/controlify/controller/gyro/GyroStateC.java deleted file mode 100644 index eabbc8f1a..000000000 --- a/src/main/java/dev/isxander/controlify/controller/gyro/GyroStateC.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.gyro; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import org.joml.Vector3fc; - -/** - * Represents the current gyro delta in radians per second. - */ -public interface GyroStateC extends Vector3fc { - GyroStateC ZERO = new GyroState(0, 0, 0); - - default float pitch() { - return x(); - } - - default float yaw() { - return y(); - } - - default float roll() { - return z(); - } - - Codec CODEC_MUTABLE = RecordCodecBuilder.create(instance -> instance.group( - Codec.FLOAT.fieldOf("pitch").forGetter(GyroStateC::pitch), - Codec.FLOAT.fieldOf("yaw").forGetter(GyroStateC::yaw), - Codec.FLOAT.fieldOf("roll").forGetter(GyroStateC::roll) - ).apply(instance, GyroState::new)); -} diff --git a/src/main/java/dev/isxander/controlify/controller/impl/ECSComponentImpl.java b/src/main/java/dev/isxander/controlify/controller/impl/ECSComponentImpl.java deleted file mode 100644 index ee13dfaa4..000000000 --- a/src/main/java/dev/isxander/controlify/controller/impl/ECSComponentImpl.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.impl; - -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.ECSComponent; - -public abstract class ECSComponentImpl implements ECSComponent { - private ControllerEntity controller; - - protected final ControllerEntity controller() { - return this.controller; - } - - @Override - public void attach(ControllerEntity controller) { - this.controller = controller; - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/impl/ECSEntityImpl.java b/src/main/java/dev/isxander/controlify/controller/impl/ECSEntityImpl.java deleted file mode 100644 index 5b65446ed..000000000 --- a/src/main/java/dev/isxander/controlify/controller/impl/ECSEntityImpl.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.impl; - -import com.google.common.collect.ImmutableMap; -import dev.isxander.controlify.controller.ECSComponent; -import dev.isxander.controlify.controller.ECSEntity; -import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.Contract; - -import java.util.*; - -public class ECSEntityImpl implements ECSEntity { - private final Map components; - - public ECSEntityImpl() { - this.components = new HashMap<>(); - } - - @SuppressWarnings("unchecked") - @Override - @Contract(pure = true) - public Optional getComponent(Identifier id) { - return Optional.ofNullable((T) this.components.get(id)); - } - - @Override - public boolean setComponent(T component) { - return this.components.put(component.id(), component) != null; - } - - @Override - public boolean removeComponent(Identifier id) { - return this.components.remove(id) != null; - } - - @Override - public Map getAllComponents() { - return ImmutableMap.copyOf(this.components); - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java b/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java deleted file mode 100644 index 1fc56b074..000000000 --- a/src/main/java/dev/isxander/controlify/controller/info/ControllerInfo.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.info; - -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.controllermanager.UniqueControllerID; -import dev.isxander.controlify.hid.HIDID; - -public record ControllerInfo(UniqueControllerID ucid, ControllerType type, HIDID hid) { -} diff --git a/src/main/java/dev/isxander/controlify/controller/info/DriverNameComponent.java b/src/main/java/dev/isxander/controlify/controller/info/DriverNameComponent.java deleted file mode 100644 index 4862ae08a..000000000 --- a/src/main/java/dev/isxander/controlify/controller/info/DriverNameComponent.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.info; - -import dev.isxander.controlify.controller.SingleValueComponent; -import dev.isxander.controlify.utils.CUtil; -import net.minecraft.resources.Identifier; - -public class DriverNameComponent extends SingleValueComponent { - public static final Identifier ID = CUtil.rl("driver_name"); - - public DriverNameComponent(String value) { - super(value, ID); - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/info/UIDComponent.java b/src/main/java/dev/isxander/controlify/controller/info/UIDComponent.java deleted file mode 100644 index 04c71f83b..000000000 --- a/src/main/java/dev/isxander/controlify/controller/info/UIDComponent.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.info; - -import dev.isxander.controlify.controller.SingleValueComponent; -import dev.isxander.controlify.utils.CUtil; -import net.minecraft.resources.Identifier; - -public class UIDComponent extends SingleValueComponent { - public static final Identifier ID = CUtil.rl("uid"); - - public UIDComponent(String value) { - super(value, ID); - } -} diff --git a/src/main/java/dev/isxander/controlify/controller/rumble/RumbleComponent.java b/src/main/java/dev/isxander/controlify/controller/rumble/RumbleComponent.java deleted file mode 100644 index a79bfa7c6..000000000 --- a/src/main/java/dev/isxander/controlify/controller/rumble/RumbleComponent.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.rumble; - -import dev.isxander.controlify.config.settings.profile.RumbleSettings; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.rumble.RumbleManager; -import dev.isxander.controlify.rumble.RumbleState; -import dev.isxander.controlify.utils.CUtil; -import net.minecraft.resources.Identifier; - -import java.util.Optional; - -public class RumbleComponent extends ECSComponentImpl { - public static final Identifier ID = CUtil.rl("rumble"); - - private RumbleState state = null; - private final RumbleManager rumbleManager; - - public RumbleComponent() { - this.rumbleManager = new RumbleManager(this); - } - - public void queueRumble(RumbleState state) { - if (settings().enabled) { - this.state = state; - } - } - - public Optional consumeRumble() { - RumbleState state = this.state; - this.state = null; - return Optional.ofNullable(state); - } - - public RumbleManager rumbleManager() { - return this.rumbleManager; - } - - public RumbleSettings settings() { - return this.controller().settings().rumble; - } - - public RumbleSettings defaultSettings() { - return this.controller().defaultSettings().rumble; - } - - @Override - public Identifier id() { - return ID; - } - -} diff --git a/src/main/java/dev/isxander/controlify/controller/steamdeck/SteamDeckComponent.java b/src/main/java/dev/isxander/controlify/controller/steamdeck/SteamDeckComponent.java deleted file mode 100644 index 849deadba..000000000 --- a/src/main/java/dev/isxander/controlify/controller/steamdeck/SteamDeckComponent.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.controller.steamdeck; - -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.utils.CUtil; -import net.minecraft.resources.Identifier; - -public class SteamDeckComponent extends ECSComponentImpl { - public static final Identifier ID = CUtil.rl("steam_deck"); - - @Override - public Identifier id() { - return ID; - } -} diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/impl/Controlify.java similarity index 82% rename from src/main/java/dev/isxander/controlify/Controlify.java rename to src/main/java/dev/isxander/controlify/impl/Controlify.java index 0be77c533..c02a7c2a8 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/impl/Controlify.java @@ -4,54 +4,55 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify; +package dev.isxander.controlify.impl; import com.mojang.blaze3d.Blaze3D; +import dev.isxander.controlify.api.InputMode; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.api.bind.ControlifyBindApi; +import dev.isxander.controlify.impl.api.bind.ControlifyBindApi; import dev.isxander.controlify.api.contextual.ContextualDomainRegistry; -import dev.isxander.controlify.api.entrypoint.InitContext; -import dev.isxander.controlify.api.entrypoint.PreInitContext; -import dev.isxander.controlify.bindings.ControlifyBindApiImpl; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.action.radial.RadialIconManager; -import dev.isxander.controlify.action.defaults.DefaultBindManager; -import dev.isxander.controlify.compatibility.ControlifyCompat; -import dev.isxander.controlify.config.ConfigManager; -import dev.isxander.controlify.config.dto.profile.defaults.DefaultConfigManager; -import dev.isxander.controlify.contextual.ContextualDomains; -import dev.isxander.controlify.contextual.RuleSetManager; -import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.controller.dualsense.TriggerEffectManager; -import dev.isxander.controlify.controller.id.ControllerTypeManager; -import dev.isxander.controlify.input.mapping.ControllerMappingManager; -import dev.isxander.controlify.controller.rumble.RumbleComponent; -import dev.isxander.controlify.controllermanager.ControllerCoordinator; -import dev.isxander.controlify.controllermanager.ControllerManager; -import dev.isxander.controlify.driver.steamdeck.SteamDeckMode; -import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; -import dev.isxander.controlify.font.InputFontMapper; -import dev.isxander.controlify.gui.screen.*; -import dev.isxander.controlify.debug.DebugProperties; -import dev.isxander.controlify.ingame.ControllerPlayerMovement; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.action.activator.ActivatorConfigManager; -import dev.isxander.controlify.platform.client.PlatformClientUtil; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.platform.network.SidedNetworkApi; -import dev.isxander.controlify.rumble.RumbleManager; -import dev.isxander.controlify.screenop.keyboard.KeyboardLayoutManager; -import dev.isxander.controlify.server.*; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.api.event.ControlifyEvents; -import dev.isxander.controlify.gui.guide.InGameButtonGuide; -import dev.isxander.controlify.ingame.InGameInputHandler; +import dev.isxander.controlify.impl.api.entrypoint.InitContext; +import dev.isxander.controlify.impl.api.entrypoint.PreInitContext; +import dev.isxander.controlify.impl.bindings.ControlifyBindApiImpl; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.action.radial.RadialIconManager; +import dev.isxander.controlify.impl.action.defaults.DefaultBindManager; +import dev.isxander.controlify.impl.compatibility.ControlifyCompat; +import dev.isxander.controlify.impl.config.ConfigManager; +import dev.isxander.controlify.impl.config.dto.profile.defaults.DefaultConfigManager; +import dev.isxander.controlify.impl.contextual.ContextualDomains; +import dev.isxander.controlify.impl.contextual.RuleSetManager; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.dualsense.TriggerEffectManager; +import dev.isxander.controlify.impl.controllermanager.ControllerTypeManager; +import dev.isxander.controlify.impl.input.mapping.ControllerMappingManager; +import dev.isxander.controlify.impl.controller.rumble.RumbleComponentImpl; +import dev.isxander.controlify.impl.controllermanager.ControllerCoordinator; +import dev.isxander.controlify.impl.controllermanager.ControllerManager; +import dev.isxander.controlify.impl.driver.steamdeck.SteamDeckMode; +import dev.isxander.controlify.impl.driver.steamdeck.SteamDeckUtil; +import dev.isxander.controlify.impl.font.InputFontMapper; +import dev.isxander.controlify.impl.gui.screen.*; +import dev.isxander.controlify.impl.debug.DebugProperties; +import dev.isxander.controlify.impl.ingame.ControllerPlayerMovement; +import dev.isxander.controlify.impl.action.activator.ActivatorConfigManager; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.platform.network.SidedNetworkApi; +import dev.isxander.controlify.impl.controller.rumble.RumbleManager; +import dev.isxander.controlify.impl.controller.rumble.RumbleSourceManager; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardLayoutManager; +import dev.isxander.controlify.impl.server.*; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.api.ControlifyEvents; +import dev.isxander.controlify.impl.gui.guide.InGameButtonGuide; +import dev.isxander.controlify.impl.ingame.InGameInputHandler; import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor; -import dev.isxander.controlify.server.packets.*; -import dev.isxander.controlify.sound.ControlifyClientSounds; -import dev.isxander.controlify.utils.*; -import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; -import dev.isxander.controlify.wireless.LowBatteryNotifier; +import dev.isxander.controlify.impl.server.packets.*; +import dev.isxander.controlify.impl.sound.ControlifyClientSounds; +import dev.isxander.controlify.impl.utils.*; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseHandler; +import dev.isxander.controlify.impl.wireless.LowBatteryNotifier; import dev.isxander.yacl3.gui.YACLScreen; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; @@ -65,7 +66,7 @@ import java.io.IOException; import java.util.*; -import static dev.isxander.controlify.utils.ControllerUtils.wrapControllerError; +import static dev.isxander.controlify.impl.utils.ControllerUtils.wrapControllerError; public class Controlify implements ControlifyApi { private static Controlify instance = null; @@ -90,6 +91,7 @@ public class Controlify implements ControlifyApi { private RadialIconManager radialIconManager; private ActivatorConfigManager activatorConfigManager; private ControllerMappingManager controllerMappingManager; + private RumbleSourceManager rumbleSourceManager; private TriggerEffectManager triggerEffectManager; @@ -136,6 +138,7 @@ public void preInitialiseControlify() { this.radialIconManager = new RadialIconManager(); this.activatorConfigManager = new ActivatorConfigManager(); this.controllerMappingManager = new ControllerMappingManager(); + this.rumbleSourceManager = new RumbleSourceManager(); PlatformClientUtil.registerAssetReloadListener(this.inputFontMapper); PlatformClientUtil.registerAssetReloadListener(this.defaultBindManager); @@ -145,6 +148,7 @@ public void preInitialiseControlify() { PlatformClientUtil.registerAssetReloadListener(this.radialIconManager); PlatformClientUtil.registerAssetReloadListener(this.activatorConfigManager); PlatformClientUtil.registerAssetReloadListener(this.controllerMappingManager); + PlatformClientUtil.registerAssetReloadListener(this.rumbleSourceManager); PlatformClientUtil.registerAssetReloadListener(RuleSetManager.GUIDE_RULES); PlatformClientUtil.registerAssetReloadListener(RuleSetManager.TRIGGER_EFFECT_RULES); ContextualDomains.touch(); @@ -157,20 +161,20 @@ public void preInitialiseControlify() { SidedNetworkApi.S2C().listenForPacket(VibrationPacket.CHANNEL, packet -> { if (config().getSettings().globalSettings().allowServerRumble) { - getCurrentController().flatMap(ControllerEntity::rumble).ifPresent(rumble -> - rumble.rumbleManager().play(packet.source(), packet.createEffect())); + getCurrentController().flatMap(ControllerImpl::rumble).ifPresent(rumble -> + rumble.rumbleManager().play(VibrationPacket.CHANNEL, packet.source(), packet.createEffect())); } }); SidedNetworkApi.S2C().listenForPacket(OriginVibrationPacket.CHANNEL, packet -> { if (config().getSettings().globalSettings().allowServerRumble) { - getCurrentController().flatMap(ControllerEntity::rumble).ifPresent(rumble -> - rumble.rumbleManager().play(packet.source(), packet.createEffect())); + getCurrentController().flatMap(ControllerImpl::rumble).ifPresent(rumble -> + rumble.rumbleManager().play(OriginVibrationPacket.CHANNEL, packet.source(), packet.createEffect())); } }); SidedNetworkApi.S2C().listenForPacket(EntityVibrationPacket.CHANNEL, packet -> { if (config().getSettings().globalSettings().allowServerRumble) { - getCurrentController().flatMap(ControllerEntity::rumble).ifPresent(rumble -> - rumble.rumbleManager().play(packet.source(), packet.createEffect())); + getCurrentController().flatMap(ControllerImpl::rumble).ifPresent(rumble -> + rumble.rumbleManager().play(EntityVibrationPacket.CHANNEL, packet.source(), packet.createEffect())); } }); SidedNetworkApi.S2C().listenForPacket(ServerPolicyPacket.CHANNEL, packet -> { @@ -366,7 +370,7 @@ public void fixedUpdate() { }); } - private void updateActiveController(ControllerEntity controller, boolean givingInput) { + private void updateActiveController(ControllerImpl controller, boolean givingInput) { if (givingInput) { minecraft.getFramerateLimitTracker().onInputReceived(); @@ -398,7 +402,7 @@ private void updateActiveController(ControllerEntity controller, boolean givingI } } - private void fixedUpdateActiveController(ControllerEntity controller, boolean outOfFocus) { + private void fixedUpdateActiveController(ControllerImpl controller, boolean outOfFocus) { boolean controllerInputSuppressed = outOfFocus || currentInputMode() == InputMode.KEYBOARD_MOUSE; this.triggerEffectManager().tick(this.minecraft, controller); this.triggerEffectManager().applyTriggerEffects(controller, controllerInputSuppressed); @@ -406,7 +410,7 @@ private void fixedUpdateActiveController(ControllerEntity controller, boolean ou boolean isPaused = minecraft.isPaused() || MinecraftUtil.getScreen() instanceof PauseScreen; boolean isConfigScreen = MinecraftUtil.getScreen() instanceof YACLScreen; - Optional rumbleManager = controller.rumble().map(RumbleComponent::rumbleManager); + Optional rumbleManager = controller.rumble().map(RumbleComponentImpl::rumbleManager); rumbleManager.ifPresent(rumble -> rumble.setSilent(outOfFocus || (isPaused && !isConfigScreen) || currentInputMode() == InputMode.KEYBOARD_MOUSE)); if (!outOfFocus) { rumbleManager.ifPresent(RumbleManager::tick); @@ -442,15 +446,15 @@ public ConfigManager config() { } @Override - public @NotNull Optional getCurrentController() { + public @NotNull Optional getCurrentController() { return this.getControllerCoordinator().flatMap(ControllerCoordinator::currentController); } - public void setCurrentController(@Nullable ControllerEntity controller, boolean changeInputMode) { + public void setCurrentController(@Nullable ControllerImpl controller, boolean changeInputMode) { this.getControllerCoordinator().ifPresent(coordinator -> coordinator.setCurrentController(controller, changeInputMode)); } - private void onCurrentControllerChanged(@Nullable ControllerEntity controller, boolean changeInputMode) { + private void onCurrentControllerChanged(@Nullable ControllerImpl controller, boolean changeInputMode) { boolean changedInputMode = false; if (controller == null) { changedInputMode = this.setInputMode(InputMode.KEYBOARD_MOUSE); @@ -510,7 +514,7 @@ public boolean setInputMode(@NotNull InputMode newInputMode) { return true; } - private void setupForController(@Nullable ControllerEntity controller) { + private void setupForController(@Nullable ControllerImpl controller) { ControllerPlayerMovement.updatePlayerInput(minecraft.player); if (controller == null) { @@ -522,7 +526,7 @@ private void setupForController(@Nullable ControllerEntity controller) { this.inGameInputHandler = new InGameInputHandler(controller); this.inGameButtonGuide = new InGameButtonGuide(controller, this.minecraft); - controller.input().ifPresent(InputComponent::resetActions); + controller.input().resetActions(); } public Optional getControllerManager() { @@ -629,6 +633,10 @@ public ControllerMappingManager controllerMappingManager() { return this.controllerMappingManager; } + public RumbleSourceManager rumbleSourceManager() { + return this.rumbleSourceManager; + } + public TriggerEffectManager triggerEffectManager() { return this.triggerEffectManager; } diff --git a/src/main/java/dev/isxander/controlify/action/Accumulator.java b/src/main/java/dev/isxander/controlify/impl/action/Accumulator.java similarity index 82% rename from src/main/java/dev/isxander/controlify/action/Accumulator.java rename to src/main/java/dev/isxander/controlify/impl/action/Accumulator.java index fb9e37d17..2737e5806 100644 --- a/src/main/java/dev/isxander/controlify/action/Accumulator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/Accumulator.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; /// Accepts action state. public interface Accumulator { diff --git a/src/main/java/dev/isxander/controlify/action/ActionAccessor.java b/src/main/java/dev/isxander/controlify/impl/action/ActionAccessor.java similarity index 64% rename from src/main/java/dev/isxander/controlify/action/ActionAccessor.java rename to src/main/java/dev/isxander/controlify/impl/action/ActionAccessor.java index 7fd0ed51a..153bbc3ce 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionAccessor.java @@ -1,7 +1,8 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.input.InputComponent; +import dev.isxander.controlify.api.action.Action; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.input.InputComponent; import net.minecraft.resources.Identifier; import org.jspecify.annotations.Nullable; @@ -11,7 +12,7 @@ public interface ActionAccessor { Identifier actionId(); - default @Nullable Action onOrNull(ControllerEntity controller) { + default @Nullable Action onOrNull(ControllerImpl controller) { return onOrNull(controller.input().orElseThrow()); } @@ -21,7 +22,7 @@ default Action on(InputComponent inputComponent) { return action; } - default Action on(ControllerEntity controller) { + default Action on(ControllerImpl controller) { return on(controller.input().orElseThrow()); } } diff --git a/src/main/java/dev/isxander/controlify/action/ActionAccessorImpl.java b/src/main/java/dev/isxander/controlify/impl/action/ActionAccessorImpl.java similarity index 64% rename from src/main/java/dev/isxander/controlify/action/ActionAccessorImpl.java rename to src/main/java/dev/isxander/controlify/impl/action/ActionAccessorImpl.java index 6ee6f2a3f..a75544968 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionAccessorImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionAccessorImpl.java @@ -1,6 +1,7 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; -import dev.isxander.controlify.controller.input.InputComponent; +import dev.isxander.controlify.api.action.Action; +import dev.isxander.controlify.impl.controller.input.InputComponent; import net.minecraft.resources.Identifier; import org.jspecify.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/action/ActionContext.java b/src/main/java/dev/isxander/controlify/impl/action/ActionContext.java similarity index 89% rename from src/main/java/dev/isxander/controlify/action/ActionContext.java rename to src/main/java/dev/isxander/controlify/impl/action/ActionContext.java index ccaaf4763..a91baeaa6 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionContext.java +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionContext.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; import net.minecraft.client.Minecraft; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/action/ActionGraph.java b/src/main/java/dev/isxander/controlify/impl/action/ActionGraph.java similarity index 93% rename from src/main/java/dev/isxander/controlify/action/ActionGraph.java rename to src/main/java/dev/isxander/controlify/impl/action/ActionGraph.java index 71be9fc45..1a6cd4ed4 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionGraph.java +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionGraph.java @@ -1,8 +1,8 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; -import dev.isxander.controlify.utils.event.EventSink; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; import net.minecraft.resources.Identifier; import java.util.*; diff --git a/src/main/java/dev/isxander/controlify/action/ActionImpl.java b/src/main/java/dev/isxander/controlify/impl/action/ActionImpl.java similarity index 82% rename from src/main/java/dev/isxander/controlify/action/ActionImpl.java rename to src/main/java/dev/isxander/controlify/impl/action/ActionImpl.java index 6e2847cf3..f6c23225f 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionImpl.java @@ -1,8 +1,11 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; -import dev.isxander.controlify.action.activator.ActivatorConfig; -import dev.isxander.controlify.action.activator.NoopActivator; -import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.api.action.Action; +import dev.isxander.controlify.api.action.ActionSpec; +import dev.isxander.controlify.api.action.Channel; +import dev.isxander.controlify.impl.action.activator.ActivatorConfig; +import dev.isxander.controlify.impl.action.activator.NoopActivator; +import dev.isxander.controlify.api.input.LogicalInput; import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/action/ActionSpecBuilder.java b/src/main/java/dev/isxander/controlify/impl/action/ActionSpecBuilder.java similarity index 64% rename from src/main/java/dev/isxander/controlify/action/ActionSpecBuilder.java rename to src/main/java/dev/isxander/controlify/impl/action/ActionSpecBuilder.java index d30c52e96..8cff36660 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionSpecBuilder.java +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionSpecBuilder.java @@ -1,6 +1,7 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.api.action.ActionSpec; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; @@ -17,7 +18,7 @@ public interface ActionSpecBuilder { ActionSpecBuilder context(Identifier... contexts); - ActionSpecBuilder shouldExpose(Predicate predicate); + ActionSpecBuilder shouldExpose(Predicate predicate); ActionSpec build(); } diff --git a/src/main/java/dev/isxander/controlify/action/ActionSpecBuilderImpl.java b/src/main/java/dev/isxander/controlify/impl/action/ActionSpecBuilderImpl.java similarity index 86% rename from src/main/java/dev/isxander/controlify/action/ActionSpecBuilderImpl.java rename to src/main/java/dev/isxander/controlify/impl/action/ActionSpecBuilderImpl.java index c6a3d10d7..337071d48 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionSpecBuilderImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionSpecBuilderImpl.java @@ -1,6 +1,7 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.api.action.ActionSpec; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; import org.apache.commons.lang3.Validate; @@ -15,7 +16,7 @@ public class ActionSpecBuilderImpl implements ActionSpecBuilder { private @Nullable Component description; private @Nullable Component category; private final Set contexts = new TreeSet<>(); - private Predicate shouldExpose = _ -> true; + private Predicate shouldExpose = _ -> true; @Override public ActionSpecBuilder id(Identifier id) { @@ -48,7 +49,7 @@ public ActionSpecBuilder context(Identifier... contexts) { } @Override - public ActionSpecBuilder shouldExpose(Predicate predicate) { + public ActionSpecBuilder shouldExpose(Predicate predicate) { this.shouldExpose = predicate; return this; } diff --git a/src/main/java/dev/isxander/controlify/impl/action/ActionSpecRegistry.java b/src/main/java/dev/isxander/controlify/impl/action/ActionSpecRegistry.java new file mode 100644 index 000000000..a65bff351 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionSpecRegistry.java @@ -0,0 +1,7 @@ +package dev.isxander.controlify.impl.action; + +import dev.isxander.controlify.api.action.ActionSpec; + +public interface ActionSpecRegistry { + ActionAccessor register(ActionSpec actionSpec); +} diff --git a/src/main/java/dev/isxander/controlify/action/ActionSpecRegistryImpl.java b/src/main/java/dev/isxander/controlify/impl/action/ActionSpecRegistryImpl.java similarity index 91% rename from src/main/java/dev/isxander/controlify/action/ActionSpecRegistryImpl.java rename to src/main/java/dev/isxander/controlify/impl/action/ActionSpecRegistryImpl.java index ae391579f..c1f832586 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionSpecRegistryImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionSpecRegistryImpl.java @@ -1,4 +1,6 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; + +import dev.isxander.controlify.api.action.ActionSpec; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/dev/isxander/controlify/action/ActionState.java b/src/main/java/dev/isxander/controlify/impl/action/ActionState.java similarity index 90% rename from src/main/java/dev/isxander/controlify/action/ActionState.java rename to src/main/java/dev/isxander/controlify/impl/action/ActionState.java index 17838159e..499b60103 100644 --- a/src/main/java/dev/isxander/controlify/action/ActionState.java +++ b/src/main/java/dev/isxander/controlify/impl/action/ActionState.java @@ -1,4 +1,6 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; + +import dev.isxander.controlify.api.action.Channel; public final class ActionState implements Accumulator, Channel.Continuous, Channel.Latch, Channel.Pulse { private int pulses = 0; diff --git a/src/main/java/dev/isxander/controlify/action/Activator.java b/src/main/java/dev/isxander/controlify/impl/action/Activator.java similarity index 64% rename from src/main/java/dev/isxander/controlify/action/Activator.java rename to src/main/java/dev/isxander/controlify/impl/action/Activator.java index 4e87f8f5a..92855b478 100644 --- a/src/main/java/dev/isxander/controlify/action/Activator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/Activator.java @@ -1,7 +1,8 @@ -package dev.isxander.controlify.action; +package dev.isxander.controlify.impl.action; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.api.action.Action; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Processes signals and activates an {@link Action}. public interface Activator { diff --git a/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfig.java b/src/main/java/dev/isxander/controlify/impl/action/activator/ActivatorConfig.java similarity index 89% rename from src/main/java/dev/isxander/controlify/action/activator/ActivatorConfig.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/ActivatorConfig.java index 908c6556c..5dfcecb8b 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/ActivatorConfig.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; import net.minecraft.util.StringRepresentable; /// An immutable structure typically containing the configuration diff --git a/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigManager.java b/src/main/java/dev/isxander/controlify/impl/action/activator/ActivatorConfigManager.java similarity index 87% rename from src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigManager.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/ActivatorConfigManager.java index 34aeecf18..4efba9b63 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigManager.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/ActivatorConfigManager.java @@ -4,16 +4,16 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.input.InputComponent; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; @@ -26,7 +26,7 @@ import java.util.concurrent.Executor; public class ActivatorConfigManager implements SimpleControlifyReloadListener>> { - private static final Identifier DEFINITIONS = CUtil.rl("activators.json"); + private static final Identifier DEFINITIONS = CUtil.rl("controller/activators.json"); private static final Codec>> CODEC = Codec.unboundedMap(Identifier.CODEC, ActivatorConfig.CODEC); private static final ActivatorConfig FALLBACK = new CompoundActivator.Config(List.of()); diff --git a/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigType.java b/src/main/java/dev/isxander/controlify/impl/action/activator/ActivatorConfigType.java similarity index 96% rename from src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigType.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/ActivatorConfigType.java index 5c8f2cb97..31fd78a74 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/ActivatorConfigType.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/ActivatorConfigType.java @@ -1,7 +1,7 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.action.Activator; +import dev.isxander.controlify.impl.action.Activator; import net.minecraft.util.StringRepresentable; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/dev/isxander/controlify/action/activator/CompoundActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/CompoundActivator.java similarity index 82% rename from src/main/java/dev/isxander/controlify/action/activator/CompoundActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/CompoundActivator.java index b39c7b18e..c90c9d9f7 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/CompoundActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/CompoundActivator.java @@ -1,11 +1,11 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/dev/isxander/controlify/action/activator/ContinuousActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/ContinuousActivator.java similarity index 74% rename from src/main/java/dev/isxander/controlify/action/activator/ContinuousActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/ContinuousActivator.java index 552d00840..4bc2daa1d 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/ContinuousActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/ContinuousActivator.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; public record ContinuousActivator(LogicalInput boundInput) implements Activator { @Override diff --git a/src/main/java/dev/isxander/controlify/action/activator/DoubleTapPulseActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/DoubleTapPulseActivator.java similarity index 76% rename from src/main/java/dev/isxander/controlify/action/activator/DoubleTapPulseActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/DoubleTapPulseActivator.java index dfd6a6c84..92d136552 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/DoubleTapPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/DoubleTapPulseActivator.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Produces a pulse when the input is double tapped. public record DoubleTapPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/action/activator/GuiPressPulseActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/GuiPressPulseActivator.java similarity index 76% rename from src/main/java/dev/isxander/controlify/action/activator/GuiPressPulseActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/GuiPressPulseActivator.java index d66ec387e..4fb6e5317 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/GuiPressPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/GuiPressPulseActivator.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Produces a pulse on release when no GUI navigation consumed the press. public record GuiPressPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/action/activator/HoldLatchActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/HoldLatchActivator.java similarity index 79% rename from src/main/java/dev/isxander/controlify/action/activator/HoldLatchActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/HoldLatchActivator.java index 35eb00978..e40dcbe21 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/HoldLatchActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/HoldLatchActivator.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Keeps the latch active from button press until release, without a hold delay. public record HoldLatchActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/action/activator/HoldPulseActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/HoldPulseActivator.java similarity index 75% rename from src/main/java/dev/isxander/controlify/action/activator/HoldPulseActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/HoldPulseActivator.java index 004e83593..6b817b9c3 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/HoldPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/HoldPulseActivator.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Produces a pulse once the input reaches the hold duration. public record HoldPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/impl/action/activator/NoopActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/NoopActivator.java new file mode 100644 index 000000000..1fc73f482 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/NoopActivator.java @@ -0,0 +1,23 @@ +package dev.isxander.controlify.impl.action.activator; + +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; + +public class NoopActivator implements Activator { + @Override + public void onSignal(LogicalSignal signal, Accumulator acc) { + + } + + @Override + public LogicalInput boundInput() { + return null; + } + + @Override + public String describe() { + return "Noop"; + } +} diff --git a/src/main/java/dev/isxander/controlify/action/activator/PressPulseActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/PressPulseActivator.java similarity index 75% rename from src/main/java/dev/isxander/controlify/action/activator/PressPulseActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/PressPulseActivator.java index 812a5616b..fa5f093fe 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/PressPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/PressPulseActivator.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Produces a pulse when the input is pressed. public record PressPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/action/activator/ReleasePulseActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/ReleasePulseActivator.java similarity index 75% rename from src/main/java/dev/isxander/controlify/action/activator/ReleasePulseActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/ReleasePulseActivator.java index c74e9bae4..698b0889f 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/ReleasePulseActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/ReleasePulseActivator.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Produces a pulse when the input is released. public record ReleasePulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/action/activator/RepeatLatchPulseActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/RepeatLatchPulseActivator.java similarity index 91% rename from src/main/java/dev/isxander/controlify/action/activator/RepeatLatchPulseActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/RepeatLatchPulseActivator.java index b87ab051e..1a6213732 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/RepeatLatchPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/RepeatLatchPulseActivator.java @@ -1,12 +1,12 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Accepts another latch binding, and sends repeat pulses out while the latch is active. public class RepeatLatchPulseActivator implements Activator { diff --git a/src/main/java/dev/isxander/controlify/action/activator/TapPulseActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/TapPulseActivator.java similarity index 75% rename from src/main/java/dev/isxander/controlify/action/activator/TapPulseActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/TapPulseActivator.java index fc8f5dd63..94679b10e 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/TapPulseActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/TapPulseActivator.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Produces a pulse when the input is tapped. public record TapPulseActivator(LogicalInput boundInput) implements Activator { diff --git a/src/main/java/dev/isxander/controlify/action/activator/ToggleLatchActivator.java b/src/main/java/dev/isxander/controlify/impl/action/activator/ToggleLatchActivator.java similarity index 85% rename from src/main/java/dev/isxander/controlify/action/activator/ToggleLatchActivator.java rename to src/main/java/dev/isxander/controlify/impl/action/activator/ToggleLatchActivator.java index 691ea2282..fe8012e29 100644 --- a/src/main/java/dev/isxander/controlify/action/activator/ToggleLatchActivator.java +++ b/src/main/java/dev/isxander/controlify/impl/action/activator/ToggleLatchActivator.java @@ -1,11 +1,11 @@ -package dev.isxander.controlify.action.activator; +package dev.isxander.controlify.impl.action.activator; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.action.Accumulator; -import dev.isxander.controlify.action.Activator; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.action.Accumulator; +import dev.isxander.controlify.impl.action.Activator; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; /// Accepts another pulse binding, and converts pulses into toggling a latch. public class ToggleLatchActivator implements Activator { diff --git a/src/main/java/dev/isxander/controlify/action/defaults/DefaultBindManager.java b/src/main/java/dev/isxander/controlify/impl/action/defaults/DefaultBindManager.java similarity index 90% rename from src/main/java/dev/isxander/controlify/action/defaults/DefaultBindManager.java rename to src/main/java/dev/isxander/controlify/impl/action/defaults/DefaultBindManager.java index bc7e14d9f..68e47e1b9 100644 --- a/src/main/java/dev/isxander/controlify/action/defaults/DefaultBindManager.java +++ b/src/main/java/dev/isxander/controlify/impl/action/defaults/DefaultBindManager.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.action.defaults; +package dev.isxander.controlify.impl.action.defaults; import com.google.gson.JsonElement; import com.google.gson.JsonParser; @@ -13,9 +13,9 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.controllermanager.ControllerType; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.FileToIdConverter; import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.Resource; @@ -31,7 +31,7 @@ public class DefaultBindManager implements SimpleControlifyReloadListener { - public static final String DIRECTORY = "controllers/default_bind"; + public static final String DIRECTORY = "controller/default_bind"; private static final FileToIdConverter converter = FileToIdConverter.json(DIRECTORY); private static final Logger LOGGER = LogUtils.getLogger(); @@ -45,7 +45,7 @@ public class DefaultBindManager implements SimpleControlifyReloadListener defaultsByNamespace = new HashMap<>(); - Identifier defaultNamespaceFile = converter.idToFile(ControllerType.DEFAULT.namespace()); + Identifier defaultNamespaceFile = converter.idToFile(ControllerType.DEFAULT.id()); if (!defaultFiles.containsKey(defaultNamespaceFile)) { LOGGER.error("No default binds found! Everything will be unbound!"); return null; @@ -55,8 +55,8 @@ public class DefaultBindManager implements SimpleControlifyReloadListener> stack : defaultFiles.entrySet()) { Identifier id = stack.getKey(); @@ -66,7 +66,7 @@ public class DefaultBindManager implements SimpleControlifyReloadListener> defaults = this.readDefaults(id, files); - // add the default namespace to the bottom + // add the default id to the bottom defaults.getSecond().add( new LayeredDefaultBindProvider.Layer(defaultNamespaceDefaults, false) ); @@ -115,7 +115,7 @@ public CompletableFuture apply(@Nullable Preparations data, ResourceManage public DefaultBindProvider getDefaultBindProvider(Identifier namespace) { DefaultBindProvider provider = this.defaultsByNamespace.get(namespace); if (provider == null) - provider = this.defaultsByNamespace.get(ControllerType.DEFAULT.namespace()); + provider = this.defaultsByNamespace.get(ControllerType.DEFAULT.id()); if (provider == null) provider = DefaultBindProvider.EMPTY; return provider; diff --git a/src/main/java/dev/isxander/controlify/action/defaults/DefaultBindProvider.java b/src/main/java/dev/isxander/controlify/impl/action/defaults/DefaultBindProvider.java similarity index 76% rename from src/main/java/dev/isxander/controlify/action/defaults/DefaultBindProvider.java rename to src/main/java/dev/isxander/controlify/impl/action/defaults/DefaultBindProvider.java index f18f820be..1c8414c09 100644 --- a/src/main/java/dev/isxander/controlify/action/defaults/DefaultBindProvider.java +++ b/src/main/java/dev/isxander/controlify/impl/action/defaults/DefaultBindProvider.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.action.defaults; +package dev.isxander.controlify.impl.action.defaults; -import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.api.input.LogicalInput; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/action/defaults/LayeredDefaultBindProvider.java b/src/main/java/dev/isxander/controlify/impl/action/defaults/LayeredDefaultBindProvider.java similarity index 92% rename from src/main/java/dev/isxander/controlify/action/defaults/LayeredDefaultBindProvider.java rename to src/main/java/dev/isxander/controlify/impl/action/defaults/LayeredDefaultBindProvider.java index e469b92ca..a37f6731c 100644 --- a/src/main/java/dev/isxander/controlify/action/defaults/LayeredDefaultBindProvider.java +++ b/src/main/java/dev/isxander/controlify/impl/action/defaults/LayeredDefaultBindProvider.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.action.defaults; +package dev.isxander.controlify.impl.action.defaults; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.api.input.LogicalInput; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/action/defaults/MapBackedDefaultBindProvider.java b/src/main/java/dev/isxander/controlify/impl/action/defaults/MapBackedDefaultBindProvider.java similarity index 83% rename from src/main/java/dev/isxander/controlify/action/defaults/MapBackedDefaultBindProvider.java rename to src/main/java/dev/isxander/controlify/impl/action/defaults/MapBackedDefaultBindProvider.java index 46d4c1824..c3697c3dd 100644 --- a/src/main/java/dev/isxander/controlify/action/defaults/MapBackedDefaultBindProvider.java +++ b/src/main/java/dev/isxander/controlify/impl/action/defaults/MapBackedDefaultBindProvider.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.action.defaults; +package dev.isxander.controlify.impl.action.defaults; import com.mojang.serialization.Codec; import com.mojang.serialization.Keyable; import com.mojang.serialization.MapCodec; -import dev.isxander.controlify.api.bind.ControlifyBindApi; -import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.impl.api.bind.ControlifyBindApi; +import dev.isxander.controlify.api.input.LogicalInput; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/action/radial/RadialIcon.java b/src/main/java/dev/isxander/controlify/impl/action/radial/RadialIcon.java similarity index 98% rename from src/main/java/dev/isxander/controlify/action/radial/RadialIcon.java rename to src/main/java/dev/isxander/controlify/impl/action/radial/RadialIcon.java index 21112c3ff..7d11c61ea 100644 --- a/src/main/java/dev/isxander/controlify/action/radial/RadialIcon.java +++ b/src/main/java/dev/isxander/controlify/impl/action/radial/RadialIcon.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.action.radial; +package dev.isxander.controlify.impl.action.radial; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; diff --git a/src/main/java/dev/isxander/controlify/action/radial/RadialIconExtractor.java b/src/main/java/dev/isxander/controlify/impl/action/radial/RadialIconExtractor.java similarity index 97% rename from src/main/java/dev/isxander/controlify/action/radial/RadialIconExtractor.java rename to src/main/java/dev/isxander/controlify/impl/action/radial/RadialIconExtractor.java index d2714c87a..6c51c493a 100644 --- a/src/main/java/dev/isxander/controlify/action/radial/RadialIconExtractor.java +++ b/src/main/java/dev/isxander/controlify/impl/action/radial/RadialIconExtractor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.action.radial; +package dev.isxander.controlify.impl.action.radial; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; diff --git a/src/main/java/dev/isxander/controlify/action/radial/RadialIconManager.java b/src/main/java/dev/isxander/controlify/impl/action/radial/RadialIconManager.java similarity index 88% rename from src/main/java/dev/isxander/controlify/action/radial/RadialIconManager.java rename to src/main/java/dev/isxander/controlify/impl/action/radial/RadialIconManager.java index ea7dbd269..aece6c14f 100644 --- a/src/main/java/dev/isxander/controlify/action/radial/RadialIconManager.java +++ b/src/main/java/dev/isxander/controlify/impl/action/radial/RadialIconManager.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.action.radial; +package dev.isxander.controlify.impl.action.radial; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; @@ -27,7 +27,7 @@ public class RadialIconManager implements SimpleControlifyReloadListener> { public static final Identifier EMPTY = CUtil.rl("empty"); - private static final Identifier DEFINITIONS = CUtil.rl("radial_icons.json"); + private static final Identifier DEFINITIONS = CUtil.rl("controller/radial_icons.json"); private static final Codec> CODEC = Codec.unboundedMap(Identifier.CODEC, RadialIcon.CODEC); private static final RadialIcon FALLBACK = RadialIcon.model(Identifier.withDefaultNamespace("book")); diff --git a/src/main/java/dev/isxander/controlify/api/entrypoint/ControlifyEntrypoint.java b/src/main/java/dev/isxander/controlify/impl/api/entrypoint/ControlifyEntrypoint.java similarity index 94% rename from src/main/java/dev/isxander/controlify/api/entrypoint/ControlifyEntrypoint.java rename to src/main/java/dev/isxander/controlify/impl/api/entrypoint/ControlifyEntrypoint.java index da3c7507c..9af422e92 100644 --- a/src/main/java/dev/isxander/controlify/api/entrypoint/ControlifyEntrypoint.java +++ b/src/main/java/dev/isxander/controlify/impl/api/entrypoint/ControlifyEntrypoint.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.entrypoint; +package dev.isxander.controlify.impl.api.entrypoint; import dev.isxander.controlify.api.ControlifyApi; diff --git a/src/main/java/dev/isxander/controlify/api/entrypoint/InitContext.java b/src/main/java/dev/isxander/controlify/impl/api/entrypoint/InitContext.java similarity index 81% rename from src/main/java/dev/isxander/controlify/api/entrypoint/InitContext.java rename to src/main/java/dev/isxander/controlify/impl/api/entrypoint/InitContext.java index bbeaa8817..404acd5f1 100644 --- a/src/main/java/dev/isxander/controlify/api/entrypoint/InitContext.java +++ b/src/main/java/dev/isxander/controlify/impl/api/entrypoint/InitContext.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.entrypoint; +package dev.isxander.controlify.impl.api.entrypoint; import dev.isxander.controlify.api.ControlifyApi; diff --git a/src/main/java/dev/isxander/controlify/api/entrypoint/PreInitContext.java b/src/main/java/dev/isxander/controlify/impl/api/entrypoint/PreInitContext.java similarity index 72% rename from src/main/java/dev/isxander/controlify/api/entrypoint/PreInitContext.java rename to src/main/java/dev/isxander/controlify/impl/api/entrypoint/PreInitContext.java index af0a053a5..da6194cc6 100644 --- a/src/main/java/dev/isxander/controlify/api/entrypoint/PreInitContext.java +++ b/src/main/java/dev/isxander/controlify/impl/api/entrypoint/PreInitContext.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.entrypoint; +package dev.isxander.controlify.impl.api.entrypoint; -import dev.isxander.controlify.api.bind.ControlifyBindApi; +import dev.isxander.controlify.impl.api.bind.ControlifyBindApi; import dev.isxander.controlify.api.contextual.ContextualDomainRegistry; public interface PreInitContext { diff --git a/src/main/java/dev/isxander/controlify/api/ingameinput/LookInputModifier.java b/src/main/java/dev/isxander/controlify/impl/api/ingameinput/LookInputModifier.java similarity index 76% rename from src/main/java/dev/isxander/controlify/api/ingameinput/LookInputModifier.java rename to src/main/java/dev/isxander/controlify/impl/api/ingameinput/LookInputModifier.java index c2f7f51d1..81baff9d5 100644 --- a/src/main/java/dev/isxander/controlify/api/ingameinput/LookInputModifier.java +++ b/src/main/java/dev/isxander/controlify/impl/api/ingameinput/LookInputModifier.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.ingameinput; +package dev.isxander.controlify.impl.api.ingameinput; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.platform.EventHandler; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.platform.EventHandler; import org.joml.Vector2f; import java.util.function.BiFunction; @@ -17,7 +17,7 @@ * Callbacks should modify the {@link #lookInput()} vector to modify the look input. * Be aware that multiple callbacks could be called, so make sure to be considerate of other mods. */ -public record LookInputModifier(Vector2f lookInput, ControllerEntity controller) { +public record LookInputModifier(Vector2f lookInput, ControllerImpl controller) { /** * Creates a callback to modify the x and y individually. * @@ -25,7 +25,7 @@ public record LookInputModifier(Vector2f lookInput, ControllerEntity controller) * @param y the function for modifying the y-axis * @return the new callback */ - public static EventHandler.Callback functional(BiFunction x, BiFunction y) { + public static EventHandler.Callback functional(BiFunction x, BiFunction y) { return event -> { event.lookInput.x = x.apply(event.lookInput.x, event.controller); event.lookInput.y = y.apply(event.lookInput.y, event.controller); @@ -38,7 +38,7 @@ public static EventHandler.Callback functional(BiFunction zeroIf(Predicate condition) { + static EventHandler.Callback zeroIf(Predicate condition) { return event -> { if (condition.test(event.controller)) { event.lookInput.set(0, 0); diff --git a/src/main/java/dev/isxander/controlify/api/vmousesnapping/ISnapBehaviour.java b/src/main/java/dev/isxander/controlify/impl/api/vmousesnapping/ISnapBehaviour.java similarity index 91% rename from src/main/java/dev/isxander/controlify/api/vmousesnapping/ISnapBehaviour.java rename to src/main/java/dev/isxander/controlify/impl/api/vmousesnapping/ISnapBehaviour.java index 2a349ed91..25a2b19f1 100644 --- a/src/main/java/dev/isxander/controlify/api/vmousesnapping/ISnapBehaviour.java +++ b/src/main/java/dev/isxander/controlify/impl/api/vmousesnapping/ISnapBehaviour.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.vmousesnapping; +package dev.isxander.controlify.impl.api.vmousesnapping; import java.util.Set; import java.util.function.Consumer; diff --git a/src/main/java/dev/isxander/controlify/api/vmousesnapping/SnapPoint.java b/src/main/java/dev/isxander/controlify/impl/api/vmousesnapping/SnapPoint.java similarity index 90% rename from src/main/java/dev/isxander/controlify/api/vmousesnapping/SnapPoint.java rename to src/main/java/dev/isxander/controlify/impl/api/vmousesnapping/SnapPoint.java index ffa6bd946..02e770bc4 100644 --- a/src/main/java/dev/isxander/controlify/api/vmousesnapping/SnapPoint.java +++ b/src/main/java/dev/isxander/controlify/impl/api/vmousesnapping/SnapPoint.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.vmousesnapping; +package dev.isxander.controlify.impl.api.vmousesnapping; import org.joml.Vector2i; import org.joml.Vector2ic; diff --git a/src/main/java/dev/isxander/controlify/bindings/BindContext.java b/src/main/java/dev/isxander/controlify/impl/bindings/BindContext.java similarity index 84% rename from src/main/java/dev/isxander/controlify/bindings/BindContext.java rename to src/main/java/dev/isxander/controlify/impl/bindings/BindContext.java index e6ba87f22..8a5aa88b9 100644 --- a/src/main/java/dev/isxander/controlify/bindings/BindContext.java +++ b/src/main/java/dev/isxander/controlify/impl/bindings/BindContext.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.bindings; +package dev.isxander.controlify.impl.bindings; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.gui.screen.RadialMenuScreen; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.MinecraftUtil; -import dev.isxander.controlify.virtualmouse.VirtualMouseBehaviour; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.gui.screen.RadialMenuScreen; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseBehaviour; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/bindings/ControlifyBindings.java b/src/main/java/dev/isxander/controlify/impl/bindings/ControlifyBindings.java similarity index 98% rename from src/main/java/dev/isxander/controlify/bindings/ControlifyBindings.java rename to src/main/java/dev/isxander/controlify/impl/bindings/ControlifyBindings.java index f1b3fd418..58e0d183c 100644 --- a/src/main/java/dev/isxander/controlify/bindings/ControlifyBindings.java +++ b/src/main/java/dev/isxander/controlify/impl/bindings/ControlifyBindings.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.bindings; +package dev.isxander.controlify.impl.bindings; -import dev.isxander.controlify.api.bind.ControlifyBindApi; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.platform.client.PlatformClientUtil; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.api.bind.ControlifyBindApi; +import dev.isxander.controlify.impl.api.bind.InputBindingSupplier; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.ChatFormatting; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/bindings/KeyMappingHandle.java b/src/main/java/dev/isxander/controlify/impl/bindings/KeyMappingHandle.java similarity index 55% rename from src/main/java/dev/isxander/controlify/bindings/KeyMappingHandle.java rename to src/main/java/dev/isxander/controlify/impl/bindings/KeyMappingHandle.java index 5b430074e..beba3d178 100644 --- a/src/main/java/dev/isxander/controlify/bindings/KeyMappingHandle.java +++ b/src/main/java/dev/isxander/controlify/impl/bindings/KeyMappingHandle.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.bindings; +package dev.isxander.controlify.impl.bindings; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.controller.ControllerImpl; import java.util.function.BooleanSupplier; public interface KeyMappingHandle { void controlify$setPressed(boolean isDown); - void controlify$addToggleCondition(ControllerEntity controller, BooleanSupplier condition); + void controlify$addToggleCondition(ControllerImpl controller, BooleanSupplier condition); } diff --git a/src/main/java/dev/isxander/controlify/fixes/boatfix/AnalogBoatInput.java b/src/main/java/dev/isxander/controlify/impl/boatfix/AnalogBoatInput.java similarity index 87% rename from src/main/java/dev/isxander/controlify/fixes/boatfix/AnalogBoatInput.java rename to src/main/java/dev/isxander/controlify/impl/boatfix/AnalogBoatInput.java index 137a98149..e9761bc6c 100644 --- a/src/main/java/dev/isxander/controlify/fixes/boatfix/AnalogBoatInput.java +++ b/src/main/java/dev/isxander/controlify/impl/boatfix/AnalogBoatInput.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fixes.boatfix; +package dev.isxander.controlify.impl.boatfix; import dev.isxander.controlify.mixins.feature.patches.analogueboat.AbstractBoatMixin; diff --git a/src/main/java/dev/isxander/controlify/compatibility/CompatMixinPlatform.java b/src/main/java/dev/isxander/controlify/impl/compatibility/CompatMixinPlatform.java similarity index 81% rename from src/main/java/dev/isxander/controlify/compatibility/CompatMixinPlatform.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/CompatMixinPlatform.java index f73a79e39..82b424b7c 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/CompatMixinPlatform.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/CompatMixinPlatform.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility; +package dev.isxander.controlify.impl.compatibility; @FunctionalInterface public interface CompatMixinPlatform { diff --git a/src/main/java/dev/isxander/controlify/compatibility/CompatMixinPlugin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/CompatMixinPlugin.java similarity index 98% rename from src/main/java/dev/isxander/controlify/compatibility/CompatMixinPlugin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/CompatMixinPlugin.java index 25186290a..bc62b26b2 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/CompatMixinPlugin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/CompatMixinPlugin.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility; +package dev.isxander.controlify.impl.compatibility; import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; diff --git a/src/main/java/dev/isxander/controlify/compatibility/ControlifyCompat.java b/src/main/java/dev/isxander/controlify/impl/compatibility/ControlifyCompat.java similarity index 80% rename from src/main/java/dev/isxander/controlify/compatibility/ControlifyCompat.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/ControlifyCompat.java index d50059884..87a47cd7f 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/ControlifyCompat.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/ControlifyCompat.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility; +package dev.isxander.controlify.impl.compatibility; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.util.Util; import java.util.HashSet; @@ -28,7 +28,7 @@ public static void init() { try { wrapCompatCall( SIMPLE_VOICE_CHAT, - dev.isxander.controlify.compatibility.simplevoicechat.SimpleVoiceChatCompat::init + dev.isxander.controlify.impl.compatibility.simplevoicechat.SimpleVoiceChatCompat::init ); } catch (NoClassDefFoundError e) { disabledMods.add(SIMPLE_VOICE_CHAT); @@ -39,7 +39,7 @@ public static void init() { try { wrapCompatCall( FANCY_MENU, - dev.isxander.controlify.compatibility.fancymenu.FancyMenuCompat::registerActions + dev.isxander.controlify.impl.compatibility.fancymenu.FancyMenuCompat::registerActions ); } catch (NoClassDefFoundError e) { disabledMods.add(FANCY_MENU); diff --git a/src/main/java/dev/isxander/controlify/compatibility/fancymenu/FancyMenuCompat.java b/src/main/java/dev/isxander/controlify/impl/compatibility/fancymenu/FancyMenuCompat.java similarity index 85% rename from src/main/java/dev/isxander/controlify/compatibility/fancymenu/FancyMenuCompat.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/fancymenu/FancyMenuCompat.java index 9c4f78d56..efc560f69 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/fancymenu/FancyMenuCompat.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/fancymenu/FancyMenuCompat.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.fancymenu; +package dev.isxander.controlify.impl.compatibility.fancymenu; //? if fancy_menu { diff --git a/src/main/java/dev/isxander/controlify/compatibility/fancymenu/OpenControlifySettingsAction.java b/src/main/java/dev/isxander/controlify/impl/compatibility/fancymenu/OpenControlifySettingsAction.java similarity index 84% rename from src/main/java/dev/isxander/controlify/compatibility/fancymenu/OpenControlifySettingsAction.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/fancymenu/OpenControlifySettingsAction.java index c0d53df54..c4905900b 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/fancymenu/OpenControlifySettingsAction.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/fancymenu/OpenControlifySettingsAction.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.fancymenu; +package dev.isxander.controlify.impl.compatibility.fancymenu; //? if fancy_menu { import de.keksuccino.fancymenu.customization.action.Action; -import dev.isxander.controlify.gui.screen.ControlifySettingsScreen; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.gui.screen.ControlifySettingsScreen; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/compatibility/iris/IrisMixinPlugin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/iris/IrisMixinPlugin.java similarity index 66% rename from src/main/java/dev/isxander/controlify/compatibility/iris/IrisMixinPlugin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/iris/IrisMixinPlugin.java index 7caf475c6..0525fa487 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/iris/IrisMixinPlugin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/iris/IrisMixinPlugin.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.iris; +package dev.isxander.controlify.impl.compatibility.iris; -import dev.isxander.controlify.compatibility.CompatMixinPlugin; +import dev.isxander.controlify.impl.compatibility.CompatMixinPlugin; public class IrisMixinPlugin extends CompatMixinPlugin { @Override diff --git a/src/main/java/dev/isxander/controlify/compatibility/iris/mixins/BaseOptionElementWidgetMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/iris/mixins/BaseOptionElementWidgetMixin.java similarity index 78% rename from src/main/java/dev/isxander/controlify/compatibility/iris/mixins/BaseOptionElementWidgetMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/iris/mixins/BaseOptionElementWidgetMixin.java index 50d7ca7f6..10803cdd8 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/iris/mixins/BaseOptionElementWidgetMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/iris/mixins/BaseOptionElementWidgetMixin.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.iris.mixins; +package dev.isxander.controlify.impl.compatibility.iris.mixins; //? if iris { -import dev.isxander.controlify.compatibility.iris.screenop.BaseOptionElementComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.compatibility.iris.screenop.BaseOptionElementComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; import net.irisshaders.iris.gui.NavigationController; import net.irisshaders.iris.gui.element.widget.BaseOptionElementWidget; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/compatibility/iris/screenop/BaseOptionElementComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/iris/screenop/BaseOptionElementComponentProcessor.java similarity index 78% rename from src/main/java/dev/isxander/controlify/compatibility/iris/screenop/BaseOptionElementComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/iris/screenop/BaseOptionElementComponentProcessor.java index 138d6ee85..70ece565d 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/iris/screenop/BaseOptionElementComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/iris/screenop/BaseOptionElementComponentProcessor.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.iris.screenop; +package dev.isxander.controlify.impl.compatibility.iris.screenop; //? if iris { -import dev.isxander.controlify.screenop.compat.AbstractSliderComponentProcessor; +import dev.isxander.controlify.impl.screenop.compat.AbstractSliderComponentProcessor; import java.util.function.Consumer; diff --git a/src/main/java/dev/isxander/controlify/compatibility/rrls/RrlsMixinPlugin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/rrls/RrlsMixinPlugin.java similarity index 66% rename from src/main/java/dev/isxander/controlify/compatibility/rrls/RrlsMixinPlugin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/rrls/RrlsMixinPlugin.java index 0b1b7f937..16f42bda5 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/rrls/RrlsMixinPlugin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/rrls/RrlsMixinPlugin.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.rrls; +package dev.isxander.controlify.impl.compatibility.rrls; -import dev.isxander.controlify.compatibility.CompatMixinPlugin; +import dev.isxander.controlify.impl.compatibility.CompatMixinPlugin; public class RrlsMixinPlugin extends CompatMixinPlugin { @Override diff --git a/src/main/java/dev/isxander/controlify/compatibility/rrls/mixins/HideTypeMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/rrls/mixins/HideTypeMixin.java similarity index 92% rename from src/main/java/dev/isxander/controlify/compatibility/rrls/mixins/HideTypeMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/rrls/mixins/HideTypeMixin.java index 68d479f57..5b80ee800 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/rrls/mixins/HideTypeMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/rrls/mixins/HideTypeMixin.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.rrls.mixins; +package dev.isxander.controlify.impl.compatibility.rrls.mixins; import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import org.spongepowered.asm.mixin.Dynamic; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Pseudo; diff --git a/src/main/java/dev/isxander/controlify/compatibility/rso/RSOMixinPlugin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/rso/RSOMixinPlugin.java similarity index 67% rename from src/main/java/dev/isxander/controlify/compatibility/rso/RSOMixinPlugin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/rso/RSOMixinPlugin.java index 867051aa0..bfb7c9ee6 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/rso/RSOMixinPlugin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/rso/RSOMixinPlugin.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.rso; +package dev.isxander.controlify.impl.compatibility.rso; -import dev.isxander.controlify.compatibility.CompatMixinPlugin; +import dev.isxander.controlify.impl.compatibility.CompatMixinPlugin; public class RSOMixinPlugin extends CompatMixinPlugin { @Override diff --git a/src/main/java/dev/isxander/controlify/compatibility/rso/mixins/AbstractFrameAccessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/rso/mixins/AbstractFrameAccessor.java similarity index 90% rename from src/main/java/dev/isxander/controlify/compatibility/rso/mixins/AbstractFrameAccessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/rso/mixins/AbstractFrameAccessor.java index d55e061be..e620bc981 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/rso/mixins/AbstractFrameAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/rso/mixins/AbstractFrameAccessor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.rso.mixins; +package dev.isxander.controlify.impl.compatibility.rso.mixins; //? if reeses_sodium_options { /*import me.flashyreese.mods.reeses_sodium_options.client.gui.frame.AbstractFrame; diff --git a/src/main/java/dev/isxander/controlify/compatibility/rso/mixins/SodiumVideoOptionsScreenMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/rso/mixins/SodiumVideoOptionsScreenMixin.java similarity index 98% rename from src/main/java/dev/isxander/controlify/compatibility/rso/mixins/SodiumVideoOptionsScreenMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/rso/mixins/SodiumVideoOptionsScreenMixin.java index 7ef7837b3..3ee55bd84 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/rso/mixins/SodiumVideoOptionsScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/rso/mixins/SodiumVideoOptionsScreenMixin.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.rso.mixins; +package dev.isxander.controlify.impl.compatibility.rso.mixins; //? if reeses_sodium_options { /*import com.llamalad7.mixinextras.injector.ModifyExpressionValue; diff --git a/src/main/java/dev/isxander/controlify/compatibility/rso/mixins/TabFrameAccessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/rso/mixins/TabFrameAccessor.java similarity index 92% rename from src/main/java/dev/isxander/controlify/compatibility/rso/mixins/TabFrameAccessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/rso/mixins/TabFrameAccessor.java index 55189e1f7..e8983b55e 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/rso/mixins/TabFrameAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/rso/mixins/TabFrameAccessor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.rso.mixins; +package dev.isxander.controlify.impl.compatibility.rso.mixins; //? if reeses_sodium_options { /*import me.flashyreese.mods.reeses_sodium_options.client.gui.frame.AbstractFrame; diff --git a/src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/SVCMixinPlugin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/SVCMixinPlugin.java similarity index 64% rename from src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/SVCMixinPlugin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/SVCMixinPlugin.java index eeb850f03..134273d6f 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/SVCMixinPlugin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/SVCMixinPlugin.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.simplevoicechat; +package dev.isxander.controlify.impl.compatibility.simplevoicechat; -import dev.isxander.controlify.compatibility.CompatMixinPlugin; +import dev.isxander.controlify.impl.compatibility.CompatMixinPlugin; public class SVCMixinPlugin extends CompatMixinPlugin { @Override diff --git a/src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/SimpleVoiceChatCompat.java b/src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/SimpleVoiceChatCompat.java similarity index 86% rename from src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/SimpleVoiceChatCompat.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/SimpleVoiceChatCompat.java index 12d0f5de2..d00ccbac0 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/SimpleVoiceChatCompat.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/SimpleVoiceChatCompat.java @@ -4,18 +4,18 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.simplevoicechat; +package dev.isxander.controlify.impl.compatibility.simplevoicechat; //? if simple_voice_chat { import de.maxhenkel.voicechat.voice.client.ClientManager; import de.maxhenkel.voicechat.voice.client.KeyEvents; -import dev.isxander.controlify.api.event.ControlifyEvents; -import dev.isxander.controlify.api.bind.ControlifyBindApi; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.compatibility.simplevoicechat.mixins.KeyEventsAccessor; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.api.ControlifyEvents; +import dev.isxander.controlify.impl.api.bind.ControlifyBindApi; +import dev.isxander.controlify.impl.api.bind.InputBindingSupplier; +import dev.isxander.controlify.impl.compatibility.simplevoicechat.mixins.KeyEventsAccessor; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; @@ -51,7 +51,7 @@ public static void init() { .keyEmulation(KeyEvents.KEY_MUTE)); ControlifyEvents.ACTIVE_CONTROLLER_TICKED.register(event -> { - ControllerEntity controller = event.controller(); + ControllerImpl controller = event.controller(); var pttHold = pttHoldSupplier.on(controller); var pttToggle = pttToggleSupplier.on(controller); diff --git a/src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/mixins/KeyEventsAccessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/mixins/KeyEventsAccessor.java similarity index 84% rename from src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/mixins/KeyEventsAccessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/mixins/KeyEventsAccessor.java index ecc4a2f14..263a98771 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/mixins/KeyEventsAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/mixins/KeyEventsAccessor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.simplevoicechat.mixins; +package dev.isxander.controlify.impl.compatibility.simplevoicechat.mixins; //? if simple_voice_chat { diff --git a/src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/mixins/PTTKeyHandlerMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/mixins/PTTKeyHandlerMixin.java similarity index 87% rename from src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/mixins/PTTKeyHandlerMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/mixins/PTTKeyHandlerMixin.java index 2ce75f8c3..9c29d6b81 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/simplevoicechat/mixins/PTTKeyHandlerMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/simplevoicechat/mixins/PTTKeyHandlerMixin.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.simplevoicechat.mixins; +package dev.isxander.controlify.impl.compatibility.simplevoicechat.mixins; //? if simple_voice_chat { import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import de.maxhenkel.voicechat.voice.client.PTTKeyHandler; -import dev.isxander.controlify.compatibility.simplevoicechat.SimpleVoiceChatCompat; +import dev.isxander.controlify.impl.compatibility.simplevoicechat.SimpleVoiceChatCompat; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/SodiumMixinPlugin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/SodiumMixinPlugin.java similarity index 66% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/SodiumMixinPlugin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/SodiumMixinPlugin.java index 2899a76a3..0f337f3ae 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/SodiumMixinPlugin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/SodiumMixinPlugin.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium; +package dev.isxander.controlify.impl.compatibility.sodium; -import dev.isxander.controlify.compatibility.CompatMixinPlugin; +import dev.isxander.controlify.impl.compatibility.CompatMixinPlugin; public class SodiumMixinPlugin extends CompatMixinPlugin { @Override diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/AbstractWidgetMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/AbstractWidgetMixin.java similarity index 88% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/AbstractWidgetMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/AbstractWidgetMixin.java index 91090a871..c936c38aa 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/AbstractWidgetMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/AbstractWidgetMixin.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.mixins; +package dev.isxander.controlify.impl.compatibility.sodium.mixins; //? if sodium { import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import net.minecraft.client.InputType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/CycleControlElementMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/CycleControlElementMixin.java similarity index 72% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/CycleControlElementMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/CycleControlElementMixin.java index 8c3aa78ba..62575c030 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/CycleControlElementMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/CycleControlElementMixin.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.mixins; +package dev.isxander.controlify.impl.compatibility.sodium.mixins; //? if sodium { -import dev.isxander.controlify.compatibility.sodium.screenop.CycleControlProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.compatibility.sodium.screenop.CycleControlProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/FlatButtonWidgetAccessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/FlatButtonWidgetAccessor.java similarity index 86% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/FlatButtonWidgetAccessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/FlatButtonWidgetAccessor.java index 6cd2513d5..0f75a167b 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/FlatButtonWidgetAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/FlatButtonWidgetAccessor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.mixins; +package dev.isxander.controlify.impl.compatibility.sodium.mixins; //? if sodium { diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/FlatButtonWidgetMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/FlatButtonWidgetMixin.java similarity index 91% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/FlatButtonWidgetMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/FlatButtonWidgetMixin.java index c9e592836..6fca9d01f 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/FlatButtonWidgetMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/FlatButtonWidgetMixin.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.mixins; +package dev.isxander.controlify.impl.compatibility.sodium.mixins; //? if sodium { import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.gui.ButtonGuideRenderer; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.gui.ButtonGuideRenderer; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import net.minecraft.network.chat.Component; import org.objectweb.asm.Opcodes; diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/SliderControlElementMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/SliderControlElementMixin.java similarity index 83% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/SliderControlElementMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/SliderControlElementMixin.java index 2b8c05ed1..13f9e9e1d 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/SliderControlElementMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/SliderControlElementMixin.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.mixins; +package dev.isxander.controlify.impl.compatibility.sodium.mixins; //? if sodium { -import dev.isxander.controlify.compatibility.sodium.screenop.SliderControlProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.compatibility.sodium.screenop.SliderControlProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; import net.caffeinemc.mods.sodium.client.config.structure.IntegerOption; import net.caffeinemc.mods.sodium.client.gui.ColorTheme; import net.caffeinemc.mods.sodium.client.gui.options.control.AbstractOptionList; diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/TickBoxControlElementMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/TickBoxControlElementMixin.java similarity index 72% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/TickBoxControlElementMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/TickBoxControlElementMixin.java index 82efa42b0..60c3297c4 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/TickBoxControlElementMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/TickBoxControlElementMixin.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.mixins; +package dev.isxander.controlify.impl.compatibility.sodium.mixins; //? if sodium { -import dev.isxander.controlify.compatibility.sodium.screenop.TickBoxControlProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.compatibility.sodium.screenop.TickBoxControlProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/VideoSettingsScreenMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/VideoSettingsScreenMixin.java similarity index 90% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/VideoSettingsScreenMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/VideoSettingsScreenMixin.java index cf87cfae3..9c29763bf 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/mixins/VideoSettingsScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/mixins/VideoSettingsScreenMixin.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.mixins; +package dev.isxander.controlify.impl.compatibility.sodium.mixins; //? if sodium { -import dev.isxander.controlify.compatibility.sodium.screenop.SodiumGuiScreenProcessor; -import dev.isxander.controlify.compatibility.sodium.screenop.SodiumScreenOperations; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.compatibility.sodium.screenop.SodiumGuiScreenProcessor; +import dev.isxander.controlify.impl.compatibility.sodium.screenop.SodiumScreenOperations; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; import net.caffeinemc.mods.sodium.client.config.ConfigManager; import net.caffeinemc.mods.sodium.client.config.structure.Page; import net.caffeinemc.mods.sodium.client.gui.VideoSettingsScreen; diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/CycleControlProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/CycleControlProcessor.java similarity index 69% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/CycleControlProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/CycleControlProcessor.java index d86593f8a..f3b87073a 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/CycleControlProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/CycleControlProcessor.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.screenop; +package dev.isxander.controlify.impl.compatibility.sodium.screenop; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import java.util.function.Consumer; @@ -21,7 +21,7 @@ public CycleControlProcessor(Consumer cycleMethod) { } @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { if (ControlifyBindings.GUI_SECONDARY_NAVI_RIGHT.on(controller).justPressed() || ControlifyBindings.GUI_PRESS.on(controller).justPressed() ) { diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/SliderControlProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/SliderControlProcessor.java similarity index 76% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/SliderControlProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/SliderControlProcessor.java index 266ba02dc..19247d025 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/SliderControlProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/SliderControlProcessor.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.screenop; +package dev.isxander.controlify.impl.compatibility.sodium.screenop; -import dev.isxander.controlify.screenop.compat.AbstractSliderComponentProcessor; +import dev.isxander.controlify.impl.screenop.compat.AbstractSliderComponentProcessor; import java.util.function.Consumer; diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/SodiumGuiScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/SodiumGuiScreenProcessor.java similarity index 73% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/SodiumGuiScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/SodiumGuiScreenProcessor.java index 12667a3fb..ab154ebd9 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/SodiumGuiScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/SodiumGuiScreenProcessor.java @@ -4,16 +4,16 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.screenop; +package dev.isxander.controlify.impl.compatibility.sodium.screenop; //? if sodium { -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.compatibility.sodium.mixins.FlatButtonWidgetAccessor; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.compatibility.sodium.mixins.FlatButtonWidgetAccessor; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import net.minecraft.client.gui.screens.Screen; public class SodiumGuiScreenProcessor extends ScreenProcessor { @@ -25,12 +25,12 @@ public SodiumGuiScreenProcessor(Screen screen, SodiumScreenOperations operations } @Override - protected void handleComponentNavigation(ControllerEntity controller) { + protected void handleComponentNavigation(ControllerImpl controller) { super.handleComponentNavigation(controller); } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { if (ControlifyBindings.GUI_ABSTRACT_ACTION_1.on(controller).justPressed()) { ((FlatButtonWidgetAccessor) operations.controlify$getApplyButton()).invokeDoAction(); } diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/SodiumScreenOperations.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/SodiumScreenOperations.java similarity index 87% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/SodiumScreenOperations.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/SodiumScreenOperations.java index be61f804f..026e253e7 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/SodiumScreenOperations.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/SodiumScreenOperations.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.screenop; +package dev.isxander.controlify.impl.compatibility.sodium.screenop; //? if sodium { diff --git a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/TickBoxControlProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/TickBoxControlProcessor.java similarity index 67% rename from src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/TickBoxControlProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/TickBoxControlProcessor.java index 376066774..11754626d 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/sodium/screenop/TickBoxControlProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/sodium/screenop/TickBoxControlProcessor.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.sodium.screenop; +package dev.isxander.controlify.impl.compatibility.sodium.screenop; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; public class TickBoxControlProcessor implements ComponentProcessor { private final Runnable toggleMethod; @@ -19,7 +19,7 @@ public TickBoxControlProcessor(Runnable toggleMethod) { } @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { if (ControlifyBindings.GUI_PRESS.on(controller).guiPressed().get()) { toggleMethod.run(); return true; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/YACLMixinPlugin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/YACLMixinPlugin.java similarity index 67% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/YACLMixinPlugin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/YACLMixinPlugin.java index ab2ad90cd..9163b7d88 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/YACLMixinPlugin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/YACLMixinPlugin.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl; +package dev.isxander.controlify.impl.compatibility.yacl; -import dev.isxander.controlify.compatibility.CompatMixinPlugin; +import dev.isxander.controlify.impl.compatibility.CompatMixinPlugin; public class YACLMixinPlugin extends CompatMixinPlugin { @Override diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/ControllerWidgetAccessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/ControllerWidgetAccessor.java similarity index 87% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/ControllerWidgetAccessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/ControllerWidgetAccessor.java index b71b7b205..ef171811c 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/ControllerWidgetAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/ControllerWidgetAccessor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; import dev.isxander.yacl3.api.Controller; import dev.isxander.yacl3.gui.controllers.ControllerWidget; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/CyclingControllerElementMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/CyclingControllerElementMixin.java similarity index 68% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/CyclingControllerElementMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/CyclingControllerElementMixin.java index 867ffaa98..2bd77edb5 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/CyclingControllerElementMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/CyclingControllerElementMixin.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.compatibility.yacl.screenop.CyclingControllerElementComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.compatibility.yacl.screenop.CyclingControllerElementComponentProcessor; import dev.isxander.yacl3.gui.controllers.cycling.CyclingControllerElement; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/GroupSeparatorEntryAccessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/GroupSeparatorEntryAccessor.java similarity index 87% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/GroupSeparatorEntryAccessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/GroupSeparatorEntryAccessor.java index 5982f854d..c6ea351fa 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/GroupSeparatorEntryAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/GroupSeparatorEntryAccessor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; import dev.isxander.yacl3.gui.OptionListWidget; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/OptionListWidgetMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/OptionListWidgetMixin.java similarity index 67% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/OptionListWidgetMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/OptionListWidgetMixin.java index 023fb1593..d47ac7454 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/OptionListWidgetMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/OptionListWidgetMixin.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; -import dev.isxander.controlify.compatibility.yacl.screenop.OptionListWidgetComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.compatibility.yacl.screenop.OptionListWidgetComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; import dev.isxander.yacl3.gui.OptionListWidget; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/SliderControllerElementMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/SliderControllerElementMixin.java similarity index 68% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/SliderControllerElementMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/SliderControllerElementMixin.java index bdc484c14..8b0f11aa7 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/SliderControllerElementMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/SliderControllerElementMixin.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.compatibility.yacl.screenop.SliderControllerElementComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.compatibility.yacl.screenop.SliderControllerElementComponentProcessor; import dev.isxander.yacl3.gui.controllers.slider.SliderControllerElement; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/StringControllerElementAccessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/StringControllerElementAccessor.java similarity index 86% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/StringControllerElementAccessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/StringControllerElementAccessor.java index e47c13b88..bd40e6141 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/StringControllerElementAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/StringControllerElementAccessor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; import dev.isxander.yacl3.gui.controllers.string.StringControllerElement; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/StringControllerElementMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/StringControllerElementMixin.java similarity index 68% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/StringControllerElementMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/StringControllerElementMixin.java index ffd082b3b..ae449df55 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/StringControllerElementMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/StringControllerElementMixin.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; -import dev.isxander.controlify.compatibility.yacl.screenop.StringControllerElementComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.compatibility.yacl.screenop.StringControllerElementComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; import dev.isxander.yacl3.gui.controllers.string.StringControllerElement; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/YACLScreenCategoryTabAccessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/YACLScreenCategoryTabAccessor.java similarity index 90% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/YACLScreenCategoryTabAccessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/YACLScreenCategoryTabAccessor.java index fae748607..09a2f3ad2 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/YACLScreenCategoryTabAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/YACLScreenCategoryTabAccessor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; import dev.isxander.yacl3.gui.OptionListWidget; import dev.isxander.yacl3.gui.WidgetAndType; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/YACLScreenCategoryTabMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/YACLScreenCategoryTabMixin.java similarity index 78% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/YACLScreenCategoryTabMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/YACLScreenCategoryTabMixin.java index 9fb2756f1..89370f043 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/YACLScreenCategoryTabMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/YACLScreenCategoryTabMixin.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; import dev.isxander.yacl3.gui.YACLScreen; import net.minecraft.client.gui.components.Button; import org.spongepowered.asm.mixin.Final; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/YACLScreenMixin.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/YACLScreenMixin.java similarity index 66% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/YACLScreenMixin.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/YACLScreenMixin.java index 3515ed9f6..c77e766e2 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/mixins/YACLScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/mixins/YACLScreenMixin.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.mixins; +package dev.isxander.controlify.impl.compatibility.yacl.mixins; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.compatibility.yacl.screenop.YACLScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.compatibility.yacl.screenop.YACLScreenProcessor; import dev.isxander.yacl3.gui.YACLScreen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/CyclingControllerElementComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/CyclingControllerElementComponentProcessor.java similarity index 73% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/CyclingControllerElementComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/CyclingControllerElementComponentProcessor.java index 1fb987ae8..216cac244 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/CyclingControllerElementComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/CyclingControllerElementComponentProcessor.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.screenop; +package dev.isxander.controlify.impl.compatibility.yacl.screenop; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.compatibility.yacl.mixins.ControllerWidgetAccessor; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.compatibility.yacl.mixins.ControllerWidgetAccessor; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import dev.isxander.yacl3.gui.controllers.cycling.CyclingControllerElement; public class CyclingControllerElementComponentProcessor implements ComponentProcessor { @@ -23,7 +23,7 @@ public CyclingControllerElementComponentProcessor(CyclingControllerElement cycli } @Override - public boolean overrideControllerNavigation(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerNavigation(ScreenProcessor screen, ControllerImpl controller) { boolean left = ControlifyBindings.GUI_SECONDARY_NAVI_LEFT.on(controller).digitalNow(); boolean right = ControlifyBindings.GUI_SECONDARY_NAVI_RIGHT.on(controller).digitalNow(); diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/OptionListWidgetComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/OptionListWidgetComponentProcessor.java similarity index 82% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/OptionListWidgetComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/OptionListWidgetComponentProcessor.java index 79e4d6a6b..160306be5 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/OptionListWidgetComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/OptionListWidgetComponentProcessor.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.screenop; +package dev.isxander.controlify.impl.compatibility.yacl.screenop; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.compatibility.yacl.mixins.GroupSeparatorEntryAccessor; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.compatibility.yacl.mixins.GroupSeparatorEntryAccessor; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import dev.isxander.yacl3.gui.OptionListWidget; import org.jetbrains.annotations.Nullable; @@ -27,7 +27,7 @@ public OptionListWidgetComponentProcessor(OptionListWidget optionListWidget) { * Allows navigating between groups using secondary navigation up/down. */ @Override - public boolean overrideControllerNavigation(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerNavigation(ScreenProcessor screen, ControllerImpl controller) { boolean up = ControlifyBindings.GUI_SECONDARY_NAVI_UP.on(controller).justPressed(); boolean down = ControlifyBindings.GUI_SECONDARY_NAVI_DOWN.on(controller).justPressed(); if (up || down) { diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/SliderControllerElementComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/SliderControllerElementComponentProcessor.java similarity index 74% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/SliderControllerElementComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/SliderControllerElementComponentProcessor.java index 4f396ebd4..35a32bf1d 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/SliderControllerElementComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/SliderControllerElementComponentProcessor.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.screenop; - -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.compatibility.yacl.mixins.ControllerWidgetAccessor; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.utils.HoldRepeatHelper; +package dev.isxander.controlify.impl.compatibility.yacl.screenop; + +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.compatibility.yacl.mixins.ControllerWidgetAccessor; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.utils.HoldRepeatHelper; import dev.isxander.yacl3.gui.controllers.slider.SliderControllerElement; public class SliderControllerElementComponentProcessor implements ComponentProcessor { @@ -23,7 +23,7 @@ public SliderControllerElementComponentProcessor(SliderControllerElement element } @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { var left = ControlifyBindings.GUI_SECONDARY_NAVI_LEFT.on(controller).digitalNow(); var leftPrev = ControlifyBindings.GUI_SECONDARY_NAVI_LEFT.on(controller).digitalPrev(); var right = ControlifyBindings.GUI_SECONDARY_NAVI_RIGHT.on(controller).digitalNow(); diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/StringControllerElementComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/StringControllerElementComponentProcessor.java similarity index 74% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/StringControllerElementComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/StringControllerElementComponentProcessor.java index ac0f15fbd..28355cb28 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/StringControllerElementComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/StringControllerElementComponentProcessor.java @@ -4,17 +4,17 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.screenop; +package dev.isxander.controlify.impl.compatibility.yacl.screenop; import com.mojang.blaze3d.platform.InputConstants; -import dev.isxander.controlify.compatibility.yacl.mixins.StringControllerElementAccessor; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.keyboard.ComponentKeyboardBehaviour; -import dev.isxander.controlify.screenop.keyboard.InputTarget; -import dev.isxander.controlify.screenop.keyboard.KeyboardLayouts; -import dev.isxander.controlify.screenop.keyboard.KeyboardOverlayScreen; +import dev.isxander.controlify.impl.compatibility.yacl.mixins.StringControllerElementAccessor; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.keyboard.ComponentKeyboardBehaviour; +import dev.isxander.controlify.impl.screenop.keyboard.InputTarget; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardLayouts; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardOverlayScreen; import dev.isxander.yacl3.gui.controllers.string.StringControllerElement; import net.minecraft.client.input.CharacterEvent; import net.minecraft.client.input.KeyEvent; @@ -27,7 +27,7 @@ public StringControllerElementComponentProcessor(StringControllerElement element } @Override - public ComponentKeyboardBehaviour getKeyboardBehaviour(ScreenProcessor screen, ControllerEntity controller) { + public ComponentKeyboardBehaviour getKeyboardBehaviour(ScreenProcessor screen, ControllerImpl controller) { return new ComponentKeyboardBehaviour.Handled( KeyboardLayouts.simple(), new StringInputTarget(), diff --git a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/YACLScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/YACLScreenProcessor.java similarity index 75% rename from src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/YACLScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/YACLScreenProcessor.java index 9c9351fad..2bcc57edf 100644 --- a/src/main/java/dev/isxander/controlify/compatibility/yacl/screenop/YACLScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/compatibility/yacl/screenop/YACLScreenProcessor.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.compatibility.yacl.screenop; +package dev.isxander.controlify.impl.compatibility.yacl.screenop; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.compatibility.yacl.mixins.YACLScreenCategoryTabAccessor; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.compatibility.yacl.mixins.YACLScreenCategoryTabAccessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import dev.isxander.yacl3.gui.OptionListWidget; import dev.isxander.yacl3.gui.WidgetAndType; import dev.isxander.yacl3.gui.YACLScreen; @@ -20,7 +20,7 @@ public YACLScreenProcessor(YACLScreen screen) { } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { if (ControlifyBindings.GUI_ABSTRACT_ACTION_1.on(controller).justPressed()) { if (screen.tabManager.getCurrentTab() instanceof YACLScreen.CategoryTab categoryTab) { ((YACLScreenCategoryTabAccessor) categoryTab).getSaveFinishedButton().onPress(null); @@ -32,7 +32,7 @@ protected void handleButtons(ControllerEntity controller) { } @Override - protected void onTabChanged(ControllerEntity controller) { + protected void onTabChanged(ControllerImpl controller) { if (screen.tabManager.getCurrentTab() instanceof YACLScreen.CategoryTab categoryTab) { WidgetAndType optionListHolder = ((YACLScreenCategoryTabAccessor) categoryTab).getOptionList(); OptionListWidget optionList = optionListHolder.getType(); diff --git a/src/main/java/dev/isxander/controlify/config/ConfigManager.java b/src/main/java/dev/isxander/controlify/impl/config/ConfigManager.java similarity index 96% rename from src/main/java/dev/isxander/controlify/config/ConfigManager.java rename to src/main/java/dev/isxander/controlify/impl/config/ConfigManager.java index f510bc58e..860a0abd3 100644 --- a/src/main/java/dev/isxander/controlify/config/ConfigManager.java +++ b/src/main/java/dev/isxander/controlify/impl/config/ConfigManager.java @@ -4,18 +4,18 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config; +package dev.isxander.controlify.impl.config; import com.google.gson.*; import com.mojang.logging.LogUtils; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.config.dto.SharedConfig; -import dev.isxander.controlify.config.dto.dfu.ControlifyDataFixer; -import dev.isxander.controlify.config.dto.profile.ProfileConfig; -import dev.isxander.controlify.config.settings.ControlifySettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; -import dev.isxander.controlify.debug.DebugProperties; +import dev.isxander.controlify.impl.config.dto.SharedConfig; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyDataFixer; +import dev.isxander.controlify.impl.config.dto.profile.ProfileConfig; +import dev.isxander.controlify.impl.config.settings.ControlifySettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.debug.DebugProperties; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; diff --git a/src/main/java/dev/isxander/controlify/config/ConfigMigrator.java b/src/main/java/dev/isxander/controlify/impl/config/ConfigMigrator.java similarity index 92% rename from src/main/java/dev/isxander/controlify/config/ConfigMigrator.java rename to src/main/java/dev/isxander/controlify/impl/config/ConfigMigrator.java index f45313fee..3db68f6c1 100644 --- a/src/main/java/dev/isxander/controlify/config/ConfigMigrator.java +++ b/src/main/java/dev/isxander/controlify/impl/config/ConfigMigrator.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config; +package dev.isxander.controlify.impl.config; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -15,13 +15,13 @@ import com.mojang.serialization.DataResult; import com.mojang.serialization.Dynamic; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.config.dto.SharedConfig; -import dev.isxander.controlify.config.dto.dfu.ControlifyDataFixer; -import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; -import dev.isxander.controlify.config.dto.profile.ProfileConfig; -import dev.isxander.controlify.config.dto.profile.defaults.DefaultConfigManager; -import dev.isxander.controlify.config.settings.ControlifySettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.config.dto.SharedConfig; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyDataFixer; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.impl.config.dto.profile.ProfileConfig; +import dev.isxander.controlify.impl.config.dto.profile.defaults.DefaultConfigManager; +import dev.isxander.controlify.impl.config.settings.ControlifySettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; import java.io.IOException; import java.util.ArrayList; diff --git a/src/main/java/dev/isxander/controlify/config/dto/GlobalConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/GlobalConfig.java similarity index 94% rename from src/main/java/dev/isxander/controlify/config/dto/GlobalConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/GlobalConfig.java index c4766d70c..5fece7c93 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/GlobalConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/GlobalConfig.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto; +package dev.isxander.controlify.impl.config.dto; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.reacharound.ReachAroundMode; +import dev.isxander.controlify.impl.reacharound.ReachAroundMode; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/config/dto/SharedConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/SharedConfig.java similarity index 85% rename from src/main/java/dev/isxander/controlify/config/dto/SharedConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/SharedConfig.java index 563556398..9aaa985c3 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/SharedConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/SharedConfig.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto; +package dev.isxander.controlify.impl.config.dto; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.config.dto.device.DeviceConfig; +import dev.isxander.controlify.impl.config.dto.device.DeviceConfig; import java.util.Map; diff --git a/src/main/java/dev/isxander/controlify/config/dto/device/DeviceConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/device/DeviceConfig.java similarity index 79% rename from src/main/java/dev/isxander/controlify/config/dto/device/DeviceConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/device/DeviceConfig.java index 56b92a71f..c74a64bf8 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/device/DeviceConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/device/DeviceConfig.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.device; +package dev.isxander.controlify.impl.config.dto.device; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.input.mapping.ControllerMapping; +import dev.isxander.controlify.impl.controllermanager.ControllerType; +import dev.isxander.controlify.impl.input.mapping.ControllerMapping; import net.minecraft.resources.Identifier; import java.util.Optional; @@ -24,7 +24,7 @@ public record DeviceConfig( public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.STRING.optionalFieldOf("name", "").forGetter(DeviceConfig::name), Codec.LONG.optionalFieldOf("last_seen", 0L).forGetter(DeviceConfig::lastSeen), - Identifier.CODEC.optionalFieldOf("controller_type", ControllerType.DEFAULT.namespace()).forGetter(DeviceConfig::controllerType), + Identifier.CODEC.optionalFieldOf("controller_type", ControllerType.DEFAULT.id()).forGetter(DeviceConfig::controllerType), GyroCalibrationConfig.CODEC.fieldOf("gyro_calibration").forGetter(DeviceConfig::gyroCalibration), ControllerMapping.CODEC.optionalFieldOf("mapping").forGetter(DeviceConfig::mapping) ).apply(instance, DeviceConfig::new)); diff --git a/src/main/java/dev/isxander/controlify/config/dto/device/GyroCalibrationConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/device/GyroCalibrationConfig.java similarity index 60% rename from src/main/java/dev/isxander/controlify/config/dto/device/GyroCalibrationConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/device/GyroCalibrationConfig.java index 409c71998..fdd059f18 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/device/GyroCalibrationConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/device/GyroCalibrationConfig.java @@ -4,16 +4,18 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.device; +package dev.isxander.controlify.impl.config.dto.device; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.gyro.GyroStateC; +import net.minecraft.util.ExtraCodecs; +import org.joml.Vector3f; +import org.joml.Vector3fc; public record GyroCalibrationConfig( - GyroStateC offset + Vector3fc offset ) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - GyroStateC.CODEC_MUTABLE.optionalFieldOf("offset", GyroStateC.ZERO).forGetter(GyroCalibrationConfig::offset) + ExtraCodecs.VECTOR3F.optionalFieldOf("offset", new Vector3f()).forGetter(GyroCalibrationConfig::offset) ).apply(instance, GyroCalibrationConfig::new)); } diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyDataFixer.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/ControlifyDataFixer.java similarity index 88% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyDataFixer.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/ControlifyDataFixer.java index f10e97d35..42b750006 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyDataFixer.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/ControlifyDataFixer.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu; +package dev.isxander.controlify.impl.config.dto.dfu; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.DataFixerBuilder; -import dev.isxander.controlify.config.dto.dfu.fixes.*; -import dev.isxander.controlify.config.settings.GlobalSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.config.dto.dfu.fixes.*; +import dev.isxander.controlify.impl.config.settings.GlobalSettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; public final class ControlifyDataFixer { public static final int CURRENT_VERSION = 9; diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifySchemas.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/ControlifySchemas.java similarity index 97% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifySchemas.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/ControlifySchemas.java index 3c01b75f4..b9113575c 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifySchemas.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/ControlifySchemas.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu; +package dev.isxander.controlify.impl.config.dto.dfu; import com.mojang.datafixers.DSL; import com.mojang.datafixers.schemas.Schema; diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyTypeReferences.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/ControlifyTypeReferences.java similarity index 93% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyTypeReferences.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/ControlifyTypeReferences.java index 5003c4a2d..69987e79a 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/ControlifyTypeReferences.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/ControlifyTypeReferences.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu; +package dev.isxander.controlify.impl.config.dto.dfu; import com.mojang.datafixers.DSL; diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/AnalogueMovementWhitelistFix.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/AnalogueMovementWhitelistFix.java similarity index 89% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/AnalogueMovementWhitelistFix.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/AnalogueMovementWhitelistFix.java index dd786fae9..e658c2ae6 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/AnalogueMovementWhitelistFix.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/AnalogueMovementWhitelistFix.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu.fixes; +package dev.isxander.controlify.impl.config.dto.dfu.fixes; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFix; import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyTypeReferences; import java.util.stream.Stream; diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/DualsenseConfigFix.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/DualsenseConfigFix.java similarity index 85% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/DualsenseConfigFix.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/DualsenseConfigFix.java index 3f11e7d53..25ae2a3f0 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/DualsenseConfigFix.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/DualsenseConfigFix.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu.fixes; +package dev.isxander.controlify.impl.config.dto.dfu.fixes; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFix; import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; public final class DualsenseConfigFix extends DataFix { private final ProfileSettings profileDefaults; diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GeneratedBindingIdsFix.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/GeneratedBindingIdsFix.java similarity index 94% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GeneratedBindingIdsFix.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/GeneratedBindingIdsFix.java index a37582f36..077416a9e 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GeneratedBindingIdsFix.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/GeneratedBindingIdsFix.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu.fixes; +package dev.isxander.controlify.impl.config.dto.dfu.fixes; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFix; import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyTypeReferences; import java.util.LinkedHashMap; import java.util.Map; diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GuideGuiScaleFix.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/GuideGuiScaleFix.java similarity index 86% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GuideGuiScaleFix.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/GuideGuiScaleFix.java index ebb376807..db939e853 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GuideGuiScaleFix.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/GuideGuiScaleFix.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu.fixes; +package dev.isxander.controlify.impl.config.dto.dfu.fixes; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFix; import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; public class GuideGuiScaleFix extends DataFix { private final ProfileSettings profileDefaults; diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GyroLowPassFix.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/GyroLowPassFix.java similarity index 82% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GyroLowPassFix.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/GyroLowPassFix.java index 27c2fef8d..d2e5eeb07 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/GyroLowPassFix.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/GyroLowPassFix.java @@ -1,12 +1,12 @@ -package dev.isxander.controlify.config.dto.dfu.fixes; +package dev.isxander.controlify.impl.config.dto.dfu.fixes; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFix; import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; public class GyroLowPassFix extends DataFix { private final ProfileSettings profileDefaults; diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/HorizontalLookInvertFix.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/HorizontalLookInvertFix.java similarity index 89% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/HorizontalLookInvertFix.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/HorizontalLookInvertFix.java index 3eb94df99..c1ce914db 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/HorizontalLookInvertFix.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/HorizontalLookInvertFix.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu.fixes; +package dev.isxander.controlify.impl.config.dto.dfu.fixes; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFix; import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyTypeReferences; public final class HorizontalLookInvertFix extends DataFix { public HorizontalLookInvertFix(Schema outputSchema) { diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/RadialMenuActionsFix.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/RadialMenuActionsFix.java similarity index 93% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/RadialMenuActionsFix.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/RadialMenuActionsFix.java index f9cd727ba..d4b0d71f5 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/RadialMenuActionsFix.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/RadialMenuActionsFix.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu.fixes; +package dev.isxander.controlify.impl.config.dto.dfu.fixes; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFix; import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyTypeReferences; import java.util.LinkedHashSet; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/TheHolyMigrationFix.java b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/TheHolyMigrationFix.java similarity index 97% rename from src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/TheHolyMigrationFix.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/TheHolyMigrationFix.java index 093f37b97..d0d7725b6 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/dfu/fixes/TheHolyMigrationFix.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/dfu/fixes/TheHolyMigrationFix.java @@ -4,16 +4,16 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.dfu.fixes; +package dev.isxander.controlify.impl.config.dto.dfu.fixes; import com.mojang.datafixers.DSL; import com.mojang.datafixers.DataFix; import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import dev.isxander.controlify.config.dto.dfu.ControlifyTypeReferences; -import dev.isxander.controlify.config.settings.GlobalSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.config.dto.dfu.ControlifyTypeReferences; +import dev.isxander.controlify.impl.config.settings.GlobalSettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; import java.util.Map; import java.util.Optional; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/BluetoothDeviceConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/BluetoothDeviceConfig.java similarity index 90% rename from src/main/java/dev/isxander/controlify/config/dto/profile/BluetoothDeviceConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/BluetoothDeviceConfig.java index 445b0d50c..bf838c791 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/BluetoothDeviceConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/BluetoothDeviceConfig.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile; +package dev.isxander.controlify.impl.config.dto.profile; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/DualsenseConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/DualsenseConfig.java similarity index 90% rename from src/main/java/dev/isxander/controlify/config/dto/profile/DualsenseConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/DualsenseConfig.java index 064842fd0..1e89db8f9 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/DualsenseConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/DualsenseConfig.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile; +package dev.isxander.controlify.impl.config.dto.profile; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/GenericControllerConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/GenericControllerConfig.java similarity index 97% rename from src/main/java/dev/isxander/controlify/config/dto/profile/GenericControllerConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/GenericControllerConfig.java index 7eccea863..c547a033c 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/GenericControllerConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/GenericControllerConfig.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile; +package dev.isxander.controlify.impl.config.dto.profile; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/GyroConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/GyroConfig.java similarity index 88% rename from src/main/java/dev/isxander/controlify/config/dto/profile/GyroConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/GyroConfig.java index 21682d7c8..774d43307 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/GyroConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/GyroConfig.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile; +package dev.isxander.controlify.impl.config.dto.profile; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.controller.gyro.GyroButtonMode; -import dev.isxander.controlify.controller.gyro.GyroYawMode; +import dev.isxander.controlify.impl.controller.gyro.GyroButtonMode; +import dev.isxander.controlify.impl.controller.gyro.GyroYawMode; public record GyroConfig( float lookSensitivity, diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/HDHapticConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/HDHapticConfig.java similarity index 89% rename from src/main/java/dev/isxander/controlify/config/dto/profile/HDHapticConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/HDHapticConfig.java index 5c43a0b32..df7204edb 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/HDHapticConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/HDHapticConfig.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile; +package dev.isxander.controlify.impl.config.dto.profile; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/InputConfig.java similarity index 95% rename from src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/InputConfig.java index 9ec34705a..efd7809ba 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/InputConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/InputConfig.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile; +package dev.isxander.controlify.impl.config.dto.profile; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.ingame.InputCurves; -import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.impl.ingame.InputCurves; +import dev.isxander.controlify.api.input.LogicalInput; import net.minecraft.resources.Identifier; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/ProfileConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/ProfileConfig.java similarity index 96% rename from src/main/java/dev/isxander/controlify/config/dto/profile/ProfileConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/ProfileConfig.java index 1daf893f6..e376ce2b9 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/ProfileConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/ProfileConfig.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile; +package dev.isxander.controlify.impl.config.dto.profile; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/RumbleConfig.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/RumbleConfig.java similarity index 92% rename from src/main/java/dev/isxander/controlify/config/dto/profile/RumbleConfig.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/RumbleConfig.java index 0b1b86505..7b31787e1 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/RumbleConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/RumbleConfig.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile; +package dev.isxander.controlify.impl.config.dto.profile; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/defaults/DefaultConfigManager.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/defaults/DefaultConfigManager.java similarity index 91% rename from src/main/java/dev/isxander/controlify/config/dto/profile/defaults/DefaultConfigManager.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/defaults/DefaultConfigManager.java index 9dc1a1e4c..2d1d58ffd 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/defaults/DefaultConfigManager.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/defaults/DefaultConfigManager.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile.defaults; +package dev.isxander.controlify.impl.config.dto.profile.defaults; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -12,9 +12,9 @@ import com.mojang.logging.LogUtils; import com.mojang.serialization.DataResult; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.config.dto.profile.ProfileConfig; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.config.dto.profile.ProfileConfig; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.CrashReport; import net.minecraft.ReportedException; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/config/dto/profile/defaults/DefaultConfigProvider.java b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/defaults/DefaultConfigProvider.java similarity index 61% rename from src/main/java/dev/isxander/controlify/config/dto/profile/defaults/DefaultConfigProvider.java rename to src/main/java/dev/isxander/controlify/impl/config/dto/profile/defaults/DefaultConfigProvider.java index 924c14fcf..efef27e0e 100644 --- a/src/main/java/dev/isxander/controlify/config/dto/profile/defaults/DefaultConfigProvider.java +++ b/src/main/java/dev/isxander/controlify/impl/config/dto/profile/defaults/DefaultConfigProvider.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.dto.profile.defaults; +package dev.isxander.controlify.impl.config.dto.profile.defaults; -import dev.isxander.controlify.config.dto.profile.ProfileConfig; +import dev.isxander.controlify.impl.config.dto.profile.ProfileConfig; public interface DefaultConfigProvider { boolean isReady(); diff --git a/src/main/java/dev/isxander/controlify/config/settings/ControlifySettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/ControlifySettings.java similarity index 90% rename from src/main/java/dev/isxander/controlify/config/settings/ControlifySettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/ControlifySettings.java index 612294d00..5b33fe0d9 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/ControlifySettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/ControlifySettings.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings; +package dev.isxander.controlify.impl.config.settings; -import dev.isxander.controlify.config.dto.SharedConfig; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.config.dto.SharedConfig; +import dev.isxander.controlify.impl.config.settings.device.DeviceSettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap; import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap; import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMaps; diff --git a/src/main/java/dev/isxander/controlify/config/settings/GlobalSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/GlobalSettings.java similarity index 95% rename from src/main/java/dev/isxander/controlify/config/settings/GlobalSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/GlobalSettings.java index 828c5abf9..c918fdb21 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/GlobalSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/GlobalSettings.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings; +package dev.isxander.controlify.impl.config.settings; import com.google.common.collect.Sets; -import dev.isxander.controlify.config.dto.GlobalConfig; -import dev.isxander.controlify.reacharound.ReachAroundMode; -import dev.isxander.controlify.server.ServerPolicies; +import dev.isxander.controlify.impl.config.dto.GlobalConfig; +import dev.isxander.controlify.impl.reacharound.ReachAroundMode; +import dev.isxander.controlify.impl.server.ServerPolicies; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.multiplayer.ServerData; diff --git a/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/device/DeviceSettings.java similarity index 82% rename from src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/device/DeviceSettings.java index 130f749d6..9f21b5b13 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/device/DeviceSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/device/DeviceSettings.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.device; +package dev.isxander.controlify.impl.config.settings.device; -import dev.isxander.controlify.config.dto.device.DeviceConfig; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.input.mapping.ControllerMapping; +import dev.isxander.controlify.impl.config.dto.device.DeviceConfig; +import dev.isxander.controlify.impl.controllermanager.ControllerType; +import dev.isxander.controlify.impl.input.mapping.ControllerMapping; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; @@ -25,7 +25,7 @@ public class DeviceSettings { private DeviceSettings(String uid) { this.name = uid; this.lastSeen = 0L; - this.controllerType = ControllerType.DEFAULT.namespace(); + this.controllerType = ControllerType.DEFAULT.id(); this.gyroCalibration = GyroCalibrationSettings.defaults(); this.mapping = null; } diff --git a/src/main/java/dev/isxander/controlify/config/settings/device/GyroCalibrationSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/device/GyroCalibrationSettings.java similarity index 64% rename from src/main/java/dev/isxander/controlify/config/settings/device/GyroCalibrationSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/device/GyroCalibrationSettings.java index 51f733d64..047c476e5 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/device/GyroCalibrationSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/device/GyroCalibrationSettings.java @@ -4,21 +4,21 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.device; +package dev.isxander.controlify.impl.config.settings.device; -import dev.isxander.controlify.config.dto.device.GyroCalibrationConfig; -import dev.isxander.controlify.controller.gyro.GyroState; -import dev.isxander.controlify.controller.gyro.GyroStateC; +import dev.isxander.controlify.impl.config.dto.device.GyroCalibrationConfig; +import org.joml.Vector3f; +import org.joml.Vector3fc; public class GyroCalibrationSettings { - public GyroStateC offset; + public Vector3fc offset; private GyroCalibrationSettings() { - this.offset = new GyroState(); + this.offset = new Vector3f(); } public GyroCalibrationSettings( - GyroStateC offset + Vector3fc offset ) { this.offset = offset; } diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/BluetoothDeviceSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/BluetoothDeviceSettings.java similarity index 79% rename from src/main/java/dev/isxander/controlify/config/settings/profile/BluetoothDeviceSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/profile/BluetoothDeviceSettings.java index b1ed3f634..4e3fb98db 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/BluetoothDeviceSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/BluetoothDeviceSettings.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.profile; +package dev.isxander.controlify.impl.config.settings.profile; -import dev.isxander.controlify.config.dto.profile.BluetoothDeviceConfig; +import dev.isxander.controlify.impl.config.dto.profile.BluetoothDeviceConfig; public class BluetoothDeviceSettings { public boolean dontShowWarning; diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/DualsenseSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/DualsenseSettings.java similarity index 78% rename from src/main/java/dev/isxander/controlify/config/settings/profile/DualsenseSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/profile/DualsenseSettings.java index a69a951ac..ab1b8e29b 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/DualsenseSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/DualsenseSettings.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.profile; +package dev.isxander.controlify.impl.config.settings.profile; -import dev.isxander.controlify.config.dto.profile.DualsenseConfig; +import dev.isxander.controlify.impl.config.dto.profile.DualsenseConfig; public class DualsenseSettings { public boolean triggerEffects; diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/GenericControllerSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/GenericControllerSettings.java similarity index 96% rename from src/main/java/dev/isxander/controlify/config/settings/profile/GenericControllerSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/profile/GenericControllerSettings.java index 278455d1a..ce5531b90 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/GenericControllerSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/GenericControllerSettings.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.profile; +package dev.isxander.controlify.impl.config.settings.profile; import dev.isxander.controlify.api.contextual.GuideVerbosity; -import dev.isxander.controlify.config.dto.profile.GenericControllerConfig; +import dev.isxander.controlify.impl.config.dto.profile.GenericControllerConfig; public class GenericControllerSettings { public boolean autoJump; diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/GyroSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/GyroSettings.java similarity index 83% rename from src/main/java/dev/isxander/controlify/config/settings/profile/GyroSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/profile/GyroSettings.java index 1a3b669c1..c52e6c33e 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/GyroSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/GyroSettings.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.profile; +package dev.isxander.controlify.impl.config.settings.profile; -import dev.isxander.controlify.config.dto.profile.GyroConfig; -import dev.isxander.controlify.controller.gyro.GyroButtonMode; -import dev.isxander.controlify.controller.gyro.GyroYawMode; +import dev.isxander.controlify.impl.config.dto.profile.GyroConfig; +import dev.isxander.controlify.impl.controller.gyro.GyroButtonMode; +import dev.isxander.controlify.impl.controller.gyro.GyroYawMode; public class GyroSettings { public float lookSensitivity; diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/HDHapticSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/HDHapticSettings.java similarity index 76% rename from src/main/java/dev/isxander/controlify/config/settings/profile/HDHapticSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/profile/HDHapticSettings.java index 8083e9f6d..1d4efd1dc 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/HDHapticSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/HDHapticSettings.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.profile; +package dev.isxander.controlify.impl.config.settings.profile; -import dev.isxander.controlify.config.dto.profile.HDHapticConfig; +import dev.isxander.controlify.impl.config.dto.profile.HDHapticConfig; public class HDHapticSettings { public boolean enabled; diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/InputSettings.java similarity index 95% rename from src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/profile/InputSettings.java index 359ada37d..97d4d7ef4 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/InputSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/InputSettings.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.profile; +package dev.isxander.controlify.impl.config.settings.profile; -import dev.isxander.controlify.config.dto.profile.InputConfig; -import dev.isxander.controlify.ingame.InputCurves; -import dev.isxander.controlify.input.LogicalInput; +import dev.isxander.controlify.impl.config.dto.profile.InputConfig; +import dev.isxander.controlify.impl.ingame.InputCurves; +import dev.isxander.controlify.api.input.LogicalInput; import net.minecraft.resources.Identifier; import java.util.HashMap; diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/ProfileSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/ProfileSettings.java similarity index 92% rename from src/main/java/dev/isxander/controlify/config/settings/profile/ProfileSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/profile/ProfileSettings.java index f4b624f37..6cdc70b68 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/ProfileSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/ProfileSettings.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.profile; +package dev.isxander.controlify.impl.config.settings.profile; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.config.dto.profile.ProfileConfig; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.config.dto.profile.ProfileConfig; import org.jetbrains.annotations.Nullable; import java.util.Optional; diff --git a/src/main/java/dev/isxander/controlify/config/settings/profile/RumbleSettings.java b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/RumbleSettings.java similarity index 83% rename from src/main/java/dev/isxander/controlify/config/settings/profile/RumbleSettings.java rename to src/main/java/dev/isxander/controlify/impl/config/settings/profile/RumbleSettings.java index ec8403ba1..b2581d0b5 100644 --- a/src/main/java/dev/isxander/controlify/config/settings/profile/RumbleSettings.java +++ b/src/main/java/dev/isxander/controlify/impl/config/settings/profile/RumbleSettings.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config.settings.profile; +package dev.isxander.controlify.impl.config.settings.profile; -import dev.isxander.controlify.config.dto.profile.RumbleConfig; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; +import dev.isxander.controlify.impl.config.dto.profile.RumbleConfig; +import dev.isxander.controlify.impl.controller.rumble.RumbleSource; +import dev.isxander.controlify.api.controller.rumble.RumbleState; import net.minecraft.resources.Identifier; import java.util.HashMap; diff --git a/src/main/java/dev/isxander/controlify/contextual/ContextualDebug.java b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualDebug.java similarity index 97% rename from src/main/java/dev/isxander/controlify/contextual/ContextualDebug.java rename to src/main/java/dev/isxander/controlify/impl/contextual/ContextualDebug.java index 8f80d80c0..39ee72840 100644 --- a/src/main/java/dev/isxander/controlify/contextual/ContextualDebug.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualDebug.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; -import dev.isxander.controlify.debug.DebugProperties; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.debug.DebugProperties; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemInstance; diff --git a/src/main/java/dev/isxander/controlify/contextual/ContextualDomainImpl.java b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualDomainImpl.java similarity index 93% rename from src/main/java/dev/isxander/controlify/contextual/ContextualDomainImpl.java rename to src/main/java/dev/isxander/controlify/impl/contextual/ContextualDomainImpl.java index 045575ca7..33b76a332 100644 --- a/src/main/java/dev/isxander/controlify/contextual/ContextualDomainImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualDomainImpl.java @@ -4,17 +4,17 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.mojang.serialization.DataResult; import com.mojang.serialization.JsonOps; import dev.isxander.controlify.api.contextual.*; -import dev.isxander.controlify.controller.dualsense.TriggerEffectInstanceImpl; -import dev.isxander.controlify.gui.guide.GuideInstanceImpl; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.controller.dualsense.TriggerEffectInstanceImpl; +import dev.isxander.controlify.impl.gui.guide.GuideInstanceImpl; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.multiplayer.CacheSlot; @@ -29,6 +29,7 @@ import net.minecraft.util.PlaceholderLookupProvider; import net.minecraft.util.RegistryContextSwapper; import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NonNull; import java.io.BufferedReader; import java.util.*; @@ -56,14 +57,14 @@ public Identifier id() { } @Override - public void registerContributor(ContextualStateContributor contributor) { + public void registerContributor(@NonNull ContextualStateContributor contributor) { Objects.requireNonNull(contributor, "contributor"); this.contributor = this.contributor.andThen(contributor); } @Override - public GuideInstance createGuideInstance(Font font) { + public GuideInstance createGuideInstance(@NonNull Font font) { RuleSetManager ruleSetManager = RuleSetManager.GUIDE_RULES; return new GuideInstanceImpl<>(this, () -> this.requireRuleEngine(ruleSetManager, "guide"), font); diff --git a/src/main/java/dev/isxander/controlify/contextual/ContextualDomains.java b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualDomains.java similarity index 90% rename from src/main/java/dev/isxander/controlify/contextual/ContextualDomains.java rename to src/main/java/dev/isxander/controlify/impl/contextual/ContextualDomains.java index f69f272b0..20fa7db36 100644 --- a/src/main/java/dev/isxander/controlify/contextual/ContextualDomains.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualDomains.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import dev.isxander.controlify.api.contextual.ContainerContext; import dev.isxander.controlify.api.contextual.InGameContext; import dev.isxander.controlify.api.contextual.Context; import dev.isxander.controlify.api.contextual.ContextualDomain; import dev.isxander.controlify.api.contextual.ContextualDomainRegistry; -import dev.isxander.controlify.platform.client.PlatformClientUtil; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import java.util.ArrayList; diff --git a/src/main/java/dev/isxander/controlify/contextual/ContextualPredicate.java b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualPredicate.java similarity index 95% rename from src/main/java/dev/isxander/controlify/contextual/ContextualPredicate.java rename to src/main/java/dev/isxander/controlify/impl/contextual/ContextualPredicate.java index b1d674da5..2dbff9805 100644 --- a/src/main/java/dev/isxander/controlify/contextual/ContextualPredicate.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualPredicate.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.utils.codec.CExtraCodecs; -import dev.isxander.controlify.utils.predicates.ClientEntityPredicate; -import dev.isxander.controlify.utils.predicates.ClientPredicateUtils; +import dev.isxander.controlify.impl.utils.codec.CExtraCodecs; +import dev.isxander.controlify.impl.utils.predicates.ClientEntityPredicate; +import dev.isxander.controlify.impl.utils.predicates.ClientPredicateUtils; //? if >=26.2 { import net.minecraft.advancements.predicates.*; //?} else { diff --git a/src/main/java/dev/isxander/controlify/contextual/ContextualState.java b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualState.java similarity index 92% rename from src/main/java/dev/isxander/controlify/contextual/ContextualState.java rename to src/main/java/dev/isxander/controlify/impl/contextual/ContextualState.java index 5e36298c8..7625e9619 100644 --- a/src/main/java/dev/isxander/controlify/contextual/ContextualState.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualState.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import net.minecraft.resources.Identifier; import net.minecraft.world.entity.Entity; diff --git a/src/main/java/dev/isxander/controlify/contextual/ContextualStateAccumulator.java b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualStateAccumulator.java similarity index 83% rename from src/main/java/dev/isxander/controlify/contextual/ContextualStateAccumulator.java rename to src/main/java/dev/isxander/controlify/impl/contextual/ContextualStateAccumulator.java index a43ea2778..09cafe5fe 100644 --- a/src/main/java/dev/isxander/controlify/contextual/ContextualStateAccumulator.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualStateAccumulator.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import dev.isxander.controlify.api.contextual.ContextualStateSink; import net.minecraft.resources.Identifier; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemInstance; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.pattern.BlockInWorld; import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NonNull; import java.util.Collections; import java.util.LinkedHashMap; @@ -36,12 +36,12 @@ public ContextualStateAccumulator(ContextualState state) { } @Override - public void contributeFact(Identifier id, boolean value) { + public void contributeFact(@NonNull Identifier id, boolean value) { this.facts.put(Objects.requireNonNull(id, "id"), value); } @Override - public void contributeItem(Identifier slot, @Nullable ItemInstance item) { + public void contributeItem(@NonNull Identifier slot, @Nullable ItemInstance item) { if (item == null) { return; } @@ -49,7 +49,7 @@ public void contributeItem(Identifier slot, @Nullable ItemInstance item) { } @Override - public void contributeBlock(Identifier slot, @Nullable BlockInWorld block) { + public void contributeBlock(@NonNull Identifier slot, @Nullable BlockInWorld block) { if (block == null) { return; } @@ -57,7 +57,7 @@ public void contributeBlock(Identifier slot, @Nullable BlockInWorld block) { } @Override - public void contributeEntity(Identifier slot, @Nullable Entity entity) { + public void contributeEntity(@NonNull Identifier slot, @Nullable Entity entity) { if (entity == null) { return; } diff --git a/src/main/java/dev/isxander/controlify/contextual/ContextualStateContributors.java b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualStateContributors.java similarity index 94% rename from src/main/java/dev/isxander/controlify/contextual/ContextualStateContributors.java rename to src/main/java/dev/isxander/controlify/impl/contextual/ContextualStateContributors.java index f2a0ad0a4..a81430411 100644 --- a/src/main/java/dev/isxander/controlify/contextual/ContextualStateContributors.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/ContextualStateContributors.java @@ -4,11 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import dev.isxander.controlify.api.contextual.*; +import dev.isxander.controlify.impl.controller.ControllerImpl; import dev.isxander.controlify.mixins.feature.guide.ingame.PlayerAccessor; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.BlockItem; @@ -103,11 +104,11 @@ public final class ContextualStateContributors { sink.contributeFact( CUtil.rl("is_toggle_sneak"), - context.controller().settings().generic.toggleSneak + ((ControllerImpl) context.controller()).settings().generic.toggleSneak ); sink.contributeFact( CUtil.rl("is_toggle_sprint"), - context.controller().settings().generic.toggleSprint + ((ControllerImpl) context.controller()).settings().generic.toggleSprint ); sink.contributeFact( CUtil.rl("input_moving"), diff --git a/src/main/java/dev/isxander/controlify/contextual/CyclicFactDependencyException.java b/src/main/java/dev/isxander/controlify/impl/contextual/CyclicFactDependencyException.java similarity index 93% rename from src/main/java/dev/isxander/controlify/contextual/CyclicFactDependencyException.java rename to src/main/java/dev/isxander/controlify/impl/contextual/CyclicFactDependencyException.java index 7fa8df3f1..458b6adf2 100644 --- a/src/main/java/dev/isxander/controlify/contextual/CyclicFactDependencyException.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/CyclicFactDependencyException.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/contextual/FactDefinition.java b/src/main/java/dev/isxander/controlify/impl/contextual/FactDefinition.java similarity index 95% rename from src/main/java/dev/isxander/controlify/contextual/FactDefinition.java rename to src/main/java/dev/isxander/controlify/impl/contextual/FactDefinition.java index 32b4782ca..49cf251a6 100644 --- a/src/main/java/dev/isxander/controlify/contextual/FactDefinition.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/FactDefinition.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import com.mojang.serialization.Codec; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/contextual/FactDependencyGraph.java b/src/main/java/dev/isxander/controlify/impl/contextual/FactDependencyGraph.java similarity index 99% rename from src/main/java/dev/isxander/controlify/contextual/FactDependencyGraph.java rename to src/main/java/dev/isxander/controlify/impl/contextual/FactDependencyGraph.java index bdfdae8c7..67ed4ffcd 100644 --- a/src/main/java/dev/isxander/controlify/contextual/FactDependencyGraph.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/FactDependencyGraph.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/api/contextual/GuideLocation.java b/src/main/java/dev/isxander/controlify/impl/contextual/GuideLocation.java similarity index 93% rename from src/main/java/dev/isxander/controlify/api/contextual/GuideLocation.java rename to src/main/java/dev/isxander/controlify/impl/contextual/GuideLocation.java index 2a5d38d15..f6d8ba2d0 100644 --- a/src/main/java/dev/isxander/controlify/api/contextual/GuideLocation.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/GuideLocation.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.api.contextual; +package dev.isxander.controlify.impl.contextual; import com.mojang.serialization.Codec; import net.minecraft.util.StringRepresentable; diff --git a/src/main/java/dev/isxander/controlify/contextual/GuideRule.java b/src/main/java/dev/isxander/controlify/impl/contextual/GuideRule.java similarity index 87% rename from src/main/java/dev/isxander/controlify/contextual/GuideRule.java rename to src/main/java/dev/isxander/controlify/impl/contextual/GuideRule.java index 8da435544..dc7927175 100644 --- a/src/main/java/dev/isxander/controlify/contextual/GuideRule.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/GuideRule.java @@ -4,12 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.api.contextual.GuideLocation; +import dev.isxander.controlify.impl.api.bind.InputBindingSupplier; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.ComponentSerialization; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/contextual/Rule.java b/src/main/java/dev/isxander/controlify/impl/contextual/Rule.java similarity index 91% rename from src/main/java/dev/isxander/controlify/contextual/Rule.java rename to src/main/java/dev/isxander/controlify/impl/contextual/Rule.java index 9c092d6cc..ecd785118 100644 --- a/src/main/java/dev/isxander/controlify/contextual/Rule.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/Rule.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; public interface Rule { /// Used to identify when multiple rules are overriding each other. diff --git a/src/main/java/dev/isxander/controlify/contextual/RuleEngine.java b/src/main/java/dev/isxander/controlify/impl/contextual/RuleEngine.java similarity index 98% rename from src/main/java/dev/isxander/controlify/contextual/RuleEngine.java rename to src/main/java/dev/isxander/controlify/impl/contextual/RuleEngine.java index 3c7fcfc26..9609a53d5 100644 --- a/src/main/java/dev/isxander/controlify/contextual/RuleEngine.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/RuleEngine.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/contextual/RuleSet.java b/src/main/java/dev/isxander/controlify/impl/contextual/RuleSet.java similarity index 93% rename from src/main/java/dev/isxander/controlify/contextual/RuleSet.java rename to src/main/java/dev/isxander/controlify/impl/contextual/RuleSet.java index 0f957ba16..8ac7b2825 100644 --- a/src/main/java/dev/isxander/controlify/contextual/RuleSet.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/RuleSet.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/contextual/RuleSetManager.java b/src/main/java/dev/isxander/controlify/impl/contextual/RuleSetManager.java similarity index 96% rename from src/main/java/dev/isxander/controlify/contextual/RuleSetManager.java rename to src/main/java/dev/isxander/controlify/impl/contextual/RuleSetManager.java index 238adf9db..a15532b2c 100644 --- a/src/main/java/dev/isxander/controlify/contextual/RuleSetManager.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/RuleSetManager.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import com.google.gson.JsonElement; import com.google.gson.JsonParser; @@ -12,8 +12,8 @@ import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.multiplayer.CacheSlot; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientRegistryLayer; @@ -37,7 +37,7 @@ public class RuleSetManager> implements SimpleControlifyRel public static final RuleSetManager TRIGGER_EFFECT_RULES = new RuleSetManager<>(TriggerEffectRule.CODEC, "trigger_effect"); - private static final String DIRECTORY = "contextual/"; + private static final String DIRECTORY = "controller/contextual/"; private final Codec> ruleSetCodec; private final Codec ruleCodec; diff --git a/src/main/java/dev/isxander/controlify/contextual/TriggerEffectRule.java b/src/main/java/dev/isxander/controlify/impl/contextual/TriggerEffectRule.java similarity index 79% rename from src/main/java/dev/isxander/controlify/contextual/TriggerEffectRule.java rename to src/main/java/dev/isxander/controlify/impl/contextual/TriggerEffectRule.java index 370401396..9fd21f190 100644 --- a/src/main/java/dev/isxander/controlify/contextual/TriggerEffectRule.java +++ b/src/main/java/dev/isxander/controlify/impl/contextual/TriggerEffectRule.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.controller.dualsense.TriggerEffectCodecs; -import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; +import dev.isxander.controlify.impl.api.bind.InputBindingSupplier; +import dev.isxander.controlify.impl.controller.dualsense.TriggerEffectCodecs; +import dev.isxander.controlify.impl.driver.dualsense.DualsenseTriggerEffect; import net.minecraft.resources.Identifier; /// @param binding the binding supplier associated with this action. diff --git a/src/main/java/dev/isxander/controlify/impl/controller/ControllerComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/ControllerComponent.java new file mode 100644 index 000000000..be775d40b --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/ControllerComponent.java @@ -0,0 +1,27 @@ +package dev.isxander.controlify.impl.controller; + +import net.minecraft.resources.Identifier; + +public abstract class ControllerComponent { + private final Identifier id; + private ControllerImpl controller; + + public ControllerComponent(Identifier id) { + this.id = id; + } + + public final Identifier id() { + return this.id; + } + + public void attach(ControllerImpl controller) { + this.controller = controller; + } + + public void close() { + } + + protected final ControllerImpl controller() { + return this.controller; + } +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/ControllerImpl.java b/src/main/java/dev/isxander/controlify/impl/controller/ControllerImpl.java new file mode 100644 index 000000000..a4a82df12 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/ControllerImpl.java @@ -0,0 +1,194 @@ +package dev.isxander.controlify.impl.controller; + +import dev.isxander.controlify.api.controller.Controller; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.controller.battery.BatteryLevelComponent; +import dev.isxander.controlify.impl.controller.dualsense.DualsenseComponent; +import dev.isxander.controlify.impl.controller.haptic.HDHapticComponent; +import dev.isxander.controlify.impl.controller.misc.BluetoothDeviceComponent; +import dev.isxander.controlify.impl.controller.misc.DriverNameComponent; +import dev.isxander.controlify.impl.controller.misc.UIDComponent; +import dev.isxander.controlify.impl.controller.gyro.GyroComponent; +import dev.isxander.controlify.impl.controller.input.InputComponent; +import dev.isxander.controlify.impl.controller.led.LEDComponent; +import dev.isxander.controlify.impl.controller.rumble.RumbleComponentImpl; +import dev.isxander.controlify.impl.controller.rumble.TriggerRumbleComponent; +import dev.isxander.controlify.impl.controller.steamdeck.SteamDeckComponent; +import dev.isxander.controlify.impl.controller.touchpad.TouchpadComponent; +import dev.isxander.controlify.impl.driver.Driver; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; +import net.minecraft.resources.Identifier; +import org.jspecify.annotations.NonNull; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +public final class ControllerImpl implements Controller { + private final ControllerInfo info; + private final Driver driver; + private final ControlifyLogger logger; + + private final Map components; + + private ProfileSettings settings; + private final ProfileSettings defaultSettings; + + private boolean active; + + public ControllerImpl( + ControllerInfo info, + Driver driver, + ControlifyLogger logger, + ProfileSettings settings, + ProfileSettings defaultSettings + ) { + this.info = info; + this.driver = driver; + this.logger = logger; + this.components = new HashMap<>(); + this.settings = settings; + this.defaultSettings = defaultSettings; + this.active = false; + + this.driver.addComponents(this); + this.getAllComponents().values().forEach(c -> c.attach(this)); + + logger.debugLog( + "Components: {}", + this.getAllComponents() + .keySet() + .stream() + .map(Identifier::toString) + .collect(Collectors.joining(", ")) + ); + } + + @Override + public @NonNull String uid() { + return this.getComponent(UIDComponent.ID).orElseThrow().value(); + } + + @Override + public @NonNull String driverReportedName() { + return this.getComponent(DriverNameComponent.ID).orElseThrow().value(); + } + + @Override + public @NonNull String name() { + return Optional.ofNullable(this.info.type().friendlyName()) + .orElse(this.driverReportedName()); + } + + @Override + public @NonNull Identifier typeId() { + return this.info.type().id(); + } + + public @NonNull ControllerInfo info() { + return this.info; + } + + public @NonNull Driver driver() { + return this.driver; + } + + public @NonNull ProfileSettings settings() { + return this.settings; + } + + public void setSettings(@NonNull ProfileSettings settings) { + this.settings = settings; + } + + public @NonNull ProfileSettings defaultSettings() { + return this.defaultSettings; + } + + public @NonNull InputComponent input() { + // assert that all controllers must have InputComponent + return this.getComponent(InputComponent.ID).orElseThrow(); + } + + @Override + public @NonNull Optional rumble() { + return this.getComponent(RumbleComponentImpl.ID); + } + + public @NonNull Optional triggerRumble() { + return this.getComponent(TriggerRumbleComponent.ID); + } + + public @NonNull Optional gyro() { + return this.getComponent(GyroComponent.ID); + } + + public @NonNull Optional led() { + return this.getComponent(LEDComponent.ID); + } + + public @NonNull Optional touchpad() { + return this.getComponent(TouchpadComponent.ID); + } + + public @NonNull Optional batteryLevel() { + return this.getComponent(BatteryLevelComponent.ID); + } + + public @NonNull Optional dualsense() { + return this.getComponent(DualsenseComponent.ID); + } + + public @NonNull Optional hdHaptic() { + return this.getComponent(HDHapticComponent.ID); + } + + public @NonNull Optional bluetoothDevice() { + return this.getComponent(BluetoothDeviceComponent.ID); + } + + public @NonNull Optional steamDeck() { + return this.getComponent(SteamDeckComponent.ID); + } + + public void update() { + this.driver.update(this); + } + + public boolean isActive() { + return this.active; + } + + public void setActive(boolean active) { + if (this.active == active) { + return; + } + this.active = active; + this.driver.setActive(active); + } + + public void close() { + this.setActive(false); + this.getAllComponents().values().forEach(ControllerComponent::close); + this.driver.close(); + } + + public ControlifyLogger logger() { + return this.logger; + } + + @SuppressWarnings("unchecked") + private Optional getComponent(Identifier id) { + return Optional.ofNullable((T) this.components.get(id)); + } + + public boolean addComponent(ControllerComponent component) { + return this.components.put(component.id(), component) != null; + } + + public Map getAllComponents() { + return Collections.unmodifiableMap(this.components); + } +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/ControllerInfo.java b/src/main/java/dev/isxander/controlify/impl/controller/ControllerInfo.java new file mode 100644 index 000000000..09c65f859 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/ControllerInfo.java @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.impl.controller; + +import dev.isxander.controlify.impl.controllermanager.ControllerType; +import dev.isxander.controlify.impl.controllermanager.UniqueControllerID; +import dev.isxander.controlify.impl.hid.HIDID; + +public record ControllerInfo(UniqueControllerID ucid, ControllerType type, HIDID hid) { +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/SingleValueControllerComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/SingleValueControllerComponent.java new file mode 100644 index 000000000..0975e1d85 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/SingleValueControllerComponent.java @@ -0,0 +1,16 @@ +package dev.isxander.controlify.impl.controller; + +import net.minecraft.resources.Identifier; + +public class SingleValueControllerComponent extends ControllerComponent { + private final T value; + + public SingleValueControllerComponent(Identifier id, T value) { + super(id); + this.value = value; + } + + public T value() { + return this.value; + } +} diff --git a/src/main/java/dev/isxander/controlify/controller/battery/BatteryLevelComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/battery/BatteryLevelComponent.java similarity index 62% rename from src/main/java/dev/isxander/controlify/controller/battery/BatteryLevelComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/battery/BatteryLevelComponent.java index cc8e748ca..3271ef9a2 100644 --- a/src/main/java/dev/isxander/controlify/controller/battery/BatteryLevelComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/battery/BatteryLevelComponent.java @@ -4,17 +4,21 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.battery; +package dev.isxander.controlify.impl.controller.battery; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; -public class BatteryLevelComponent extends ECSComponentImpl { +public class BatteryLevelComponent extends ControllerComponent { public static final Identifier ID = CUtil.rl("battery_level"); private PowerState batteryLevel = new PowerState.Unknown(); + public BatteryLevelComponent() { + super(ID); + } + public PowerState getBatteryLevel() { return this.batteryLevel; } @@ -22,9 +26,4 @@ public PowerState getBatteryLevel() { public void setBatteryLevel(PowerState batteryLevel) { this.batteryLevel = batteryLevel; } - - @Override - public Identifier id() { - return ID; - } } diff --git a/src/main/java/dev/isxander/controlify/controller/battery/PowerState.java b/src/main/java/dev/isxander/controlify/impl/controller/battery/PowerState.java similarity index 89% rename from src/main/java/dev/isxander/controlify/controller/battery/PowerState.java rename to src/main/java/dev/isxander/controlify/impl/controller/battery/PowerState.java index 82ce9a6ed..26e07e07c 100644 --- a/src/main/java/dev/isxander/controlify/controller/battery/PowerState.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/battery/PowerState.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.battery; +package dev.isxander.controlify.impl.controller.battery; public sealed interface PowerState { default int percent() { diff --git a/src/main/java/dev/isxander/controlify/controller/dualsense/DualsenseComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/dualsense/DualsenseComponent.java similarity index 77% rename from src/main/java/dev/isxander/controlify/controller/dualsense/DualsenseComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/dualsense/DualsenseComponent.java index 7f8741f2f..70f8719c2 100644 --- a/src/main/java/dev/isxander/controlify/controller/dualsense/DualsenseComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/dualsense/DualsenseComponent.java @@ -4,17 +4,17 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.dualsense; +package dev.isxander.controlify.impl.controller.dualsense; -import dev.isxander.controlify.config.settings.profile.DualsenseSettings; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.config.settings.profile.DualsenseSettings; +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.driver.dualsense.DualsenseTriggerEffect; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import java.util.Objects; -public class DualsenseComponent extends ECSComponentImpl { +public class DualsenseComponent extends ControllerComponent { public static final Identifier ID = CUtil.rl("dualsense"); private boolean muteLight; @@ -24,6 +24,10 @@ public class DualsenseComponent extends ECSComponentImpl { private boolean dirty; + public DualsenseComponent() { + super(ID); + } + public void setLeftTriggerEffect(DualsenseTriggerEffect effect) { if (!Objects.equals(effect, this.leftTriggerEffect)) { this.setDirty(); @@ -74,9 +78,4 @@ public DualsenseSettings settings() { public DualsenseSettings defaultSettings() { return this.controller().defaultSettings().dualsense; } - - @Override - public Identifier id() { - return ID; - } } diff --git a/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectCodecs.java b/src/main/java/dev/isxander/controlify/impl/controller/dualsense/TriggerEffectCodecs.java similarity index 96% rename from src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectCodecs.java rename to src/main/java/dev/isxander/controlify/impl/controller/dualsense/TriggerEffectCodecs.java index 8f1822d89..c8b31cb4f 100644 --- a/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectCodecs.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/dualsense/TriggerEffectCodecs.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.dualsense; +package dev.isxander.controlify.impl.controller.dualsense; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; -import dev.isxander.controlify.utils.codec.CExtraCodecs; +import dev.isxander.controlify.impl.driver.dualsense.DualsenseTriggerEffect; +import dev.isxander.controlify.impl.utils.codec.CExtraCodecs; import net.minecraft.util.ExtraCodecs; import java.util.Map; diff --git a/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectInstanceImpl.java b/src/main/java/dev/isxander/controlify/impl/controller/dualsense/TriggerEffectInstanceImpl.java similarity index 81% rename from src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectInstanceImpl.java rename to src/main/java/dev/isxander/controlify/impl/controller/dualsense/TriggerEffectInstanceImpl.java index 735a5f09e..36d120e9f 100644 --- a/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectInstanceImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/dualsense/TriggerEffectInstanceImpl.java @@ -4,18 +4,18 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.dualsense; +package dev.isxander.controlify.impl.controller.dualsense; -import dev.isxander.controlify.api.bind.InputBinding; +import dev.isxander.controlify.impl.api.bind.InputBinding; import dev.isxander.controlify.api.contextual.Context; import dev.isxander.controlify.api.contextual.TriggerEffectInstance; -import dev.isxander.controlify.contextual.ContextualDomainImpl; -import dev.isxander.controlify.contextual.ContextualState; -import dev.isxander.controlify.contextual.RuleEngine; -import dev.isxander.controlify.contextual.TriggerEffectRule; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.input.mapping.GamepadInputs; -import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; +import dev.isxander.controlify.impl.contextual.ContextualDomainImpl; +import dev.isxander.controlify.impl.contextual.ContextualState; +import dev.isxander.controlify.impl.contextual.RuleEngine; +import dev.isxander.controlify.impl.contextual.TriggerEffectRule; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.input.mapping.GamepadInputs; +import dev.isxander.controlify.impl.driver.dualsense.DualsenseTriggerEffect; import net.minecraft.resources.Identifier; import java.util.List; @@ -78,7 +78,7 @@ public DualsenseTriggerEffect getRightTriggerEffect() { return this.rightEffect; } - private Trigger getTrigger(ControllerEntity controller, TriggerEffectRule rule) { + private Trigger getTrigger(ControllerImpl controller, TriggerEffectRule rule) { InputBinding binding = rule.binding().onOrNull(controller); if (binding == null) { diff --git a/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectManager.java b/src/main/java/dev/isxander/controlify/impl/controller/dualsense/TriggerEffectManager.java similarity index 73% rename from src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectManager.java rename to src/main/java/dev/isxander/controlify/impl/controller/dualsense/TriggerEffectManager.java index 1052acf8c..86de48682 100644 --- a/src/main/java/dev/isxander/controlify/controller/dualsense/TriggerEffectManager.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/dualsense/TriggerEffectManager.java @@ -4,18 +4,16 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.dualsense; +package dev.isxander.controlify.impl.controller.dualsense; import dev.isxander.controlify.api.contextual.InGameContext; import dev.isxander.controlify.api.contextual.TriggerEffectInstance; -import dev.isxander.controlify.contextual.ContextualDomains; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.driver.dualsense.DualsenseTriggerEffect; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.contextual.ContextualDomains; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.driver.dualsense.DualsenseTriggerEffect; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.Minecraft; -import java.util.*; - public class TriggerEffectManager { private final TriggerEffectInstance instance; @@ -25,13 +23,13 @@ public TriggerEffectManager() { } public void applyTriggerEffects( - ControllerEntity controller, + ControllerImpl controller, boolean inputSuppressed ) { applyTriggerEffects(controller, instance, inputSuppressed); } - public void tick(Minecraft minecraft, ControllerEntity controller) { + public void tick(Minecraft minecraft, ControllerImpl controller) { if (minecraft.player == null || minecraft.level == null) { return; } @@ -42,7 +40,7 @@ public void tick(Minecraft minecraft, ControllerEntity controller) { } public static void applyTriggerEffects( - ControllerEntity controller, + ControllerImpl controller, TriggerEffectInstance instance, boolean inputSuppressed ) { @@ -58,7 +56,7 @@ public static void applyTriggerEffects( }); } - public static boolean shouldUseTriggerEffects(ControllerEntity controller, boolean inputSuppressed) { + public static boolean shouldUseTriggerEffects(ControllerImpl controller, boolean inputSuppressed) { return !inputSuppressed && MinecraftUtil.getScreen() == null && Minecraft.getInstance().player != null diff --git a/src/main/java/dev/isxander/controlify/controller/gyro/GyroButtonMode.java b/src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroButtonMode.java similarity index 91% rename from src/main/java/dev/isxander/controlify/controller/gyro/GyroButtonMode.java rename to src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroButtonMode.java index 7b5c48cf5..880e7467d 100644 --- a/src/main/java/dev/isxander/controlify/controller/gyro/GyroButtonMode.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroButtonMode.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.gyro; +package dev.isxander.controlify.impl.controller.gyro; import com.mojang.serialization.Codec; import net.minecraft.util.StringRepresentable; diff --git a/src/main/java/dev/isxander/controlify/controller/gyro/GyroCalibrator.java b/src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroCalibrator.java similarity index 89% rename from src/main/java/dev/isxander/controlify/controller/gyro/GyroCalibrator.java rename to src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroCalibrator.java index a626e4fe7..0545cf3ae 100644 --- a/src/main/java/dev/isxander/controlify/controller/gyro/GyroCalibrator.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroCalibrator.java @@ -4,7 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.gyro; +package dev.isxander.controlify.impl.controller.gyro; + +import org.joml.Vector3f; +import org.joml.Vector3fc; /** * Implements rolling gyro calibration using exponential moving average @@ -24,7 +27,7 @@ public class GyroCalibrator { private static final int MIN_STATIONARY_SAMPLES = 10; // Current bias estimate (offset to subtract from raw readings) - private final GyroState biasEstimate = new GyroState(0, 0, 0); + private final Vector3f biasEstimate = new Vector3f(0, 0, 0); // Counter for consecutive stationary samples private int stationarySampleCount = 0; @@ -62,11 +65,11 @@ private boolean isStationary(float x, float y, float z) { /** * Get the current bias estimate (for saving to config). */ - public GyroStateC getCurrentBias() { - return new GyroState(this.biasEstimate); + public Vector3f getCurrentBias() { + return new Vector3f(this.biasEstimate); } - public void setBias(GyroStateC bias) { + public void setBias(Vector3fc bias) { this.biasEstimate.set(bias.x(), bias.y(), bias.z()); this.stationarySampleCount = 0; } diff --git a/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroComponent.java similarity index 69% rename from src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroComponent.java index c8409deb9..e3a057d4a 100644 --- a/src/main/java/dev/isxander/controlify/controller/gyro/GyroComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroComponent.java @@ -4,57 +4,60 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.gyro; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.config.settings.profile.GyroSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.input.pipeline.InputPipeline; -import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.signal.LogicalSignal; -import dev.isxander.controlify.input.signal.PhysicalSensorSignal; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.event.EventSource; +package dev.isxander.controlify.impl.controller.gyro; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.config.settings.device.DeviceSettings; +import dev.isxander.controlify.impl.config.settings.profile.GyroSettings; +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.input.pipeline.InputPipeline; +import dev.isxander.controlify.impl.input.SensorType; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.event.EventSource; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; +import org.joml.Vector3f; +import org.joml.Vector3fc; import java.util.Objects; -public class GyroComponent extends ECSComponentImpl { +public class GyroComponent extends ControllerComponent { public static final Identifier ID = CUtil.rl("gyro"); private final InputPipeline inputPipeline; private @Nullable EventSource.Subscription calibrationSubscription; private @Nullable EventSource.Subscription sensorSubscription; private DeviceSettings deviceSettings; - private GyroStateC gyroState = GyroStateC.ZERO; + private Vector3fc gyroState = new Vector3f(); private static final long MAX_SAMPLE_AGE_NANOS = 50_000_000L; private long lastStateTimeNanos; private final GyroCalibrator calibrator = new GyroCalibrator(); private static final long CALIBRATION_SAVE_INTERVAL_NANOS = 5_000_000_000L; private long lastCalibrationSaveTimeNanos; - private GyroStateC lastSavedBias = GyroStateC.ZERO; + private Vector3fc lastSavedBias = new Vector3f(); public GyroComponent(InputPipeline inputPipeline) { + super(ID); this.inputPipeline = Objects.requireNonNull(inputPipeline); } @Override - public void attach(ControllerEntity controller) { + public void attach(ControllerImpl controller) { super.attach(controller); // Load the calibration from device settings this.deviceSettings = Controlify.instance().config().getSettings() .getOrCreateDeviceSettings(controller.uid()); - GyroStateC savedOffset = this.deviceSettings.gyroCalibration.offset; + Vector3fc savedOffset = this.deviceSettings.gyroCalibration.offset; // Initialize the calibrator with the saved offset calibrator.setBias(savedOffset); - lastSavedBias = new GyroState(savedOffset); + lastSavedBias = new Vector3f(savedOffset); this.lastCalibrationSaveTimeNanos = System.nanoTime(); this.calibrationSubscription = this.inputPipeline.sourceRawPhysicalSignals().subscribe(this::onRawSignal); @@ -84,31 +87,31 @@ private void onSignal(LogicalSignal signal) { if (signal instanceof LogicalSignal.SensorInterval(_, _, SensorType sensorType, float x, float y, float z) && sensorType == SensorType.GYROSCOPE) { // The pipeline has already calibrated, filtered and integrated these values into radians. - this.gyroState = new GyroState(x, y, z); + this.gyroState = new Vector3f(x, y, z); this.lastStateTimeNanos = System.nanoTime(); } } /// Returns the latest integrated gyro interval in radians. /// Missing samples expire naturally, independently of controller selection. - public GyroStateC getState() { + public Vector3fc getState() { return System.nanoTime() - this.lastStateTimeNanos > MAX_SAMPLE_AGE_NANOS - ? GyroStateC.ZERO : this.gyroState; + ? new Vector3f() : this.gyroState; } private void saveCalibrationIfChanged() { - GyroStateC currentBias = this.deviceSettings.gyroCalibration.offset; + Vector3fc currentBias = this.deviceSettings.gyroCalibration.offset; // Check if bias has changed significantly (more than 0.001 rad/s on any axis) float threshold = 0.001f; - if (Math.abs(currentBias.pitch() - lastSavedBias.pitch()) > threshold || - Math.abs(currentBias.yaw() - lastSavedBias.yaw()) > threshold || - Math.abs(currentBias.roll() - lastSavedBias.roll()) > threshold) { + if (Math.abs(currentBias.x() - lastSavedBias.x()) > threshold || + Math.abs(currentBias.y() - lastSavedBias.y()) > threshold || + Math.abs(currentBias.z() - lastSavedBias.z()) > threshold) { // Settings update on every sample; persistence is checked at a fixed time interval. Controlify.instance().config().markDirty(); - lastSavedBias = new GyroState(currentBias); + lastSavedBias = new Vector3f(currentBias); } } @@ -124,11 +127,6 @@ public GyroSettings defaultSettings() { return this.controller().defaultSettings().gyro; } - @Override - public Identifier id() { - return ID; - } - @Override public void close() { if (this.calibrationSubscription != null) { diff --git a/src/main/java/dev/isxander/controlify/controller/gyro/GyroYawMode.java b/src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroYawMode.java similarity index 90% rename from src/main/java/dev/isxander/controlify/controller/gyro/GyroYawMode.java rename to src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroYawMode.java index ab31977bf..2214b10a5 100644 --- a/src/main/java/dev/isxander/controlify/controller/gyro/GyroYawMode.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/gyro/GyroYawMode.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.gyro; +package dev.isxander.controlify.impl.controller.gyro; import com.mojang.serialization.Codec; import net.minecraft.util.StringRepresentable; diff --git a/src/main/java/dev/isxander/controlify/controller/haptic/CompleteSoundData.java b/src/main/java/dev/isxander/controlify/impl/controller/haptic/CompleteSoundData.java similarity index 80% rename from src/main/java/dev/isxander/controlify/controller/haptic/CompleteSoundData.java rename to src/main/java/dev/isxander/controlify/impl/controller/haptic/CompleteSoundData.java index 91beaf208..a287508b0 100644 --- a/src/main/java/dev/isxander/controlify/controller/haptic/CompleteSoundData.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/haptic/CompleteSoundData.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.haptic; +package dev.isxander.controlify.impl.controller.haptic; import javax.sound.sampled.AudioFormat; diff --git a/src/main/java/dev/isxander/controlify/controller/haptic/HDHapticComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/haptic/HDHapticComponent.java similarity index 90% rename from src/main/java/dev/isxander/controlify/controller/haptic/HDHapticComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/haptic/HDHapticComponent.java index 08d072574..35ba1b068 100644 --- a/src/main/java/dev/isxander/controlify/controller/haptic/HDHapticComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/haptic/HDHapticComponent.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.haptic; +package dev.isxander.controlify.impl.controller.haptic; import com.mojang.blaze3d.audio.SoundBuffer; -import dev.isxander.controlify.config.settings.profile.HDHapticSettings; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; +import dev.isxander.controlify.impl.config.settings.profile.HDHapticSettings; +import dev.isxander.controlify.impl.controller.ControllerComponent; import dev.isxander.controlify.mixins.feature.hdhaptics.SoundBufferAccessor; import dev.isxander.controlify.mixins.feature.hdhaptics.SoundEngineAccessor; import dev.isxander.controlify.mixins.feature.hdhaptics.SoundManagerAccessor; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.sounds.SoundBufferLibrary; import net.minecraft.client.sounds.SoundEngine; @@ -28,7 +28,7 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; -public class HDHapticComponent extends ECSComponentImpl { +public class HDHapticComponent extends ControllerComponent { public static final Identifier ID = CUtil.rl("hd_haptics"); private Consumer playHapticConsumer; @@ -40,6 +40,7 @@ public class HDHapticComponent extends ECSComponentImpl { private static final Map hapticData = new HashMap<>(); public HDHapticComponent() { + super(ID); this.randomSource = RandomSource.create(); } @@ -105,9 +106,4 @@ public HDHapticSettings settings() { public HDHapticSettings defaultSettings() { return this.controller().defaultSettings().hdHaptic; } - - @Override - public Identifier id() { - return ID; - } } diff --git a/src/main/java/dev/isxander/controlify/controller/haptic/HapticEffects.java b/src/main/java/dev/isxander/controlify/impl/controller/haptic/HapticEffects.java similarity index 72% rename from src/main/java/dev/isxander/controlify/controller/haptic/HapticEffects.java rename to src/main/java/dev/isxander/controlify/impl/controller/haptic/HapticEffects.java index ae911302f..263e70480 100644 --- a/src/main/java/dev/isxander/controlify/controller/haptic/HapticEffects.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/haptic/HapticEffects.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.haptic; +package dev.isxander.controlify.impl.controller.haptic; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; public final class HapticEffects { diff --git a/src/main/java/dev/isxander/controlify/controller/input/InputComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/input/InputComponent.java similarity index 75% rename from src/main/java/dev/isxander/controlify/controller/input/InputComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/input/InputComponent.java index 2a93f7b71..24348e5a9 100644 --- a/src/main/java/dev/isxander/controlify/controller/input/InputComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/input/InputComponent.java @@ -1,30 +1,32 @@ -package dev.isxander.controlify.controller.input; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.action.defaults.DefaultBindProvider; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.config.settings.profile.InputSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.mapping.ControllerMapping; -import dev.isxander.controlify.input.mapping.ControllerMappingManager; -import dev.isxander.controlify.action.ActionGraph; -import dev.isxander.controlify.action.ActionImpl; -import dev.isxander.controlify.action.ActionSpec; -import dev.isxander.controlify.action.ActionSpecRegistryImpl; -import dev.isxander.controlify.action.activator.ActivatorConfig; -import dev.isxander.controlify.input.pipeline.InputPipeline; -import dev.isxander.controlify.input.pipeline.SensorProcessorStage; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.event.EventSource; +package dev.isxander.controlify.impl.controller.input; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.action.defaults.DefaultBindProvider; +import dev.isxander.controlify.impl.config.settings.device.DeviceSettings; +import dev.isxander.controlify.impl.config.settings.profile.InputSettings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.impl.ECSComponentImpl; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.input.SensorType; +import dev.isxander.controlify.impl.input.mapping.ControllerMapping; +import dev.isxander.controlify.impl.input.mapping.ControllerMappingManager; +import dev.isxander.controlify.impl.action.ActionGraph; +import dev.isxander.controlify.impl.action.ActionImpl; +import dev.isxander.controlify.api.action.ActionSpec; +import dev.isxander.controlify.impl.action.ActionSpecRegistryImpl; +import dev.isxander.controlify.impl.action.activator.ActivatorConfig; +import dev.isxander.controlify.impl.input.pipeline.InputPipeline; +import dev.isxander.controlify.impl.input.pipeline.SensorProcessorStage; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.event.EventSource; import net.minecraft.resources.Identifier; import org.jspecify.annotations.Nullable; import java.util.*; -public class InputComponent extends ECSComponentImpl { +public class InputComponent extends ControllerComponent { public static final Identifier ID = CUtil.rl("input"); private final Identifier controllerType; @@ -49,6 +51,7 @@ public InputComponent( Set supportedSensors, boolean isGamepad ) { + super(ID); this.controllerType = controllerType; this.inputPipeline = inputPipeline; @@ -62,7 +65,7 @@ public InputComponent( } @Override - public void attach(ControllerEntity controller) { + public void attach(ControllerImpl controller) { super.attach(controller); this.deviceSettings = Controlify.instance().config().getSettings() @@ -126,11 +129,6 @@ public void onGuiNavigate() { this.inputPipeline.stagePhysicalToLogical().onGuiNavigate(); } - @Override - public Identifier id() { - return ID; - } - public InputSettings settings() { return this.controller().settings().input; } diff --git a/src/main/java/dev/isxander/controlify/controller/led/LEDComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/led/LEDComponent.java similarity index 86% rename from src/main/java/dev/isxander/controlify/controller/led/LEDComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/led/LEDComponent.java index 3d78419ed..820faaddf 100644 --- a/src/main/java/dev/isxander/controlify/controller/led/LEDComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/led/LEDComponent.java @@ -4,22 +4,22 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.led; +package dev.isxander.controlify.impl.controller.led; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; -import org.jetbrains.annotations.ApiStatus; import java.util.Arrays; -public class LEDComponent extends ECSComponentImpl { +public class LEDComponent extends ControllerComponent { public static final Identifier ID = CUtil.rl("led"); private final int[] ledColors; private boolean dirty = false; public LEDComponent(int ledCount) { + super(ID); this.ledColors = new int[ledCount]; } @@ -77,15 +77,9 @@ public int getCount() { return ledColors.length; } - @ApiStatus.Internal public boolean consumeDirty() { boolean old = this.dirty; this.dirty = false; return old; } - - @Override - public Identifier id() { - return ID; - } } diff --git a/src/main/java/dev/isxander/controlify/controller/misc/BluetoothDeviceComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/misc/BluetoothDeviceComponent.java similarity index 50% rename from src/main/java/dev/isxander/controlify/controller/misc/BluetoothDeviceComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/misc/BluetoothDeviceComponent.java index 73171ce2b..b9483aac5 100644 --- a/src/main/java/dev/isxander/controlify/controller/misc/BluetoothDeviceComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/misc/BluetoothDeviceComponent.java @@ -4,16 +4,21 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.misc; +package dev.isxander.controlify.impl.controller.misc; -import dev.isxander.controlify.config.settings.profile.BluetoothDeviceSettings; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.config.settings.profile.BluetoothDeviceSettings; +import dev.isxander.controlify.impl.controller.impl.ECSComponentImpl; +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; -public class BluetoothDeviceComponent extends ECSComponentImpl { +public class BluetoothDeviceComponent extends ControllerComponent { public static final Identifier ID = CUtil.rl("bluetooth"); + public BluetoothDeviceComponent() { + super(ID); + } + public BluetoothDeviceSettings settings() { return this.controller().settings().bluetoothDevice; } @@ -21,9 +26,4 @@ public BluetoothDeviceSettings settings() { public BluetoothDeviceSettings defaultSettings() { return this.controller().defaultSettings().bluetoothDevice; } - - @Override - public Identifier id() { - return ID; - } } diff --git a/src/main/java/dev/isxander/controlify/impl/controller/misc/DriverNameComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/misc/DriverNameComponent.java new file mode 100644 index 000000000..83b6c630d --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/misc/DriverNameComponent.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.impl.controller.misc; + +import dev.isxander.controlify.impl.controller.SingleValueControllerComponent; +import dev.isxander.controlify.impl.utils.CUtil; +import net.minecraft.resources.Identifier; + +public class DriverNameComponent extends SingleValueControllerComponent { + public static final Identifier ID = CUtil.rl("driver_name"); + + public DriverNameComponent(String value) { + super(ID, value); + } +} diff --git a/src/main/java/dev/isxander/controlify/controller/info/GUIDComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/misc/GUIDComponent.java similarity index 67% rename from src/main/java/dev/isxander/controlify/controller/info/GUIDComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/misc/GUIDComponent.java index 8fa487c0b..61e978b0c 100644 --- a/src/main/java/dev/isxander/controlify/controller/info/GUIDComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/misc/GUIDComponent.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.info; +package dev.isxander.controlify.impl.controller.misc; -import dev.isxander.controlify.controller.SingleValueComponent; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.controller.SingleValueComponent; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; public class GUIDComponent extends SingleValueComponent { diff --git a/src/main/java/dev/isxander/controlify/impl/controller/misc/UIDComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/misc/UIDComponent.java new file mode 100644 index 000000000..f8e0bf97f --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/misc/UIDComponent.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.impl.controller.misc; + +import dev.isxander.controlify.impl.controller.SingleValueControllerComponent; +import dev.isxander.controlify.impl.utils.CUtil; +import net.minecraft.resources.Identifier; + +public class UIDComponent extends SingleValueControllerComponent { + public static final Identifier ID = CUtil.rl("uid"); + + public UIDComponent(String value) { + super(ID, value); + } +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/rumble/ContinuousRumbleEffectImpl.java b/src/main/java/dev/isxander/controlify/impl/controller/rumble/ContinuousRumbleEffectImpl.java new file mode 100644 index 000000000..eb9ce78b6 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/rumble/ContinuousRumbleEffectImpl.java @@ -0,0 +1,122 @@ +package dev.isxander.controlify.impl.controller.rumble; + +import dev.isxander.controlify.api.controller.rumble.ContinuousRumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import net.minecraft.client.Minecraft; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; +import org.jspecify.annotations.NonNull; + +import java.util.Objects; +import java.util.function.BooleanSupplier; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; + +public final class ContinuousRumbleEffectImpl implements ContinuousRumbleEffect { + private final IntFunction state; + private final BooleanSupplier stop; + private final int timeout, minimum; + private final UnaryOperator attenuation; + + public ContinuousRumbleEffectImpl() { + this(_ -> RumbleState.NONE, () -> false, 0, 0, value -> value); + } + + private ContinuousRumbleEffectImpl(IntFunction state, BooleanSupplier stop, + int timeout, int minimum, UnaryOperator attenuation) { + this.state = Objects.requireNonNull(state); + this.stop = stop; + this.timeout = timeout; + this.minimum = minimum; + this.attenuation = attenuation; + } + + @Override + public int timeoutTicks() { + return this.timeout; + } + + @Override + public int minimumTicks() { + return this.minimum; + } + + @Override + public boolean shouldStop() { + return this.stop.getAsBoolean(); + } + + @Override + public @NonNull RumbleState stateAt(int tick) { + return this.attenuation.apply(Objects.requireNonNull(this.state.apply(tick))); + } + + @Override + public @NonNull ContinuousRumbleEffect byTick(@NonNull IntFunction state) { + return new ContinuousRumbleEffectImpl(state, this.stop, this.timeout, this.minimum, this.attenuation); + } + + @Override + public @NonNull ContinuousRumbleEffect constant(float strong, float weak) { + return byTick(_ -> new RumbleState(strong, weak)); + } + + @Override + public @NonNull ContinuousRumbleEffect stopCondition(@NonNull BooleanSupplier condition) { + Objects.requireNonNull(condition); + return new ContinuousRumbleEffectImpl( + this.state, + () -> this.stop.getAsBoolean() || condition.getAsBoolean(), + this.timeout, + this.minimum, + this.attenuation + ); + } + + @Override + public @NonNull ContinuousRumbleEffect timeout(int ticks) { + if (ticks < 0) { + throw new IllegalArgumentException("Timeout cannot be negative"); + } + return new ContinuousRumbleEffectImpl(this.state, this.stop, ticks, this.minimum, this.attenuation); + } + + @Override + public @NonNull ContinuousRumbleEffect minTime(int ticks) { + if (ticks < 0) { + throw new IllegalArgumentException("Minimum duration cannot be negative"); + } + return new ContinuousRumbleEffectImpl(this.state, this.stop, this.timeout, ticks, this.attenuation); + } + + @Override + public @NonNull ContinuousRumbleEffect inWorld( + @NonNull Supplier location, + float minMagnitude, float maxMagnitude, + float range, + @NonNull Function falloff + ) { + Objects.requireNonNull(location); + Objects.requireNonNull(falloff); + if (!Float.isFinite(range) || range <= 0) { + throw new IllegalArgumentException("Range must be finite and positive"); + } + if (!Float.isFinite(minMagnitude) || !Float.isFinite(maxMagnitude) || minMagnitude < 0 || maxMagnitude < minMagnitude) { + throw new IllegalArgumentException("Magnitudes must be finite, nonnegative and ordered"); + } + return new ContinuousRumbleEffectImpl( + this.state, + () -> this.stop.getAsBoolean() || Minecraft.getInstance().getCameraEntity() == null, + this.timeout, this.minimum, value -> { + var camera = Minecraft.getInstance().getCameraEntity(); + if (camera == null) { + return RumbleState.NONE; + } + float distance = (float) Mth.clamp(camera.distanceToSqr(location.get()) / ((double) range * range), 0, 1); + return value.mul(Mth.lerp(falloff.apply(1 - distance), minMagnitude, maxMagnitude)); + } + ); + } +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/rumble/FiniteRumbleEffectImpl.java b/src/main/java/dev/isxander/controlify/impl/controller/rumble/FiniteRumbleEffectImpl.java new file mode 100644 index 000000000..64f32ba34 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/rumble/FiniteRumbleEffectImpl.java @@ -0,0 +1,97 @@ +package dev.isxander.controlify.impl.controller.rumble; + +import dev.isxander.controlify.api.controller.rumble.FiniteRumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import org.jspecify.annotations.NonNull; + +import java.util.Arrays; +import java.util.Objects; +import java.util.function.BooleanSupplier; +import java.util.function.Function; +import java.util.function.IntFunction; + +public final class FiniteRumbleEffectImpl implements FiniteRumbleEffect { + private final RumbleState[] frames; + private final BooleanSupplier stop; + + public FiniteRumbleEffectImpl() { + this(new RumbleState[0], () -> false); + } + + private FiniteRumbleEffectImpl(RumbleState[] frames, BooleanSupplier stop) { + this.frames = frames; + this.stop = stop; + } + + @Override + public int durationTicks() { + return this.frames.length; + } + + @Override + public @NonNull RumbleState stateAt(int tick) { + return this.frames[tick]; + } + + @Override + public boolean shouldStop() { + return this.stop.getAsBoolean(); + } + + @Override + public @NonNull FiniteRumbleEffect stopCondition(@NonNull BooleanSupplier condition) { + Objects.requireNonNull(condition); + return new FiniteRumbleEffectImpl(this.frames, () -> this.stop.getAsBoolean() || condition.getAsBoolean()); + } + + @Override + public @NonNull FiniteRumbleEffect byTick(@NonNull IntFunction state, int durationTicks) { + Objects.requireNonNull(state); + if (durationTicks < 0) { + throw new IllegalArgumentException("Duration cannot be negative"); + } + RumbleState[] frames = new RumbleState[durationTicks]; + for (int i = 0; i < frames.length; i++) { + frames[i] = Objects.requireNonNull(state.apply(i)); + } + return new FiniteRumbleEffectImpl(frames, this.stop); + } + + @Override + public @NonNull FiniteRumbleEffect byTime(@NonNull Function state, int durationTicks) { + Objects.requireNonNull(state); + return byTick(tick -> state.apply((float) tick / durationTicks), durationTicks); + } + + @Override + public @NonNull FiniteRumbleEffect constant(float strong, float weak, int durationTicks) { + return byTick(_ -> new RumbleState(strong, weak), durationTicks); + } + + @Override + public @NonNull FiniteRumbleEffect then(@NonNull FiniteRumbleEffect next) { + Objects.requireNonNull(next); + int length = next.durationTicks(); + if (length < 0) { + throw new IllegalArgumentException("Duration cannot be negative"); + } + + RumbleState[] frames = Arrays.copyOf(this.frames, Math.addExact(this.frames.length, length)); + for (int i = 0; i < length; i++) { + frames[this.frames.length + i] = Objects.requireNonNull(next.stateAt(i)); + } + return new FiniteRumbleEffectImpl(frames, this.stop); + } + + @Override + public @NonNull FiniteRumbleEffect repeat(int count) { + if (count <= 0) { + throw new IllegalArgumentException("Repeat count must be positive"); + } + RumbleState[] frames = new RumbleState[Math.multiplyExact(this.frames.length, count)]; + for (int i = 0; i < count && this.frames.length > 0; i++) { + System.arraycopy(this.frames, 0, frames, i * this.frames.length, this.frames.length); + } + return new FiniteRumbleEffectImpl(frames, this.stop); + } +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleComponentImpl.java b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleComponentImpl.java new file mode 100644 index 000000000..ed6469e50 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleComponentImpl.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.impl.controller.rumble; + +import dev.isxander.controlify.api.controller.rumble.RumbleComponent; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.config.settings.profile.RumbleSettings; +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.utils.CUtil; +import net.minecraft.resources.Identifier; +import org.jspecify.annotations.NonNull; + +import java.util.Optional; + +public class RumbleComponentImpl extends ControllerComponent implements RumbleComponent { + public static final Identifier ID = CUtil.rl("rumble"); + + private RumbleState state = null; + private final RumbleManager rumbleManager; + + public RumbleComponentImpl() { + super(ID); + this.rumbleManager = new RumbleManager(this); + } + + @Override + public @NonNull RumbleEffectInstance playEffect(@NonNull Identifier effectId, @NonNull RumbleEffect effect) { + return this.rumbleManager.play(effectId, effect); + } + + public void queueRumble(RumbleState state) { + if (settings().enabled || state.isZero()) { + this.state = state; + } + } + + public Optional consumeRumble() { + RumbleState state = this.state; + this.state = null; + return Optional.ofNullable(state); + } + + public RumbleManager rumbleManager() { + return this.rumbleManager; + } + + public RumbleSettings settings() { + return this.controller().settings().rumble; + } + + public RumbleSettings defaultSettings() { + return this.controller().defaultSettings().rumble; + } + +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleEffectInstanceImpl.java b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleEffectInstanceImpl.java new file mode 100644 index 000000000..1292bb2fa --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleEffectInstanceImpl.java @@ -0,0 +1,98 @@ +package dev.isxander.controlify.impl.controller.rumble; + +import dev.isxander.controlify.api.controller.rumble.ContinuousRumbleEffect; +import dev.isxander.controlify.api.controller.rumble.FiniteRumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import net.minecraft.resources.Identifier; + +import java.util.Objects; + +/// Playback state belongs to the handle, never to the reusable definition. +public final class RumbleEffectInstanceImpl implements RumbleEffectInstance { + private final Identifier effectId; + private final RumbleEffect effect; + private int tick, inactivity; + private boolean started, finished, stopRequested; + private RumbleState state = RumbleState.NONE; + + public RumbleEffectInstanceImpl(Identifier effectId, RumbleEffect effect) { + this.effectId = Objects.requireNonNull(effectId); + this.effect = Objects.requireNonNull(effect); + } + + public Identifier effectId() { + return effectId; + } + + @Override + public boolean hasStarted() { + return this.started || this.finished; + } + + @Override + public boolean hasFinished() { + return this.finished; + } + + public RumbleState currentState() { + return this.state; + } + + @Override + public boolean stop() { + if (this.finished) { + return false; + } + this.finished = true; + this.state = RumbleState.NONE; + return true; + } + + @Override + public boolean keepAlive() { + if (this.finished || !(this.effect instanceof ContinuousRumbleEffect)) { + return false; + } + this.inactivity = 0; + return true; + } + + public void tick() { + if (this.finished) { + return; + } + this.stopRequested |= this.effect.shouldStop(); + switch (this.effect) { + case FiniteRumbleEffect finite -> { + if (this.stopRequested || this.tick >= finite.durationTicks()) { + this.stop(); + return; + } + } + case ContinuousRumbleEffect continuous -> { + if (this.tick >= continuous.minimumTicks() && (stopRequested || continuous.timeoutTicks() > 0 && inactivity >= continuous.timeoutTicks())) { + this.stop(); + return; + } + } + } + + this.state = Objects.requireNonNull(effect.stateAt(tick)); + this.started = true; + if (this.tick < Integer.MAX_VALUE) { + tick++; + } + if (this.inactivity < Integer.MAX_VALUE) { + this.inactivity++; + } + + if (this.effect instanceof FiniteRumbleEffect finite && this.tick >= finite.durationTicks()) + this.finished = true; + if (this.effect instanceof ContinuousRumbleEffect continuous && this.tick >= continuous.minimumTicks() + && (this.stopRequested || continuous.timeoutTicks() > 0 && this.inactivity >= continuous.timeoutTicks())) { + this.finished = true; + } + } +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleManager.java b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleManager.java new file mode 100644 index 000000000..1d5c5ab4b --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleManager.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.impl.controller.rumble; + +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.Controlify; +import net.minecraft.resources.Identifier; + +import java.util.ArrayList; +import java.util.List; + +public class RumbleManager { + private final RumbleComponentImpl controller; + private final List effectQueue = new ArrayList<>(); + + private boolean silent, wasSilent; + + public RumbleManager(RumbleComponentImpl controller) { + this.controller = controller; + } + + public RumbleEffectInstance play(Identifier effectId, RumbleEffect effect) { + return play(effectId, RumbleSource.MASTER, effect); + } + + /// Internal entry point for server-specified fallback sources. + public RumbleEffectInstance play(Identifier effectId, RumbleSource source, RumbleEffect effect) { + var instance = new RumbleEffectInstanceImpl(effectId, effect); + this.effectQueue.add(new PlayingEffect(source, instance)); + return instance; + } + + public void tick() { + this.effectQueue.removeIf(e -> e.effect().hasFinished()); + this.effectQueue.forEach(e -> e.effect().tick()); + + if (effectQueue.isEmpty()) { + clearRumble(); + return; + } + + float strong = 0f, weak = 0f; + RumbleSourceManager sourceManager = Controlify.instance().rumbleSourceManager(); + for (PlayingEffect effect : effectQueue) { + RumbleSource source = sourceManager.getSource(effect.effect().effectId(), effect.source()); + RumbleState effectState = controller.settings().applyRumbleStrength(effect.effect().currentState(), source); + strong = Math.max(strong, effectState.strong()); + weak = Math.max(weak, effectState.weak()); + } + RumbleState state = new RumbleState(strong, weak); + + if (state.isZero()) { + clearRumble(); + return; + } + + if (silent || !controller.settings().enabled) { + clearRumble(); + } else { + controller.queueRumble(state); + wasSilent = false; + } + } + + private void clearRumble() { + if (wasSilent) + return; + + controller.queueRumble(RumbleState.NONE); + wasSilent = true; + } + + public void clearEffects() { + for (PlayingEffect instance : effectQueue) { + instance.effect().stop(); + } + effectQueue.clear(); + clearRumble(); + } + + public void setSilent(boolean silent) { + this.silent = silent; + } + + public boolean isPlaying() { + return !effectQueue.isEmpty(); + } + + private record PlayingEffect(RumbleSource source, RumbleEffectInstanceImpl effect) { + } +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleSource.java b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleSource.java new file mode 100644 index 000000000..3bc24ffe5 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleSource.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.impl.controller.rumble; + +import com.mojang.serialization.Codec; +import dev.isxander.controlify.impl.utils.CUtil; +import net.minecraft.resources.Identifier; + +import java.util.Objects; + +/// A source identifier, with no registration or availability implied by construction. +/// Available sources are determined by RumbleSourceManager's resource-pack assignments. +public record RumbleSource(Identifier id) { + public static final Codec CODEC = Identifier.CODEC + .xmap(RumbleSource::new, RumbleSource::id); + + /// The global gain/fallback source; this constant does not declare its availability. + public static final RumbleSource MASTER = new RumbleSource(CUtil.rl("master")); + + public RumbleSource { + Objects.requireNonNull(id); + } +} diff --git a/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleSourceManager.java b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleSourceManager.java new file mode 100644 index 000000000..5753e2a33 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/rumble/RumbleSourceManager.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.impl.controller.rumble; + +import com.google.gson.JsonParser; +import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; +import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; + +import java.io.BufferedReader; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +/// Merges effect-to-source assignments from assets/controlify/controller/rumble_sources.json. +/// Higher-priority packs override individual effect IDs. The distinct source IDs in +/// the merged assignments define all available sources. Unassigned effects use their +/// caller-specified fallback if available, otherwise master. +public final class RumbleSourceManager implements SimpleControlifyReloadListener> { + private static final Identifier DEFINITIONS = CUtil.rl("controller/rumble_sources.json"); + private static final Codec> CODEC = Codec.unboundedMap(Identifier.CODEC, RumbleSource.CODEC); + + private volatile Map sourcesByEffect = Map.of(); + + public RumbleSource getSource(Identifier effectId, RumbleSource fallback) { + Map assignments = this.sourcesByEffect; + RumbleSource assigned = assignments.get(effectId); + if (assigned != null) return assigned; + return assignments.containsValue(fallback) ? fallback : RumbleSource.MASTER; + } + + /// Every distinct source named in the loaded assignments, including custom namespaces. + /// No built-in list is added; removing assignments also removes otherwise unused sources. + public List sources() { + return this.sourcesByEffect.values().stream() + .distinct() + .sorted(Comparator.comparing(source -> source.id().toString())) + .toList(); + } + + @Override + public CompletableFuture> load(ResourceManager manager, Executor executor) { + return CompletableFuture.supplyAsync(() -> { + Map assignments = new HashMap<>(); + // Resource stacks are ordered from lowest to highest pack priority. + for (Resource resource : manager.getResourceStack(DEFINITIONS)) { + try (BufferedReader reader = resource.openAsReader()) { + CODEC.parse(JsonOps.INSTANCE, JsonParser.parseReader(reader)) + .resultOrPartial(error -> CUtil.LOGGER.error( + "Failed to parse rumble source assignments from pack '{}': {}", + resource.sourcePackId(), error + )) + .ifPresent(assignments::putAll); + } catch (Exception e) { + CUtil.LOGGER.error("Failed to load rumble source assignments from pack '{}'", resource.sourcePackId(), e); + } + } + return Map.copyOf(assignments); + }, executor); + } + + @Override + public CompletableFuture apply(Map data, ResourceManager manager, Executor executor) { + return CompletableFuture.runAsync(() -> this.sourcesByEffect = Map.copyOf(data), executor); + } + + @Override + public Identifier getReloadId() { + return CUtil.rl("rumble_sources"); + } +} diff --git a/src/main/java/dev/isxander/controlify/controller/rumble/TriggerRumbleComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/rumble/TriggerRumbleComponent.java similarity index 62% rename from src/main/java/dev/isxander/controlify/controller/rumble/TriggerRumbleComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/rumble/TriggerRumbleComponent.java index 916196661..a3493167f 100644 --- a/src/main/java/dev/isxander/controlify/controller/rumble/TriggerRumbleComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/rumble/TriggerRumbleComponent.java @@ -4,21 +4,25 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.rumble; +package dev.isxander.controlify.impl.controller.rumble; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.rumble.TriggerRumbleState; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.api.controller.rumble.TriggerRumbleState; +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.NotNull; import java.util.Optional; -public class TriggerRumbleComponent extends ECSComponentImpl { +public class TriggerRumbleComponent extends ControllerComponent { public static final Identifier ID = CUtil.rl("trigger_rumble"); private TriggerRumbleState state = null; + public TriggerRumbleComponent() { + super(ID); + } + public void queueTriggerRumble(@NotNull TriggerRumbleState state) { this.state = state; } @@ -28,9 +32,4 @@ public Optional consumeTriggerRumble() { this.state = null; return Optional.ofNullable(state); } - - @Override - public Identifier id() { - return ID; - } } diff --git a/src/main/java/dev/isxander/controlify/rumble/effects/UseItemEffectHolder.java b/src/main/java/dev/isxander/controlify/impl/controller/rumble/effects/UseItemEffectHolder.java similarity index 50% rename from src/main/java/dev/isxander/controlify/rumble/effects/UseItemEffectHolder.java rename to src/main/java/dev/isxander/controlify/impl/controller/rumble/effects/UseItemEffectHolder.java index 5e2b86a4c..d660ebb46 100644 --- a/src/main/java/dev/isxander/controlify/rumble/effects/UseItemEffectHolder.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/rumble/effects/UseItemEffectHolder.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.rumble.effects; +package dev.isxander.controlify.impl.controller.rumble.effects; -import dev.isxander.controlify.rumble.ContinuousRumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; import org.jetbrains.annotations.Nullable; public interface UseItemEffectHolder { - @Nullable ContinuousRumbleEffect controlify$getUseItemEffect(); + @Nullable RumbleEffectInstance controlify$getUseItemEffect(); } diff --git a/src/main/java/dev/isxander/controlify/impl/controller/steamdeck/SteamDeckComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/steamdeck/SteamDeckComponent.java new file mode 100644 index 000000000..d5ccf8521 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/impl/controller/steamdeck/SteamDeckComponent.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2026 isXander + * This file is part of Controlify. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +package dev.isxander.controlify.impl.controller.steamdeck; + +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.utils.CUtil; +import net.minecraft.resources.Identifier; + +public class SteamDeckComponent extends ControllerComponent { + public static final Identifier ID = CUtil.rl("steam_deck"); + + public SteamDeckComponent() { + super(ID); + } +} diff --git a/src/main/java/dev/isxander/controlify/controller/touchpad/TouchpadComponent.java b/src/main/java/dev/isxander/controlify/impl/controller/touchpad/TouchpadComponent.java similarity index 60% rename from src/main/java/dev/isxander/controlify/controller/touchpad/TouchpadComponent.java rename to src/main/java/dev/isxander/controlify/impl/controller/touchpad/TouchpadComponent.java index ba47c98a3..e202afd4e 100644 --- a/src/main/java/dev/isxander/controlify/controller/touchpad/TouchpadComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/touchpad/TouchpadComponent.java @@ -4,27 +4,23 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.touchpad; +package dev.isxander.controlify.impl.controller.touchpad; -import dev.isxander.controlify.controller.impl.ECSComponentImpl; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.controller.ControllerComponent; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; -public class TouchpadComponent extends ECSComponentImpl { +public class TouchpadComponent extends ControllerComponent { public static final Identifier ID = CUtil.rl("touchpad"); private final Touchpads touchpads; public TouchpadComponent(Touchpads touchpads) { + super(ID); this.touchpads = touchpads; } public Touchpads.Touchpad[] touchpads() { return touchpads.touchpads(); } - - @Override - public Identifier id() { - return ID; - } } diff --git a/src/main/java/dev/isxander/controlify/controller/touchpad/Touchpads.java b/src/main/java/dev/isxander/controlify/impl/controller/touchpad/Touchpads.java similarity index 95% rename from src/main/java/dev/isxander/controlify/controller/touchpad/Touchpads.java rename to src/main/java/dev/isxander/controlify/impl/controller/touchpad/Touchpads.java index 2c403902c..45148dd1f 100644 --- a/src/main/java/dev/isxander/controlify/controller/touchpad/Touchpads.java +++ b/src/main/java/dev/isxander/controlify/impl/controller/touchpad/Touchpads.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.touchpad; +package dev.isxander.controlify.impl.controller.touchpad; import org.joml.Vector2fc; diff --git a/src/main/java/dev/isxander/controlify/controllermanager/ControllerBackend.java b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerBackend.java similarity index 85% rename from src/main/java/dev/isxander/controlify/controllermanager/ControllerBackend.java rename to src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerBackend.java index 75317ffdb..18974c4d7 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/ControllerBackend.java +++ b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerBackend.java @@ -1,8 +1,7 @@ -package dev.isxander.controlify.controllermanager; +package dev.isxander.controlify.impl.controllermanager; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.hid.HIDID; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.hid.HIDID; /// A controller backend is responsible for listening to controller events /// and creating controllers using the referenced {@link ControllerManager controller manager}. diff --git a/src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerCoordinator.java similarity index 79% rename from src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java rename to src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerCoordinator.java index 54c2fe21e..626dc785a 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/ControllerCoordinator.java +++ b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerCoordinator.java @@ -4,24 +4,24 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controllermanager; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.event.ControlifyEvents; -import dev.isxander.controlify.config.ConfigManager; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.driver.sdl.SDLNativesLoader; -import dev.isxander.controlify.gui.screen.AskToMapControllerScreen; -import dev.isxander.controlify.gui.screen.BluetoothWarningScreen; -import dev.isxander.controlify.input.signal.PhysicalInputSignal; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.DebugLog; -import dev.isxander.controlify.utils.MinecraftUtil; -import dev.isxander.controlify.utils.SetupWizard; -import dev.isxander.controlify.utils.SetupWizardManager; -import dev.isxander.controlify.utils.event.EventSource; +package dev.isxander.controlify.impl.controllermanager; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.ControlifyEvents; +import dev.isxander.controlify.impl.config.ConfigManager; +import dev.isxander.controlify.impl.config.settings.device.DeviceSettings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.driver.sdl.SDLNativesLoader; +import dev.isxander.controlify.impl.gui.screen.AskToMapControllerScreen; +import dev.isxander.controlify.impl.gui.screen.BluetoothWarningScreen; +import dev.isxander.controlify.impl.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.DebugLog; +import dev.isxander.controlify.impl.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.SetupWizard; +import dev.isxander.controlify.impl.utils.SetupWizardManager; +import dev.isxander.controlify.impl.utils.event.EventSource; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.Nullable; @@ -31,7 +31,7 @@ import java.util.Optional; import java.util.Set; -import static dev.isxander.controlify.utils.ControllerUtils.wrapControllerError; +import static dev.isxander.controlify.impl.utils.ControllerUtils.wrapControllerError; /// Owns controller discovery, selection, activation and activity subscriptions. /// Publishes selection changes through {@link ControlifyEvents#CURRENT_CONTROLLER_CHANGED}. @@ -40,11 +40,11 @@ public class ControllerCoordinator implements AutoCloseable { private final ConfigManager config; private final SetupWizardManager setupWizardManager; private final ControllerManager controllerManager = new ControllerManager(); - private final Map inputSubscriptions = new HashMap<>(); - private final Set controllersWithInput = new LinkedHashSet<>(); + private final Map inputSubscriptions = new HashMap<>(); + private final Set controllersWithInput = new LinkedHashSet<>(); private @Nullable ControllerBackend backend; - private @Nullable ControllerEntity currentController; + private @Nullable ControllerImpl currentController; private boolean hasDiscoveredControllers; private boolean closed; @@ -78,7 +78,7 @@ public ControllerManager controllerManager() { return this.controllerManager; } - public Optional currentController() { + public Optional currentController() { return Optional.ofNullable(this.currentController); } @@ -129,7 +129,7 @@ public boolean update(boolean outOfFocus) { return !outOfFocus && this.controllersWithInput.contains(this.currentController); } - public void setCurrentController(@Nullable ControllerEntity controller, boolean changeInputMode) { + public void setCurrentController(@Nullable ControllerImpl controller, boolean changeInputMode) { if (this.closed || this.currentController == controller) { return; } @@ -149,7 +149,7 @@ public void setCurrentController(@Nullable ControllerEntity controller, boolean public void applyControllerSelection(boolean changeInputMode) { String selectedUid = this.config.getActiveProfile().controllerUid; - ControllerEntity selected = this.controllerManager.getAllControllers().stream() + ControllerImpl selected = this.controllerManager.getAllControllers().stream() .filter(controller -> selectedUid == null || selectedUid.equals(controller.uid())) .findFirst().orElse(null); this.setCurrentController(selected, changeInputMode); @@ -161,7 +161,7 @@ public void applyActiveProfile() { this.applyControllerSelection(true); } - private void onControllerAdded(ControllerEntity controller, boolean hotplugged) { + private void onControllerAdded(ControllerImpl controller, boolean hotplugged) { if (this.closed) { return; } @@ -178,7 +178,7 @@ private void onControllerAdded(ControllerEntity controller, boolean hotplugged) DeviceSettings rememberedDevice = this.config.getSettings().getOrCreateDeviceSettings(controller.uid()); rememberedDevice.name = controller.name(); rememberedDevice.lastSeen = System.currentTimeMillis(); - rememberedDevice.controllerType = controller.info().type().namespace(); + rememberedDevice.controllerType = controller.info().type().id(); this.config.markDirty(); String selectedUid = this.config.getActiveProfile().controllerUid; @@ -205,7 +205,7 @@ private void onControllerAdded(ControllerEntity controller, boolean hotplugged) this.setupWizardManager.push(wizard); } - private void onControllerRemoved(ControllerEntity controller) { + private void onControllerRemoved(ControllerImpl controller) { if (this.closed) { return; } @@ -215,7 +215,7 @@ private void onControllerRemoved(ControllerEntity controller) { } this.controllersWithInput.remove(controller); if (this.currentController == controller) { - ControllerEntity fallback = this.config.getActiveProfile().controllerUid == null + ControllerImpl fallback = this.config.getActiveProfile().controllerUid == null ? this.controllerManager.getAllControllers().stream() .filter(candidate -> candidate != controller).findFirst().orElse(null) : null; diff --git a/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerManager.java similarity index 66% rename from src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java rename to src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerManager.java index 46b6e8161..7b5ee0ca8 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/ControllerManager.java +++ b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerManager.java @@ -1,20 +1,19 @@ -package dev.isxander.controlify.controllermanager; +package dev.isxander.controlify.impl.controllermanager; -import dev.isxander.controlify.api.event.ControlifyEvents; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; -import dev.isxander.controlify.hid.HIDID; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.ControllerUtils; -import dev.isxander.controlify.utils.log.ControlifyLogger; +import dev.isxander.controlify.api.ControlifyEvents; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.driver.steamdeck.SteamDeckUtil; +import dev.isxander.controlify.impl.hid.HIDID; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.ControllerUtils; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; import java.io.Closeable; import java.util.*; public class ControllerManager implements Closeable { - private final Map controllersByUid; - private final Map controllersByUcid; + private final Map controllersByUid; + private final Map controllersByUcid; public ControllerManager() { this.controllersByUid = new HashMap<>(); @@ -47,7 +46,7 @@ public boolean canAddController( return true; } - public void addController(ControllerEntity controller, boolean hotplugged) { + public void addController(ControllerImpl controller, boolean hotplugged) { this.controllersByUcid.put(controller.info().ucid(), controller); this.controllersByUid.put(controller.uid(), controller); @@ -61,7 +60,7 @@ public void addController(ControllerEntity controller, boolean hotplugged) { } public void removeController(UniqueControllerID controllerUcid) { - ControllerEntity controller = this.controllersByUcid.get(controllerUcid); + ControllerImpl controller = this.controllersByUcid.get(controllerUcid); ControlifyEvents.CONTROLLER_DISCONNECTED.invoke(new ControlifyEvents.ControllerDisconnected(controller)); @@ -75,20 +74,20 @@ public void removeController(UniqueControllerID controllerUcid) { controller.close(); } - public Optional getControllerByUcid(UniqueControllerID ucid) { + public Optional getControllerByUcid(UniqueControllerID ucid) { return Optional.ofNullable(this.controllersByUcid.get(ucid)); } - public Optional getControllerByUid(String uid) { + public Optional getControllerByUid(String uid) { return Optional.ofNullable(this.controllersByUid.get(uid)); } - public Collection getAllControllers() { + public Collection getAllControllers() { return Collections.unmodifiableCollection(this.controllersByUcid.values()); } @Override public void close() { - this.controllersByUcid.values().forEach(ControllerEntity::close); + this.controllersByUcid.values().forEach(ControllerImpl::close); } } diff --git a/src/main/java/dev/isxander/controlify/controller/id/ControllerType.java b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerType.java similarity index 73% rename from src/main/java/dev/isxander/controlify/controller/id/ControllerType.java rename to src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerType.java index 4b0d01146..b7a190313 100644 --- a/src/main/java/dev/isxander/controlify/controller/id/ControllerType.java +++ b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerType.java @@ -4,19 +4,19 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.id; +package dev.isxander.controlify.impl.controllermanager; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.codec.CExtraCodecs; +import dev.isxander.controlify.impl.driver.steamdeck.SteamDeckUtil; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.codec.CExtraCodecs; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; public record ControllerType( - Identifier namespace, + Identifier id, @Nullable String friendlyName, @Nullable Identifier mappingId, boolean forceJoystick, @@ -25,7 +25,7 @@ public record ControllerType( public static final ControllerType DEFAULT = new ControllerType(CUtil.rl("default"), null, null, false, false); public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Identifier.CODEC.optionalFieldOf("namespace", DEFAULT.namespace()).forGetter(ControllerType::namespace), + Identifier.CODEC.optionalFieldOf("namespace", DEFAULT.id()).forGetter(ControllerType::id), CExtraCodecs.nullableField(Codec.STRING, "name").forGetter(ControllerType::friendlyName), CExtraCodecs.nullableField(Identifier.CODEC, "mapping").forGetter(ControllerType::mappingId), Codec.BOOL.optionalFieldOf("force_joystick", false).forGetter(ControllerType::forceJoystick), @@ -33,10 +33,10 @@ public record ControllerType( ).apply(instance, ControllerType::new)); public Identifier getIconSprite() { - return namespace.withPrefix("controllers/"); + return id.withPrefix("controllers/"); } public boolean isSteamDeck() { - return namespace.equals(SteamDeckUtil.STEAM_DECK_NAMESPACE); + return id.equals(SteamDeckUtil.STEAM_DECK_NAMESPACE); } } diff --git a/src/main/java/dev/isxander/controlify/controller/id/ControllerTypeManager.java b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerTypeManager.java similarity index 87% rename from src/main/java/dev/isxander/controlify/controller/id/ControllerTypeManager.java rename to src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerTypeManager.java index 458afcf3f..ea6c3fa1b 100644 --- a/src/main/java/dev/isxander/controlify/controller/id/ControllerTypeManager.java +++ b/src/main/java/dev/isxander/controlify/impl/controllermanager/ControllerTypeManager.java @@ -4,22 +4,21 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controller.id; +package dev.isxander.controlify.impl.controllermanager; import com.google.gson.JsonElement; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.JsonOps; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controllermanager.ControllerManager; -import dev.isxander.controlify.hid.ControllerHIDInfo; -import dev.isxander.controlify.hid.HIDDevice; -import dev.isxander.controlify.hid.HIDID; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.JsonTreeParser; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.hid.ControllerHIDInfo; +import dev.isxander.controlify.impl.hid.HIDDevice; +import dev.isxander.controlify.impl.hid.HIDID; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.JsonTreeParser; import net.minecraft.util.Util; import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.Resource; @@ -108,13 +107,13 @@ public void triggerFullTypeReload() { if (controllerManagerOpt.isPresent()) { ControllerManager controllerManager = controllerManagerOpt.get(); - for (ControllerEntity controller : controllerManager.getConnectedControllers()) { + for (ControllerImpl controller : controllerManager.getAllControllers()) { reloadTypeForController(controllerManager, controller); } } } - public void reloadTypeForController(ControllerManager controllerManager, ControllerEntity controller) { + public void reloadTypeForController(ControllerManager controllerManager, ControllerImpl controller) { Optional hidOpt = controller.info().hid(); if (hidOpt.isEmpty()) return; diff --git a/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java b/src/main/java/dev/isxander/controlify/impl/controllermanager/SDLControllerBackend.java similarity index 88% rename from src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java rename to src/main/java/dev/isxander/controlify/impl/controllermanager/SDLControllerBackend.java index fc0d497a1..7393070c3 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/SDLControllerBackend.java +++ b/src/main/java/dev/isxander/controlify/impl/controllermanager/SDLControllerBackend.java @@ -1,18 +1,17 @@ -package dev.isxander.controlify.controllermanager; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.controller.info.ControllerInfo; -import dev.isxander.controlify.debug.DebugProperties; -import dev.isxander.controlify.driver.Driver; -import dev.isxander.controlify.driver.sdl.*; -import dev.isxander.controlify.hid.HIDID; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.event.EventSource; -import dev.isxander.controlify.utils.event.EventTap; -import dev.isxander.controlify.utils.log.ControlifyLogger; +package dev.isxander.controlify.impl.controllermanager; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.ControllerInfo; +import dev.isxander.controlify.impl.debug.DebugProperties; +import dev.isxander.controlify.impl.driver.Driver; +import dev.isxander.controlify.impl.driver.sdl.*; +import dev.isxander.controlify.impl.hid.HIDID; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.event.EventSource; +import dev.isxander.controlify.impl.utils.event.EventTap; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; import dev.isxander.sdl.*; import net.minecraft.client.Minecraft; import net.minecraft.server.packs.resources.Resource; @@ -165,7 +164,7 @@ private void createAndAddController( } var controllerInfo = new ControllerInfo(ucid, type, hidId); - var controller = new ControllerEntity( + var controller = new ControllerImpl( controllerInfo, driver, Controlify.instance().config().getActiveProfile(), diff --git a/src/main/java/dev/isxander/controlify/controllermanager/SDLUniqueControllerID.java b/src/main/java/dev/isxander/controlify/impl/controllermanager/SDLUniqueControllerID.java similarity index 90% rename from src/main/java/dev/isxander/controlify/controllermanager/SDLUniqueControllerID.java rename to src/main/java/dev/isxander/controlify/impl/controllermanager/SDLUniqueControllerID.java index f888c57ef..002e3e94c 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/SDLUniqueControllerID.java +++ b/src/main/java/dev/isxander/controlify/impl/controllermanager/SDLUniqueControllerID.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.controllermanager; +package dev.isxander.controlify.impl.controllermanager; import dev.isxander.sdl.SdlJoystickId; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/dev/isxander/controlify/controllermanager/UniqueControllerID.java b/src/main/java/dev/isxander/controlify/impl/controllermanager/UniqueControllerID.java similarity index 88% rename from src/main/java/dev/isxander/controlify/controllermanager/UniqueControllerID.java rename to src/main/java/dev/isxander/controlify/impl/controllermanager/UniqueControllerID.java index 99886cb70..05284e8fd 100644 --- a/src/main/java/dev/isxander/controlify/controllermanager/UniqueControllerID.java +++ b/src/main/java/dev/isxander/controlify/impl/controllermanager/UniqueControllerID.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.controllermanager; +package dev.isxander.controlify.impl.controllermanager; /** * A unique, abstract identifier for a controller. diff --git a/src/main/java/dev/isxander/controlify/debug/DebugProperties.java b/src/main/java/dev/isxander/controlify/impl/debug/DebugProperties.java similarity index 95% rename from src/main/java/dev/isxander/controlify/debug/DebugProperties.java rename to src/main/java/dev/isxander/controlify/impl/debug/DebugProperties.java index b33753310..87209d97f 100644 --- a/src/main/java/dev/isxander/controlify/debug/DebugProperties.java +++ b/src/main/java/dev/isxander/controlify/impl/debug/DebugProperties.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.debug; +package dev.isxander.controlify.impl.debug; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.utils.CUtil; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; diff --git a/src/main/java/dev/isxander/controlify/driver/ComponentAdderDriver.java b/src/main/java/dev/isxander/controlify/impl/driver/ComponentAdderDriver.java similarity index 51% rename from src/main/java/dev/isxander/controlify/driver/ComponentAdderDriver.java rename to src/main/java/dev/isxander/controlify/impl/driver/ComponentAdderDriver.java index b1a87c928..49fb63d81 100644 --- a/src/main/java/dev/isxander/controlify/driver/ComponentAdderDriver.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/ComponentAdderDriver.java @@ -4,21 +4,21 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver; +package dev.isxander.controlify.impl.driver; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.controller.ControllerImpl; import java.util.function.Consumer; public class ComponentAdderDriver implements Driver { - private final Consumer componentAdder; + private final Consumer componentAdder; - public ComponentAdderDriver(Consumer componentAdder) { + public ComponentAdderDriver(Consumer componentAdder) { this.componentAdder = componentAdder; } @Override - public void addComponents(ControllerEntity controller) { + public void addComponents(ControllerImpl controller) { componentAdder.accept(controller); } } diff --git a/src/main/java/dev/isxander/controlify/driver/CompoundDriver.java b/src/main/java/dev/isxander/controlify/impl/driver/CompoundDriver.java similarity index 77% rename from src/main/java/dev/isxander/controlify/driver/CompoundDriver.java rename to src/main/java/dev/isxander/controlify/impl/driver/CompoundDriver.java index 5175847a9..460cc2b71 100644 --- a/src/main/java/dev/isxander/controlify/driver/CompoundDriver.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/CompoundDriver.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver; +package dev.isxander.controlify.impl.driver; import com.google.common.collect.Lists; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.controller.ControllerImpl; import java.util.List; import java.util.stream.Collectors; @@ -20,16 +20,16 @@ public CompoundDriver(List drivers) { } @Override - public void addComponents(ControllerEntity controller) { + public void addComponents(ControllerImpl controller) { for (Driver driver : Lists.reverse(drivers)) { driver.addComponents(controller); } } @Override - public void update(ControllerEntity controller, boolean outOfFocus) { + public void update(ControllerImpl controller, boolean outOfFocus) { for (Driver driver : drivers) { - driver.update(controller, outOfFocus); + driver.update(controller); } } diff --git a/src/main/java/dev/isxander/controlify/driver/Driver.java b/src/main/java/dev/isxander/controlify/impl/driver/Driver.java similarity index 62% rename from src/main/java/dev/isxander/controlify/driver/Driver.java rename to src/main/java/dev/isxander/controlify/impl/driver/Driver.java index 3f4e0c43f..a58727298 100644 --- a/src/main/java/dev/isxander/controlify/driver/Driver.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/Driver.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver; +package dev.isxander.controlify.impl.driver; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.controller.ControllerImpl; public interface Driver { - default void addComponents(ControllerEntity controller) {} + default void addComponents(ControllerImpl controller) {} - default void update(ControllerEntity controller, boolean outOfFocus) {} + default void update(ControllerImpl controller) {} /// Enables resources needed only by the active controller, such as sensor sampling. /// Buttons and axes must remain available while inactive for controller selection. diff --git a/src/main/java/dev/isxander/controlify/driver/dualsense/DualsenseEffectsState.java b/src/main/java/dev/isxander/controlify/impl/driver/dualsense/DualsenseEffectsState.java similarity index 99% rename from src/main/java/dev/isxander/controlify/driver/dualsense/DualsenseEffectsState.java rename to src/main/java/dev/isxander/controlify/impl/driver/dualsense/DualsenseEffectsState.java index 48d02c485..9fdd683a4 100644 --- a/src/main/java/dev/isxander/controlify/driver/dualsense/DualsenseEffectsState.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/dualsense/DualsenseEffectsState.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.dualsense; +package dev.isxander.controlify.impl.driver.dualsense; import org.intellij.lang.annotations.MagicConstant; diff --git a/src/main/java/dev/isxander/controlify/driver/dualsense/DualsenseTriggerEffect.java b/src/main/java/dev/isxander/controlify/impl/driver/dualsense/DualsenseTriggerEffect.java similarity index 99% rename from src/main/java/dev/isxander/controlify/driver/dualsense/DualsenseTriggerEffect.java rename to src/main/java/dev/isxander/controlify/impl/driver/dualsense/DualsenseTriggerEffect.java index 33edb3e73..b825d9664 100644 --- a/src/main/java/dev/isxander/controlify/driver/dualsense/DualsenseTriggerEffect.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/dualsense/DualsenseTriggerEffect.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.dualsense; +package dev.isxander.controlify.impl.driver.dualsense; import org.apache.commons.lang3.Validate; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/dev/isxander/controlify/driver/dualsense/DualsenseTriggerEffectTypes.java b/src/main/java/dev/isxander/controlify/impl/driver/dualsense/DualsenseTriggerEffectTypes.java similarity index 96% rename from src/main/java/dev/isxander/controlify/driver/dualsense/DualsenseTriggerEffectTypes.java rename to src/main/java/dev/isxander/controlify/impl/driver/dualsense/DualsenseTriggerEffectTypes.java index 9fc0680a7..01a77b78e 100644 --- a/src/main/java/dev/isxander/controlify/driver/dualsense/DualsenseTriggerEffectTypes.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/dualsense/DualsenseTriggerEffectTypes.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.dualsense; +package dev.isxander.controlify.impl.driver.dualsense; public final class DualsenseTriggerEffectTypes { diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/DecodedGUID.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/DecodedGUID.java similarity index 98% rename from src/main/java/dev/isxander/controlify/driver/sdl/DecodedGUID.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/DecodedGUID.java index 1b11e4ab7..a66b07ce1 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/DecodedGUID.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/DecodedGUID.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.sdl; +package dev.isxander.controlify.impl.driver.sdl; import dev.isxander.sdl.SdlGuid; import org.apache.commons.lang3.Validate; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDL3GamepadDriver.java similarity index 89% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDL3GamepadDriver.java index 7f2ae3f30..16ca790ab 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDL3GamepadDriver.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDL3GamepadDriver.java @@ -4,17 +4,16 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.sdl; - -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.controller.touchpad.TouchpadComponent; -import dev.isxander.controlify.controller.gyro.GyroComponent; -import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.controller.touchpad.Touchpads; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.utils.event.EventSource; -import dev.isxander.controlify.utils.log.ControlifyLogger; +package dev.isxander.controlify.impl.driver.sdl; + +import dev.isxander.controlify.impl.controllermanager.ControllerType; +import dev.isxander.controlify.impl.controller.touchpad.TouchpadComponent; +import dev.isxander.controlify.impl.controller.gyro.GyroComponent; +import dev.isxander.controlify.impl.controller.touchpad.Touchpads; +import dev.isxander.controlify.impl.controller.input.InputComponent; +import dev.isxander.controlify.impl.input.SensorType; +import dev.isxander.controlify.impl.utils.event.EventSource; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; import dev.isxander.sdl.*; import net.minecraft.resources.Identifier; @@ -63,12 +62,12 @@ public SDL3GamepadDriver(Sdl sdl, SdlGamepadHandle ptrController, EventSource implements Driver { private EventSource.Subscription eventSubscription; protected BatteryLevelComponent batteryLevelComponent; - protected RumbleComponent rumbleComponent; + protected RumbleComponentImpl rumbleComponent; protected TriggerRumbleComponent triggerRumbleComponent; protected HDHapticComponent hdHapticComponent; protected LEDComponent ledComponent; @@ -128,7 +128,7 @@ public SDLCommonDriver(Sdl sdl, SdlController ptrController, SdlJoystickId jid, // open audio device for dualsense hd haptics this.dualsenseAudioHandles = new ArrayList<>(); - this.isDualsense = CUtil.rl("dualsense").equals(type.namespace()); + this.isDualsense = CUtil.rl("dualsense").equals(type.id()); if (this.isDualsense) { logger.debugLog("DualSense controller detected."); @@ -160,14 +160,14 @@ public SDLCommonDriver(Sdl sdl, SdlController ptrController, SdlJoystickId jid, } @Override - public void addComponents(ControllerEntity controller) { + public void addComponents(ControllerImpl controller) { controller.setComponent(new DriverNameComponent(this.name)); controller.setComponent(new GUIDComponent(this.guidString)); controller.setComponent(new UIDComponent(createUid())); controller.setComponent(this.batteryLevelComponent = new BatteryLevelComponent()); if (this.isRumbleSupported) { - controller.setComponent(this.rumbleComponent = new RumbleComponent()); + controller.setComponent(this.rumbleComponent = new RumbleComponentImpl()); } if (this.isTriggerRumbleSupported) { controller.setComponent(this.triggerRumbleComponent = new TriggerRumbleComponent()); @@ -214,7 +214,7 @@ private void onBatteryEvent(SDLControllerEvent.Battery event) { } @Override - public void update(ControllerEntity controller, boolean outOfFocus) { + public void update(ControllerImpl controller) { if (ptrController == null) { throw new IllegalStateException("Tried to update controller when it's closed."); } diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLControllerEvent.java similarity index 99% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLControllerEvent.java index b1d763393..944ee9898 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEvent.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLControllerEvent.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.driver.sdl; +package dev.isxander.controlify.impl.driver.sdl; import dev.isxander.sdl.SdlJoystickId; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEventStage.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLControllerEventStage.java similarity index 93% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEventStage.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLControllerEventStage.java index dc862b7a9..cd0c73c93 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLControllerEventStage.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLControllerEventStage.java @@ -1,7 +1,7 @@ -package dev.isxander.controlify.driver.sdl; +package dev.isxander.controlify.impl.driver.sdl; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.EventStage; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.EventStage; import dev.isxander.sdl.*; public class SDLControllerEventStage implements EventStage { diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLException.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLException.java similarity index 91% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDLException.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLException.java index c416b6c90..06b9b90a8 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLException.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLException.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.sdl; +package dev.isxander.controlify.impl.driver.sdl; import dev.isxander.sdl.Sdl; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLGamepadInputMapping.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLGamepadInputMapping.java similarity index 90% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDLGamepadInputMapping.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLGamepadInputMapping.java index e7dad49a1..7004736dc 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLGamepadInputMapping.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLGamepadInputMapping.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.sdl; +package dev.isxander.controlify.impl.driver.sdl; -import dev.isxander.controlify.controller.impl.ControllerStateImpl; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.controller.impl.ControllerStateImpl; +import dev.isxander.controlify.impl.utils.CUtil; import dev.isxander.sdl.SdlGamepad; import dev.isxander.sdl.SdlGamepadHandle; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLInputConversions.java similarity index 97% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLInputConversions.java index dda85452f..033fb493e 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLInputConversions.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLInputConversions.java @@ -1,7 +1,7 @@ -package dev.isxander.controlify.driver.sdl; +package dev.isxander.controlify.impl.driver.sdl; -import dev.isxander.controlify.input.mapping.GamepadInputs; -import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.impl.input.mapping.GamepadInputs; +import dev.isxander.controlify.impl.input.SensorType; import dev.isxander.sdl.SdlEvents; import dev.isxander.sdl.SdlGamepad; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLJoystickConnectionState.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLJoystickConnectionState.java similarity index 92% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDLJoystickConnectionState.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLJoystickConnectionState.java index 3b445b171..cb1b2a912 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLJoystickConnectionState.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLJoystickConnectionState.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.sdl; +package dev.isxander.controlify.impl.driver.sdl; public enum SDLJoystickConnectionState { INVALID(-1), diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLNativesLoader.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLNativesLoader.java similarity index 95% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDLNativesLoader.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLNativesLoader.java index 6524f9184..b2b83498d 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLNativesLoader.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLNativesLoader.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.sdl; +package dev.isxander.controlify.impl.driver.sdl; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.Platform; -import dev.isxander.controlify.utils.log.ControlifyLogger; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.Platform; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; import dev.isxander.sdl.Sdl; import dev.isxander.sdl.SdlLoader; import dev.isxander.sdl.SdlVersion; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLToPhysicalStage.java similarity index 86% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLToPhysicalStage.java index bf22dcbe5..da46ad9a0 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLToPhysicalStage.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLToPhysicalStage.java @@ -1,12 +1,12 @@ -package dev.isxander.controlify.driver.sdl; - -import dev.isxander.controlify.input.mapping.JoystickInputs; -import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.signal.PhysicalInputSignal; -import dev.isxander.controlify.input.signal.PhysicalSensorSignal; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.EventStage; +package dev.isxander.controlify.impl.driver.sdl; + +import dev.isxander.controlify.impl.input.mapping.JoystickInputs; +import dev.isxander.controlify.impl.input.SensorType; +import dev.isxander.controlify.impl.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.EventStage; import net.minecraft.resources.Identifier; import java.util.Arrays; diff --git a/src/main/java/dev/isxander/controlify/driver/sdl/SDLUtil.java b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLUtil.java similarity index 94% rename from src/main/java/dev/isxander/controlify/driver/sdl/SDLUtil.java rename to src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLUtil.java index 21ddc2a34..29214a77e 100644 --- a/src/main/java/dev/isxander/controlify/driver/sdl/SDLUtil.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/sdl/SDLUtil.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.sdl; +package dev.isxander.controlify.impl.driver.sdl; import dev.isxander.sdl.Sdl; import dev.isxander.sdl.SdlGamepadHandle; diff --git a/src/main/java/dev/isxander/controlify/driver/steamdeck/CEFDebuggerFileResult.java b/src/main/java/dev/isxander/controlify/impl/driver/steamdeck/CEFDebuggerFileResult.java similarity index 93% rename from src/main/java/dev/isxander/controlify/driver/steamdeck/CEFDebuggerFileResult.java rename to src/main/java/dev/isxander/controlify/impl/driver/steamdeck/CEFDebuggerFileResult.java index 960b2ac2f..722e460aa 100644 --- a/src/main/java/dev/isxander/controlify/driver/steamdeck/CEFDebuggerFileResult.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/steamdeck/CEFDebuggerFileResult.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.steamdeck; +package dev.isxander.controlify.impl.driver.steamdeck; public enum CEFDebuggerFileResult { /** The file has just been created, but requires steam to restart to take effect **/ diff --git a/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckDriver.java b/src/main/java/dev/isxander/controlify/impl/driver/steamdeck/SteamDeckDriver.java similarity index 87% rename from src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckDriver.java rename to src/main/java/dev/isxander/controlify/impl/driver/steamdeck/SteamDeckDriver.java index 021e6fc3b..e88f7b966 100644 --- a/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckDriver.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/steamdeck/SteamDeckDriver.java @@ -4,26 +4,26 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.steamdeck; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.battery.BatteryLevelComponent; -import dev.isxander.controlify.controller.battery.PowerState; -import dev.isxander.controlify.controller.gyro.GyroComponent; -import dev.isxander.controlify.controller.gyro.GyroState; -import dev.isxander.controlify.controller.impl.ControllerStateImpl; -import dev.isxander.controlify.controller.info.DriverNameComponent; -import dev.isxander.controlify.controller.info.GUIDComponent; -import dev.isxander.controlify.controller.info.UIDComponent; -import dev.isxander.controlify.input.mapping.GamepadInputs; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.controller.steamdeck.SteamDeckComponent; -import dev.isxander.controlify.controller.touchpad.TouchpadComponent; -import dev.isxander.controlify.controller.touchpad.Touchpads; -import dev.isxander.controlify.driver.Driver; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.log.ControlifyLogger; +package dev.isxander.controlify.impl.driver.steamdeck; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.battery.BatteryLevelComponent; +import dev.isxander.controlify.impl.controller.battery.PowerState; +import dev.isxander.controlify.impl.controller.gyro.GyroComponent; +import dev.isxander.controlify.impl.controller.gyro.GyroState; +import dev.isxander.controlify.impl.controller.impl.ControllerStateImpl; +import dev.isxander.controlify.impl.controller.misc.DriverNameComponent; +import dev.isxander.controlify.impl.controller.misc.GUIDComponent; +import dev.isxander.controlify.impl.controller.misc.UIDComponent; +import dev.isxander.controlify.impl.input.mapping.GamepadInputs; +import dev.isxander.controlify.impl.controller.input.InputComponent; +import dev.isxander.controlify.impl.controller.steamdeck.SteamDeckComponent; +import dev.isxander.controlify.impl.controller.touchpad.TouchpadComponent; +import dev.isxander.controlify.impl.controller.touchpad.Touchpads; +import dev.isxander.controlify.impl.driver.Driver; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; import dev.isxander.deckapi.api.ControllerButton; import dev.isxander.deckapi.api.ControllerState; import dev.isxander.deckapi.api.SteamDeck; @@ -36,7 +36,7 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; -import static dev.isxander.controlify.utils.CUtil.*; +import static dev.isxander.controlify.impl.utils.CUtil.*; public class SteamDeckDriver implements Driver { private static SteamDeck deck; @@ -56,7 +56,7 @@ public SteamDeckDriver(ControlifyLogger logger) { } @Override - public void addComponents(ControllerEntity controller) { + public void addComponents(ControllerImpl controller) { controller.setComponent(new DriverNameComponent("Steam Deck")); controller.setComponent(new GUIDComponent("steamdeck")); controller.setComponent(new UIDComponent(CUtil.createUIDFromBytes("steamdeck".getBytes()))); @@ -123,7 +123,7 @@ private void ensurePolling() { } @Override - public void update(ControllerEntity controller, boolean outOfFocus) { + public void update(ControllerImpl controller, boolean outOfFocus) { ensurePolling(); ControllerStateImpl state = new ControllerStateImpl(); diff --git a/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckMode.java b/src/main/java/dev/isxander/controlify/impl/driver/steamdeck/SteamDeckMode.java similarity index 87% rename from src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckMode.java rename to src/main/java/dev/isxander/controlify/impl/driver/steamdeck/SteamDeckMode.java index 9de0fc616..bc671aa5c 100644 --- a/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckMode.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/steamdeck/SteamDeckMode.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.steamdeck; +package dev.isxander.controlify.impl.driver.steamdeck; public enum SteamDeckMode { GAMING_MODE, diff --git a/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckUtil.java b/src/main/java/dev/isxander/controlify/impl/driver/steamdeck/SteamDeckUtil.java similarity index 94% rename from src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckUtil.java rename to src/main/java/dev/isxander/controlify/impl/driver/steamdeck/SteamDeckUtil.java index 010e05184..3c7c65033 100644 --- a/src/main/java/dev/isxander/controlify/driver/steamdeck/SteamDeckUtil.java +++ b/src/main/java/dev/isxander/controlify/impl/driver/steamdeck/SteamDeckUtil.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.driver.steamdeck; +package dev.isxander.controlify.impl.driver.steamdeck; -import dev.isxander.controlify.debug.DebugProperties; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.log.ControlifyLogger; +import dev.isxander.controlify.impl.debug.DebugProperties; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; import dev.isxander.deckapi.api.SteamDeck; import dev.isxander.deckapi.api.SteamDeckException; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/font/BindingFontHelper.java b/src/main/java/dev/isxander/controlify/impl/font/BindingFontHelper.java similarity index 94% rename from src/main/java/dev/isxander/controlify/font/BindingFontHelper.java rename to src/main/java/dev/isxander/controlify/impl/font/BindingFontHelper.java index 40d1e1eaf..5abb256ee 100644 --- a/src/main/java/dev/isxander/controlify/font/BindingFontHelper.java +++ b/src/main/java/dev/isxander/controlify/impl/font/BindingFontHelper.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.font; +package dev.isxander.controlify.impl.font; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.gui.Font; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FontDescription; diff --git a/src/main/java/dev/isxander/controlify/font/InputFontMapper.java b/src/main/java/dev/isxander/controlify/impl/font/InputFontMapper.java similarity index 91% rename from src/main/java/dev/isxander/controlify/font/InputFontMapper.java rename to src/main/java/dev/isxander/controlify/impl/font/InputFontMapper.java index d7d4322ad..4a17525eb 100644 --- a/src/main/java/dev/isxander/controlify/font/InputFontMapper.java +++ b/src/main/java/dev/isxander/controlify/impl/font/InputFontMapper.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.font; +package dev.isxander.controlify.impl.font; import com.google.common.collect.ImmutableMap; import com.google.gson.JsonElement; @@ -13,11 +13,11 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.input.Input; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.bindings.input.Input; +import dev.isxander.controlify.impl.controllermanager.ControllerType; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FontDescription; import net.minecraft.network.chat.MutableComponent; @@ -54,7 +54,7 @@ public class InputFontMapper implements SimpleControlifyReloadListener load(ResourceManager manager, Executor executor) { @@ -75,7 +75,7 @@ public CompletableFuture load(ResourceManager manager, Executor ex return Stream.of(Pair.of(namespace, map)); } } catch (Exception e) { - CUtil.LOGGER.error("Failed to load font mappings for namespace {}", namespace, e); + CUtil.LOGGER.error("Failed to load font mappings for id {}", namespace, e); } return Stream.empty(); @@ -91,7 +91,7 @@ public CompletableFuture apply(Preparations data, ResourceManager manager, ImmutableMap.Builder builder = ImmutableMap.builder(); data.mappings().forEach(builder::put); mappings = builder.build(); - defaultFontMap = mappings.get(ControllerType.DEFAULT.namespace()); + defaultFontMap = mappings.get(ControllerType.DEFAULT.id()); }, executor); } diff --git a/src/main/java/dev/isxander/controlify/gui/ButtonGuideRenderer.java b/src/main/java/dev/isxander/controlify/impl/gui/ButtonGuideRenderer.java similarity index 87% rename from src/main/java/dev/isxander/controlify/gui/ButtonGuideRenderer.java rename to src/main/java/dev/isxander/controlify/impl/gui/ButtonGuideRenderer.java index ac55002a1..88d675032 100644 --- a/src/main/java/dev/isxander/controlify/gui/ButtonGuideRenderer.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/ButtonGuideRenderer.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui; +package dev.isxander.controlify.impl.gui; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.action.Action; -import dev.isxander.controlify.action.ActionAccessor; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.action.Action; +import dev.isxander.controlify.impl.action.ActionAccessor; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; diff --git a/src/main/java/dev/isxander/controlify/gui/components/FakePositionPlainTextButton.java b/src/main/java/dev/isxander/controlify/impl/gui/components/FakePositionPlainTextButton.java similarity index 95% rename from src/main/java/dev/isxander/controlify/gui/components/FakePositionPlainTextButton.java rename to src/main/java/dev/isxander/controlify/impl/gui/components/FakePositionPlainTextButton.java index 4bb2e35d9..22bc4399a 100644 --- a/src/main/java/dev/isxander/controlify/gui/components/FakePositionPlainTextButton.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/components/FakePositionPlainTextButton.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.components; +package dev.isxander.controlify.impl.gui.components; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.components.PlainTextButton; diff --git a/src/main/java/dev/isxander/controlify/gui/components/PlainTextWidget.java b/src/main/java/dev/isxander/controlify/impl/gui/components/PlainTextWidget.java similarity index 96% rename from src/main/java/dev/isxander/controlify/gui/components/PlainTextWidget.java rename to src/main/java/dev/isxander/controlify/impl/gui/components/PlainTextWidget.java index c4d806498..b6e7cee13 100644 --- a/src/main/java/dev/isxander/controlify/gui/components/PlainTextWidget.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/components/PlainTextWidget.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.components; +package dev.isxander.controlify.impl.gui.components; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.ComponentPath; diff --git a/src/main/java/dev/isxander/controlify/gui/controllers/BindController.java b/src/main/java/dev/isxander/controlify/impl/gui/controllers/BindController.java similarity index 82% rename from src/main/java/dev/isxander/controlify/gui/controllers/BindController.java rename to src/main/java/dev/isxander/controlify/impl/gui/controllers/BindController.java index fe076895f..4d0afc7c6 100644 --- a/src/main/java/dev/isxander/controlify/gui/controllers/BindController.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/controllers/BindController.java @@ -4,20 +4,19 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.controllers; +package dev.isxander.controlify.impl.gui.controllers; import com.mojang.blaze3d.platform.InputConstants; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.bindings.input.*; -import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.controller.input.ControllerStateView; -import dev.isxander.controlify.controller.input.HatState; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.gui.screen.BindConsumerScreen; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.bindings.input.*; +import dev.isxander.controlify.impl.controller.input.ControllerStateView; +import dev.isxander.controlify.impl.controller.input.HatState; +import dev.isxander.controlify.impl.controller.input.InputComponent; +import dev.isxander.controlify.impl.gui.screen.BindConsumerScreen; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import dev.isxander.yacl3.api.Controller; import dev.isxander.yacl3.api.Option; import dev.isxander.yacl3.api.utils.Dimension; @@ -34,10 +33,10 @@ public class BindController implements Controller { private final Option option; - public final ControllerEntity controller; + public final ControllerImpl controller; private boolean conflicting; - public BindController(Option option, ControllerEntity controller) { + public BindController(Option option, ControllerImpl controller) { this.option = option; this.controller = controller; } @@ -82,7 +81,7 @@ protected void extractValueText(GuiGraphicsExtractor graphics, int mouseX, int m if (EmptyInput.equals(bind)) return; Component text = Controlify.instance().inputFontMapper() - .getComponentFromBind(control.controller.info().type().namespace(), bind); + .getComponentFromBind(control.controller.info().type().id(), bind); int width = textRenderer.width(text); graphics.text(textRenderer, text, getDimension().xLimit() - width - 1, (int)(getDimension().centerY() - textRenderer.lineHeight / 2f + 1), -1, false); @@ -115,7 +114,7 @@ private void openConsumerScreen() { } @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { if (controller != control.controller) return true; if (ControlifyBindings.GUI_PRESS.on(controller).justPressed()) { @@ -137,7 +136,7 @@ protected int getUnhoveredControlWidth() { return textRenderer.width(awaitingText); Component text = Controlify.instance().inputFontMapper() - .getComponentFromBind(control.controller.info().type().namespace(), control.option().pendingValue()); + .getComponentFromBind(control.controller.info().type().id(), control.option().pendingValue()); return textRenderer.width(text); } diff --git a/src/main/java/dev/isxander/controlify/gui/controllers/Deadzone2DImageRenderer.java b/src/main/java/dev/isxander/controlify/impl/gui/controllers/Deadzone2DImageRenderer.java similarity index 90% rename from src/main/java/dev/isxander/controlify/gui/controllers/Deadzone2DImageRenderer.java rename to src/main/java/dev/isxander/controlify/impl/gui/controllers/Deadzone2DImageRenderer.java index 30c7eace6..8bd12aa78 100644 --- a/src/main/java/dev/isxander/controlify/gui/controllers/Deadzone2DImageRenderer.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/controllers/Deadzone2DImageRenderer.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.controllers; +package dev.isxander.controlify.impl.gui.controllers; -import dev.isxander.controlify.input.mapping.DeadzoneGroup; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.utils.render.elements.CircleElementRenderState; +import dev.isxander.controlify.impl.input.mapping.DeadzoneGroup; +import dev.isxander.controlify.impl.controller.input.InputComponent; +import dev.isxander.controlify.impl.utils.render.elements.CircleElementRenderState; import dev.isxander.yacl3.api.Option; import dev.isxander.yacl3.gui.image.ImageRenderer; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/gui/guide/GuideInstanceImpl.java b/src/main/java/dev/isxander/controlify/impl/gui/guide/GuideInstanceImpl.java similarity index 81% rename from src/main/java/dev/isxander/controlify/gui/guide/GuideInstanceImpl.java rename to src/main/java/dev/isxander/controlify/impl/gui/guide/GuideInstanceImpl.java index 1b0444259..d51f8cfc6 100644 --- a/src/main/java/dev/isxander/controlify/gui/guide/GuideInstanceImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/guide/GuideInstanceImpl.java @@ -4,23 +4,24 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.guide; +package dev.isxander.controlify.impl.gui.guide; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.api.contextual.GuideLocation; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.contextual.GuideLocation; import dev.isxander.controlify.api.contextual.Context; import dev.isxander.controlify.api.contextual.GuideInstance; -import dev.isxander.controlify.contextual.ContextualDomainImpl; -import dev.isxander.controlify.contextual.ContextualState; -import dev.isxander.controlify.contextual.GuideRule; -import dev.isxander.controlify.contextual.RuleEngine; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.font.BindingFontHelper; +import dev.isxander.controlify.impl.contextual.ContextualDomainImpl; +import dev.isxander.controlify.impl.contextual.ContextualState; +import dev.isxander.controlify.impl.contextual.GuideRule; +import dev.isxander.controlify.impl.contextual.RuleEngine; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.font.BindingFontHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.Renderable; import net.minecraft.network.chat.Component; +import org.jspecify.annotations.NonNull; import java.util.List; import java.util.function.Supplier; @@ -52,7 +53,7 @@ public void update(C context) { var leftBuilder = new PrecomputedLines.Builder(); var rightBuilder = new PrecomputedLines.Builder(); - ControllerEntity controller = context.controller(); + ControllerImpl controller = context.controller(); for (GuideRule guide : guides) { InputBinding binding = guide.binding().onOrNull(controller); @@ -91,7 +92,7 @@ public void update(C context) { } @Override - public void extractRenderState(GuiGraphicsExtractor graphics, boolean bottomAligned, boolean textContrast, int guiScale) { + public void extractRenderState(@NonNull GuiGraphicsExtractor graphics, boolean bottomAligned, boolean textContrast, int guiScale) { GuideRenderer.extractRenderState( graphics, this, diff --git a/src/main/java/dev/isxander/controlify/gui/guide/GuideRenderer.java b/src/main/java/dev/isxander/controlify/impl/gui/guide/GuideRenderer.java similarity index 98% rename from src/main/java/dev/isxander/controlify/gui/guide/GuideRenderer.java rename to src/main/java/dev/isxander/controlify/impl/gui/guide/GuideRenderer.java index d0864217d..aa3ab56c9 100644 --- a/src/main/java/dev/isxander/controlify/gui/guide/GuideRenderer.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/guide/GuideRenderer.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.guide; +package dev.isxander.controlify.impl.gui.guide; import com.google.common.collect.Lists; import com.mojang.blaze3d.platform.Window; diff --git a/src/main/java/dev/isxander/controlify/gui/guide/InGameButtonGuide.java b/src/main/java/dev/isxander/controlify/impl/gui/guide/InGameButtonGuide.java similarity index 75% rename from src/main/java/dev/isxander/controlify/gui/guide/InGameButtonGuide.java rename to src/main/java/dev/isxander/controlify/impl/gui/guide/InGameButtonGuide.java index e29e7182c..e0f72c38c 100644 --- a/src/main/java/dev/isxander/controlify/gui/guide/InGameButtonGuide.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/guide/InGameButtonGuide.java @@ -4,24 +4,23 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.guide; +package dev.isxander.controlify.impl.gui.guide; import dev.isxander.controlify.api.contextual.GuideInstance; -import dev.isxander.controlify.config.settings.profile.GenericControllerSettings; -import dev.isxander.controlify.contextual.ContextualDomains; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.config.settings.profile.GenericControllerSettings; +import dev.isxander.controlify.impl.contextual.ContextualDomains; +import dev.isxander.controlify.impl.controller.ControllerImpl; import dev.isxander.controlify.api.contextual.InGameContext; -import dev.isxander.controlify.mixins.feature.guide.ingame.MinecraftAccessor; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; public class InGameButtonGuide { - private final ControllerEntity controller; + private final ControllerImpl controller; private final Minecraft minecraft; private final GuideInstance guideInstance; - public InGameButtonGuide(ControllerEntity controller, Minecraft minecraft) { + public InGameButtonGuide(ControllerImpl controller, Minecraft minecraft) { this.controller = controller; this.minecraft = minecraft; this.guideInstance = ContextualDomains.INSTANCE.inGame().createGuideInstance(minecraft.font); diff --git a/src/main/java/dev/isxander/controlify/gui/guide/PrecomputedLines.java b/src/main/java/dev/isxander/controlify/impl/gui/guide/PrecomputedLines.java similarity index 95% rename from src/main/java/dev/isxander/controlify/gui/guide/PrecomputedLines.java rename to src/main/java/dev/isxander/controlify/impl/gui/guide/PrecomputedLines.java index b8465f8b4..db2d162ba 100644 --- a/src/main/java/dev/isxander/controlify/gui/guide/PrecomputedLines.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/guide/PrecomputedLines.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.guide; +package dev.isxander.controlify.impl.gui.guide; import net.minecraft.network.chat.Component; diff --git a/src/main/java/dev/isxander/controlify/gui/layout/AbstractLayoutComponent.java b/src/main/java/dev/isxander/controlify/impl/gui/layout/AbstractLayoutComponent.java similarity index 95% rename from src/main/java/dev/isxander/controlify/gui/layout/AbstractLayoutComponent.java rename to src/main/java/dev/isxander/controlify/impl/gui/layout/AbstractLayoutComponent.java index c340d8821..48b6d5446 100644 --- a/src/main/java/dev/isxander/controlify/gui/layout/AbstractLayoutComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/layout/AbstractLayoutComponent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.layout; +package dev.isxander.controlify.impl.gui.layout; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/gui/layout/AnchorPoint.java b/src/main/java/dev/isxander/controlify/impl/gui/layout/AnchorPoint.java similarity index 92% rename from src/main/java/dev/isxander/controlify/gui/layout/AnchorPoint.java rename to src/main/java/dev/isxander/controlify/impl/gui/layout/AnchorPoint.java index 236c1be60..91d5750a6 100644 --- a/src/main/java/dev/isxander/controlify/gui/layout/AnchorPoint.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/layout/AnchorPoint.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.layout; +package dev.isxander.controlify.impl.gui.layout; import org.joml.Vector2i; diff --git a/src/main/java/dev/isxander/controlify/gui/layout/ColumnLayoutComponent.java b/src/main/java/dev/isxander/controlify/impl/gui/layout/ColumnLayoutComponent.java similarity index 98% rename from src/main/java/dev/isxander/controlify/gui/layout/ColumnLayoutComponent.java rename to src/main/java/dev/isxander/controlify/impl/gui/layout/ColumnLayoutComponent.java index 9df464f94..da856ba3f 100644 --- a/src/main/java/dev/isxander/controlify/gui/layout/ColumnLayoutComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/layout/ColumnLayoutComponent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.layout; +package dev.isxander.controlify.impl.gui.layout; import net.minecraft.client.gui.GuiGraphicsExtractor; import org.apache.commons.lang3.Validate; diff --git a/src/main/java/dev/isxander/controlify/gui/layout/PositionedComponent.java b/src/main/java/dev/isxander/controlify/impl/gui/layout/PositionedComponent.java similarity index 97% rename from src/main/java/dev/isxander/controlify/gui/layout/PositionedComponent.java rename to src/main/java/dev/isxander/controlify/impl/gui/layout/PositionedComponent.java index 84eb8f482..533f925a6 100644 --- a/src/main/java/dev/isxander/controlify/gui/layout/PositionedComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/layout/PositionedComponent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.layout; +package dev.isxander.controlify.impl.gui.layout; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.Renderable; diff --git a/src/main/java/dev/isxander/controlify/gui/layout/RenderComponent.java b/src/main/java/dev/isxander/controlify/impl/gui/layout/RenderComponent.java similarity index 89% rename from src/main/java/dev/isxander/controlify/gui/layout/RenderComponent.java rename to src/main/java/dev/isxander/controlify/impl/gui/layout/RenderComponent.java index 9bb67b2db..1afb27ab6 100644 --- a/src/main/java/dev/isxander/controlify/gui/layout/RenderComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/layout/RenderComponent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.layout; +package dev.isxander.controlify.impl.gui.layout; import net.minecraft.client.gui.GuiGraphicsExtractor; import org.joml.Vector2ic; diff --git a/src/main/java/dev/isxander/controlify/gui/layout/RowLayoutComponent.java b/src/main/java/dev/isxander/controlify/impl/gui/layout/RowLayoutComponent.java similarity index 98% rename from src/main/java/dev/isxander/controlify/gui/layout/RowLayoutComponent.java rename to src/main/java/dev/isxander/controlify/impl/gui/layout/RowLayoutComponent.java index 691455dc3..69f1e282c 100644 --- a/src/main/java/dev/isxander/controlify/gui/layout/RowLayoutComponent.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/layout/RowLayoutComponent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.layout; +package dev.isxander.controlify.impl.gui.layout; import net.minecraft.client.gui.GuiGraphicsExtractor; import org.apache.commons.lang3.Validate; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/AskToMapControllerScreen.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/AskToMapControllerScreen.java similarity index 77% rename from src/main/java/dev/isxander/controlify/gui/screen/AskToMapControllerScreen.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/AskToMapControllerScreen.java index dbeaa46d4..5acb702f2 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/AskToMapControllerScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/AskToMapControllerScreen.java @@ -4,16 +4,16 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.gui.screens.ConfirmScreen; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; public class AskToMapControllerScreen extends ConfirmScreen { - public AskToMapControllerScreen(ControllerEntity controller, Screen lastScreen) { + public AskToMapControllerScreen(ControllerImpl controller, Screen lastScreen) { super( (confirmed) -> { if (confirmed) { diff --git a/src/main/java/dev/isxander/controlify/gui/screen/BindConsumerScreen.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/BindConsumerScreen.java similarity index 89% rename from src/main/java/dev/isxander/controlify/gui/screen/BindConsumerScreen.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/BindConsumerScreen.java index 764eb1ebf..54450313f 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/BindConsumerScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/BindConsumerScreen.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; - -import dev.isxander.controlify.bindings.input.Input; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.gui.controllers.BindController; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.utils.MinecraftUtil; +package dev.isxander.controlify.impl.gui.screen; + +import dev.isxander.controlify.impl.bindings.input.Input; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.gui.controllers.BindController; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import dev.isxander.yacl3.api.Option; import dev.isxander.yacl3.api.utils.Dimension; import net.minecraft.client.gui.GuiGraphicsExtractor; @@ -150,7 +150,7 @@ public ScreenProcessorImpl(BindConsumerScreen screen) { } @Override - public void onControllerFixedUpdate(ControllerEntity controller) { + public void onControllerFixedUpdate(ControllerImpl controller) { // prevent all other controller input logic } } diff --git a/src/main/java/dev/isxander/controlify/gui/screen/BluetoothWarningScreen.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/BluetoothWarningScreen.java similarity index 79% rename from src/main/java/dev/isxander/controlify/gui/screen/BluetoothWarningScreen.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/BluetoothWarningScreen.java index 3ec03631c..12b792119 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/BluetoothWarningScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/BluetoothWarningScreen.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.misc.BluetoothDeviceComponent; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.misc.BluetoothDeviceComponent; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.gui.screens.ConfirmScreen; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.CommonComponents; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ControlifySettingsScreen.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/ControlifySettingsScreen.java similarity index 94% rename from src/main/java/dev/isxander/controlify/gui/screen/ControlifySettingsScreen.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/ControlifySettingsScreen.java index 54057a692..e9b9f8f92 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ControlifySettingsScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/ControlifySettingsScreen.java @@ -4,22 +4,22 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; import com.google.common.collect.ImmutableList; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.gui.components.PlainTextWidget; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.config.settings.device.DeviceSettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controllermanager.ControllerType; +import dev.isxander.controlify.impl.gui.components.PlainTextWidget; import dev.isxander.controlify.mixins.feature.ui.AbstractSelectionListAccessor; -import dev.isxander.controlify.screenop.ScreenControllerEventListener; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.screenop.ScreenControllerEventListener; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.*; @@ -37,7 +37,6 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.Identifier; import net.minecraft.util.Mth; -import net.minecraft.util.Util; import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; @@ -193,7 +192,7 @@ public void extractBackground(@NonNull GuiGraphicsExtractor graphics, int mouseX } @Override - public void onControllerInput(ControllerEntity controller) { + public void onControllerInput(ControllerImpl controller) { if (ControlifyBindings.GUI_ABSTRACT_ACTION_1.on(controller).justPressed()) { // Button impl does not use NonNull parameter globalSettingsButton.onPress(null); @@ -333,12 +332,12 @@ private void updateProfileInfo(boolean force) { ? Component.translatable("controlify.gui.carousel.entry.profile", displayedProfileIndex) : Component.translatable("controlify.gui.carousel.entry.named_profile", displayedProfileIndex, profileSettings.name); - Optional controller = this.getController(profileSettings); + Optional controller = this.getController(profileSettings); Component controllerName; Identifier controllerIcon; boolean controllerConnected; if (controller.isPresent()) { - ControllerEntity entity = controller.get(); + ControllerImpl entity = controller.get(); controllerName = Component.literal(entity.name()); controllerIcon = entity.info().type().getIconSprite(); controllerConnected = true; @@ -390,7 +389,7 @@ private ProfileSettings getProfileSettings() { return profile; } - private Optional getController(ProfileSettings profileSettings) { + private Optional getController(ProfileSettings profileSettings) { if (profileSettings.controllerUid == null) { return Controlify.instance().getCurrentController(); } diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/ControllerConfigScreenFactory.java similarity index 92% rename from src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/ControllerConfigScreenFactory.java index 3473aa7d5..5ad143665 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/ControllerConfigScreenFactory.java @@ -4,53 +4,51 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; -import dev.isxander.controlify.Controlify; import dev.isxander.controlify.api.contextual.GuideVerbosity; -import dev.isxander.controlify.bindings.BindContext; -import dev.isxander.controlify.bindings.ControlifyBindApiImpl; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.bindings.input.EmptyInput; -import dev.isxander.controlify.bindings.input.Input; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; -import dev.isxander.controlify.config.settings.profile.GenericControllerSettings; -import dev.isxander.controlify.config.settings.profile.InputSettings; -import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.controller.gyro.GyroButtonMode; -import dev.isxander.controlify.controller.gyro.GyroYawMode; -import dev.isxander.controlify.input.mapping.DeadzoneGroup; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.input.mapping.Inputs; -import dev.isxander.controlify.controller.rumble.RumbleComponent; -import dev.isxander.controlify.gui.controllers.BindController; -import dev.isxander.controlify.gui.controllers.Deadzone2DImageRenderer; -import dev.isxander.controlify.ingame.InputCurves; -import dev.isxander.controlify.rumble.BasicRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; -import dev.isxander.controlify.server.ServerPolicies; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.api.bind.InputBindingSupplier; +import dev.isxander.controlify.impl.bindings.BindContext; +import dev.isxander.controlify.impl.bindings.ControlifyBindApiImpl; +import dev.isxander.controlify.impl.bindings.input.EmptyInput; +import dev.isxander.controlify.impl.bindings.input.Input; +import dev.isxander.controlify.impl.config.settings.device.DeviceSettings; +import dev.isxander.controlify.impl.config.settings.profile.GenericControllerSettings; +import dev.isxander.controlify.impl.config.settings.profile.InputSettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.controller.gyro.GyroButtonMode; +import dev.isxander.controlify.impl.controller.gyro.GyroYawMode; +import dev.isxander.controlify.impl.controller.input.InputComponent; +import dev.isxander.controlify.impl.controller.rumble.RumbleComponentImpl; +import dev.isxander.controlify.impl.controller.rumble.RumbleSource; +import dev.isxander.controlify.impl.gui.controllers.BindController; +import dev.isxander.controlify.impl.gui.controllers.Deadzone2DImageRenderer; +import dev.isxander.controlify.impl.ingame.InputCurves; +import dev.isxander.controlify.impl.input.mapping.DeadzoneGroup; +import dev.isxander.controlify.impl.input.mapping.Inputs; +import dev.isxander.controlify.impl.server.ServerPolicies; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.controller.*; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.util.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.Identifier; +import net.minecraft.util.Util; import org.jetbrains.annotations.Nullable; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; - public class ControllerConfigScreenFactory { private static final ValueFormatter percentFormatter = v -> Component.literal(String.format("%.0f%%", v*100)); private static final ValueFormatter percentOrOffFormatter = v -> v == 0 ? CommonComponents.OPTION_OFF : percentFormatter.format(v); @@ -62,7 +60,7 @@ public class ControllerConfigScreenFactory { public static Screen generateConfigScreen( Screen parent, ProfileSettings settings, ProfileSettings defaults, - @Nullable ControllerEntity controller + @Nullable ControllerImpl controller ) { return new ControllerConfigScreenFactory().generateConfigScreen0( parent, @@ -76,7 +74,7 @@ private Screen generateConfigScreen0( Screen parent, ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { String initialControllerUid = settings.controllerUid; var advancedCategory = createAdvancedCategory(settings, defaults, controller); @@ -102,7 +100,7 @@ private Screen generateConfigScreen0( private ConfigCategory createBasicCategory( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { var sensitivityGroup = makeSensitivityGroup(settings, defaults, controller); var controlsGroup = makeControlsGroup(settings, defaults, controller); @@ -174,7 +172,7 @@ private OptionGroup makeProfileGroup(ProfileSettings settings) { private Optional makeSensitivityGroup( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { var builder = OptionGroup.createBuilder() .name(Component.translatable("controlify.gui.config.group.sensitivity")); @@ -268,7 +266,7 @@ private Optional makeSensitivityGroup( private Optional makeControlsGroup( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { if (controller.isEmpty()) return Optional.empty(); @@ -331,7 +329,7 @@ private Optional makeControlsGroup( private Optional makeAccessibilityGroup( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { GenericControllerSettings gSettings = settings.generic; GenericControllerSettings gDefaults = defaults.generic; @@ -415,9 +413,9 @@ private Optional makeAccessibilityGroup( private Optional makeDeadzoneGroup( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { - Optional inputOpt = controller.flatMap(ControllerEntity::input); + Optional inputOpt = controller.flatMap(ControllerImpl::input); if (inputOpt.isEmpty()) return Optional.empty(); @@ -474,7 +472,7 @@ private Optional makeDeadzoneGroup( private ConfigCategory createAdvancedCategory( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { var builder = ConfigCategory.createBuilder() .name(Component.translatable("controlify.config.category.advanced")); @@ -490,16 +488,16 @@ private ConfigCategory createAdvancedCategory( private Optional makeControllerMappingGroup( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { - Optional inputOpt = controller.flatMap(ControllerEntity::input); + Optional inputOpt = controller.flatMap(ControllerImpl::input); if (inputOpt.isEmpty()) return Optional.empty(); InputComponent input = inputOpt.get(); DeviceSettings config = Controlify.instance().config().getSettings() .getOrCreateDeviceSettings(controller.get().uid()); - DeviceSettings def = DeviceSettings.defaults(controller.map(ControllerEntity::uid).orElse("")); + DeviceSettings def = DeviceSettings.defaults(controller.map(ControllerImpl::uid).orElse("")); return Optional.of(OptionGroup.createBuilder() .name(Component.translatable("controlify.gui.group.controller_mapping")) @@ -521,7 +519,7 @@ private Optional makeControllerMappingGroup( private Optional makeVibrationGroup( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { var vibrationGroup = OptionGroup.createBuilder() .name(Component.translatable("controlify.gui.group.vibration")) @@ -556,7 +554,7 @@ private Optional makeVibrationGroup( .controller(TickBoxControllerBuilder::create) .build()); - for (RumbleSource source : RumbleSource.values()) { + for (RumbleSource source : Controlify.instance().rumbleSourceManager().sources()) { var option = Option.createBuilder() .name(Component.translatable("controlify.vibration_strength." + source.id().getNamespace() + "." + source.id().getPath())) .description(OptionDescription.createBuilder() @@ -577,21 +575,21 @@ private Optional makeVibrationGroup( vibrationGroup.option(option); } if (controller.isPresent() && controller.get().rumble().isPresent()) { - RumbleComponent rumble = controller.get().rumble().get(); + RumbleComponentImpl rumble = controller.get().rumble().get(); vibrationGroup.option(ButtonOption.createBuilder() .name(Component.translatable("controlify.gui.test_vibration")) .description(OptionDescription.of(Component.translatable("controlify.gui.test_vibration.tooltip"))) .action((screen, btn) -> { - rumble.rumbleManager().play( - RumbleSource.MASTER, - BasicRumbleEffect.byTime(t -> new RumbleState(0f, t), 20) - .seq(BasicRumbleEffect.byTime(t -> new RumbleState(0f, 1 - t), 20)) + rumble.playEffect( + CUtil.rl("test_vibration"), + RumbleEffect.finite().byTime(t -> new RumbleState(0f, t), 20) + .then(RumbleEffect.finite().byTime(t -> new RumbleState(0f, 1 - t), 20)) .repeat(3) - .seq(BasicRumbleEffect.constant(1f, 0f, 5) - .seq(BasicRumbleEffect.constant(0f, 1f, 5)) + .then(RumbleEffect.finite().constant(1f, 0f, 5) + .then(RumbleEffect.finite().constant(0f, 1f, 5)) .repeat(10) ) - .earlyFinish(BasicRumbleEffect.finishOnScreenChange()) + .stopCondition(() -> MinecraftUtil.getScreen() != screen) ); }) .build()); @@ -603,7 +601,7 @@ private Optional makeVibrationGroup( private Optional makeGyroGroup( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { var gyroGroup = OptionGroup.createBuilder() .name(Component.translatable("controlify.gui.group.gyro")) @@ -716,7 +714,7 @@ private Optional makeGyroGroup( private Optional makeTriggerEffectsGroup( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { var group = OptionGroup.createBuilder() .name(Component.translatable("controlify.gui.group.trigger_effects")) @@ -742,7 +740,7 @@ private Optional makeTriggerEffectsGroup( private Optional makeBindsCategory( ProfileSettings settings, ProfileSettings defaults, - Optional controller + Optional controller ) { var category = ConfigCategory.createBuilder() @@ -840,11 +838,11 @@ private static Map> groupBindings(Collection createBindingOpt(InputBindingSupplier bindingSupplier, ControllerEntity controller) { + private static Option.Builder createBindingOpt(InputBindingSupplier bindingSupplier, ControllerImpl controller) { return createBindingOpt(bindingSupplier.on(controller), controller); } - private static Option.Builder createBindingOpt(InputBinding binding, @Nullable ControllerEntity controller) { + private static Option.Builder createBindingOpt(InputBinding binding, @Nullable ControllerImpl controller) { return Option.createBuilder() .name(binding.name()) .description(v -> OptionDescription.createBuilder() @@ -852,7 +850,7 @@ private static Option.Builder createBindingOpt(InputBinding binding, @Nul .text(Component.translatable("controlify.gui.bind.currently_bound_to", Component.empty() .append(Controlify.instance().inputFontMapper().getComponentFromInputs( - controller.info().type().namespace(), + controller.info().type().id(), v.getRelevantInputs() )) .append(CommonComponents.SPACE) @@ -861,7 +859,7 @@ private static Option.Builder createBindingOpt(InputBinding binding, @Nul .text(v.equals(binding.defaultInput()) ? Component.empty() : Component.translatable("controlify.gui.bind.default_bound_to", Component.empty() .append(Controlify.instance().inputFontMapper().getComponentFromInputs( - controller.info().type().namespace(), + controller.info().type().id(), binding.defaultInput().getRelevantInputs() )) .append(CommonComponents.SPACE) diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/ControllerMappingMakerScreen.java similarity index 93% rename from src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/ControllerMappingMakerScreen.java index 8e080af83..322ebbbed 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ControllerMappingMakerScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/ControllerMappingMakerScreen.java @@ -4,20 +4,20 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.input.mapping.*; -import dev.isxander.controlify.input.mapping.*; -import dev.isxander.controlify.screenop.ScreenControllerEventListener; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.MinecraftUtil; -import dev.isxander.controlify.utils.render.RenderUtils; -import dev.isxander.controlify.utils.ColorUtils; +package dev.isxander.controlify.impl.gui.screen; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.config.settings.device.DeviceSettings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.input.mapping.*; +import dev.isxander.controlify.impl.input.mapping.*; +import dev.isxander.controlify.impl.screenop.ScreenControllerEventListener; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.render.RenderUtils; +import dev.isxander.controlify.impl.utils.ColorUtils; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Tooltip; @@ -326,7 +326,7 @@ public ScreenProcessorImpl(ControllerMappingMakerScreen screen) { } @Override - public void onControllerFixedUpdate(ControllerEntity controller) { + public void onControllerFixedUpdate(ControllerImpl controller) { } } diff --git a/src/main/java/dev/isxander/controlify/gui/screen/DontInterruptScreen.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/DontInterruptScreen.java similarity index 77% rename from src/main/java/dev/isxander/controlify/gui/screen/DontInterruptScreen.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/DontInterruptScreen.java index dcc9cd965..54bbabf7c 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/DontInterruptScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/DontInterruptScreen.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; public interface DontInterruptScreen { } diff --git a/src/main/java/dev/isxander/controlify/gui/screen/GlobalSettingsScreenFactory.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/GlobalSettingsScreenFactory.java similarity index 94% rename from src/main/java/dev/isxander/controlify/gui/screen/GlobalSettingsScreenFactory.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/GlobalSettingsScreenFactory.java index 1e885fe5a..58385aff3 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/GlobalSettingsScreenFactory.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/GlobalSettingsScreenFactory.java @@ -4,18 +4,18 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.config.settings.GlobalSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.driver.steamdeck.SteamDeckUtil; -import dev.isxander.controlify.reacharound.ReachAroundMode; -import dev.isxander.controlify.server.ServerPolicies; -import dev.isxander.controlify.server.ServerPolicy; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.DebugDump; +import dev.isxander.controlify.impl.config.settings.GlobalSettings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.driver.steamdeck.SteamDeckUtil; +import dev.isxander.controlify.impl.reacharound.ReachAroundMode; +import dev.isxander.controlify.impl.server.ServerPolicies; +import dev.isxander.controlify.impl.server.ServerPolicy; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.DebugDump; import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.controller.*; import net.minecraft.ChatFormatting; @@ -72,7 +72,7 @@ public static Screen createGlobalSettingsScreen(Screen parent) { .controller(TickBoxControllerBuilder::create) .addListener((opt, val) -> { ControlifyApi.get().getCurrentController() - .flatMap(ControllerEntity::rumble) + .flatMap(ControllerImpl::rumble) .ifPresent(rumble -> rumble.rumbleManager().clearEffects()); }) .build()) diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ProfileSelectionScreen.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/ProfileSelectionScreen.java similarity index 94% rename from src/main/java/dev/isxander/controlify/gui/screen/ProfileSelectionScreen.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/ProfileSelectionScreen.java index a77ac7bb5..86cfd07cb 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ProfileSelectionScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/ProfileSelectionScreen.java @@ -4,19 +4,19 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.config.settings.device.DeviceSettings; -import dev.isxander.controlify.config.settings.profile.ProfileSettings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.screenop.ScreenControllerEventListener; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.MinecraftUtil; +package dev.isxander.controlify.impl.gui.screen; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.config.settings.device.DeviceSettings; +import dev.isxander.controlify.impl.config.settings.profile.ProfileSettings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controllermanager.ControllerType; +import dev.isxander.controlify.impl.screenop.ScreenControllerEventListener; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.AbstractButton; @@ -200,7 +200,7 @@ public void extractRenderState(@NonNull GuiGraphicsExtractor graphics, int mouse } @Override - public void onControllerInput(ControllerEntity controller) { + public void onControllerInput(ControllerImpl controller) { if (this.selectedProfileIndex >= 0 && ControlifyBindings.GUI_ABSTRACT_ACTION_1.on(controller).justPressed()) { this.switchProfile(this.selectedProfileIndex, false); @@ -326,7 +326,7 @@ private ControllerDisplay controllerDisplay(ProfileSettings profile) { ); } - ControllerEntity connected = Controlify.instance().getControllerManager() + ControllerImpl connected = Controlify.instance().getControllerManager() .flatMap(manager -> manager.getConnectedControllers().stream() .filter(controller -> profile.controllerUid.equals(controller.uid())) .findFirst()) diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialItems.java similarity index 92% rename from src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/RadialItems.java index f910ed596..2f3ee3e06 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialItems.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialItems.java @@ -4,16 +4,16 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.action.radial.RadialIcon; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.action.radial.RadialIconManager; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.utils.CUtil; +package dev.isxander.controlify.impl.gui.screen; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.api.bind.InputBindingSupplier; +import dev.isxander.controlify.impl.action.radial.RadialIcon; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.action.radial.RadialIconManager; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; import net.minecraft.client.player.inventory.Hotbar; @@ -33,7 +33,7 @@ public final class RadialItems { public static final RadialMenuScreen.RadialItem EMPTY_ACTION = new RadialItemRecord(Component.empty(), RadialIcon.EMPTY, () -> false, RadialIconManager.EMPTY); - public static RadialMenuScreen.RadialItem[] createBindings(ControllerEntity controller) { + public static RadialMenuScreen.RadialItem[] createBindings(ControllerImpl controller) { List actions = controller.settings().input.radialMenu.radialActions; RadialMenuScreen.RadialItem[] items = new RadialMenuScreen.RadialItem[actions.size()]; @@ -44,7 +44,7 @@ public static RadialMenuScreen.RadialItem[] createBindings(ControllerEntity cont return items; } - public static List createBindingPages(ControllerEntity controller) { + public static List createBindingPages(ControllerImpl controller) { RadialMenuScreen.RadialItem[] items = createBindings(controller); return RadialMenuPages.partition(Arrays.asList(items)).stream() .map(page -> page.toArray(RadialMenuScreen.RadialItem[]::new)) @@ -134,7 +134,7 @@ public static RadialMenuScreen.RadialItem[] createHotbarItemSelect() { return items; } - public static RadialMenuScreen.RadialItem[] createDebug(ControllerEntity controller) { + public static RadialMenuScreen.RadialItem[] createDebug(ControllerImpl controller) { return List.of( ControlifyBindings.TOGGLE_DEBUG_MENU, ControlifyBindings.TOGGLE_DEBUG_MENU_FPS, @@ -180,7 +180,7 @@ private static RadialIcon getIconForItem(ItemStack stack) { return model != null ? RadialIcon.model(model) : RadialIcon.EMPTY; } - private static RadialMenuScreen.RadialItem getItemForBinding(Identifier id, ControllerEntity controller) { + private static RadialMenuScreen.RadialItem getItemForBinding(Identifier id, ControllerImpl controller) { InputBinding binding = controller.input().orElseThrow().getBinding(id); RadialIconManager radialIconManager = Controlify.instance().radialIconManager(); diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditModel.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuEditModel.java similarity index 97% rename from src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditModel.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuEditModel.java index c9f81df74..2c0c18b77 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditModel.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuEditModel.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuEditScreen.java similarity index 95% rename from src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuEditScreen.java index 1ce96d25a..dcbe5340f 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuEditScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuEditScreen.java @@ -4,22 +4,22 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; import com.mojang.blaze3d.platform.InputConstants; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.action.radial.RadialIcon; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.action.radial.RadialIconExtractor; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.haptic.HapticEffects; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.utils.MinecraftUtil; -import dev.isxander.controlify.virtualmouse.VirtualMouseBehaviour; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.action.radial.RadialIcon; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.action.radial.RadialIconExtractor; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.haptic.HapticEffects; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.utils.MinecraftUtil; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseBehaviour; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.AbstractButton; @@ -61,7 +61,7 @@ public class RadialMenuEditScreen extends Screen implements ScreenProcessorProvi private static final int ROW_GAP = 2; private final Screen parent; - private final ControllerEntity controller; + private final ControllerImpl controller; private final RadialMenuEditModel model; private final List candidates; private final Map candidatesById; @@ -75,7 +75,7 @@ public class RadialMenuEditScreen extends Screen implements ScreenProcessorProvi private Identifier focusAfterRebuild; private int equippedInsertionIndex; - public RadialMenuEditScreen(Screen parent, ControllerEntity controller) { + public RadialMenuEditScreen(Screen parent, ControllerImpl controller) { super(Component.translatable("controlify.radial_menu.editor.title")); this.parent = parent; this.controller = controller; @@ -640,7 +640,7 @@ public Processor(RadialMenuEditScreen screen) { } @Override - protected void handleComponentNavigation(ControllerEntity controller) { + protected void handleComponentNavigation(ControllerImpl controller) { if (!screen.model.isCarrying()) { super.handleComponentNavigation(controller); return; @@ -664,7 +664,7 @@ protected void handleComponentNavigation(ControllerEntity controller) { } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { if (screen.model.isCarrying()) { if (ControlifyBindings.GUI_PRESS.on(controller).guiPressed().get()) { screen.dropCarried(); diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuPages.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuPages.java similarity index 93% rename from src/main/java/dev/isxander/controlify/gui/screen/RadialMenuPages.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuPages.java index 6ae415e11..442eb276f 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuPages.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuPages.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuScreen.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuScreen.java similarity index 87% rename from src/main/java/dev/isxander/controlify/gui/screen/RadialMenuScreen.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuScreen.java index 0e07e4b47..2df14d4f8 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/RadialMenuScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/RadialMenuScreen.java @@ -4,24 +4,24 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; - -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.action.radial.RadialIcon; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.action.radial.RadialIconExtractor; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.haptic.HapticEffects; -import dev.isxander.controlify.gui.screen.RadialItems.RadialPage; -import dev.isxander.controlify.screenop.ScreenControllerEventListener; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.sound.ControlifyClientSounds; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.MinecraftUtil; -import dev.isxander.controlify.utils.animation.api.Animation; -import dev.isxander.controlify.utils.animation.api.EasingFunction; -import dev.isxander.controlify.virtualmouse.VirtualMouseBehaviour; +package dev.isxander.controlify.impl.gui.screen; + +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.action.radial.RadialIcon; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.action.radial.RadialIconExtractor; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.haptic.HapticEffects; +import dev.isxander.controlify.impl.gui.screen.RadialItems.RadialPage; +import dev.isxander.controlify.impl.screenop.ScreenControllerEventListener; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.sound.ControlifyClientSounds; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.animation.api.Animation; +import dev.isxander.controlify.impl.utils.animation.api.EasingFunction; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseBehaviour; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.TextAlignment; import net.minecraft.client.gui.components.MultiLineLabel; @@ -46,7 +46,7 @@ import java.util.List; public class RadialMenuScreen extends Screen implements ScreenControllerEventListener, ScreenProcessorProvider { - private final ControllerEntity controller; + private final ControllerImpl controller; private final @Nullable Screen parent; private final Component footerText; private final List userPages; @@ -65,19 +65,19 @@ public class RadialMenuScreen extends Screen implements ScreenControllerEventLis /** * Creates a single-page radial menu. Existing special-purpose radial menus use this path. */ - public RadialMenuScreen(ControllerEntity controller, InputBinding openBind, RadialItem[] items, Component text, @Nullable Screen parent) { + public RadialMenuScreen(ControllerImpl controller, InputBinding openBind, RadialItem[] items, Component text, @Nullable Screen parent) { this(controller, openBind, Collections.singletonList(items), List.of(), text, parent); } /** * Creates a paged radial menu. Page boundaries are a presentation concern and are not persisted. */ - public RadialMenuScreen(ControllerEntity controller, @Nullable InputBinding openBind, List pages, Component text, @Nullable Screen parent) { + public RadialMenuScreen(ControllerImpl controller, @Nullable InputBinding openBind, List pages, Component text, @Nullable Screen parent) { this(controller, openBind, pages, List.of(), text, parent); } public RadialMenuScreen( - ControllerEntity controller, + ControllerImpl controller, @Nullable InputBinding openBind, List userPages, List bonusPages, @@ -147,7 +147,7 @@ private void changePage(int direction) { } @Override - public void onControllerInput(ControllerEntity controller) { + public void onControllerInput(ControllerImpl controller) { if (this.controller != controller) return; if (openBind == null) { @@ -364,7 +364,7 @@ public Processor(RadialMenuScreen screen) { } @Override - protected void handleTabNavigation(ControllerEntity controller) { + protected void handleTabNavigation(ControllerImpl controller) { if (ControlifyBindings.GUI_NEXT_TAB.on(controller).justPressed()) { screen.changePage(1); } else if (ControlifyBindings.GUI_PREV_TAB.on(controller).justPressed()) { diff --git a/src/main/java/dev/isxander/controlify/gui/screen/SteamDeckAlerts.java b/src/main/java/dev/isxander/controlify/impl/gui/screen/SteamDeckAlerts.java similarity index 96% rename from src/main/java/dev/isxander/controlify/gui/screen/SteamDeckAlerts.java rename to src/main/java/dev/isxander/controlify/impl/gui/screen/SteamDeckAlerts.java index ef4844534..a0efa0920 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/SteamDeckAlerts.java +++ b/src/main/java/dev/isxander/controlify/impl/gui/screen/SteamDeckAlerts.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.gui.screen; +package dev.isxander.controlify.impl.gui.screen; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/hid/ControllerHIDInfo.java b/src/main/java/dev/isxander/controlify/impl/hid/ControllerHIDInfo.java similarity index 78% rename from src/main/java/dev/isxander/controlify/hid/ControllerHIDInfo.java rename to src/main/java/dev/isxander/controlify/impl/hid/ControllerHIDInfo.java index 5435db2b3..8047d7b70 100644 --- a/src/main/java/dev/isxander/controlify/hid/ControllerHIDInfo.java +++ b/src/main/java/dev/isxander/controlify/impl/hid/ControllerHIDInfo.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.hid; +package dev.isxander.controlify.impl.hid; import com.google.common.primitives.Ints; -import dev.isxander.controlify.controller.id.ControllerType; +import dev.isxander.controlify.impl.controllermanager.ControllerType; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -29,10 +29,10 @@ public Optional createControllerUID(int controllerIndex) { md.update(Ints.toByteArray(hid.productId())); }); - String namespace = type().namespace().toString(); - if ("controlify".equals(type().namespace().getNamespace())) { + String namespace = type().id().toString(); + if ("controlify".equals(type().id().getNamespace())) { // maintains backwards compatibility - namespace = type().namespace().getPath(); + namespace = type().id().getPath(); } md.update(namespace.getBytes()); diff --git a/src/main/java/dev/isxander/controlify/hid/HIDDevice.java b/src/main/java/dev/isxander/controlify/impl/hid/HIDDevice.java similarity index 87% rename from src/main/java/dev/isxander/controlify/hid/HIDDevice.java rename to src/main/java/dev/isxander/controlify/impl/hid/HIDDevice.java index e6c5697a0..057d6ba9e 100644 --- a/src/main/java/dev/isxander/controlify/hid/HIDDevice.java +++ b/src/main/java/dev/isxander/controlify/impl/hid/HIDDevice.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.hid; +package dev.isxander.controlify.impl.hid; public record HIDDevice(HIDID hidid, String path) { public int vendorId() { diff --git a/src/main/java/dev/isxander/controlify/hid/HIDID.java b/src/main/java/dev/isxander/controlify/impl/hid/HIDID.java similarity index 85% rename from src/main/java/dev/isxander/controlify/hid/HIDID.java rename to src/main/java/dev/isxander/controlify/impl/hid/HIDID.java index bcfb3db8c..84f90c292 100644 --- a/src/main/java/dev/isxander/controlify/hid/HIDID.java +++ b/src/main/java/dev/isxander/controlify/impl/hid/HIDID.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.hid; +package dev.isxander.controlify.impl.hid; import com.mojang.serialization.Codec; -import dev.isxander.controlify.utils.codec.CExtraCodecs; +import dev.isxander.controlify.impl.utils.codec.CExtraCodecs; import org.jetbrains.annotations.NotNull; import java.util.HexFormat; diff --git a/src/main/java/dev/isxander/controlify/ingame/ControllerPlayerMovement.java b/src/main/java/dev/isxander/controlify/impl/ingame/ControllerPlayerMovement.java similarity index 90% rename from src/main/java/dev/isxander/controlify/ingame/ControllerPlayerMovement.java rename to src/main/java/dev/isxander/controlify/impl/ingame/ControllerPlayerMovement.java index c450a3c43..4ab5c12a6 100644 --- a/src/main/java/dev/isxander/controlify/ingame/ControllerPlayerMovement.java +++ b/src/main/java/dev/isxander/controlify/impl/ingame/ControllerPlayerMovement.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.ingame; +package dev.isxander.controlify.impl.ingame; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.player.KeyboardInput; import net.minecraft.client.player.LocalPlayer; @@ -20,11 +20,11 @@ import net.minecraft.world.entity.player.Input; public class ControllerPlayerMovement extends ClientInput { - private final ControllerEntity controller; + private final ControllerImpl controller; private final LocalPlayer player; private boolean wasFlying, wasPassenger; - public ControllerPlayerMovement(ControllerEntity controller, LocalPlayer player) { + public ControllerPlayerMovement(ControllerImpl controller, LocalPlayer player) { this.controller = controller; this.player = player; } diff --git a/src/main/java/dev/isxander/controlify/ingame/DualInput.java b/src/main/java/dev/isxander/controlify/impl/ingame/DualInput.java similarity index 97% rename from src/main/java/dev/isxander/controlify/ingame/DualInput.java rename to src/main/java/dev/isxander/controlify/impl/ingame/DualInput.java index e2b6ea6ba..e03bb0611 100644 --- a/src/main/java/dev/isxander/controlify/ingame/DualInput.java +++ b/src/main/java/dev/isxander/controlify/impl/ingame/DualInput.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.ingame; +package dev.isxander.controlify.impl.ingame; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec2; diff --git a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java b/src/main/java/dev/isxander/controlify/impl/ingame/InGameInputHandler.java similarity index 92% rename from src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java rename to src/main/java/dev/isxander/controlify/impl/ingame/InGameInputHandler.java index 4f8a86587..5997bbf52 100644 --- a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java +++ b/src/main/java/dev/isxander/controlify/impl/ingame/InGameInputHandler.java @@ -4,31 +4,31 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.ingame; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.ingameinput.LookInputModifier; -import dev.isxander.controlify.api.event.ControlifyEvents; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.config.settings.profile.GyroSettings; -import dev.isxander.controlify.config.settings.profile.InputSettings; -import dev.isxander.controlify.controller.gyro.GyroState; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.gyro.GyroButtonMode; -import dev.isxander.controlify.controller.gyro.GyroComponent; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.driver.steamdeck.SteamDeckDriver; -import dev.isxander.controlify.gui.screen.RadialItems; -import dev.isxander.controlify.gui.screen.RadialItems.RadialPage; -import dev.isxander.controlify.gui.screen.RadialMenuScreen; +package dev.isxander.controlify.impl.ingame; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.api.ingameinput.LookInputModifier; +import dev.isxander.controlify.api.ControlifyEvents; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.config.settings.profile.GyroSettings; +import dev.isxander.controlify.impl.config.settings.profile.InputSettings; +import dev.isxander.controlify.impl.controller.gyro.GyroState; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.gyro.GyroButtonMode; +import dev.isxander.controlify.impl.controller.gyro.GyroComponent; +import dev.isxander.controlify.impl.controller.input.InputComponent; +import dev.isxander.controlify.impl.driver.steamdeck.SteamDeckDriver; +import dev.isxander.controlify.impl.gui.screen.RadialItems; +import dev.isxander.controlify.impl.gui.screen.RadialItems.RadialPage; +import dev.isxander.controlify.impl.gui.screen.RadialMenuScreen; import dev.isxander.controlify.mixins.feature.steamdeck.ScreenshotAccessor; -import dev.isxander.controlify.server.ServerPolicies; -import dev.isxander.controlify.utils.ControllerUtils; -import dev.isxander.controlify.utils.DebugOverlayHelper; -import dev.isxander.controlify.utils.HoldRepeatHelper; -import dev.isxander.controlify.utils.MinecraftUtil; -import dev.isxander.controlify.utils.animation.api.Animation; -import dev.isxander.controlify.utils.animation.api.EasingFunction; +import dev.isxander.controlify.impl.server.ServerPolicies; +import dev.isxander.controlify.impl.utils.ControllerUtils; +import dev.isxander.controlify.impl.utils.DebugOverlayHelper; +import dev.isxander.controlify.impl.utils.HoldRepeatHelper; +import dev.isxander.controlify.impl.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.animation.api.Animation; +import dev.isxander.controlify.impl.utils.animation.api.EasingFunction; import net.minecraft.client.CameraType; import net.minecraft.client.Minecraft; import net.minecraft.client.Screenshot; @@ -54,7 +54,7 @@ import java.util.List; public class InGameInputHandler { - private final ControllerEntity controller; + private final ControllerImpl controller; private final Controlify controlify; private final Minecraft minecraft; @@ -72,7 +72,7 @@ public class InGameInputHandler { private final HoldRepeatHelper hotbarNextRepeatHelper; private final HoldRepeatHelper hotbarPrevRepeatHelper; - public InGameInputHandler(ControllerEntity controller) { + public InGameInputHandler(ControllerImpl controller) { this.controller = controller; this.minecraft = Minecraft.getInstance(); this.controlify = Controlify.instance(); diff --git a/src/main/java/dev/isxander/controlify/ingame/InputCurve.java b/src/main/java/dev/isxander/controlify/impl/ingame/InputCurve.java similarity index 95% rename from src/main/java/dev/isxander/controlify/ingame/InputCurve.java rename to src/main/java/dev/isxander/controlify/impl/ingame/InputCurve.java index 6baa60075..e65140541 100644 --- a/src/main/java/dev/isxander/controlify/ingame/InputCurve.java +++ b/src/main/java/dev/isxander/controlify/impl/ingame/InputCurve.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.ingame; +package dev.isxander.controlify.impl.ingame; /** * A functional interface representing an input curve transformation. diff --git a/src/main/java/dev/isxander/controlify/ingame/InputCurves.java b/src/main/java/dev/isxander/controlify/impl/ingame/InputCurves.java similarity index 96% rename from src/main/java/dev/isxander/controlify/ingame/InputCurves.java rename to src/main/java/dev/isxander/controlify/impl/ingame/InputCurves.java index 6e2229ee5..2e7dc1cdf 100644 --- a/src/main/java/dev/isxander/controlify/ingame/InputCurves.java +++ b/src/main/java/dev/isxander/controlify/impl/ingame/InputCurves.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.ingame; +package dev.isxander.controlify.impl.ingame; import com.mojang.serialization.Codec; import dev.isxander.yacl3.api.NameableEnum; diff --git a/src/main/java/dev/isxander/controlify/ingame/PickBlockAccessor.java b/src/main/java/dev/isxander/controlify/impl/ingame/PickBlockAccessor.java similarity index 83% rename from src/main/java/dev/isxander/controlify/ingame/PickBlockAccessor.java rename to src/main/java/dev/isxander/controlify/impl/ingame/PickBlockAccessor.java index 677bb8dc9..36aa7c2e1 100644 --- a/src/main/java/dev/isxander/controlify/ingame/PickBlockAccessor.java +++ b/src/main/java/dev/isxander/controlify/impl/ingame/PickBlockAccessor.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.ingame; +package dev.isxander.controlify.impl.ingame; public interface PickBlockAccessor { void controlify$pickBlock(); diff --git a/src/main/java/dev/isxander/controlify/input/SensorType.java b/src/main/java/dev/isxander/controlify/impl/input/SensorType.java similarity index 93% rename from src/main/java/dev/isxander/controlify/input/SensorType.java rename to src/main/java/dev/isxander/controlify/impl/input/SensorType.java index 220cba2cc..4087817a6 100644 --- a/src/main/java/dev/isxander/controlify/input/SensorType.java +++ b/src/main/java/dev/isxander/controlify/impl/input/SensorType.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input; +package dev.isxander.controlify.impl.input; public enum SensorType { /// Sensor components are `xyz` and in radians. diff --git a/src/main/java/dev/isxander/controlify/input/mapping/ControllerMapping.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/ControllerMapping.java similarity index 97% rename from src/main/java/dev/isxander/controlify/input/mapping/ControllerMapping.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/ControllerMapping.java index 8559df0c9..4b7987801 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/ControllerMapping.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/ControllerMapping.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; diff --git a/src/main/java/dev/isxander/controlify/input/mapping/ControllerMappingManager.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/ControllerMappingManager.java similarity index 92% rename from src/main/java/dev/isxander/controlify/input/mapping/ControllerMappingManager.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/ControllerMappingManager.java index 6224bdd7b..be909bf06 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/ControllerMappingManager.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/ControllerMappingManager.java @@ -1,11 +1,11 @@ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.mojang.serialization.DataResult; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.FileToIdConverter; import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.Resource; diff --git a/src/main/java/dev/isxander/controlify/input/mapping/DeadzoneGroup.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/DeadzoneGroup.java similarity index 92% rename from src/main/java/dev/isxander/controlify/input/mapping/DeadzoneGroup.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/DeadzoneGroup.java index 7cbbb3cb1..fc1f8c1ac 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/DeadzoneGroup.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/DeadzoneGroup.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/input/mapping/GamepadInputs.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/GamepadInputs.java similarity index 97% rename from src/main/java/dev/isxander/controlify/input/mapping/GamepadInputs.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/GamepadInputs.java index bd654e24d..309bb3ce7 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/GamepadInputs.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/GamepadInputs.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; import com.google.common.collect.Sets; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/input/mapping/GestureInputs.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/GestureInputs.java similarity index 64% rename from src/main/java/dev/isxander/controlify/input/mapping/GestureInputs.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/GestureInputs.java index 66fcfb7cf..ba67cfafc 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/GestureInputs.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/GestureInputs.java @@ -1,6 +1,6 @@ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; public final class GestureInputs { diff --git a/src/main/java/dev/isxander/controlify/input/mapping/Inputs.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/Inputs.java similarity index 94% rename from src/main/java/dev/isxander/controlify/input/mapping/Inputs.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/Inputs.java index beccfc754..74ffc4bdb 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/Inputs.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/Inputs.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; diff --git a/src/main/java/dev/isxander/controlify/input/mapping/JoystickInputs.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/JoystickInputs.java similarity index 91% rename from src/main/java/dev/isxander/controlify/input/mapping/JoystickInputs.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/JoystickInputs.java index 8fbf51cb8..bb20148f9 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/JoystickInputs.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/JoystickInputs.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; public final class JoystickInputs { diff --git a/src/main/java/dev/isxander/controlify/input/mapping/MapType.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/MapType.java similarity index 90% rename from src/main/java/dev/isxander/controlify/input/mapping/MapType.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/MapType.java index f5fbbddcd..c80b207c5 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/MapType.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/MapType.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; import com.mojang.serialization.Codec; import net.minecraft.util.StringRepresentable; diff --git a/src/main/java/dev/isxander/controlify/input/mapping/MappingEntry.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/MappingEntry.java similarity index 95% rename from src/main/java/dev/isxander/controlify/input/mapping/MappingEntry.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/MappingEntry.java index 845b81f6b..a1743f2bd 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/MappingEntry.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/MappingEntry.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; import com.mojang.serialization.Codec; -import dev.isxander.controlify.input.signal.PhysicalInputSignal; -import dev.isxander.controlify.utils.MthExt; +import dev.isxander.controlify.impl.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.impl.utils.MthExt; import net.minecraft.resources.Identifier; public sealed interface MappingEntry { diff --git a/src/main/java/dev/isxander/controlify/input/mapping/MappingEntryCodecs.java b/src/main/java/dev/isxander/controlify/impl/input/mapping/MappingEntryCodecs.java similarity index 98% rename from src/main/java/dev/isxander/controlify/input/mapping/MappingEntryCodecs.java rename to src/main/java/dev/isxander/controlify/impl/input/mapping/MappingEntryCodecs.java index 94c6ca3f2..8e94a35b1 100644 --- a/src/main/java/dev/isxander/controlify/input/mapping/MappingEntryCodecs.java +++ b/src/main/java/dev/isxander/controlify/impl/input/mapping/MappingEntryCodecs.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.input.mapping; +package dev.isxander.controlify.impl.input.mapping; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; diff --git a/src/main/java/dev/isxander/controlify/input/pipeline/DeadzoneStage.java b/src/main/java/dev/isxander/controlify/impl/input/pipeline/DeadzoneStage.java similarity index 89% rename from src/main/java/dev/isxander/controlify/input/pipeline/DeadzoneStage.java rename to src/main/java/dev/isxander/controlify/impl/input/pipeline/DeadzoneStage.java index 26020acb4..4e9aa5a14 100644 --- a/src/main/java/dev/isxander/controlify/input/pipeline/DeadzoneStage.java +++ b/src/main/java/dev/isxander/controlify/impl/input/pipeline/DeadzoneStage.java @@ -1,10 +1,10 @@ -package dev.isxander.controlify.input.pipeline; +package dev.isxander.controlify.impl.input.pipeline; -import dev.isxander.controlify.input.mapping.DeadzoneGroup; -import dev.isxander.controlify.input.signal.PhysicalInputSignal; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.UnaryEventStage; +import dev.isxander.controlify.impl.input.mapping.DeadzoneGroup; +import dev.isxander.controlify.impl.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.UnaryEventStage; import it.unimi.dsi.fastutil.objects.*; import net.minecraft.resources.Identifier; import net.minecraft.util.Mth; diff --git a/src/main/java/dev/isxander/controlify/input/pipeline/GestureRecogniserStage.java b/src/main/java/dev/isxander/controlify/impl/input/pipeline/GestureRecogniserStage.java similarity index 56% rename from src/main/java/dev/isxander/controlify/input/pipeline/GestureRecogniserStage.java rename to src/main/java/dev/isxander/controlify/impl/input/pipeline/GestureRecogniserStage.java index ec478d8f7..c5042ea49 100644 --- a/src/main/java/dev/isxander/controlify/input/pipeline/GestureRecogniserStage.java +++ b/src/main/java/dev/isxander/controlify/impl/input/pipeline/GestureRecogniserStage.java @@ -1,10 +1,10 @@ -package dev.isxander.controlify.input.pipeline; +package dev.isxander.controlify.impl.input.pipeline; -import dev.isxander.controlify.input.mapping.GestureInputs; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.input.signal.PhysicalInputSignal; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.UnaryEventStage; +import dev.isxander.controlify.impl.input.mapping.GestureInputs; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.UnaryEventStage; /// Processes sensor data and recognizes distinct gestures such as shaking of the controller. /// This stage then emits {@link PhysicalInputSignal.ButtonChanged} events diff --git a/src/main/java/dev/isxander/controlify/input/pipeline/InputDomainExpansionStage.java b/src/main/java/dev/isxander/controlify/impl/input/pipeline/InputDomainExpansionStage.java similarity index 83% rename from src/main/java/dev/isxander/controlify/input/pipeline/InputDomainExpansionStage.java rename to src/main/java/dev/isxander/controlify/impl/input/pipeline/InputDomainExpansionStage.java index 4b94ca556..50516b2f2 100644 --- a/src/main/java/dev/isxander/controlify/input/pipeline/InputDomainExpansionStage.java +++ b/src/main/java/dev/isxander/controlify/impl/input/pipeline/InputDomainExpansionStage.java @@ -1,9 +1,9 @@ -package dev.isxander.controlify.input.pipeline; +package dev.isxander.controlify.impl.input.pipeline; -import dev.isxander.controlify.input.signal.PhysicalInputSignal; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.UnaryEventStage; +import dev.isxander.controlify.impl.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.UnaryEventStage; import net.minecraft.resources.Identifier; import java.util.HashSet; diff --git a/src/main/java/dev/isxander/controlify/input/pipeline/InputPipeline.java b/src/main/java/dev/isxander/controlify/impl/input/pipeline/InputPipeline.java similarity index 86% rename from src/main/java/dev/isxander/controlify/input/pipeline/InputPipeline.java rename to src/main/java/dev/isxander/controlify/impl/input/pipeline/InputPipeline.java index 764b924d3..5475b9921 100644 --- a/src/main/java/dev/isxander/controlify/input/pipeline/InputPipeline.java +++ b/src/main/java/dev/isxander/controlify/impl/input/pipeline/InputPipeline.java @@ -1,11 +1,11 @@ -package dev.isxander.controlify.input.pipeline; - -import dev.isxander.controlify.input.mapping.ControllerMapping; -import dev.isxander.controlify.input.signal.LogicalSignal; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.EventSource; -import dev.isxander.controlify.utils.event.EventTap; +package dev.isxander.controlify.impl.input.pipeline; + +import dev.isxander.controlify.impl.input.mapping.ControllerMapping; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.EventSource; +import dev.isxander.controlify.impl.utils.event.EventTap; public class InputPipeline implements EventSink { private final EventTap tapRawPhysicalSignals; diff --git a/src/main/java/dev/isxander/controlify/input/pipeline/MappingStage.java b/src/main/java/dev/isxander/controlify/impl/input/pipeline/MappingStage.java similarity index 68% rename from src/main/java/dev/isxander/controlify/input/pipeline/MappingStage.java rename to src/main/java/dev/isxander/controlify/impl/input/pipeline/MappingStage.java index 38d83fcba..d87e2a87d 100644 --- a/src/main/java/dev/isxander/controlify/input/pipeline/MappingStage.java +++ b/src/main/java/dev/isxander/controlify/impl/input/pipeline/MappingStage.java @@ -1,11 +1,11 @@ -package dev.isxander.controlify.input.pipeline; +package dev.isxander.controlify.impl.input.pipeline; -import dev.isxander.controlify.input.mapping.ControllerMapping; -import dev.isxander.controlify.input.mapping.MappingEntry; -import dev.isxander.controlify.input.signal.PhysicalInputSignal; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.UnaryEventStage; +import dev.isxander.controlify.impl.input.mapping.ControllerMapping; +import dev.isxander.controlify.impl.input.mapping.MappingEntry; +import dev.isxander.controlify.impl.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.UnaryEventStage; import net.minecraft.resources.Identifier; import java.util.Map; diff --git a/src/main/java/dev/isxander/controlify/input/pipeline/PhysicalToLogicalStage.java b/src/main/java/dev/isxander/controlify/impl/input/pipeline/PhysicalToLogicalStage.java similarity index 93% rename from src/main/java/dev/isxander/controlify/input/pipeline/PhysicalToLogicalStage.java rename to src/main/java/dev/isxander/controlify/impl/input/pipeline/PhysicalToLogicalStage.java index 385d2d0bd..0c7938cf7 100644 --- a/src/main/java/dev/isxander/controlify/input/pipeline/PhysicalToLogicalStage.java +++ b/src/main/java/dev/isxander/controlify/impl/input/pipeline/PhysicalToLogicalStage.java @@ -1,12 +1,12 @@ -package dev.isxander.controlify.input.pipeline; - -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.signal.LogicalSignal; -import dev.isxander.controlify.input.signal.PhysicalInputSignal; -import dev.isxander.controlify.input.signal.PhysicalSensorSignal; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.EventStage; +package dev.isxander.controlify.impl.input.pipeline; + +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalInputSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.EventStage; import net.minecraft.resources.Identifier; import java.util.HashMap; diff --git a/src/main/java/dev/isxander/controlify/input/pipeline/SensorAccumulatorStage.java b/src/main/java/dev/isxander/controlify/impl/input/pipeline/SensorAccumulatorStage.java similarity index 87% rename from src/main/java/dev/isxander/controlify/input/pipeline/SensorAccumulatorStage.java rename to src/main/java/dev/isxander/controlify/impl/input/pipeline/SensorAccumulatorStage.java index 24fb9310f..da13d90ed 100644 --- a/src/main/java/dev/isxander/controlify/input/pipeline/SensorAccumulatorStage.java +++ b/src/main/java/dev/isxander/controlify/impl/input/pipeline/SensorAccumulatorStage.java @@ -1,11 +1,11 @@ -package dev.isxander.controlify.input.pipeline; - -import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.signal.LogicalSignal; -import dev.isxander.controlify.input.signal.PhysicalSensorSignal; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.EventStage; +package dev.isxander.controlify.impl.input.pipeline; + +import dev.isxander.controlify.impl.input.SensorType; +import dev.isxander.controlify.impl.input.signal.LogicalSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.EventStage; import java.util.EnumMap; import java.util.Map; diff --git a/src/main/java/dev/isxander/controlify/input/pipeline/SensorProcessorStage.java b/src/main/java/dev/isxander/controlify/impl/input/pipeline/SensorProcessorStage.java similarity index 90% rename from src/main/java/dev/isxander/controlify/input/pipeline/SensorProcessorStage.java rename to src/main/java/dev/isxander/controlify/impl/input/pipeline/SensorProcessorStage.java index 4ec21c7d5..77185a49c 100644 --- a/src/main/java/dev/isxander/controlify/input/pipeline/SensorProcessorStage.java +++ b/src/main/java/dev/isxander/controlify/impl/input/pipeline/SensorProcessorStage.java @@ -1,10 +1,10 @@ -package dev.isxander.controlify.input.pipeline; +package dev.isxander.controlify.impl.input.pipeline; -import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.signal.PhysicalSensorSignal; -import dev.isxander.controlify.input.signal.PhysicalSignal; -import dev.isxander.controlify.utils.event.EventSink; -import dev.isxander.controlify.utils.event.UnaryEventStage; +import dev.isxander.controlify.impl.input.SensorType; +import dev.isxander.controlify.impl.input.signal.PhysicalSensorSignal; +import dev.isxander.controlify.impl.input.signal.PhysicalSignal; +import dev.isxander.controlify.impl.utils.event.EventSink; +import dev.isxander.controlify.impl.utils.event.UnaryEventStage; import org.joml.Vector3f; import org.joml.Vector3fc; import org.jspecify.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/input/signal/LogicalSignal.java b/src/main/java/dev/isxander/controlify/impl/input/signal/LogicalSignal.java similarity index 87% rename from src/main/java/dev/isxander/controlify/input/signal/LogicalSignal.java rename to src/main/java/dev/isxander/controlify/impl/input/signal/LogicalSignal.java index 233d4c1a4..d8bf4ae14 100644 --- a/src/main/java/dev/isxander/controlify/input/signal/LogicalSignal.java +++ b/src/main/java/dev/isxander/controlify/impl/input/signal/LogicalSignal.java @@ -1,8 +1,8 @@ -package dev.isxander.controlify.input.signal; +package dev.isxander.controlify.impl.input.signal; -import dev.isxander.controlify.input.LogicalInput; -import dev.isxander.controlify.input.SensorType; -import dev.isxander.controlify.input.pipeline.SensorAccumulatorStage; +import dev.isxander.controlify.api.input.LogicalInput; +import dev.isxander.controlify.impl.input.SensorType; +import dev.isxander.controlify.impl.input.pipeline.SensorAccumulatorStage; public sealed interface LogicalSignal { /// The time this signal occurred. diff --git a/src/main/java/dev/isxander/controlify/input/signal/PhysicalInputSignal.java b/src/main/java/dev/isxander/controlify/impl/input/signal/PhysicalInputSignal.java similarity index 94% rename from src/main/java/dev/isxander/controlify/input/signal/PhysicalInputSignal.java rename to src/main/java/dev/isxander/controlify/impl/input/signal/PhysicalInputSignal.java index aaf72386d..d8d19fd9e 100644 --- a/src/main/java/dev/isxander/controlify/input/signal/PhysicalInputSignal.java +++ b/src/main/java/dev/isxander/controlify/impl/input/signal/PhysicalInputSignal.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.signal; +package dev.isxander.controlify.impl.input.signal; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/input/signal/PhysicalSensorSignal.java b/src/main/java/dev/isxander/controlify/impl/input/signal/PhysicalSensorSignal.java similarity index 88% rename from src/main/java/dev/isxander/controlify/input/signal/PhysicalSensorSignal.java rename to src/main/java/dev/isxander/controlify/impl/input/signal/PhysicalSensorSignal.java index 69367f56f..87389424c 100644 --- a/src/main/java/dev/isxander/controlify/input/signal/PhysicalSensorSignal.java +++ b/src/main/java/dev/isxander/controlify/impl/input/signal/PhysicalSensorSignal.java @@ -1,6 +1,6 @@ -package dev.isxander.controlify.input.signal; +package dev.isxander.controlify.impl.input.signal; -import dev.isxander.controlify.input.SensorType; +import dev.isxander.controlify.impl.input.SensorType; /// Represents a single IMU sample /// @param timeNanos timestamp of the event in nanoseconds diff --git a/src/main/java/dev/isxander/controlify/input/signal/PhysicalSignal.java b/src/main/java/dev/isxander/controlify/impl/input/signal/PhysicalSignal.java similarity index 86% rename from src/main/java/dev/isxander/controlify/input/signal/PhysicalSignal.java rename to src/main/java/dev/isxander/controlify/impl/input/signal/PhysicalSignal.java index 10ec1a5cc..37485d8f2 100644 --- a/src/main/java/dev/isxander/controlify/input/signal/PhysicalSignal.java +++ b/src/main/java/dev/isxander/controlify/impl/input/signal/PhysicalSignal.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.input.signal; +package dev.isxander.controlify.impl.input.signal; public sealed interface PhysicalSignal permits PhysicalInputSignal, PhysicalSensorSignal, PhysicalSignal.Frame { /// timestamp of the signal in nanoseconds diff --git a/src/main/java/dev/isxander/controlify/platform/ArrayBackedEventHandler.java b/src/main/java/dev/isxander/controlify/impl/platform/ArrayBackedEventHandler.java similarity index 91% rename from src/main/java/dev/isxander/controlify/platform/ArrayBackedEventHandler.java rename to src/main/java/dev/isxander/controlify/impl/platform/ArrayBackedEventHandler.java index 7235d782c..1ec13c73e 100644 --- a/src/main/java/dev/isxander/controlify/platform/ArrayBackedEventHandler.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/ArrayBackedEventHandler.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform; +package dev.isxander.controlify.impl.platform; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/platform/Environment.java b/src/main/java/dev/isxander/controlify/impl/platform/Environment.java similarity index 78% rename from src/main/java/dev/isxander/controlify/platform/Environment.java rename to src/main/java/dev/isxander/controlify/impl/platform/Environment.java index c76124bc3..772ddd4ad 100644 --- a/src/main/java/dev/isxander/controlify/platform/Environment.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/Environment.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform; +package dev.isxander.controlify.impl.platform; public enum Environment { CLIENT, diff --git a/src/main/java/dev/isxander/controlify/platform/Event.java b/src/main/java/dev/isxander/controlify/impl/platform/Event.java similarity index 76% rename from src/main/java/dev/isxander/controlify/platform/Event.java rename to src/main/java/dev/isxander/controlify/impl/platform/Event.java index 35c1e70bd..9a38b539a 100644 --- a/src/main/java/dev/isxander/controlify/platform/Event.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/Event.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform; +package dev.isxander.controlify.impl.platform; public interface Event { } diff --git a/src/main/java/dev/isxander/controlify/platform/EventHandler.java b/src/main/java/dev/isxander/controlify/impl/platform/EventHandler.java similarity index 89% rename from src/main/java/dev/isxander/controlify/platform/EventHandler.java rename to src/main/java/dev/isxander/controlify/impl/platform/EventHandler.java index 8566a2fb1..bcd4311e2 100644 --- a/src/main/java/dev/isxander/controlify/platform/EventHandler.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/EventHandler.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform; +package dev.isxander.controlify.impl.platform; public interface EventHandler { void register(Callback event); diff --git a/src/main/java/dev/isxander/controlify/platform/client/CreativeTabHelper.java b/src/main/java/dev/isxander/controlify/impl/platform/client/CreativeTabHelper.java similarity index 89% rename from src/main/java/dev/isxander/controlify/platform/client/CreativeTabHelper.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/CreativeTabHelper.java index 0f7c35230..cf9b14dbd 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/CreativeTabHelper.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/CreativeTabHelper.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client; +package dev.isxander.controlify.impl.platform.client; import net.minecraft.world.item.CreativeModeTab; diff --git a/src/main/java/dev/isxander/controlify/platform/client/HudRenderLayer.java b/src/main/java/dev/isxander/controlify/impl/platform/client/HudRenderLayer.java similarity index 86% rename from src/main/java/dev/isxander/controlify/platform/client/HudRenderLayer.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/HudRenderLayer.java index 468194d54..67d6e1343 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/HudRenderLayer.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/HudRenderLayer.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client; +package dev.isxander.controlify.impl.platform.client; import net.minecraft.client.DeltaTracker; import net.minecraft.client.gui.GuiGraphicsExtractor; diff --git a/src/main/java/dev/isxander/controlify/platform/client/PlatformClientUtil.java b/src/main/java/dev/isxander/controlify/impl/platform/client/PlatformClientUtil.java similarity index 87% rename from src/main/java/dev/isxander/controlify/platform/client/PlatformClientUtil.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/PlatformClientUtil.java index 26b5b97b6..54126f35b 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/PlatformClientUtil.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/PlatformClientUtil.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client; +package dev.isxander.controlify.impl.platform.client; -import dev.isxander.controlify.platform.client.events.DisconnectedEvent; -import dev.isxander.controlify.platform.client.events.LifecycleEvent; -import dev.isxander.controlify.platform.client.events.ScreenRenderEvent; -import dev.isxander.controlify.platform.client.events.TickEvent; -import dev.isxander.controlify.platform.client.resource.ControlifyReloadListener; +import dev.isxander.controlify.impl.platform.client.events.DisconnectedEvent; +import dev.isxander.controlify.impl.platform.client.events.LifecycleEvent; +import dev.isxander.controlify.impl.platform.client.events.ScreenRenderEvent; +import dev.isxander.controlify.impl.platform.client.events.TickEvent; +import dev.isxander.controlify.impl.platform.client.resource.ControlifyReloadListener; import net.minecraft.client.KeyMapping; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.navigation.ScreenRectangle; diff --git a/src/main/java/dev/isxander/controlify/platform/client/PlatformClientUtilImpl.java b/src/main/java/dev/isxander/controlify/impl/platform/client/PlatformClientUtilImpl.java similarity index 90% rename from src/main/java/dev/isxander/controlify/platform/client/PlatformClientUtilImpl.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/PlatformClientUtilImpl.java index 39d0deeb7..4b59befc4 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/PlatformClientUtilImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/PlatformClientUtilImpl.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client; +package dev.isxander.controlify.impl.platform.client; -import dev.isxander.controlify.platform.client.events.*; -import dev.isxander.controlify.platform.client.resource.ControlifyReloadListener; +import dev.isxander.controlify.impl.platform.client.events.*; +import dev.isxander.controlify.impl.platform.client.resource.ControlifyReloadListener; import net.minecraft.client.KeyMapping; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.navigation.ScreenRectangle; diff --git a/src/main/java/dev/isxander/controlify/platform/client/events/DisconnectedEvent.java b/src/main/java/dev/isxander/controlify/impl/platform/client/events/DisconnectedEvent.java similarity index 81% rename from src/main/java/dev/isxander/controlify/platform/client/events/DisconnectedEvent.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/events/DisconnectedEvent.java index a82216988..c355084f3 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/events/DisconnectedEvent.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/events/DisconnectedEvent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client.events; +package dev.isxander.controlify.impl.platform.client.events; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/platform/client/events/LifecycleEvent.java b/src/main/java/dev/isxander/controlify/impl/platform/client/events/LifecycleEvent.java similarity index 81% rename from src/main/java/dev/isxander/controlify/platform/client/events/LifecycleEvent.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/events/LifecycleEvent.java index 82cad65c1..c72576056 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/events/LifecycleEvent.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/events/LifecycleEvent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client.events; +package dev.isxander.controlify.impl.platform.client.events; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/platform/client/events/ScreenRenderEvent.java b/src/main/java/dev/isxander/controlify/impl/platform/client/events/ScreenRenderEvent.java similarity index 86% rename from src/main/java/dev/isxander/controlify/platform/client/events/ScreenRenderEvent.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/events/ScreenRenderEvent.java index 229a32215..d5e21459e 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/events/ScreenRenderEvent.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/events/ScreenRenderEvent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client.events; +package dev.isxander.controlify.impl.platform.client.events; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; diff --git a/src/main/java/dev/isxander/controlify/platform/client/events/TickEvent.java b/src/main/java/dev/isxander/controlify/impl/platform/client/events/TickEvent.java similarity index 93% rename from src/main/java/dev/isxander/controlify/platform/client/events/TickEvent.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/events/TickEvent.java index ca04c021b..6df6bb8f2 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/events/TickEvent.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/events/TickEvent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client.events; +package dev.isxander.controlify.impl.platform.client.events; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/platform/client/resource/ControlifyReloadListener.java b/src/main/java/dev/isxander/controlify/impl/platform/client/resource/ControlifyReloadListener.java similarity index 84% rename from src/main/java/dev/isxander/controlify/platform/client/resource/ControlifyReloadListener.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/resource/ControlifyReloadListener.java index 35e338da9..b1aeb615a 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/resource/ControlifyReloadListener.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/resource/ControlifyReloadListener.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client.resource; +package dev.isxander.controlify.impl.platform.client.resource; import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.PreparableReloadListener; diff --git a/src/main/java/dev/isxander/controlify/platform/client/resource/SimpleControlifyReloadListener.java b/src/main/java/dev/isxander/controlify/impl/platform/client/resource/SimpleControlifyReloadListener.java similarity index 96% rename from src/main/java/dev/isxander/controlify/platform/client/resource/SimpleControlifyReloadListener.java rename to src/main/java/dev/isxander/controlify/impl/platform/client/resource/SimpleControlifyReloadListener.java index d99326e4c..0760b3eb0 100644 --- a/src/main/java/dev/isxander/controlify/platform/client/resource/SimpleControlifyReloadListener.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/client/resource/SimpleControlifyReloadListener.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.client.resource; +package dev.isxander.controlify.impl.platform.client.resource; import net.minecraft.server.packs.resources.ResourceManager; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/dev/isxander/controlify/platform/main/PlatformMainUtil.java b/src/main/java/dev/isxander/controlify/impl/platform/main/PlatformMainUtil.java similarity index 80% rename from src/main/java/dev/isxander/controlify/platform/main/PlatformMainUtil.java rename to src/main/java/dev/isxander/controlify/impl/platform/main/PlatformMainUtil.java index b421b1d96..89960b99c 100644 --- a/src/main/java/dev/isxander/controlify/platform/main/PlatformMainUtil.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/main/PlatformMainUtil.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.main; - -import dev.isxander.controlify.api.entrypoint.ControlifyEntrypoint; -import dev.isxander.controlify.platform.Environment; -import dev.isxander.controlify.platform.main.events.CommandRegistrationCallbackEvent; -import dev.isxander.controlify.platform.main.events.HandshakeCompletionEvent; -import dev.isxander.controlify.platform.main.events.PlayerJoinedEvent; -import dev.isxander.controlify.platform.network.C2SNetworkApi; -import dev.isxander.controlify.platform.network.S2CNetworkApi; +package dev.isxander.controlify.impl.platform.main; + +import dev.isxander.controlify.impl.api.entrypoint.ControlifyEntrypoint; +import dev.isxander.controlify.impl.platform.Environment; +import dev.isxander.controlify.impl.platform.main.events.CommandRegistrationCallbackEvent; +import dev.isxander.controlify.impl.platform.main.events.HandshakeCompletionEvent; +import dev.isxander.controlify.impl.platform.main.events.PlayerJoinedEvent; +import dev.isxander.controlify.impl.platform.network.C2SNetworkApi; +import dev.isxander.controlify.impl.platform.network.S2CNetworkApi; import net.minecraft.core.Registry; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; diff --git a/src/main/java/dev/isxander/controlify/platform/main/PlatformMainUtilImpl.java b/src/main/java/dev/isxander/controlify/impl/platform/main/PlatformMainUtilImpl.java similarity index 71% rename from src/main/java/dev/isxander/controlify/platform/main/PlatformMainUtilImpl.java rename to src/main/java/dev/isxander/controlify/impl/platform/main/PlatformMainUtilImpl.java index 09a116265..31b0d89f4 100644 --- a/src/main/java/dev/isxander/controlify/platform/main/PlatformMainUtilImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/main/PlatformMainUtilImpl.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.main; - -import dev.isxander.controlify.api.entrypoint.ControlifyEntrypoint; -import dev.isxander.controlify.platform.Environment; -import dev.isxander.controlify.platform.main.events.CommandRegistrationCallbackEvent; -import dev.isxander.controlify.platform.main.events.HandshakeCompletionEvent; -import dev.isxander.controlify.platform.main.events.PlayerJoinedEvent; -import dev.isxander.controlify.platform.network.C2SNetworkApi; -import dev.isxander.controlify.platform.network.S2CNetworkApi; +package dev.isxander.controlify.impl.platform.main; + +import dev.isxander.controlify.impl.api.entrypoint.ControlifyEntrypoint; +import dev.isxander.controlify.impl.platform.Environment; +import dev.isxander.controlify.impl.platform.main.events.CommandRegistrationCallbackEvent; +import dev.isxander.controlify.impl.platform.main.events.HandshakeCompletionEvent; +import dev.isxander.controlify.impl.platform.main.events.PlayerJoinedEvent; +import dev.isxander.controlify.impl.platform.network.C2SNetworkApi; +import dev.isxander.controlify.impl.platform.network.S2CNetworkApi; import net.minecraft.core.Registry; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; diff --git a/src/main/java/dev/isxander/controlify/platform/main/events/CommandRegistrationCallbackEvent.java b/src/main/java/dev/isxander/controlify/impl/platform/main/events/CommandRegistrationCallbackEvent.java similarity index 89% rename from src/main/java/dev/isxander/controlify/platform/main/events/CommandRegistrationCallbackEvent.java rename to src/main/java/dev/isxander/controlify/impl/platform/main/events/CommandRegistrationCallbackEvent.java index 405fef1ce..12d52d30d 100644 --- a/src/main/java/dev/isxander/controlify/platform/main/events/CommandRegistrationCallbackEvent.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/main/events/CommandRegistrationCallbackEvent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.main.events; +package dev.isxander.controlify.impl.platform.main.events; import com.mojang.brigadier.CommandDispatcher; import net.minecraft.commands.CommandBuildContext; diff --git a/src/main/java/dev/isxander/controlify/platform/main/events/HandshakeCompletionEvent.java b/src/main/java/dev/isxander/controlify/impl/platform/main/events/HandshakeCompletionEvent.java similarity index 86% rename from src/main/java/dev/isxander/controlify/platform/main/events/HandshakeCompletionEvent.java rename to src/main/java/dev/isxander/controlify/impl/platform/main/events/HandshakeCompletionEvent.java index ec4d107b7..374675f42 100644 --- a/src/main/java/dev/isxander/controlify/platform/main/events/HandshakeCompletionEvent.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/main/events/HandshakeCompletionEvent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.main.events; +package dev.isxander.controlify.impl.platform.main.events; import net.minecraft.server.network.ServerLoginPacketListenerImpl; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/platform/main/events/PlayerJoinedEvent.java b/src/main/java/dev/isxander/controlify/impl/platform/main/events/PlayerJoinedEvent.java similarity index 81% rename from src/main/java/dev/isxander/controlify/platform/main/events/PlayerJoinedEvent.java rename to src/main/java/dev/isxander/controlify/impl/platform/main/events/PlayerJoinedEvent.java index 2bb5cc0f4..fc6c20196 100644 --- a/src/main/java/dev/isxander/controlify/platform/main/events/PlayerJoinedEvent.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/main/events/PlayerJoinedEvent.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.main.events; +package dev.isxander.controlify.impl.platform.main.events; import net.minecraft.server.level.ServerPlayer; diff --git a/src/main/java/dev/isxander/controlify/platform/network/C2SNetworkApi.java b/src/main/java/dev/isxander/controlify/impl/platform/network/C2SNetworkApi.java similarity index 92% rename from src/main/java/dev/isxander/controlify/platform/network/C2SNetworkApi.java rename to src/main/java/dev/isxander/controlify/impl/platform/network/C2SNetworkApi.java index 8870ac944..677fcde12 100644 --- a/src/main/java/dev/isxander/controlify/platform/network/C2SNetworkApi.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/network/C2SNetworkApi.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.network; +package dev.isxander.controlify.impl.platform.network; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/platform/network/S2CNetworkApi.java b/src/main/java/dev/isxander/controlify/impl/platform/network/S2CNetworkApi.java similarity index 90% rename from src/main/java/dev/isxander/controlify/platform/network/S2CNetworkApi.java rename to src/main/java/dev/isxander/controlify/impl/platform/network/S2CNetworkApi.java index 97c935404..73315e5a7 100644 --- a/src/main/java/dev/isxander/controlify/platform/network/S2CNetworkApi.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/network/S2CNetworkApi.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.network; +package dev.isxander.controlify.impl.platform.network; import net.minecraft.resources.Identifier; import net.minecraft.server.level.ServerPlayer; diff --git a/src/main/java/dev/isxander/controlify/platform/network/SidedNetworkApi.java b/src/main/java/dev/isxander/controlify/impl/platform/network/SidedNetworkApi.java similarity index 81% rename from src/main/java/dev/isxander/controlify/platform/network/SidedNetworkApi.java rename to src/main/java/dev/isxander/controlify/impl/platform/network/SidedNetworkApi.java index 3987bf612..a1e9471ed 100644 --- a/src/main/java/dev/isxander/controlify/platform/network/SidedNetworkApi.java +++ b/src/main/java/dev/isxander/controlify/impl/platform/network/SidedNetworkApi.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.platform.network; +package dev.isxander.controlify.impl.platform.network; -import dev.isxander.controlify.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/reacharound/ReachAroundHandler.java b/src/main/java/dev/isxander/controlify/impl/reacharound/ReachAroundHandler.java similarity index 93% rename from src/main/java/dev/isxander/controlify/reacharound/ReachAroundHandler.java rename to src/main/java/dev/isxander/controlify/impl/reacharound/ReachAroundHandler.java index 44afd6814..76b15fdea 100644 --- a/src/main/java/dev/isxander/controlify/reacharound/ReachAroundHandler.java +++ b/src/main/java/dev/isxander/controlify/impl/reacharound/ReachAroundHandler.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.reacharound; +package dev.isxander.controlify.impl.reacharound; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.server.ServerPolicies; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.server.ServerPolicies; import net.minecraft.world.entity.Entity; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; diff --git a/src/main/java/dev/isxander/controlify/reacharound/ReachAroundMode.java b/src/main/java/dev/isxander/controlify/impl/reacharound/ReachAroundMode.java similarity index 94% rename from src/main/java/dev/isxander/controlify/reacharound/ReachAroundMode.java rename to src/main/java/dev/isxander/controlify/impl/reacharound/ReachAroundMode.java index b714f4c19..fcf7d8375 100644 --- a/src/main/java/dev/isxander/controlify/reacharound/ReachAroundMode.java +++ b/src/main/java/dev/isxander/controlify/impl/reacharound/ReachAroundMode.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.reacharound; +package dev.isxander.controlify.impl.reacharound; import com.mojang.serialization.Codec; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import dev.isxander.yacl3.api.NameableEnum; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.Component; diff --git a/src/main/java/dev/isxander/controlify/screenop/ComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/ComponentProcessor.java similarity index 70% rename from src/main/java/dev/isxander/controlify/screenop/ComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/ComponentProcessor.java index 7afa9fdb5..1c563aad9 100644 --- a/src/main/java/dev/isxander/controlify/screenop/ComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/ComponentProcessor.java @@ -4,30 +4,30 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop; +package dev.isxander.controlify.impl.screenop; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.keyboard.ComponentKeyboardBehaviour; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.keyboard.ComponentKeyboardBehaviour; public interface ComponentProcessor extends ComponentProcessorProvider { ComponentProcessor EMPTY = new ComponentProcessor(){}; - default boolean overrideControllerNavigation(ScreenProcessor screen, ControllerEntity controller) { + default boolean overrideControllerNavigation(ScreenProcessor screen, ControllerImpl controller) { return false; } - default boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + default boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { return false; } - default void onFocusGained(ScreenProcessor screen, ControllerEntity controller) { + default void onFocusGained(ScreenProcessor screen, ControllerImpl controller) { } default boolean shouldKeepFocusOnKeyboardMode(ScreenProcessor screen) { return false; } - default ComponentKeyboardBehaviour getKeyboardBehaviour(ScreenProcessor screen, ControllerEntity controller) { + default ComponentKeyboardBehaviour getKeyboardBehaviour(ScreenProcessor screen, ControllerImpl controller) { return ComponentKeyboardBehaviour.UNDEFINED; } diff --git a/src/main/java/dev/isxander/controlify/screenop/ComponentProcessorProvider.java b/src/main/java/dev/isxander/controlify/impl/screenop/ComponentProcessorProvider.java similarity index 93% rename from src/main/java/dev/isxander/controlify/screenop/ComponentProcessorProvider.java rename to src/main/java/dev/isxander/controlify/impl/screenop/ComponentProcessorProvider.java index 975013be6..847162b9d 100644 --- a/src/main/java/dev/isxander/controlify/screenop/ComponentProcessorProvider.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/ComponentProcessorProvider.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop; +package dev.isxander.controlify.impl.screenop; import net.minecraft.client.gui.components.events.GuiEventListener; diff --git a/src/main/java/dev/isxander/controlify/screenop/CustomFocus.java b/src/main/java/dev/isxander/controlify/impl/screenop/CustomFocus.java similarity index 84% rename from src/main/java/dev/isxander/controlify/screenop/CustomFocus.java rename to src/main/java/dev/isxander/controlify/impl/screenop/CustomFocus.java index 911b95650..715e199b0 100644 --- a/src/main/java/dev/isxander/controlify/screenop/CustomFocus.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/CustomFocus.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop; +package dev.isxander.controlify.impl.screenop; import net.minecraft.client.gui.components.events.GuiEventListener; diff --git a/src/main/java/dev/isxander/controlify/screenop/Registry.java b/src/main/java/dev/isxander/controlify/impl/screenop/Registry.java similarity index 96% rename from src/main/java/dev/isxander/controlify/screenop/Registry.java rename to src/main/java/dev/isxander/controlify/impl/screenop/Registry.java index a40487638..bcb1132ff 100644 --- a/src/main/java/dev/isxander/controlify/screenop/Registry.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/Registry.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop; +package dev.isxander.controlify.impl.screenop; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.ApiStatus; diff --git a/src/main/java/dev/isxander/controlify/screenop/ScreenControllerEventListener.java b/src/main/java/dev/isxander/controlify/impl/screenop/ScreenControllerEventListener.java similarity index 50% rename from src/main/java/dev/isxander/controlify/screenop/ScreenControllerEventListener.java rename to src/main/java/dev/isxander/controlify/impl/screenop/ScreenControllerEventListener.java index d3dccd778..4aec4936d 100644 --- a/src/main/java/dev/isxander/controlify/screenop/ScreenControllerEventListener.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/ScreenControllerEventListener.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop; +package dev.isxander.controlify.impl.screenop; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.controller.ControllerImpl; public interface ScreenControllerEventListener { - default void onControllerInput(ControllerEntity controller) {} + default void onControllerInput(ControllerImpl controller) {} } diff --git a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/ScreenProcessor.java similarity index 87% rename from src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/ScreenProcessor.java index 330fc61e0..42253b38b 100644 --- a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/ScreenProcessor.java @@ -4,26 +4,25 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop; +package dev.isxander.controlify.impl.screenop; import com.mojang.blaze3d.platform.InputConstants; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.controller.haptic.HapticEffects; -import dev.isxander.controlify.controller.input.ControllerStateView; -import dev.isxander.controlify.input.mapping.GamepadInputs; -import dev.isxander.controlify.controller.input.InputComponent; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.InputMode; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.controller.haptic.HapticEffects; +import dev.isxander.controlify.impl.controller.input.ControllerStateView; +import dev.isxander.controlify.impl.input.mapping.GamepadInputs; +import dev.isxander.controlify.impl.controller.input.InputComponent; import dev.isxander.controlify.mixins.feature.screenop.ScreenAccessor; import dev.isxander.controlify.mixins.feature.screenop.impl.outofgame.TabNavigationBarAccessor; -import dev.isxander.controlify.screenop.keyboard.*; -import dev.isxander.controlify.sound.ControlifyClientSounds; -import dev.isxander.controlify.utils.HoldRepeatHelper; -import dev.isxander.controlify.utils.MinecraftUtil; -import dev.isxander.controlify.virtualmouse.VirtualMouseBehaviour; -import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; +import dev.isxander.controlify.impl.screenop.keyboard.*; +import dev.isxander.controlify.impl.sound.ControlifyClientSounds; +import dev.isxander.controlify.impl.utils.HoldRepeatHelper; +import dev.isxander.controlify.impl.utils.MinecraftUtil; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseBehaviour; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseHandler; import net.minecraft.client.InputType; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; @@ -58,7 +57,7 @@ public ScreenProcessor(T screen) { this.holdRepeatHelper = createHoldRepeatHelper(); } - public void onControllerFixedUpdate(ControllerEntity controller) { + public void onControllerFixedUpdate(ControllerImpl controller) { Controlify.instance().virtualMouseHandler().handleControllerInput(controller); if (!Controlify.instance().virtualMouseHandler().isVirtualMouseEnabled()) { @@ -76,7 +75,7 @@ public void onControllerFixedUpdate(ControllerEntity controller) { eventListeners.forEach(listener -> listener.onControllerInput(controller)); } - public void render(ControllerEntity controller, GuiGraphicsExtractor graphics, float tickDelta) { + public void render(ControllerImpl controller, GuiGraphicsExtractor graphics, float tickDelta) { var vmouse = Controlify.instance().virtualMouseHandler(); this.render(controller, graphics, tickDelta, vmouse.isVirtualMouseEnabled() ? Optional.of(vmouse) : Optional.empty()); } @@ -99,7 +98,7 @@ public void onInputModeChanged(InputMode mode) { } } - protected void handleComponentNavigation(ControllerEntity controller) { + protected void handleComponentNavigation(ControllerImpl controller) { if (screen.getFocused() == null) { ((ScreenAccessor) screen).invokeSetInitialFocus(); } @@ -196,7 +195,7 @@ protected void handleComponentNavigation(ControllerEntity controller) { }; } - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { boolean vmouseEnabled = Controlify.instance().virtualMouseHandler().isVirtualMouseEnabled(); InputComponent input = controller.input().orElseThrow(); boolean touchpadPressed = input.stateNow().isButtonDown(GamepadInputs.TOUCHPAD_1_BUTTON); @@ -213,11 +212,11 @@ protected void handleButtons(ControllerEntity controller) { } } - protected void handleScreenVMouse(ControllerEntity controller, VirtualMouseHandler vmouse) { + protected void handleScreenVMouse(ControllerImpl controller, VirtualMouseHandler vmouse) { Minecraft.getInstance().setLastInputType(InputType.MOUSE); } - protected boolean handleComponentButtonOverride(ControllerEntity controller) { + protected boolean handleComponentButtonOverride(ControllerImpl controller) { var focusTree = getFocusTree(); while (!focusTree.isEmpty()) { var focused = focusTree.poll(); @@ -228,7 +227,7 @@ protected boolean handleComponentButtonOverride(ControllerEntity controller) { return false; } - protected boolean handleComponentNavOverride(ControllerEntity controller) { + protected boolean handleComponentNavOverride(ControllerImpl controller) { var focusTree = getFocusTree(); while (!focusTree.isEmpty()) { var focused = focusTree.poll(); @@ -238,7 +237,7 @@ protected boolean handleComponentNavOverride(ControllerEntity controller) { return false; } - protected void handleTabNavigation(ControllerEntity controller) { + protected void handleTabNavigation(ControllerImpl controller) { var nextTab = ControlifyBindings.GUI_NEXT_TAB.on(controller).justPressed(); var prevTab = ControlifyBindings.GUI_PREV_TAB.on(controller).justPressed(); @@ -262,7 +261,7 @@ protected void handleTabNavigation(ControllerEntity controller) { } } - protected void onTabChanged(ControllerEntity controller) { + protected void onTabChanged(ControllerImpl controller) { } @@ -282,7 +281,7 @@ public void onVirtualMouseToggled(boolean enabled) { } } - protected void render(ControllerEntity controller, GuiGraphicsExtractor graphics, float tickDelta, Optional vmouse) { + protected void render(ControllerImpl controller, GuiGraphicsExtractor graphics, float tickDelta, Optional vmouse) { } @@ -294,7 +293,7 @@ public void addEventListener(ScreenControllerEventListener listener) { eventListeners.add(listener); } - public boolean tryOpenKeyboard(ControllerEntity controller, @Nullable GuiEventListener element) { + public boolean tryOpenKeyboard(ControllerImpl controller, @Nullable GuiEventListener element) { var componentProcessor = ComponentProcessorProvider.provide(element); ComponentKeyboardBehaviour behaviour = componentProcessor.getKeyboardBehaviour(this, controller); diff --git a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessorFactory.java b/src/main/java/dev/isxander/controlify/impl/screenop/ScreenProcessorFactory.java similarity index 96% rename from src/main/java/dev/isxander/controlify/screenop/ScreenProcessorFactory.java rename to src/main/java/dev/isxander/controlify/impl/screenop/ScreenProcessorFactory.java index e828ad843..567acfdbe 100644 --- a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessorFactory.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/ScreenProcessorFactory.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop; +package dev.isxander.controlify.impl.screenop; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.client.gui.screens.Screen; diff --git a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessorProvider.java b/src/main/java/dev/isxander/controlify/impl/screenop/ScreenProcessorProvider.java similarity index 93% rename from src/main/java/dev/isxander/controlify/screenop/ScreenProcessorProvider.java rename to src/main/java/dev/isxander/controlify/impl/screenop/ScreenProcessorProvider.java index d472e2e09..d2c52c79f 100644 --- a/src/main/java/dev/isxander/controlify/screenop/ScreenProcessorProvider.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/ScreenProcessorProvider.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop; +package dev.isxander.controlify.impl.screenop; import net.minecraft.client.gui.screens.Screen; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/AbstractSliderComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/AbstractSliderComponentProcessor.java similarity index 67% rename from src/main/java/dev/isxander/controlify/screenop/compat/AbstractSliderComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/AbstractSliderComponentProcessor.java index 00ba690c4..95276c4d1 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/AbstractSliderComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/AbstractSliderComponentProcessor.java @@ -4,23 +4,23 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat; +package dev.isxander.controlify.impl.screenop.compat; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.utils.HoldRepeatHelper; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.utils.HoldRepeatHelper; /** * A component processor that handles incrementing and decrementing a slider. - * This uses {@link dev.isxander.controlify.bindings.ControllerBindings#CYCLE_OPT_FORWARD} and {@link dev.isxander.controlify.bindings.ControllerBindings#CYCLE_OPT_BACKWARD} to increment and decrement the slider. + * This uses {@link dev.isxander.controlify.impl.bindings.ControllerBindings#CYCLE_OPT_FORWARD} and {@link dev.isxander.controlify.impl.bindings.ControllerBindings#CYCLE_OPT_BACKWARD} to increment and decrement the slider. */ public abstract class AbstractSliderComponentProcessor implements ComponentProcessor { private final HoldRepeatHelper holdRepeatHelper = new HoldRepeatHelper(15, 3); @Override - public boolean overrideControllerNavigation(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerNavigation(ScreenProcessor screen, ControllerImpl controller) { var left = ControlifyBindings.GUI_SECONDARY_NAVI_LEFT.on(controller).digitalNow(); var leftPrev = ControlifyBindings.GUI_SECONDARY_NAVI_LEFT.on(controller).digitalPrev(); var right = ControlifyBindings.GUI_SECONDARY_NAVI_RIGHT.on(controller).digitalNow(); diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AbstractButtonComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AbstractButtonComponentProcessor.java similarity index 68% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AbstractButtonComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AbstractButtonComponentProcessor.java index b7aeb4503..06e96e3ce 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AbstractButtonComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AbstractButtonComponentProcessor.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.haptic.HapticEffects; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.haptic.HapticEffects; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.AbstractButton; import com.mojang.blaze3d.platform.InputConstants; @@ -24,7 +24,7 @@ public AbstractButtonComponentProcessor(AbstractButton button) { } @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { if (ControlifyBindings.GUI_PRESS.on(controller).guiPressed().get()) { controller.hdHaptics().ifPresent(hh -> hh.playHaptic(HapticEffects.NAVIGATE)); button.playDownSound(Minecraft.getInstance().getSoundManager()); diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AbstractContainerScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AbstractContainerScreenProcessor.java similarity index 83% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AbstractContainerScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AbstractContainerScreenProcessor.java index 4753536c1..bb0891943 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AbstractContainerScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AbstractContainerScreenProcessor.java @@ -4,22 +4,22 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.InputMode; +import dev.isxander.controlify.api.InputMode; import dev.isxander.controlify.api.ControlifyApi; import dev.isxander.controlify.api.contextual.ContainerContext; import dev.isxander.controlify.api.contextual.GuideInstance; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.contextual.ContextualDomains; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.haptic.HapticEffects; -import dev.isxander.controlify.gui.guide.GuideRenderer; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.contextual.ContextualDomains; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.haptic.HapticEffects; +import dev.isxander.controlify.impl.gui.guide.GuideRenderer; import dev.isxander.controlify.mixins.feature.guide.screen.AbstractContainerScreenAccessor; import dev.isxander.controlify.mixins.feature.screenop.ScreenAccessor; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.virtualmouse.VirtualMouseBehaviour; -import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseBehaviour; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseHandler; import net.minecraft.client.gui.components.Renderable; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; @@ -38,13 +38,13 @@ public class AbstractContainerScreenProcessor hoveredSlot; private final ClickSlotFunction clickSlotFunction; - private final Predicate doItemSlotActions; + private final Predicate doItemSlotActions; public AbstractContainerScreenProcessor( T screen, Supplier hoveredSlot, ClickSlotFunction clickSlotFunction, - Predicate doItemSlotActions + Predicate doItemSlotActions ) { super(screen); this.hoveredSlot = hoveredSlot; @@ -54,7 +54,7 @@ public AbstractContainerScreenProcessor( } @Override - protected void handleScreenVMouse(ControllerEntity controller, VirtualMouseHandler vmouse) { + protected void handleScreenVMouse(ControllerImpl controller, VirtualMouseHandler vmouse) { var accessor = (AbstractContainerScreenAccessor) screen; var ctx = new ContainerContext( @@ -147,7 +147,7 @@ public void onHoveredSlotChanged(Slot newSlot, Slot oldSlot) { } private void hapticNavigate() { - ControlifyApi.get().getCurrentController().flatMap(ControllerEntity::hdHaptics).ifPresent(hh -> { + ControlifyApi.get().getCurrentController().flatMap(ControllerImpl::hdHaptics).ifPresent(hh -> { hh.playHaptic(HapticEffects.NAVIGATE); }); } diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AbstractSignEditScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AbstractSignEditScreenProcessor.java similarity index 80% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AbstractSignEditScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AbstractSignEditScreenProcessor.java index 5ec4835ce..1c35109a8 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AbstractSignEditScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AbstractSignEditScreenProcessor.java @@ -4,20 +4,20 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.keyboard.CommonKeyboardHints; -import dev.isxander.controlify.screenop.keyboard.KeyboardWidget; -import dev.isxander.controlify.utils.LazyComponentDims; -import dev.isxander.controlify.utils.PrecomputedComponentDims; -import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; +package dev.isxander.controlify.impl.screenop.compat.vanilla; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.InputMode; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.keyboard.CommonKeyboardHints; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardWidget; +import dev.isxander.controlify.impl.utils.LazyComponentDims; +import dev.isxander.controlify.impl.utils.PrecomputedComponentDims; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseHandler; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.AbstractButton; import net.minecraft.client.gui.screens.inventory.AbstractSignEditScreen; @@ -56,7 +56,7 @@ public AbstractSignEditScreenProcessor( } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { super.handleButtons(controller); var config = controller.settings().generic; @@ -87,7 +87,7 @@ protected void handleButtons(ControllerEntity controller) { } @Override - protected void render(ControllerEntity controller, GuiGraphicsExtractor graphics, float tickDelta, Optional vmouse) { + protected void render(ControllerImpl controller, GuiGraphicsExtractor graphics, float tickDelta, Optional vmouse) { var config = controller.settings().generic; KeyboardWidget keyboardWidget = this.keyboardWidgetSupplier.get(); if (keyboardWidget != null && config.guide.showScreenGuides) { diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AddServerLikeScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AddServerLikeScreenProcessor.java similarity index 77% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AddServerLikeScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AddServerLikeScreenProcessor.java index f0eeda1c9..323a2e867 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/AddServerLikeScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/AddServerLikeScreenProcessor.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.keyboard.KeyboardLayouts; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardLayouts; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; @@ -70,7 +70,7 @@ public void onWidgetRebuild() { } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { if (ControlifyBindings.GUI_ABSTRACT_ACTION_1.on(controller).guiPressed().get()) { Button doneButton = doneButtonSupplier.get(); if (doneButton != null && !doneButton.isFocused()) { diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/BundleItemSlotControllerAction.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/BundleItemSlotControllerAction.java similarity index 89% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/BundleItemSlotControllerAction.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/BundleItemSlotControllerAction.java index 42795f07f..060caac87 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/BundleItemSlotControllerAction.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/BundleItemSlotControllerAction.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.util.Mth; import net.minecraft.world.item.BundleItem; import net.minecraft.world.item.ItemStack; @@ -17,7 +17,7 @@ public class BundleItemSlotControllerAction { public static boolean onControllerInput( ItemStack stack, int hoveredSlotIndex, - ControllerEntity controller, + ControllerImpl controller, SelectedBundleItemConsumer consumer ) { int uniqueItems = BundleItem.getNumberOfItemsToShow(stack); diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/ChatScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/ChatScreenProcessor.java similarity index 81% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/ChatScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/ChatScreenProcessor.java index 52ca35e56..4915d22ca 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/ChatScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/ChatScreenProcessor.java @@ -4,19 +4,19 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.keyboard.ComponentKeyboardBehaviour; -import dev.isxander.controlify.screenop.keyboard.CommonKeyboardHints; -import dev.isxander.controlify.screenop.keyboard.KeyboardWidget; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.utils.HoldRepeatHelper; -import dev.isxander.controlify.utils.LazyComponentDims; -import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; +package dev.isxander.controlify.impl.screenop.compat.vanilla; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.keyboard.ComponentKeyboardBehaviour; +import dev.isxander.controlify.impl.screenop.keyboard.CommonKeyboardHints; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardWidget; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.utils.HoldRepeatHelper; +import dev.isxander.controlify.impl.utils.LazyComponentDims; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseHandler; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.ChatScreen; @@ -54,7 +54,7 @@ public ChatScreenProcessor( } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { super.handleButtons(controller); CmdSuggestionsController suggestionsController = this.suggestionsController.get(); @@ -93,7 +93,7 @@ protected void handleButtons(ControllerEntity controller) { } @Override - protected void render(ControllerEntity controller, GuiGraphicsExtractor graphics, float tickDelta, Optional vmouse) { + protected void render(ControllerImpl controller, GuiGraphicsExtractor graphics, float tickDelta, Optional vmouse) { var settings = controller.settings().generic; if (this.keyboardSupplier.get() != null && settings.guide.showScreenGuides) { @@ -133,7 +133,7 @@ public void onWidgetRebuild() { } } - private void clearCommandSuggesterHint(ControllerEntity controller) { + private void clearCommandSuggesterHint(ControllerImpl controller) { var settings = controller.settings().generic; if (settings.keyboard.hintCommandSuggester && settings.guide.showScreenGuides) { settings.keyboard.hintCommandSuggester = false; diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/CreateWorldScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/CreateWorldScreenProcessor.java similarity index 67% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/CreateWorldScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/CreateWorldScreenProcessor.java index 0ca837e28..e8ee85fa7 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/CreateWorldScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/CreateWorldScreenProcessor.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; public class CreateWorldScreenProcessor extends ScreenProcessor { @@ -20,7 +20,7 @@ public CreateWorldScreenProcessor(CreateWorldScreen screen, Runnable onCreateBut } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { if (ControlifyBindings.GUI_ABSTRACT_ACTION_1.on(controller).justPressed()) { playClackSound(); this.onCreateButton.run(); diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/CreativeModeInventoryScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/CreativeModeInventoryScreenProcessor.java similarity index 77% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/CreativeModeInventoryScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/CreativeModeInventoryScreenProcessor.java index d35252b1d..0542dad4e 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/CreativeModeInventoryScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/CreativeModeInventoryScreenProcessor.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.platform.client.CreativeTabHelper; -import dev.isxander.controlify.platform.client.PlatformClientUtil; -import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.platform.client.CreativeTabHelper; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseHandler; import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.CreativeModeTab; @@ -23,7 +23,7 @@ public class CreativeModeInventoryScreenProcessor extends AbstractContainerScreenProcessor { private final CreativeTabHelper tabHelper; - public CreativeModeInventoryScreenProcessor(CreativeModeInventoryScreen screen, Supplier hoveredSlot, ClickSlotFunction clickSlotFunction, Predicate itemSlotAction) { + public CreativeModeInventoryScreenProcessor(CreativeModeInventoryScreen screen, Supplier hoveredSlot, ClickSlotFunction clickSlotFunction, Predicate itemSlotAction) { super(screen, hoveredSlot, clickSlotFunction, itemSlotAction); this.tabHelper = PlatformClientUtil.createCreativeTabHelper(screen); } @@ -36,7 +36,7 @@ public void onWidgetRebuild() { @SuppressWarnings("UnreachableCode") @Override - protected void handleScreenVMouse(ControllerEntity controller, VirtualMouseHandler vmouse) { + protected void handleScreenVMouse(ControllerImpl controller, VirtualMouseHandler vmouse) { List tabs = tabHelper.getTabsForPage(tabHelper.getCurrentPage()); if (ControlifyBindings.GUI_NEXT_TAB.on(controller).justPressed()) { int newIndex = tabs.indexOf(tabHelper.getSelectedTab()) + 1; diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/EditBoxComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/EditBoxComponentProcessor.java similarity index 90% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/EditBoxComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/EditBoxComponentProcessor.java index 4f71ff0c6..11d5897c6 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/EditBoxComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/EditBoxComponentProcessor.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.keyboard.*; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.keyboard.*; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.input.CharacterEvent; @@ -40,7 +40,7 @@ public EditBoxComponentProcessor(EditBox editBox, int screenWidth, int screenHei } @Override - public ComponentKeyboardBehaviour getKeyboardBehaviour(ScreenProcessor screen, ControllerEntity controller) { + public ComponentKeyboardBehaviour getKeyboardBehaviour(ScreenProcessor screen, ControllerImpl controller) { return this.getKeyboardBehaviour(); } diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/ItemSlotControllerAction.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/ItemSlotControllerAction.java similarity index 71% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/ItemSlotControllerAction.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/ItemSlotControllerAction.java index c08d1ab2e..d3f59852b 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/ItemSlotControllerAction.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/ItemSlotControllerAction.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.client.gui.ItemSlotMouseAction; import net.minecraft.world.item.ItemStack; @@ -14,6 +14,6 @@ public interface ItemSlotControllerAction extends ItemSlotMouseAction { boolean controlify$onControllerInput( ItemStack stack, int hoveredSlotIndex, - ControllerEntity controller + ControllerImpl controller ); } diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/JoinMultiplayerScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/JoinMultiplayerScreenProcessor.java similarity index 86% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/JoinMultiplayerScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/JoinMultiplayerScreenProcessor.java index b91e99d8e..feee12cd0 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/JoinMultiplayerScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/JoinMultiplayerScreenProcessor.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; import net.minecraft.client.gui.screens.multiplayer.ServerSelectionList; @@ -38,7 +38,7 @@ public JoinMultiplayerScreenProcessor( } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { if (screen.getFocused() != null && screen.getFocused() instanceof Button) { if (ControlifyBindings.GUI_BACK.on(controller).guiPressed().get()) { screen.setFocused(listSupplier.get()); diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/LanguageSelectionListComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/LanguageSelectionListComponentProcessor.java similarity index 72% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/LanguageSelectionListComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/LanguageSelectionListComponentProcessor.java index b0e520707..e4c0d61c9 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/LanguageSelectionListComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/LanguageSelectionListComponentProcessor.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; import dev.isxander.controlify.mixins.feature.screenop.impl.outofgame.OptionsSubScreenAccessor; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.Minecraft; public class LanguageSelectionListComponentProcessor implements ComponentProcessor { @@ -22,7 +22,7 @@ public LanguageSelectionListComponentProcessor(String code) { } @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { if (ControlifyBindings.GUI_PRESS.on(controller).justPressed()) { var minecraft = Minecraft.getInstance(); var languageManager = minecraft.getLanguageManager(); diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/OptionsScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/OptionsScreenProcessor.java similarity index 73% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/OptionsScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/OptionsScreenProcessor.java index 3bcec8dd0..02998f467 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/OptionsScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/OptionsScreenProcessor.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.options.OptionsScreen; diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/OptionsSubScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/OptionsSubScreenProcessor.java similarity index 73% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/OptionsSubScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/OptionsSubScreenProcessor.java index 3a1f61e49..8ee0e326c 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/OptionsSubScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/OptionsSubScreenProcessor.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.options.OptionsSubScreen; diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/PauseScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/PauseScreenProcessor.java similarity index 81% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/PauseScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/PauseScreenProcessor.java index 5d99796d3..bcabb2fd6 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/PauseScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/PauseScreenProcessor.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; import dev.isxander.controlify.mixins.feature.screenop.impl.outofgame.PauseScreenAccessor; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.gui.components.AbstractButton; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.options.OptionsScreen; @@ -30,7 +30,7 @@ public PauseScreenProcessor(PauseScreen screen, Supplier<@Nullable Button> disco } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { super.handleButtons(controller); if (ControlifyBindings.GUI_ABSTRACT_ACTION_1.on(controller).justPressed()) { diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/RecipeBookScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/RecipeBookScreenProcessor.java similarity index 88% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/RecipeBookScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/RecipeBookScreenProcessor.java index 61187d063..84e6e4065 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/RecipeBookScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/RecipeBookScreenProcessor.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; import com.mojang.blaze3d.platform.InputConstants; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; import dev.isxander.controlify.mixins.feature.virtualmouse.snapping.RecipeBookComponentAccessor; import dev.isxander.controlify.mixins.feature.virtualmouse.snapping.RecipeBookPageAccessor; -import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseHandler; import net.minecraft.client.gui.components.ImageButton; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; import net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton; @@ -34,14 +34,14 @@ public RecipeBookScreenProcessor( RecipeBookScreenAccessor recipeBookScreenAccessor, Supplier hoveredSlot, ClickSlotFunction clickSlotFunction, - Predicate doItemSlotActions + Predicate doItemSlotActions ) { super(screen, hoveredSlot, clickSlotFunction, doItemSlotActions); this.recipeBookScreenAccessor = recipeBookScreenAccessor; } @Override - protected void handleScreenVMouse(ControllerEntity controller, VirtualMouseHandler vmouse) { + protected void handleScreenVMouse(ControllerImpl controller, VirtualMouseHandler vmouse) { super.handleScreenVMouse(controller, vmouse); RecipeBookComponent recipeBookComponent = recipeBookScreenAccessor.controlify$getRecipeBookComponent(); diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/SelectWorldScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/SelectWorldScreenProcessor.java similarity index 76% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/SelectWorldScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/SelectWorldScreenProcessor.java index 776beed79..854a4c1ba 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/SelectWorldScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/SelectWorldScreenProcessor.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import dev.isxander.controlify.mixins.feature.screenop.impl.outofgame.SelectWorldScreenAccessor; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; @@ -22,7 +22,7 @@ public SelectWorldScreenProcessor(SelectWorldScreen screen) { } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { if (ControlifyBindings.GUI_ABSTRACT_ACTION_1.on(controller).justPressed()) { playClackSound(); var minecraft = Minecraft.getInstance(); diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/ServerSelectionListEntryComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/ServerSelectionListEntryComponentProcessor.java similarity index 63% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/ServerSelectionListEntryComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/ServerSelectionListEntryComponentProcessor.java index 46cfb2ea5..5aec5e5f0 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/ServerSelectionListEntryComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/ServerSelectionListEntryComponentProcessor.java @@ -4,17 +4,17 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; import dev.isxander.controlify.mixins.feature.screenop.impl.outofgame.JoinMultiplayerScreenAccessor; public class ServerSelectionListEntryComponentProcessor implements ComponentProcessor { @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { if (ControlifyBindings.GUI_PRESS.on(controller).guiPressed().get()) { screen.screen.setFocused(((JoinMultiplayerScreenAccessor) screen.screen).controlify$getJoinButton()); return true; diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/SliderComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/SliderComponentProcessor.java similarity index 83% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/SliderComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/SliderComponentProcessor.java index d23c8ec08..90dc8057a 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/SliderComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/SliderComponentProcessor.java @@ -4,13 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; import com.mojang.blaze3d.platform.InputConstants; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; import net.minecraft.client.gui.components.AbstractSliderButton; import net.minecraft.client.input.KeyEvent; @@ -33,7 +33,7 @@ public SliderComponentProcessor(AbstractSliderButton component, Supplier screen, ControllerEntity controller) { + public boolean overrideControllerNavigation(ScreenProcessor screen, ControllerImpl controller) { if (!this.canChangeValueGetter.get()) return false; var canSliderChange = ++lastSliderChange > SLIDER_CHANGE_DELAY; @@ -58,7 +58,7 @@ public boolean overrideControllerNavigation(ScreenProcessor screen, Controlle } @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { if (!this.canChangeValueGetter.get()) return false; if (ControlifyBindings.GUI_BACK.on(controller).justPressed()) { @@ -70,7 +70,7 @@ public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEn } @Override - public void onFocusGained(ScreenProcessor screen, ControllerEntity controller) { + public void onFocusGained(ScreenProcessor screen, ControllerImpl controller) { this.canChangeValueSetter.accept(false); } } diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/TitleScreenProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/TitleScreenProcessor.java similarity index 75% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/TitleScreenProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/TitleScreenProcessor.java index 95715778b..d5ff4a4d0 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/TitleScreenProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/TitleScreenProcessor.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.gui.components.AbstractButton; import net.minecraft.client.gui.screens.options.OptionsScreen; import net.minecraft.client.gui.screens.TitleScreen; @@ -22,7 +22,7 @@ public TitleScreenProcessor(TitleScreen screen) { } @Override - protected void handleButtons(ControllerEntity controller) { + protected void handleButtons(ControllerImpl controller) { if (ControlifyBindings.GUI_BACK.on(controller).justPressed()) { getWidget("menu.quit").ifPresent(widget -> { screen.setFocused(widget); diff --git a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/WorldListEntryComponentProcessor.java b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/WorldListEntryComponentProcessor.java similarity index 67% rename from src/main/java/dev/isxander/controlify/screenop/compat/vanilla/WorldListEntryComponentProcessor.java rename to src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/WorldListEntryComponentProcessor.java index 35d7324eb..ca505e3ca 100644 --- a/src/main/java/dev/isxander/controlify/screenop/compat/vanilla/WorldListEntryComponentProcessor.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/compat/vanilla/WorldListEntryComponentProcessor.java @@ -4,18 +4,18 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.compat.vanilla; +package dev.isxander.controlify.impl.screenop.compat.vanilla; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; import dev.isxander.controlify.mixins.feature.screenop.impl.outofgame.SelectWorldScreenAccessor; import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen; public class WorldListEntryComponentProcessor implements ComponentProcessor { @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { if (ControlifyBindings.GUI_PRESS.on(controller).guiPressed().get()) { var selectWorldScreen = (SelectWorldScreen) screen.screen; selectWorldScreen.setFocused(((SelectWorldScreenAccessor) selectWorldScreen).controlify$getPlayWorldButton()); diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/ChatKeyboardDucky.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/ChatKeyboardDucky.java similarity index 87% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/ChatKeyboardDucky.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/ChatKeyboardDucky.java index 3d297b666..573da02a9 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/ChatKeyboardDucky.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/ChatKeyboardDucky.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; import net.minecraft.client.gui.screens.ChatScreen; diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/CommonKeyboardHints.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/CommonKeyboardHints.java similarity index 79% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/CommonKeyboardHints.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/CommonKeyboardHints.java index 7a215fbef..d3bf8e35f 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/CommonKeyboardHints.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/CommonKeyboardHints.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.utils.LazyComponentDims; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.utils.LazyComponentDims; import net.minecraft.network.chat.Component; public final class CommonKeyboardHints { diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/ComponentKeyboardBehaviour.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/ComponentKeyboardBehaviour.java similarity index 90% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/ComponentKeyboardBehaviour.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/ComponentKeyboardBehaviour.java index 07420dc38..e7e0371a7 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/ComponentKeyboardBehaviour.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/ComponentKeyboardBehaviour.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; /** * Represents the behaviour of a GUI component with respect to keyboard input. - * This is used by {@link dev.isxander.controlify.screenop.ScreenProcessor} to + * This is used by {@link dev.isxander.controlify.impl.screenop.ScreenProcessor} to * determine how/if to open a keyboard for this component when it is pressed. */ public sealed interface ComponentKeyboardBehaviour { diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/FallbackKeyboardLayout.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/FallbackKeyboardLayout.java similarity index 83% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/FallbackKeyboardLayout.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/FallbackKeyboardLayout.java index 72c6100af..d586e974f 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/FallbackKeyboardLayout.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/FallbackKeyboardLayout.java @@ -4,19 +4,19 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.api.bind.InputBindingSupplier; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Optional; -import static dev.isxander.controlify.screenop.keyboard.KeyboardLayout.Key; -import static dev.isxander.controlify.screenop.keyboard.KeyboardLayout.KeyFunction.*; +import static dev.isxander.controlify.impl.screenop.keyboard.KeyboardLayout.Key; +import static dev.isxander.controlify.impl.screenop.keyboard.KeyboardLayout.KeyFunction.*; /** * A code-defined fallback keyboard layout if the resource-pack driven ones diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/InputTarget.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/InputTarget.java similarity index 97% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/InputTarget.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/InputTarget.java index 0fc082b4a..419f56d11 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/InputTarget.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/InputTarget.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; /** * Represents a target/consumer for keyboard input. diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyWidget.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyWidget.java similarity index 93% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/KeyWidget.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyWidget.java index 75ba270ee..9151926cd 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyWidget.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyWidget.java @@ -4,19 +4,19 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; import com.mojang.blaze3d.platform.InputConstants; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.font.BindingFontHelper; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenControllerEventListener; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.HoldRepeatHelper; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.font.BindingFontHelper; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenControllerEventListener; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.HoldRepeatHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.AbstractWidget; @@ -116,7 +116,7 @@ protected void extractWidgetRenderState(@NonNull GuiGraphicsExtractor graphics, } @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { var guiPress = ControlifyBindings.GUI_PRESS.on(controller); // this means if you were holding the button down and navigated to this key, @@ -138,7 +138,7 @@ public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEn } @Override - public void onControllerInput(ControllerEntity controller) { + public void onControllerInput(ControllerImpl controller) { this.key.shortcutBinding().ifPresent(supplier -> { InputBinding shortcutBinding = supplier.on(controller); diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayout.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayout.java similarity index 98% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayout.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayout.java index 2173a0a46..ee02c6fd5 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayout.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayout.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Pair; @@ -12,8 +12,8 @@ import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.codecs.RecordCodecBuilder; -import dev.isxander.controlify.api.bind.InputBindingSupplier; -import dev.isxander.controlify.utils.codec.CExtraCodecs; +import dev.isxander.controlify.impl.api.bind.InputBindingSupplier; +import dev.isxander.controlify.impl.utils.codec.CExtraCodecs; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.ComponentSerialization; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayoutManager.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayoutManager.java similarity index 93% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayoutManager.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayoutManager.java index 5c4485523..67cbd594b 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayoutManager.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayoutManager.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.platform.client.resource.SimpleControlifyReloadListener; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.log.ControlifyLogger; +import dev.isxander.controlify.impl.platform.client.resource.SimpleControlifyReloadListener; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; import net.minecraft.util.Util; import net.minecraft.client.Minecraft; import net.minecraft.resources.Identifier; @@ -30,7 +30,7 @@ */ public class KeyboardLayoutManager implements SimpleControlifyReloadListener { - private static final String PREFIX = "keyboard_layout"; + private static final String PREFIX = "controller/keyboard_layout"; private static final ControlifyLogger LOGGER = CUtil.LOGGER.createSubLogger("KeyboardLayoutManager"); private Map layouts = Map.of(); diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayoutWithId.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayoutWithId.java similarity index 89% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayoutWithId.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayoutWithId.java index 3ddb18786..3a180ec4b 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayoutWithId.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayoutWithId.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayouts.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayouts.java similarity index 88% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayouts.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayouts.java index 76a37a142..a6a1e6c5d 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardLayouts.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardLayouts.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; /** diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardOverlayScreen.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardOverlayScreen.java similarity index 97% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardOverlayScreen.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardOverlayScreen.java index dfdde2771..54fcd4979 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardOverlayScreen.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardOverlayScreen.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; import com.mojang.blaze3d.platform.InputConstants; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import dev.isxander.controlify.mixins.feature.screenop.GuiMixin; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.navigation.ScreenAxis; import net.minecraft.client.gui.navigation.ScreenRectangle; diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardWidget.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardWidget.java similarity index 95% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardWidget.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardWidget.java index cc28107fd..67a3c5006 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/KeyboardWidget.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/KeyboardWidget.java @@ -4,15 +4,15 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; import com.google.common.collect.ImmutableList; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.utils.HoldRepeatHelper; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.utils.HoldRepeatHelper; import net.minecraft.client.gui.ComponentPath; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.AbstractWidget; @@ -147,7 +147,7 @@ protected void extractWidgetRenderState(@NonNull GuiGraphicsExtractor graphics, } @Override - public boolean overrideControllerButtons(ScreenProcessor screen, ControllerEntity controller) { + public boolean overrideControllerButtons(ScreenProcessor screen, ControllerImpl controller) { InputTarget inputTarget = this.getInputTarget(); var settings = controller.settings().generic; diff --git a/src/main/java/dev/isxander/controlify/screenop/keyboard/MixinInputTarget.java b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/MixinInputTarget.java similarity index 96% rename from src/main/java/dev/isxander/controlify/screenop/keyboard/MixinInputTarget.java rename to src/main/java/dev/isxander/controlify/impl/screenop/keyboard/MixinInputTarget.java index 976db419a..b94c1668a 100644 --- a/src/main/java/dev/isxander/controlify/screenop/keyboard/MixinInputTarget.java +++ b/src/main/java/dev/isxander/controlify/impl/screenop/keyboard/MixinInputTarget.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.screenop.keyboard; +package dev.isxander.controlify.impl.screenop.keyboard; /** * A wrapper to {@link InputTarget} to add alternative method names, diff --git a/src/main/java/dev/isxander/controlify/server/ControlifyHandshake.java b/src/main/java/dev/isxander/controlify/impl/server/ControlifyHandshake.java similarity index 89% rename from src/main/java/dev/isxander/controlify/server/ControlifyHandshake.java rename to src/main/java/dev/isxander/controlify/impl/server/ControlifyHandshake.java index 950771ee9..ed0cd697b 100644 --- a/src/main/java/dev/isxander/controlify/server/ControlifyHandshake.java +++ b/src/main/java/dev/isxander/controlify/impl/server/ControlifyHandshake.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server; +package dev.isxander.controlify.impl.server; import com.mojang.logging.LogUtils; -import dev.isxander.controlify.platform.client.PlatformClientUtil; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.ChatFormatting; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; diff --git a/src/main/java/dev/isxander/controlify/server/ControlifyServer.java b/src/main/java/dev/isxander/controlify/impl/server/ControlifyServer.java similarity index 91% rename from src/main/java/dev/isxander/controlify/server/ControlifyServer.java rename to src/main/java/dev/isxander/controlify/impl/server/ControlifyServer.java index a381e9f31..5b0b0f5d1 100644 --- a/src/main/java/dev/isxander/controlify/server/ControlifyServer.java +++ b/src/main/java/dev/isxander/controlify/impl/server/ControlifyServer.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server; +package dev.isxander.controlify.impl.server; -import dev.isxander.controlify.platform.network.SidedNetworkApi; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.server.packets.*; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.platform.network.SidedNetworkApi; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.server.packets.*; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.server.level.ServerPlayer; import org.jetbrains.annotations.VisibleForTesting; diff --git a/src/main/java/dev/isxander/controlify/server/ControlifyServerConfig.java b/src/main/java/dev/isxander/controlify/impl/server/ControlifyServerConfig.java similarity index 84% rename from src/main/java/dev/isxander/controlify/server/ControlifyServerConfig.java rename to src/main/java/dev/isxander/controlify/impl/server/ControlifyServerConfig.java index ce61501df..66fc2f412 100644 --- a/src/main/java/dev/isxander/controlify/server/ControlifyServerConfig.java +++ b/src/main/java/dev/isxander/controlify/impl/server/ControlifyServerConfig.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server; +package dev.isxander.controlify.impl.server; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.utils.CUtil; import dev.isxander.yacl3.config.v2.api.ConfigClassHandler; import dev.isxander.yacl3.config.v2.api.SerialEntry; import dev.isxander.yacl3.config.v2.api.serializer.GsonConfigSerializerBuilder; diff --git a/src/main/java/dev/isxander/controlify/server/ServerPolicies.java b/src/main/java/dev/isxander/controlify/impl/server/ServerPolicies.java similarity index 96% rename from src/main/java/dev/isxander/controlify/server/ServerPolicies.java rename to src/main/java/dev/isxander/controlify/impl/server/ServerPolicies.java index 0b9125bd0..40b20ccef 100644 --- a/src/main/java/dev/isxander/controlify/server/ServerPolicies.java +++ b/src/main/java/dev/isxander/controlify/impl/server/ServerPolicies.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server; +package dev.isxander.controlify.impl.server; import java.util.Arrays; import java.util.Map; diff --git a/src/main/java/dev/isxander/controlify/server/ServerPolicy.java b/src/main/java/dev/isxander/controlify/impl/server/ServerPolicy.java similarity index 88% rename from src/main/java/dev/isxander/controlify/server/ServerPolicy.java rename to src/main/java/dev/isxander/controlify/impl/server/ServerPolicy.java index bb7494013..8ece3cdae 100644 --- a/src/main/java/dev/isxander/controlify/server/ServerPolicy.java +++ b/src/main/java/dev/isxander/controlify/impl/server/ServerPolicy.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server; +package dev.isxander.controlify.impl.server; public enum ServerPolicy { ALLOWED, diff --git a/src/main/java/dev/isxander/controlify/server/VibrateCommand.java b/src/main/java/dev/isxander/controlify/impl/server/VibrateCommand.java similarity index 87% rename from src/main/java/dev/isxander/controlify/server/VibrateCommand.java rename to src/main/java/dev/isxander/controlify/impl/server/VibrateCommand.java index e723f5403..9be937abb 100644 --- a/src/main/java/dev/isxander/controlify/server/VibrateCommand.java +++ b/src/main/java/dev/isxander/controlify/impl/server/VibrateCommand.java @@ -4,25 +4,21 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server; +package dev.isxander.controlify.impl.server; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.FloatArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType; -import com.mojang.brigadier.suggestion.SuggestionProvider; -import dev.isxander.controlify.platform.network.SidedNetworkApi; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; -import dev.isxander.controlify.server.packets.EntityVibrationPacket; -import dev.isxander.controlify.server.packets.OriginVibrationPacket; -import dev.isxander.controlify.server.packets.VibrationPacket; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.platform.network.SidedNetworkApi; +import dev.isxander.controlify.impl.controller.rumble.RumbleSource; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.server.packets.EntityVibrationPacket; +import dev.isxander.controlify.impl.server.packets.OriginVibrationPacket; +import dev.isxander.controlify.impl.server.packets.VibrationPacket; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; -import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.commands.arguments.EntityArgument; import net.minecraft.commands.arguments.coordinates.Vec3Argument; -import net.minecraft.commands.synchronization.SuggestionProviders; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; @@ -33,16 +29,6 @@ import java.util.Locale; public class VibrateCommand { - private static final SuggestionProvider SOURCES_SUGGESTION = SuggestionProviders.register( - CUtil.rl("vibration_sources"), - (context, builder) -> SharedSuggestionProvider.suggestResource( - RumbleSource.values().stream() - .map(RumbleSource::id) - .toList(), - builder - ) - ); - public static void register(CommandDispatcher dispatcher) { dispatcher.register( Commands.literal("vibratecontroller") diff --git a/src/main/java/dev/isxander/controlify/server/packets/EntityVibrationPacket.java b/src/main/java/dev/isxander/controlify/impl/server/packets/EntityVibrationPacket.java similarity index 70% rename from src/main/java/dev/isxander/controlify/server/packets/EntityVibrationPacket.java rename to src/main/java/dev/isxander/controlify/impl/server/packets/EntityVibrationPacket.java index 7e3316ed6..a779bf497 100644 --- a/src/main/java/dev/isxander/controlify/server/packets/EntityVibrationPacket.java +++ b/src/main/java/dev/isxander/controlify/impl/server/packets/EntityVibrationPacket.java @@ -4,14 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server.packets; +package dev.isxander.controlify.impl.server.packets; -import dev.isxander.controlify.rumble.ContinuousRumbleEffect; -import dev.isxander.controlify.rumble.RumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.Easings; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.controller.rumble.RumbleSource; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.Easings; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; @@ -34,16 +33,15 @@ public record EntityVibrationPacket(int entityId, float range, int duration, Rum buf.readFloat(), buf.readInt(), RumbleState.unpackFromInt(buf.readInt()), - RumbleSource.get(buf.readIdentifier()) + new RumbleSource(buf.readIdentifier()) ) ); public RumbleEffect createEffect() { Entity entity = Minecraft.getInstance().level.getEntity(entityId); - return ContinuousRumbleEffect.builder() - .constant(state) + return RumbleEffect.continuous() + .constant(state.strong(), state.weak()) .inWorld(entity::position, 0, 1, range, Easings.toFloat(Easings::easeInSine)) - .timeout(duration) - .build(); + .timeout(duration); } } diff --git a/src/main/java/dev/isxander/controlify/server/packets/OriginVibrationPacket.java b/src/main/java/dev/isxander/controlify/impl/server/packets/OriginVibrationPacket.java similarity index 70% rename from src/main/java/dev/isxander/controlify/server/packets/OriginVibrationPacket.java rename to src/main/java/dev/isxander/controlify/impl/server/packets/OriginVibrationPacket.java index 950c4f850..84827c2e5 100644 --- a/src/main/java/dev/isxander/controlify/server/packets/OriginVibrationPacket.java +++ b/src/main/java/dev/isxander/controlify/impl/server/packets/OriginVibrationPacket.java @@ -4,14 +4,13 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server.packets; +package dev.isxander.controlify.impl.server.packets; -import dev.isxander.controlify.rumble.ContinuousRumbleEffect; -import dev.isxander.controlify.rumble.RumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; -import dev.isxander.controlify.utils.CUtil; -import dev.isxander.controlify.utils.Easings; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.controller.rumble.RumbleSource; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.Easings; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.Identifier; @@ -34,16 +33,15 @@ public record OriginVibrationPacket(Vector3f origin, float effectRange, int dura buf.readFloat(), buf.readVarInt(), RumbleState.unpackFromInt(buf.readInt()), - RumbleSource.get(buf.readIdentifier()) + new RumbleSource(buf.readIdentifier()) ) ); public RumbleEffect createEffect() { var originVec3 = new Vec3(origin); - return ContinuousRumbleEffect.builder() - .constant(state) + return RumbleEffect.continuous() + .constant(state.strong(), state.weak()) .inWorld(() -> originVec3, 0, 1, effectRange, Easings.toFloat(Easings::easeInSine)) - .timeout(duration) - .build(); + .timeout(duration); } } diff --git a/src/main/java/dev/isxander/controlify/server/packets/ServerPolicyPacket.java b/src/main/java/dev/isxander/controlify/impl/server/packets/ServerPolicyPacket.java similarity index 86% rename from src/main/java/dev/isxander/controlify/server/packets/ServerPolicyPacket.java rename to src/main/java/dev/isxander/controlify/impl/server/packets/ServerPolicyPacket.java index e96679ed9..f6d6ecc20 100644 --- a/src/main/java/dev/isxander/controlify/server/packets/ServerPolicyPacket.java +++ b/src/main/java/dev/isxander/controlify/impl/server/packets/ServerPolicyPacket.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server.packets; +package dev.isxander.controlify.impl.server.packets; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.Identifier; diff --git a/src/main/java/dev/isxander/controlify/server/packets/VibrationPacket.java b/src/main/java/dev/isxander/controlify/impl/server/packets/VibrationPacket.java similarity index 67% rename from src/main/java/dev/isxander/controlify/server/packets/VibrationPacket.java rename to src/main/java/dev/isxander/controlify/impl/server/packets/VibrationPacket.java index 5c5708a44..ea3397697 100644 --- a/src/main/java/dev/isxander/controlify/server/packets/VibrationPacket.java +++ b/src/main/java/dev/isxander/controlify/impl/server/packets/VibrationPacket.java @@ -4,13 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.server.packets; +package dev.isxander.controlify.impl.server.packets; -import dev.isxander.controlify.rumble.BasicRumbleEffect; -import dev.isxander.controlify.rumble.RumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.controller.rumble.RumbleSource; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; @@ -28,7 +27,7 @@ public record VibrationPacket(RumbleSource source, RumbleState[] frames) { } }, buf -> { - RumbleSource source = RumbleSource.get(buf.readIdentifier()); + RumbleSource source = new RumbleSource(buf.readIdentifier()); RumbleState[] frames = new RumbleState[buf.readInt()]; for (int i = 0; i < frames.length; i++) { frames[i] = RumbleState.unpackFromInt(buf.readInt()); @@ -38,6 +37,6 @@ public record VibrationPacket(RumbleSource source, RumbleState[] frames) { ); public RumbleEffect createEffect() { - return new BasicRumbleEffect(frames).earlyFinish(() -> Minecraft.getInstance().level == null); + return RumbleEffect.finite().byTick(tick -> frames[tick], frames.length).stopCondition(() -> Minecraft.getInstance().level == null); } } diff --git a/src/main/java/dev/isxander/controlify/sound/ControlifyClientSounds.java b/src/main/java/dev/isxander/controlify/impl/sound/ControlifyClientSounds.java similarity index 89% rename from src/main/java/dev/isxander/controlify/sound/ControlifyClientSounds.java rename to src/main/java/dev/isxander/controlify/impl/sound/ControlifyClientSounds.java index add2833f1..f2d7ea12c 100644 --- a/src/main/java/dev/isxander/controlify/sound/ControlifyClientSounds.java +++ b/src/main/java/dev/isxander/controlify/impl/sound/ControlifyClientSounds.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.sound; +package dev.isxander.controlify.impl.sound; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvent; diff --git a/src/main/java/dev/isxander/controlify/utils/CUtil.java b/src/main/java/dev/isxander/controlify/impl/utils/CUtil.java similarity index 94% rename from src/main/java/dev/isxander/controlify/utils/CUtil.java rename to src/main/java/dev/isxander/controlify/impl/utils/CUtil.java index 31ecbc478..cee65883f 100644 --- a/src/main/java/dev/isxander/controlify/utils/CUtil.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/CUtil.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import com.mojang.blaze3d.Blaze3D; -import dev.isxander.controlify.platform.client.PlatformClientUtil; -import dev.isxander.controlify.utils.log.ControlifyLogger; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.utils.log.ControlifyLogger; import net.minecraft.core.HolderSet; import net.minecraft.core.TypedInstance; import net.minecraft.util.Util; @@ -18,7 +18,6 @@ import org.apache.commons.codec.binary.Hex; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.net.URI; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; diff --git a/src/main/java/dev/isxander/controlify/utils/ColorUtils.java b/src/main/java/dev/isxander/controlify/impl/utils/ColorUtils.java similarity index 91% rename from src/main/java/dev/isxander/controlify/utils/ColorUtils.java rename to src/main/java/dev/isxander/controlify/impl/utils/ColorUtils.java index a42520d28..e716ce941 100644 --- a/src/main/java/dev/isxander/controlify/utils/ColorUtils.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/ColorUtils.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import net.minecraft.util.Mth; diff --git a/src/main/java/dev/isxander/controlify/utils/ControllerUtils.java b/src/main/java/dev/isxander/controlify/impl/utils/ControllerUtils.java similarity index 92% rename from src/main/java/dev/isxander/controlify/utils/ControllerUtils.java rename to src/main/java/dev/isxander/controlify/impl/utils/ControllerUtils.java index 3c9b55f70..2c39d1f9e 100644 --- a/src/main/java/dev/isxander/controlify/utils/ControllerUtils.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/ControllerUtils.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.touchpad.Touchpads; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.touchpad.Touchpads; import net.minecraft.CrashReport; import net.minecraft.CrashReportCategory; import net.minecraft.ReportedException; @@ -20,7 +20,7 @@ import java.util.stream.Stream; public class ControllerUtils { - public static String createControllerString(ControllerEntity controller) { + public static String createControllerString(ControllerImpl controller) { return String.format("'%s'#%s-%s (%s)", controller.name(), controller.info().ucid().toString(), @@ -29,7 +29,7 @@ public static String createControllerString(ControllerEntity controller) { ); } - public static void wrapControllerError(Runnable runnable, String errorTitle, ControllerEntity controller) { + public static void wrapControllerError(Runnable runnable, String errorTitle, ControllerImpl controller) { try { runnable.run(); } catch (Throwable e) { diff --git a/src/main/java/dev/isxander/controlify/utils/CursorUtils.java b/src/main/java/dev/isxander/controlify/impl/utils/CursorUtils.java similarity index 95% rename from src/main/java/dev/isxander/controlify/utils/CursorUtils.java rename to src/main/java/dev/isxander/controlify/impl/utils/CursorUtils.java index a99eddab9..3c1f76a20 100644 --- a/src/main/java/dev/isxander/controlify/utils/CursorUtils.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/CursorUtils.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import com.mojang.blaze3d.platform.Window; diff --git a/src/main/java/dev/isxander/controlify/utils/DebugDump.java b/src/main/java/dev/isxander/controlify/impl/utils/DebugDump.java similarity index 89% rename from src/main/java/dev/isxander/controlify/utils/DebugDump.java rename to src/main/java/dev/isxander/controlify/impl/utils/DebugDump.java index 90986cb95..fac722efd 100644 --- a/src/main/java/dev/isxander/controlify/utils/DebugDump.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/DebugDump.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import com.sun.jna.Platform; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controllermanager.ControllerManager; -import dev.isxander.controlify.platform.Environment; -import dev.isxander.controlify.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controllermanager.ControllerManager; +import dev.isxander.controlify.impl.platform.Environment; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; import net.minecraft.SharedConstants; import net.minecraft.resources.Identifier; @@ -49,7 +49,7 @@ private static void dumpClientDebug(IndentedStringBuilder dump) { dump.line("Controller-manager: ", controllerManager.getClass().getName()); dump.line("Connected Controllers:").pushIndent(); - for (ControllerEntity controller : controllerManager.getConnectedControllers()) { + for (ControllerImpl controller : controllerManager.getConnectedControllers()) { dump.line("Name: ", controller.name()); dump.line("Identified type: ", controller.info().type()); dump.line("GUID: ", controller.guid()); diff --git a/src/main/java/dev/isxander/controlify/utils/DebugLog.java b/src/main/java/dev/isxander/controlify/impl/utils/DebugLog.java similarity index 74% rename from src/main/java/dev/isxander/controlify/utils/DebugLog.java rename to src/main/java/dev/isxander/controlify/impl/utils/DebugLog.java index 7d41b2c9f..ef29c9f36 100644 --- a/src/main/java/dev/isxander/controlify/utils/DebugLog.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/DebugLog.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; -import dev.isxander.controlify.debug.DebugProperties; +import dev.isxander.controlify.impl.debug.DebugProperties; public class DebugLog { public static void log(String message, Object... args) { diff --git a/src/main/java/dev/isxander/controlify/utils/DebugOverlayHelper.java b/src/main/java/dev/isxander/controlify/impl/utils/DebugOverlayHelper.java similarity index 98% rename from src/main/java/dev/isxander/controlify/utils/DebugOverlayHelper.java rename to src/main/java/dev/isxander/controlify/impl/utils/DebugOverlayHelper.java index bf5d3d95b..f4c7e06bc 100644 --- a/src/main/java/dev/isxander/controlify/utils/DebugOverlayHelper.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/DebugOverlayHelper.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/utils/DummyMixinTarget.java b/src/main/java/dev/isxander/controlify/impl/utils/DummyMixinTarget.java similarity index 88% rename from src/main/java/dev/isxander/controlify/utils/DummyMixinTarget.java rename to src/main/java/dev/isxander/controlify/impl/utils/DummyMixinTarget.java index 2dbe9d43b..ae80b6ffc 100644 --- a/src/main/java/dev/isxander/controlify/utils/DummyMixinTarget.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/DummyMixinTarget.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; /** * This class is used when you need stonecutter to comment out a mixin completely, diff --git a/src/main/java/dev/isxander/controlify/utils/Easings.java b/src/main/java/dev/isxander/controlify/impl/utils/Easings.java similarity index 94% rename from src/main/java/dev/isxander/controlify/utils/Easings.java rename to src/main/java/dev/isxander/controlify/impl/utils/Easings.java index 525e2fbef..07d958293 100644 --- a/src/main/java/dev/isxander/controlify/utils/Easings.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/Easings.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import net.minecraft.util.Mth; diff --git a/src/main/java/dev/isxander/controlify/utils/HoldRepeatHelper.java b/src/main/java/dev/isxander/controlify/impl/utils/HoldRepeatHelper.java similarity index 90% rename from src/main/java/dev/isxander/controlify/utils/HoldRepeatHelper.java rename to src/main/java/dev/isxander/controlify/impl/utils/HoldRepeatHelper.java index c742548e9..366d161e3 100644 --- a/src/main/java/dev/isxander/controlify/utils/HoldRepeatHelper.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/HoldRepeatHelper.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; -import dev.isxander.controlify.api.bind.InputBinding; +import dev.isxander.controlify.impl.api.bind.InputBinding; public class HoldRepeatHelper { private final int initialDelay, repeatDelay; diff --git a/src/main/java/dev/isxander/controlify/utils/InitialScreenRegistryDuck.java b/src/main/java/dev/isxander/controlify/impl/utils/InitialScreenRegistryDuck.java similarity index 94% rename from src/main/java/dev/isxander/controlify/utils/InitialScreenRegistryDuck.java rename to src/main/java/dev/isxander/controlify/impl/utils/InitialScreenRegistryDuck.java index 36a9b9987..d8792ee79 100644 --- a/src/main/java/dev/isxander/controlify/utils/InitialScreenRegistryDuck.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/InitialScreenRegistryDuck.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; diff --git a/src/main/java/dev/isxander/controlify/utils/JsonTreeParser.java b/src/main/java/dev/isxander/controlify/impl/utils/JsonTreeParser.java similarity index 97% rename from src/main/java/dev/isxander/controlify/utils/JsonTreeParser.java rename to src/main/java/dev/isxander/controlify/impl/utils/JsonTreeParser.java index 17038c402..088279850 100644 --- a/src/main/java/dev/isxander/controlify/utils/JsonTreeParser.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/JsonTreeParser.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import com.google.gson.*; import org.quiltmc.parsers.json.JsonReader; diff --git a/src/main/java/dev/isxander/controlify/utils/LazyComponentDims.java b/src/main/java/dev/isxander/controlify/impl/utils/LazyComponentDims.java similarity index 83% rename from src/main/java/dev/isxander/controlify/utils/LazyComponentDims.java rename to src/main/java/dev/isxander/controlify/impl/utils/LazyComponentDims.java index afc7c3136..92bd98793 100644 --- a/src/main/java/dev/isxander/controlify/utils/LazyComponentDims.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/LazyComponentDims.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.id.ControllerType; -import dev.isxander.controlify.font.BindingFontHelper; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controllermanager.ControllerType; +import dev.isxander.controlify.impl.font.BindingFontHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.network.chat.Component; @@ -62,8 +62,8 @@ private int getCacheKey() { minecraft.getWindow().getGuiScaledHeight(), minecraft.font, Controlify.instance().getCurrentController() - .map(c -> c.info().type().namespace()) - .orElse(ControllerType.DEFAULT.namespace()) + .map(c -> c.info().type().id()) + .orElse(ControllerType.DEFAULT.id()) ); } } diff --git a/src/main/java/dev/isxander/controlify/utils/MinecraftUtil.java b/src/main/java/dev/isxander/controlify/impl/utils/MinecraftUtil.java similarity index 97% rename from src/main/java/dev/isxander/controlify/utils/MinecraftUtil.java rename to src/main/java/dev/isxander/controlify/impl/utils/MinecraftUtil.java index 992b75634..ba763aefe 100644 --- a/src/main/java/dev/isxander/controlify/utils/MinecraftUtil.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/MinecraftUtil.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import dev.isxander.controlify.mixins.feature.bind.GuiAccessor; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/utils/MouseMinecraftCallNotifier.java b/src/main/java/dev/isxander/controlify/impl/utils/MouseMinecraftCallNotifier.java similarity index 83% rename from src/main/java/dev/isxander/controlify/utils/MouseMinecraftCallNotifier.java rename to src/main/java/dev/isxander/controlify/impl/utils/MouseMinecraftCallNotifier.java index f0ec7e47e..50a8b79ff 100644 --- a/src/main/java/dev/isxander/controlify/utils/MouseMinecraftCallNotifier.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/MouseMinecraftCallNotifier.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; public interface MouseMinecraftCallNotifier { void controlify$imFromMinecraftSetScreen(); diff --git a/src/main/java/dev/isxander/controlify/utils/MthExt.java b/src/main/java/dev/isxander/controlify/impl/utils/MthExt.java similarity index 89% rename from src/main/java/dev/isxander/controlify/utils/MthExt.java rename to src/main/java/dev/isxander/controlify/impl/utils/MthExt.java index 794c51f22..f7eadd197 100644 --- a/src/main/java/dev/isxander/controlify/utils/MthExt.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/MthExt.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import net.minecraft.util.Mth; diff --git a/src/main/java/dev/isxander/controlify/utils/Platform.java b/src/main/java/dev/isxander/controlify/impl/utils/Platform.java similarity index 98% rename from src/main/java/dev/isxander/controlify/utils/Platform.java rename to src/main/java/dev/isxander/controlify/impl/utils/Platform.java index a1dda9278..4ab6534af 100644 --- a/src/main/java/dev/isxander/controlify/utils/Platform.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/Platform.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; public enum Platform { UNKNOWN, diff --git a/src/main/java/dev/isxander/controlify/utils/PrecomputedComponentDims.java b/src/main/java/dev/isxander/controlify/impl/utils/PrecomputedComponentDims.java similarity index 89% rename from src/main/java/dev/isxander/controlify/utils/PrecomputedComponentDims.java rename to src/main/java/dev/isxander/controlify/impl/utils/PrecomputedComponentDims.java index 535bab134..ae5bfe9a2 100644 --- a/src/main/java/dev/isxander/controlify/utils/PrecomputedComponentDims.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/PrecomputedComponentDims.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; -import dev.isxander.controlify.font.BindingFontHelper; +import dev.isxander.controlify.impl.font.BindingFontHelper; import net.minecraft.client.gui.Font; import net.minecraft.network.chat.Component; import net.minecraft.util.FormattedCharSequence; diff --git a/src/main/java/dev/isxander/controlify/utils/ResizableRingBuffer.java b/src/main/java/dev/isxander/controlify/impl/utils/ResizableRingBuffer.java similarity index 97% rename from src/main/java/dev/isxander/controlify/utils/ResizableRingBuffer.java rename to src/main/java/dev/isxander/controlify/impl/utils/ResizableRingBuffer.java index fc5c0a051..24eab2379 100644 --- a/src/main/java/dev/isxander/controlify/utils/ResizableRingBuffer.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/ResizableRingBuffer.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import java.util.function.Supplier; diff --git a/src/main/java/dev/isxander/controlify/utils/SetupWizard.java b/src/main/java/dev/isxander/controlify/impl/utils/SetupWizard.java similarity index 97% rename from src/main/java/dev/isxander/controlify/utils/SetupWizard.java rename to src/main/java/dev/isxander/controlify/impl/utils/SetupWizard.java index 224ef4934..4cf79c7b1 100644 --- a/src/main/java/dev/isxander/controlify/utils/SetupWizard.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/SetupWizard.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import net.minecraft.client.gui.screens.Screen; diff --git a/src/main/java/dev/isxander/controlify/utils/SetupWizardManager.java b/src/main/java/dev/isxander/controlify/impl/utils/SetupWizardManager.java similarity index 86% rename from src/main/java/dev/isxander/controlify/utils/SetupWizardManager.java rename to src/main/java/dev/isxander/controlify/impl/utils/SetupWizardManager.java index ca601f2ca..87422053c 100644 --- a/src/main/java/dev/isxander/controlify/utils/SetupWizardManager.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/SetupWizardManager.java @@ -1,6 +1,6 @@ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; -import dev.isxander.controlify.gui.screen.DontInterruptScreen; +import dev.isxander.controlify.impl.gui.screen.DontInterruptScreen; import java.util.ArrayDeque; import java.util.Queue; diff --git a/src/main/java/dev/isxander/controlify/utils/TrackingBodySubscriber.java b/src/main/java/dev/isxander/controlify/impl/utils/TrackingBodySubscriber.java similarity index 97% rename from src/main/java/dev/isxander/controlify/utils/TrackingBodySubscriber.java rename to src/main/java/dev/isxander/controlify/impl/utils/TrackingBodySubscriber.java index ab95f429e..2777b3b37 100644 --- a/src/main/java/dev/isxander/controlify/utils/TrackingBodySubscriber.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/TrackingBodySubscriber.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import java.net.http.HttpResponse; import java.nio.ByteBuffer; diff --git a/src/main/java/dev/isxander/controlify/utils/TrackingConsumer.java b/src/main/java/dev/isxander/controlify/impl/utils/TrackingConsumer.java similarity index 89% rename from src/main/java/dev/isxander/controlify/utils/TrackingConsumer.java rename to src/main/java/dev/isxander/controlify/impl/utils/TrackingConsumer.java index 10df886c7..94e29ff7b 100644 --- a/src/main/java/dev/isxander/controlify/utils/TrackingConsumer.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/TrackingConsumer.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import java.util.Optional; import java.util.function.BiConsumer; diff --git a/src/main/java/dev/isxander/controlify/utils/UnhandledCompletableFutures.java b/src/main/java/dev/isxander/controlify/impl/utils/UnhandledCompletableFutures.java similarity index 95% rename from src/main/java/dev/isxander/controlify/utils/UnhandledCompletableFutures.java rename to src/main/java/dev/isxander/controlify/impl/utils/UnhandledCompletableFutures.java index 8283a1f47..98ba6da8c 100644 --- a/src/main/java/dev/isxander/controlify/utils/UnhandledCompletableFutures.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/UnhandledCompletableFutures.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils; +package dev.isxander.controlify.impl.utils; import net.minecraft.ReportedException; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/utils/animation/api/Animatable.java b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/Animatable.java similarity index 95% rename from src/main/java/dev/isxander/controlify/utils/animation/api/Animatable.java rename to src/main/java/dev/isxander/controlify/impl/utils/animation/api/Animatable.java index cbc0d05c2..ad6efa79e 100644 --- a/src/main/java/dev/isxander/controlify/utils/animation/api/Animatable.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/Animatable.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.animation.api; +package dev.isxander.controlify.impl.utils.animation.api; import org.jetbrains.annotations.ApiStatus; diff --git a/src/main/java/dev/isxander/controlify/utils/animation/api/Animation.java b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/Animation.java similarity index 96% rename from src/main/java/dev/isxander/controlify/utils/animation/api/Animation.java rename to src/main/java/dev/isxander/controlify/impl/utils/animation/api/Animation.java index 0f9b3b6f3..99a462502 100644 --- a/src/main/java/dev/isxander/controlify/utils/animation/api/Animation.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/Animation.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.animation.api; +package dev.isxander.controlify.impl.utils.animation.api; -import dev.isxander.controlify.utils.animation.impl.AnimationImpl; +import dev.isxander.controlify.impl.utils.animation.impl.AnimationImpl; import java.util.function.Consumer; diff --git a/src/main/java/dev/isxander/controlify/utils/animation/api/AnimationGroup.java b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/AnimationGroup.java similarity index 90% rename from src/main/java/dev/isxander/controlify/utils/animation/api/AnimationGroup.java rename to src/main/java/dev/isxander/controlify/impl/utils/animation/api/AnimationGroup.java index cfdf32aa3..e7359188e 100644 --- a/src/main/java/dev/isxander/controlify/utils/animation/api/AnimationGroup.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/AnimationGroup.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.animation.api; +package dev.isxander.controlify.impl.utils.animation.api; -import dev.isxander.controlify.utils.animation.impl.AnimationGroupImpl; +import dev.isxander.controlify.impl.utils.animation.impl.AnimationGroupImpl; /** * A group of {@link Animatable}s where all are played concurrently diff --git a/src/main/java/dev/isxander/controlify/utils/animation/api/AnimationSequence.java b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/AnimationSequence.java similarity index 90% rename from src/main/java/dev/isxander/controlify/utils/animation/api/AnimationSequence.java rename to src/main/java/dev/isxander/controlify/impl/utils/animation/api/AnimationSequence.java index db303d8f3..4b8ffec6b 100644 --- a/src/main/java/dev/isxander/controlify/utils/animation/api/AnimationSequence.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/AnimationSequence.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.animation.api; +package dev.isxander.controlify.impl.utils.animation.api; -import dev.isxander.controlify.utils.animation.impl.AnimationSequenceImpl; +import dev.isxander.controlify.impl.utils.animation.impl.AnimationSequenceImpl; /** * A sequence of {@link Animatable}s where each animatable is played one diff --git a/src/main/java/dev/isxander/controlify/utils/animation/api/EasingFunction.java b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/EasingFunction.java similarity index 98% rename from src/main/java/dev/isxander/controlify/utils/animation/api/EasingFunction.java rename to src/main/java/dev/isxander/controlify/impl/utils/animation/api/EasingFunction.java index 410f14e4d..6ced261d3 100644 --- a/src/main/java/dev/isxander/controlify/utils/animation/api/EasingFunction.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/animation/api/EasingFunction.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.animation.api; +package dev.isxander.controlify.impl.utils.animation.api; import net.minecraft.util.Mth; diff --git a/src/main/java/dev/isxander/controlify/utils/animation/impl/AnimationGroupImpl.java b/src/main/java/dev/isxander/controlify/impl/utils/animation/impl/AnimationGroupImpl.java similarity index 90% rename from src/main/java/dev/isxander/controlify/utils/animation/impl/AnimationGroupImpl.java rename to src/main/java/dev/isxander/controlify/impl/utils/animation/impl/AnimationGroupImpl.java index 41f96bc0a..3ce55b795 100644 --- a/src/main/java/dev/isxander/controlify/utils/animation/impl/AnimationGroupImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/animation/impl/AnimationGroupImpl.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.animation.impl; +package dev.isxander.controlify.impl.utils.animation.impl; -import dev.isxander.controlify.utils.animation.api.Animatable; -import dev.isxander.controlify.utils.animation.api.AnimationGroup; +import dev.isxander.controlify.impl.utils.animation.api.Animatable; +import dev.isxander.controlify.impl.utils.animation.api.AnimationGroup; import it.unimi.dsi.fastutil.objects.ObjectArraySet; import org.apache.commons.lang3.Validate; diff --git a/src/main/java/dev/isxander/controlify/utils/animation/impl/AnimationImpl.java b/src/main/java/dev/isxander/controlify/impl/utils/animation/impl/AnimationImpl.java similarity index 95% rename from src/main/java/dev/isxander/controlify/utils/animation/impl/AnimationImpl.java rename to src/main/java/dev/isxander/controlify/impl/utils/animation/impl/AnimationImpl.java index eb9019fff..3d31c0e55 100644 --- a/src/main/java/dev/isxander/controlify/utils/animation/impl/AnimationImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/animation/impl/AnimationImpl.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.animation.impl; +package dev.isxander.controlify.impl.utils.animation.impl; -import dev.isxander.controlify.utils.animation.api.Animation; -import dev.isxander.controlify.utils.animation.api.EasingFunction; +import dev.isxander.controlify.impl.utils.animation.api.Animation; +import dev.isxander.controlify.impl.utils.animation.api.EasingFunction; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/utils/animation/impl/AnimationSequenceImpl.java b/src/main/java/dev/isxander/controlify/impl/utils/animation/impl/AnimationSequenceImpl.java similarity index 90% rename from src/main/java/dev/isxander/controlify/utils/animation/impl/AnimationSequenceImpl.java rename to src/main/java/dev/isxander/controlify/impl/utils/animation/impl/AnimationSequenceImpl.java index 90a94a2a3..63eef4fae 100644 --- a/src/main/java/dev/isxander/controlify/utils/animation/impl/AnimationSequenceImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/animation/impl/AnimationSequenceImpl.java @@ -4,10 +4,10 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.animation.impl; +package dev.isxander.controlify.impl.utils.animation.impl; -import dev.isxander.controlify.utils.animation.api.Animatable; -import dev.isxander.controlify.utils.animation.api.AnimationSequence; +import dev.isxander.controlify.impl.utils.animation.api.Animatable; +import dev.isxander.controlify.impl.utils.animation.api.AnimationSequence; import org.apache.commons.lang3.Validate; import java.util.ArrayDeque; diff --git a/src/main/java/dev/isxander/controlify/utils/animation/impl/Animator.java b/src/main/java/dev/isxander/controlify/impl/utils/animation/impl/Animator.java similarity index 83% rename from src/main/java/dev/isxander/controlify/utils/animation/impl/Animator.java rename to src/main/java/dev/isxander/controlify/impl/utils/animation/impl/Animator.java index cd1fe8f3c..9352cdfc3 100644 --- a/src/main/java/dev/isxander/controlify/utils/animation/impl/Animator.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/animation/impl/Animator.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.animation.impl; +package dev.isxander.controlify.impl.utils.animation.impl; -import dev.isxander.controlify.utils.animation.api.Animatable; +import dev.isxander.controlify.impl.utils.animation.api.Animatable; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.util.List; diff --git a/src/main/java/dev/isxander/controlify/utils/codec/CExtraCodecs.java b/src/main/java/dev/isxander/controlify/impl/utils/codec/CExtraCodecs.java similarity index 98% rename from src/main/java/dev/isxander/controlify/utils/codec/CExtraCodecs.java rename to src/main/java/dev/isxander/controlify/impl/utils/codec/CExtraCodecs.java index 8b33daf6c..68a0ff556 100644 --- a/src/main/java/dev/isxander/controlify/utils/codec/CExtraCodecs.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/codec/CExtraCodecs.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.codec; +package dev.isxander.controlify.impl.utils.codec; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.*; diff --git a/src/main/java/dev/isxander/controlify/utils/codec/FuzzyCodec.java b/src/main/java/dev/isxander/controlify/impl/utils/codec/FuzzyCodec.java similarity index 96% rename from src/main/java/dev/isxander/controlify/utils/codec/FuzzyCodec.java rename to src/main/java/dev/isxander/controlify/impl/utils/codec/FuzzyCodec.java index 110e3e7b2..39ec15a77 100644 --- a/src/main/java/dev/isxander/controlify/utils/codec/FuzzyCodec.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/codec/FuzzyCodec.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.codec; +package dev.isxander.controlify.impl.utils.codec; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; diff --git a/src/main/java/dev/isxander/controlify/utils/codec/FuzzyMapCodec.java b/src/main/java/dev/isxander/controlify/impl/utils/codec/FuzzyMapCodec.java similarity index 96% rename from src/main/java/dev/isxander/controlify/utils/codec/FuzzyMapCodec.java rename to src/main/java/dev/isxander/controlify/impl/utils/codec/FuzzyMapCodec.java index 1c49aceda..c31de7149 100644 --- a/src/main/java/dev/isxander/controlify/utils/codec/FuzzyMapCodec.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/codec/FuzzyMapCodec.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.codec; +package dev.isxander.controlify.impl.utils.codec; import com.mojang.serialization.*; diff --git a/src/main/java/dev/isxander/controlify/utils/codec/SetCodec.java b/src/main/java/dev/isxander/controlify/impl/utils/codec/SetCodec.java similarity index 98% rename from src/main/java/dev/isxander/controlify/utils/codec/SetCodec.java rename to src/main/java/dev/isxander/controlify/impl/utils/codec/SetCodec.java index 54c09eb6a..7b4e1bdbe 100644 --- a/src/main/java/dev/isxander/controlify/utils/codec/SetCodec.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/codec/SetCodec.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.codec; +package dev.isxander.controlify.impl.utils.codec; import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Unit; diff --git a/src/main/java/dev/isxander/controlify/utils/codec/StrictEitherMapCodec.java b/src/main/java/dev/isxander/controlify/impl/utils/codec/StrictEitherMapCodec.java similarity index 95% rename from src/main/java/dev/isxander/controlify/utils/codec/StrictEitherMapCodec.java rename to src/main/java/dev/isxander/controlify/impl/utils/codec/StrictEitherMapCodec.java index f8181654d..284ae5050 100644 --- a/src/main/java/dev/isxander/controlify/utils/codec/StrictEitherMapCodec.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/codec/StrictEitherMapCodec.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.codec; +package dev.isxander.controlify.impl.utils.codec; import com.mojang.serialization.*; diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventSink.java b/src/main/java/dev/isxander/controlify/impl/utils/event/EventSink.java similarity index 61% rename from src/main/java/dev/isxander/controlify/utils/event/EventSink.java rename to src/main/java/dev/isxander/controlify/impl/utils/event/EventSink.java index ef93c6831..37436842d 100644 --- a/src/main/java/dev/isxander/controlify/utils/event/EventSink.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/event/EventSink.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.utils.event; +package dev.isxander.controlify.impl.utils.event; @FunctionalInterface public interface EventSink { diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventSource.java b/src/main/java/dev/isxander/controlify/impl/utils/event/EventSource.java similarity index 91% rename from src/main/java/dev/isxander/controlify/utils/event/EventSource.java rename to src/main/java/dev/isxander/controlify/impl/utils/event/EventSource.java index d96dbfec8..46556805e 100644 --- a/src/main/java/dev/isxander/controlify/utils/event/EventSource.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/event/EventSource.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.utils.event; +package dev.isxander.controlify.impl.utils.event; import java.util.function.Predicate; diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventStage.java b/src/main/java/dev/isxander/controlify/impl/utils/event/EventStage.java similarity index 94% rename from src/main/java/dev/isxander/controlify/utils/event/EventStage.java rename to src/main/java/dev/isxander/controlify/impl/utils/event/EventStage.java index 8d9de4c17..0f9391d99 100644 --- a/src/main/java/dev/isxander/controlify/utils/event/EventStage.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/event/EventStage.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.utils.event; +package dev.isxander.controlify.impl.utils.event; @FunctionalInterface public interface EventStage { diff --git a/src/main/java/dev/isxander/controlify/utils/event/EventTap.java b/src/main/java/dev/isxander/controlify/impl/utils/event/EventTap.java similarity index 96% rename from src/main/java/dev/isxander/controlify/utils/event/EventTap.java rename to src/main/java/dev/isxander/controlify/impl/utils/event/EventTap.java index b8658c026..ee73a45d8 100644 --- a/src/main/java/dev/isxander/controlify/utils/event/EventTap.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/event/EventTap.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.utils.event; +package dev.isxander.controlify.impl.utils.event; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; diff --git a/src/main/java/dev/isxander/controlify/utils/event/UnaryEventStage.java b/src/main/java/dev/isxander/controlify/impl/utils/event/UnaryEventStage.java similarity index 63% rename from src/main/java/dev/isxander/controlify/utils/event/UnaryEventStage.java rename to src/main/java/dev/isxander/controlify/impl/utils/event/UnaryEventStage.java index cbf80fb8e..d62293485 100644 --- a/src/main/java/dev/isxander/controlify/utils/event/UnaryEventStage.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/event/UnaryEventStage.java @@ -1,4 +1,4 @@ -package dev.isxander.controlify.utils.event; +package dev.isxander.controlify.impl.utils.event; @FunctionalInterface public interface UnaryEventStage extends EventStage { diff --git a/src/main/java/dev/isxander/controlify/utils/log/AbstractControlifyLogger.java b/src/main/java/dev/isxander/controlify/impl/utils/log/AbstractControlifyLogger.java similarity index 98% rename from src/main/java/dev/isxander/controlify/utils/log/AbstractControlifyLogger.java rename to src/main/java/dev/isxander/controlify/impl/utils/log/AbstractControlifyLogger.java index 6a5f7969b..a19fd3d57 100644 --- a/src/main/java/dev/isxander/controlify/utils/log/AbstractControlifyLogger.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/log/AbstractControlifyLogger.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.log; +package dev.isxander.controlify.impl.utils.log; import net.minecraft.CrashReport; import net.minecraft.ReportType; diff --git a/src/main/java/dev/isxander/controlify/utils/log/ControlifyLogger.java b/src/main/java/dev/isxander/controlify/impl/utils/log/ControlifyLogger.java similarity index 97% rename from src/main/java/dev/isxander/controlify/utils/log/ControlifyLogger.java rename to src/main/java/dev/isxander/controlify/impl/utils/log/ControlifyLogger.java index ebda7cb66..ca0401577 100644 --- a/src/main/java/dev/isxander/controlify/utils/log/ControlifyLogger.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/log/ControlifyLogger.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.log; +package dev.isxander.controlify.impl.utils.log; import net.minecraft.CrashReport; import org.jetbrains.annotations.Contract; diff --git a/src/main/java/dev/isxander/controlify/utils/log/ControlifyMasterLogger.java b/src/main/java/dev/isxander/controlify/impl/utils/log/ControlifyMasterLogger.java similarity index 91% rename from src/main/java/dev/isxander/controlify/utils/log/ControlifyMasterLogger.java rename to src/main/java/dev/isxander/controlify/impl/utils/log/ControlifyMasterLogger.java index 0928c23ea..721e9f8f8 100644 --- a/src/main/java/dev/isxander/controlify/utils/log/ControlifyMasterLogger.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/log/ControlifyMasterLogger.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.log; +package dev.isxander.controlify.impl.utils.log; -import dev.isxander.controlify.debug.DebugProperties; +import dev.isxander.controlify.impl.debug.DebugProperties; import org.jetbrains.annotations.Nullable; public class ControlifyMasterLogger extends AbstractControlifyLogger { diff --git a/src/main/java/dev/isxander/controlify/utils/log/ControlifySubLogger.java b/src/main/java/dev/isxander/controlify/impl/utils/log/ControlifySubLogger.java similarity index 81% rename from src/main/java/dev/isxander/controlify/utils/log/ControlifySubLogger.java rename to src/main/java/dev/isxander/controlify/impl/utils/log/ControlifySubLogger.java index f1228f8fe..3017a9bd2 100644 --- a/src/main/java/dev/isxander/controlify/utils/log/ControlifySubLogger.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/log/ControlifySubLogger.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.log; +package dev.isxander.controlify.impl.utils.log; public interface ControlifySubLogger extends ControlifyLogger { String name(); diff --git a/src/main/java/dev/isxander/controlify/utils/log/ControlifySubLoggerImpl.java b/src/main/java/dev/isxander/controlify/impl/utils/log/ControlifySubLoggerImpl.java similarity index 95% rename from src/main/java/dev/isxander/controlify/utils/log/ControlifySubLoggerImpl.java rename to src/main/java/dev/isxander/controlify/impl/utils/log/ControlifySubLoggerImpl.java index dc5d69c55..4c64becdb 100644 --- a/src/main/java/dev/isxander/controlify/utils/log/ControlifySubLoggerImpl.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/log/ControlifySubLoggerImpl.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.log; +package dev.isxander.controlify.impl.utils.log; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/utils/log/LogLevel.java b/src/main/java/dev/isxander/controlify/impl/utils/log/LogLevel.java similarity index 78% rename from src/main/java/dev/isxander/controlify/utils/log/LogLevel.java rename to src/main/java/dev/isxander/controlify/impl/utils/log/LogLevel.java index 33b56d989..c09af6476 100644 --- a/src/main/java/dev/isxander/controlify/utils/log/LogLevel.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/log/LogLevel.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.log; +package dev.isxander.controlify.impl.utils.log; public enum LogLevel { INFO, diff --git a/src/main/java/dev/isxander/controlify/utils/log/LogMessage.java b/src/main/java/dev/isxander/controlify/impl/utils/log/LogMessage.java similarity index 96% rename from src/main/java/dev/isxander/controlify/utils/log/LogMessage.java rename to src/main/java/dev/isxander/controlify/impl/utils/log/LogMessage.java index f62d033d4..08ffff759 100644 --- a/src/main/java/dev/isxander/controlify/utils/log/LogMessage.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/log/LogMessage.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.log; +package dev.isxander.controlify.impl.utils.log; import java.io.PrintWriter; import java.io.StringWriter; diff --git a/src/main/java/dev/isxander/controlify/utils/predicates/ClientEntityPredicate.java b/src/main/java/dev/isxander/controlify/impl/utils/predicates/ClientEntityPredicate.java similarity index 98% rename from src/main/java/dev/isxander/controlify/utils/predicates/ClientEntityPredicate.java rename to src/main/java/dev/isxander/controlify/impl/utils/predicates/ClientEntityPredicate.java index 28318fb0c..e99f2efdf 100644 --- a/src/main/java/dev/isxander/controlify/utils/predicates/ClientEntityPredicate.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/predicates/ClientEntityPredicate.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.predicates; +package dev.isxander.controlify.impl.utils.predicates; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/utils/predicates/ClientPredicateUtils.java b/src/main/java/dev/isxander/controlify/impl/utils/predicates/ClientPredicateUtils.java similarity index 94% rename from src/main/java/dev/isxander/controlify/utils/predicates/ClientPredicateUtils.java rename to src/main/java/dev/isxander/controlify/impl/utils/predicates/ClientPredicateUtils.java index 6e48b0cd2..559ca9cfc 100644 --- a/src/main/java/dev/isxander/controlify/utils/predicates/ClientPredicateUtils.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/predicates/ClientPredicateUtils.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.predicates; +package dev.isxander.controlify.impl.utils.predicates; -import dev.isxander.controlify.utils.CUtil; +import dev.isxander.controlify.impl.utils.CUtil; import it.unimi.dsi.fastutil.ints.IntList; //? if >=26.2 { import net.minecraft.advancements.predicates.*; diff --git a/src/main/java/dev/isxander/controlify/utils/predicates/EntityEquipmentPredicate.java b/src/main/java/dev/isxander/controlify/impl/utils/predicates/EntityEquipmentPredicate.java similarity index 98% rename from src/main/java/dev/isxander/controlify/utils/predicates/EntityEquipmentPredicate.java rename to src/main/java/dev/isxander/controlify/impl/utils/predicates/EntityEquipmentPredicate.java index 971862f2b..5b62a3e5d 100644 --- a/src/main/java/dev/isxander/controlify/utils/predicates/EntityEquipmentPredicate.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/predicates/EntityEquipmentPredicate.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.predicates; +package dev.isxander.controlify.impl.utils.predicates; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; diff --git a/src/main/java/dev/isxander/controlify/utils/render/BaseRenderState.java b/src/main/java/dev/isxander/controlify/impl/utils/render/BaseRenderState.java similarity index 95% rename from src/main/java/dev/isxander/controlify/utils/render/BaseRenderState.java rename to src/main/java/dev/isxander/controlify/impl/utils/render/BaseRenderState.java index f61f4bc81..de219062d 100644 --- a/src/main/java/dev/isxander/controlify/utils/render/BaseRenderState.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/render/BaseRenderState.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.render; +package dev.isxander.controlify.impl.utils.render; -import dev.isxander.controlify.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.navigation.ScreenRectangle; diff --git a/src/main/java/dev/isxander/controlify/utils/render/CGuiElementRenderState.java b/src/main/java/dev/isxander/controlify/impl/utils/render/CGuiElementRenderState.java similarity index 90% rename from src/main/java/dev/isxander/controlify/utils/render/CGuiElementRenderState.java rename to src/main/java/dev/isxander/controlify/impl/utils/render/CGuiElementRenderState.java index f0a0de30b..563af49e9 100644 --- a/src/main/java/dev/isxander/controlify/utils/render/CGuiElementRenderState.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/render/CGuiElementRenderState.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.render; +package dev.isxander.controlify.impl.utils.render; -import dev.isxander.controlify.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.renderer.state.gui.GuiElementRenderState; import net.minecraft.client.gui.render.TextureSetup; diff --git a/src/main/java/dev/isxander/controlify/utils/render/RenderUtils.java b/src/main/java/dev/isxander/controlify/impl/utils/render/RenderUtils.java similarity index 95% rename from src/main/java/dev/isxander/controlify/utils/render/RenderUtils.java rename to src/main/java/dev/isxander/controlify/impl/utils/render/RenderUtils.java index 912bb9be9..5de1781cd 100644 --- a/src/main/java/dev/isxander/controlify/utils/render/RenderUtils.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/render/RenderUtils.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.render; +package dev.isxander.controlify.impl.utils.render; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.renderer.RenderPipelines; diff --git a/src/main/java/dev/isxander/controlify/utils/render/elements/CircleElementRenderState.java b/src/main/java/dev/isxander/controlify/impl/utils/render/elements/CircleElementRenderState.java similarity index 92% rename from src/main/java/dev/isxander/controlify/utils/render/elements/CircleElementRenderState.java rename to src/main/java/dev/isxander/controlify/impl/utils/render/elements/CircleElementRenderState.java index 527cd9954..3109f6360 100644 --- a/src/main/java/dev/isxander/controlify/utils/render/elements/CircleElementRenderState.java +++ b/src/main/java/dev/isxander/controlify/impl/utils/render/elements/CircleElementRenderState.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.utils.render.elements; +package dev.isxander.controlify.impl.utils.render.elements; import com.mojang.blaze3d.vertex.VertexConsumer; -import dev.isxander.controlify.utils.render.BaseRenderState; -import dev.isxander.controlify.utils.render.CGuiElementRenderState; +import dev.isxander.controlify.impl.utils.render.BaseRenderState; +import dev.isxander.controlify.impl.utils.render.CGuiElementRenderState; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.util.Mth; import org.jspecify.annotations.NonNull; diff --git a/src/main/java/dev/isxander/controlify/virtualmouse/SnapUtils.java b/src/main/java/dev/isxander/controlify/impl/virtualmouse/SnapUtils.java similarity index 95% rename from src/main/java/dev/isxander/controlify/virtualmouse/SnapUtils.java rename to src/main/java/dev/isxander/controlify/impl/virtualmouse/SnapUtils.java index e0e1a9bf4..cc54809cd 100644 --- a/src/main/java/dev/isxander/controlify/virtualmouse/SnapUtils.java +++ b/src/main/java/dev/isxander/controlify/impl/virtualmouse/SnapUtils.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.virtualmouse; +package dev.isxander.controlify.impl.virtualmouse; -import dev.isxander.controlify.api.vmousesnapping.SnapPoint; +import dev.isxander.controlify.impl.api.vmousesnapping.SnapPoint; import dev.isxander.controlify.mixins.feature.virtualmouse.snapping.RecipeBookComponentAccessor; import dev.isxander.controlify.mixins.feature.virtualmouse.snapping.RecipeBookPageAccessor; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; diff --git a/src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseBehaviour.java b/src/main/java/dev/isxander/controlify/impl/virtualmouse/VirtualMouseBehaviour.java similarity index 88% rename from src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseBehaviour.java rename to src/main/java/dev/isxander/controlify/impl/virtualmouse/VirtualMouseBehaviour.java index dd640771d..1768e6322 100644 --- a/src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseBehaviour.java +++ b/src/main/java/dev/isxander/controlify/impl/virtualmouse/VirtualMouseBehaviour.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.virtualmouse; +package dev.isxander.controlify.impl.virtualmouse; public enum VirtualMouseBehaviour { DEFAULT, diff --git a/src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseHandler.java b/src/main/java/dev/isxander/controlify/impl/virtualmouse/VirtualMouseHandler.java similarity index 94% rename from src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseHandler.java rename to src/main/java/dev/isxander/controlify/impl/virtualmouse/VirtualMouseHandler.java index b5409039c..79160747c 100644 --- a/src/main/java/dev/isxander/controlify/virtualmouse/VirtualMouseHandler.java +++ b/src/main/java/dev/isxander/controlify/impl/virtualmouse/VirtualMouseHandler.java @@ -4,26 +4,25 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.virtualmouse; +package dev.isxander.controlify.impl.virtualmouse; import com.mojang.blaze3d.platform.InputConstants; import com.mojang.datafixers.util.Pair; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; -import dev.isxander.controlify.api.vmousesnapping.ISnapBehaviour; -import dev.isxander.controlify.api.vmousesnapping.SnapPoint; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.controller.*; -import dev.isxander.controlify.input.mapping.GamepadInputs; -import dev.isxander.controlify.controller.input.InputComponent; -import dev.isxander.controlify.controller.touchpad.TouchpadComponent; -import dev.isxander.controlify.debug.DebugProperties; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.api.event.ControlifyEvents; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.InputMode; +import dev.isxander.controlify.impl.api.vmousesnapping.ISnapBehaviour; +import dev.isxander.controlify.impl.api.vmousesnapping.SnapPoint; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.input.mapping.GamepadInputs; +import dev.isxander.controlify.impl.controller.input.InputComponent; +import dev.isxander.controlify.impl.controller.touchpad.TouchpadComponent; +import dev.isxander.controlify.impl.debug.DebugProperties; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.api.ControlifyEvents; import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor; -import dev.isxander.controlify.utils.*; +import dev.isxander.controlify.impl.utils.*; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.navigation.ScreenAxis; @@ -63,7 +62,7 @@ public VirtualMouseHandler() { ControlifyEvents.INPUT_MODE_CHANGED.register(event -> this.onInputModeChanged(event.mode())); } - public void handleControllerInput(ControllerEntity controller) { + public void handleControllerInput(ControllerImpl controller) { if (MinecraftUtil.getScreen() == null) return; if (ControlifyBindings.VMOUSE_TOGGLE.on(controller).justPressed()) { @@ -177,7 +176,7 @@ public void handleControllerInput(ControllerEntity controller) { } } - public void handleCompatibilityBinds(ControllerEntity controller) { + public void handleCompatibilityBinds(ControllerImpl controller) { var windowHandle = minecraft.getWindow().handle(); // Optional touchpad = controller.touchpad(); @@ -206,7 +205,7 @@ public void handleCompatibilityBinds(ControllerEntity controller) { } } - public void handleScroll(ControllerEntity controller) { + public void handleScroll(ControllerImpl controller) { scrollY += ControlifyBindings.VMOUSE_SCROLL_UP.on(controller).analogueNow() - ControlifyBindings.VMOUSE_SCROLL_DOWN.on(controller).analogueNow(); } diff --git a/src/main/java/dev/isxander/controlify/wireless/LowBatteryNotifier.java b/src/main/java/dev/isxander/controlify/impl/wireless/LowBatteryNotifier.java similarity index 72% rename from src/main/java/dev/isxander/controlify/wireless/LowBatteryNotifier.java rename to src/main/java/dev/isxander/controlify/impl/wireless/LowBatteryNotifier.java index c06014598..939f2c16b 100644 --- a/src/main/java/dev/isxander/controlify/wireless/LowBatteryNotifier.java +++ b/src/main/java/dev/isxander/controlify/impl/wireless/LowBatteryNotifier.java @@ -4,14 +4,14 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.wireless; - -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.battery.PowerState; -import dev.isxander.controlify.controller.battery.BatteryLevelComponent; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controllermanager.ControllerManager; -import dev.isxander.controlify.utils.MinecraftUtil; +package dev.isxander.controlify.impl.wireless; + +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.battery.PowerState; +import dev.isxander.controlify.impl.controller.battery.BatteryLevelComponent; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controllermanager.ControllerManager; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.network.chat.Component; import java.util.HashSet; @@ -35,7 +35,7 @@ public static void tick() { if (controllerManager == null) return; - for (ControllerEntity controller : controllerManager.getAllControllers()) { + for (ControllerImpl controller : controllerManager.getAllControllers()) { PowerState batteryLevel = controller.batteryLevel() .map(BatteryLevelComponent::getBatteryLevel) .orElse(new PowerState.Unknown()); diff --git a/src/main/java/dev/isxander/controlify/mixins/core/ClientPacketListenerMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/ClientPacketListenerMixin.java index 73cf3dbd1..d9c5bb82a 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/ClientPacketListenerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/ClientPacketListenerMixin.java @@ -9,7 +9,7 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.sugar.Local; -import dev.isxander.controlify.ingame.ControllerPlayerMovement; +import dev.isxander.controlify.impl.ingame.ControllerPlayerMovement; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.player.LocalPlayer; diff --git a/src/main/java/dev/isxander/controlify/mixins/core/GuiMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/GuiMixin.java index bc4264d9d..0a4a29cb2 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/GuiMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/GuiMixin.java @@ -8,11 +8,11 @@ import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.utils.InitialScreenRegistryDuck; -import dev.isxander.controlify.utils.MinecraftUtil; -import dev.isxander.controlify.utils.MouseMinecraftCallNotifier; +import dev.isxander.controlify.impl.utils.InitialScreenRegistryDuck; +import dev.isxander.controlify.impl.utils.MinecraftUtil; +import dev.isxander.controlify.impl.utils.MouseMinecraftCallNotifier; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/core/HudMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/HudMixin.java index 9266b7b96..b03395087 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/HudMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/HudMixin.java @@ -7,8 +7,8 @@ package dev.isxander.controlify.mixins.core; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.ingame.InGameInputHandler; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.ingame.InGameInputHandler; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/dev/isxander/controlify/mixins/core/KeyboardHandlerMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/KeyboardHandlerMixin.java index 638c93cbc..3d73b72db 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/KeyboardHandlerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/KeyboardHandlerMixin.java @@ -68,7 +68,7 @@ private void wrapKeyboardEvents( } } *///?} else { -@Mixin(dev.isxander.controlify.utils.DummyMixinTarget.class) +@Mixin(dev.isxander.controlify.impl.utils.DummyMixinTarget.class) public class KeyboardHandlerMixin { } //?} diff --git a/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java index 736a94226..b41984492 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/MinecraftMixin.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.mixins.core; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controllermanager.ControllerCoordinator; -import dev.isxander.controlify.utils.animation.impl.Animator; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controllermanager.ControllerCoordinator; +import dev.isxander.controlify.impl.utils.animation.impl.Animator; import net.minecraft.CrashReport; import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; diff --git a/src/main/java/dev/isxander/controlify/mixins/core/MouseHandlerMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/MouseHandlerMixin.java index 1ebe42f4b..7aa123023 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/MouseHandlerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/MouseHandlerMixin.java @@ -7,13 +7,9 @@ package dev.isxander.controlify.mixins.core; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.mojang.blaze3d.platform.Window; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; +import dev.isxander.controlify.impl.Controlify; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.utils.MouseMinecraftCallNotifier; +import dev.isxander.controlify.impl.utils.MouseMinecraftCallNotifier; import net.minecraft.client.Minecraft; import net.minecraft.client.MouseHandler; import org.spongepowered.asm.mixin.Final; diff --git a/src/main/java/dev/isxander/controlify/mixins/core/SDLEventHandlerMixin.java b/src/main/java/dev/isxander/controlify/mixins/core/SDLEventHandlerMixin.java index fdbcedc8a..06dfcecbd 100644 --- a/src/main/java/dev/isxander/controlify/mixins/core/SDLEventHandlerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/core/SDLEventHandlerMixin.java @@ -10,8 +10,8 @@ //? if >=26.3 { import com.mojang.blaze3d.platform.SDLEventHandler; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.InputMode; import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Shadow; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/bind/GuiMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/bind/GuiMixin.java index 3dfedee28..f50134fe1 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/bind/GuiMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/bind/GuiMixin.java @@ -7,8 +7,8 @@ package dev.isxander.controlify.mixins.feature.bind; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.controller.input.InputComponent; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.controller.input.InputComponent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -24,7 +24,7 @@ public class GuiMixin { @Inject(method = "setScreen", at = @At("HEAD")) private void notifyBindGuiOutputOfScreenChange(CallbackInfo ci) { - ControlifyApi.get().getCurrentController().flatMap(ControllerEntity::input) + ControlifyApi.get().getCurrentController().flatMap(ControllerImpl::input) .ifPresent(InputComponent::notifyGuiPressOutputsOfNavigate); } } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/bind/HudMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/bind/HudMixin.java index 91ea5f781..a23256fac 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/bind/HudMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/bind/HudMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.bind; -import dev.isxander.controlify.gui.screen.RadialMenuScreen; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.gui.screen.RadialMenuScreen; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/bind/KeyMappingMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/bind/KeyMappingMixin.java index 19fb2e0ef..a976dd5c7 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/bind/KeyMappingMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/bind/KeyMappingMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.bind; -import dev.isxander.controlify.bindings.KeyMappingHandle; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.bindings.KeyMappingHandle; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.client.KeyMapping; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -35,7 +35,7 @@ public class KeyMappingMixin implements KeyMappingHandle { } @Override - public void controlify$addToggleCondition(ControllerEntity controller, BooleanSupplier condition) { + public void controlify$addToggleCondition(ControllerImpl controller, BooleanSupplier condition) { } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/bind/ToggleKeyMappingMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/bind/ToggleKeyMappingMixin.java index edb3d1ba8..6c18974b7 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/bind/ToggleKeyMappingMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/bind/ToggleKeyMappingMixin.java @@ -7,9 +7,9 @@ package dev.isxander.controlify.mixins.feature.bind; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.KeyMappingHandle; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.bindings.KeyMappingHandle; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.client.ToggleKeyMapping; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; @@ -40,7 +40,7 @@ private boolean modifyToggleMode(boolean vanillaToggleMode) { } @Override - public void controlify$addToggleCondition(ControllerEntity controller, BooleanSupplier condition) { + public void controlify$addToggleCondition(ControllerImpl controller, BooleanSupplier condition) { BooleanSupplier oldCondition = controlifyToggleSupplier; controlifyToggleSupplier = () -> { boolean thisToggle = condition.getAsBoolean() diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/font/KeybindContentsMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/font/KeybindContentsMixin.java index 2463d8917..401c4f9e8 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/font/KeybindContentsMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/font/KeybindContentsMixin.java @@ -9,9 +9,9 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.font.BindingFontHelper; +import dev.isxander.controlify.impl.font.BindingFontHelper; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Style; import net.minecraft.network.chat.contents.KeybindContents; @@ -40,7 +40,7 @@ private Component testVisitWithStyle(KeybindContents instance, Operation c.input().isPresent()) .map(c -> Controlify.instance().inputFontMapper() .getComponentFromBinding( - c.info().type().namespace(), + c.info().type().id(), c.input().get().getBinding(Identifier.tryParse(this.name)) ) ); diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/font/TranslatableContentsMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/font/TranslatableContentsMixin.java index 7822079a4..7661cdd8c 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/font/TranslatableContentsMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/font/TranslatableContentsMixin.java @@ -8,7 +8,7 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.font.BindingFontHelper; +import dev.isxander.controlify.impl.font.BindingFontHelper; import net.minecraft.network.chat.contents.TranslatableContents; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/ClientPacketListenerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/ClientPacketListenerMixin.java index 1e1c1768f..2fa398a92 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/ClientPacketListenerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/ClientPacketListenerMixin.java @@ -8,8 +8,8 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.gui.guide.InGameButtonGuide; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.gui.guide.InGameButtonGuide; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.network.protocol.game.ClientboundLoginPacket; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/HudMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/HudMixin.java index a347853ee..42c30980c 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/HudMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/guide/ingame/HudMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.guide.ingame; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.gui.guide.InGameButtonGuide; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.gui.guide.InGameButtonGuide; import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/guide/screen/AbstractButtonMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/guide/screen/AbstractButtonMixin.java index 28ad2d86e..42dfe6e79 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/guide/screen/AbstractButtonMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/guide/screen/AbstractButtonMixin.java @@ -7,8 +7,8 @@ package dev.isxander.controlify.mixins.feature.guide.screen; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.gui.ButtonGuideRenderer; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.gui.ButtonGuideRenderer; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import net.minecraft.client.gui.components.AbstractButton; import net.minecraft.network.chat.Component; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/guide/screen/TabNavigationBarMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/guide/screen/TabNavigationBarMixin.java index 707da705e..1c15a76f9 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/guide/screen/TabNavigationBarMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/guide/screen/TabNavigationBarMixin.java @@ -7,9 +7,9 @@ package dev.isxander.controlify.mixins.feature.guide.screen; import com.google.common.collect.ImmutableList; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphicsExtractor; @@ -43,7 +43,7 @@ private void renderControllerButtonOverlay(GuiGraphicsExtractor graphics, int mo } } - @Unique private void renderControllerButtonOverlay(GuiGraphicsExtractor graphics, ControllerEntity controller) { + @Unique private void renderControllerButtonOverlay(GuiGraphicsExtractor graphics, ControllerImpl controller) { if (tabButtons.size() <= 1) return; // no controls necessary TabButton firstTab = tabButtons.get(0); diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/input/MinecraftMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/input/MinecraftMixin.java index 27423f9f5..ab72ea92f 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/input/MinecraftMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/input/MinecraftMixin.java @@ -7,7 +7,7 @@ package dev.isxander.controlify.mixins.feature.input; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.ingame.PickBlockAccessor; +import dev.isxander.controlify.impl.ingame.PickBlockAccessor; import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/oofinput/MinecraftMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/oofinput/MinecraftMixin.java index 8ce668950..f2bc51be6 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/oofinput/MinecraftMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/oofinput/MinecraftMixin.java @@ -7,7 +7,7 @@ package dev.isxander.controlify.mixins.feature.oofinput; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import net.minecraft.client.Minecraft; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/patches/analogueboat/AbstractBoatMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/patches/analogueboat/AbstractBoatMixin.java index a26853db1..155fb123f 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/patches/analogueboat/AbstractBoatMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/patches/analogueboat/AbstractBoatMixin.java @@ -7,7 +7,7 @@ package dev.isxander.controlify.mixins.feature.patches.analogueboat; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.fixes.boatfix.AnalogBoatInput; +import dev.isxander.controlify.impl.boatfix.AnalogBoatInput; import net.minecraft.world.entity.vehicle.boat.AbstractBoat; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/patches/analogueboat/LocalPlayerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/patches/analogueboat/LocalPlayerMixin.java index 6bfa0dcd5..bfdcf8fe8 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/patches/analogueboat/LocalPlayerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/patches/analogueboat/LocalPlayerMixin.java @@ -8,11 +8,11 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.fixes.boatfix.AnalogBoatInput; -import dev.isxander.controlify.ingame.InGameInputHandler; -import dev.isxander.controlify.utils.MthExt; +import dev.isxander.controlify.impl.boatfix.AnalogBoatInput; +import dev.isxander.controlify.impl.ingame.InGameInputHandler; +import dev.isxander.controlify.impl.utils.MthExt; import net.minecraft.client.player.ClientInput; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.phys.Vec2; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/ClientPacketListenerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/ClientPacketListenerMixin.java index 8ba47c34a..696b7768a 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/ClientPacketListenerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/ClientPacketListenerMixin.java @@ -10,9 +10,9 @@ import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.api.bind.InputBinding; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.font.BindingFontHelper; +import dev.isxander.controlify.impl.api.bind.InputBinding; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.font.BindingFontHelper; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/MovementTutorialStepInstanceMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/MovementTutorialStepInstanceMixin.java index 073025ab0..120c24a14 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/MovementTutorialStepInstanceMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/MovementTutorialStepInstanceMixin.java @@ -9,8 +9,8 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.font.BindingFontHelper; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.font.BindingFontHelper; import net.minecraft.client.tutorial.MovementTutorialStepInstance; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/OpenInventoryTutorialStepMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/OpenInventoryTutorialStepMixin.java index 3a7455452..64d382f0f 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/OpenInventoryTutorialStepMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/OpenInventoryTutorialStepMixin.java @@ -9,8 +9,8 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.font.BindingFontHelper; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.font.BindingFontHelper; import net.minecraft.client.tutorial.OpenInventoryTutorialStep; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/PunchTreeTutorialStepInstanceMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/PunchTreeTutorialStepInstanceMixin.java index a1d01749a..0984119e3 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/PunchTreeTutorialStepInstanceMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/patches/keymessages/PunchTreeTutorialStepInstanceMixin.java @@ -9,8 +9,8 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.font.BindingFontHelper; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.font.BindingFontHelper; import net.minecraft.client.tutorial.PunchTreeTutorialStepInstance; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/patches/sprintfix/LocalPlayerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/patches/sprintfix/LocalPlayerMixin.java index b5b5f7956..1cf5c4c6f 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/patches/sprintfix/LocalPlayerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/patches/sprintfix/LocalPlayerMixin.java @@ -11,7 +11,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import net.minecraft.client.player.ClientInput; import net.minecraft.client.player.LocalPlayer; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/reacharound/MinecraftMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/reacharound/MinecraftMixin.java index a4eb82d50..27335390c 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/reacharound/MinecraftMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/reacharound/MinecraftMixin.java @@ -7,7 +7,7 @@ package dev.isxander.controlify.mixins.feature.reacharound; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.reacharound.ReachAroundHandler; +import dev.isxander.controlify.impl.reacharound.ReachAroundHandler; import net.minecraft.client.Minecraft; import net.minecraft.world.entity.Entity; import net.minecraft.world.phys.HitResult; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/MinecraftMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/MinecraftMixin.java index 9e5bbe5e2..be4f096b9 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/MinecraftMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/MinecraftMixin.java @@ -7,7 +7,7 @@ package dev.isxander.controlify.mixins.feature.rumble; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.controller.ControllerImpl; import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -19,7 +19,7 @@ public class MinecraftMixin { @Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;Z)V", at = @At("HEAD")) private void clearRumbleEffects(CallbackInfo ci) { ControlifyApi.get().getCurrentController() - .flatMap(ControllerEntity::rumble) + .flatMap(ControllerImpl::rumble) .ifPresent(controller -> controller.rumbleManager().clearEffects()); } } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/blockbreak/MultiPlayerGameModeMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/blockbreak/MultiPlayerGameModeMixin.java index 04c2f5082..f229dadde 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/blockbreak/MultiPlayerGameModeMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/blockbreak/MultiPlayerGameModeMixin.java @@ -9,10 +9,11 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.rumble.ContinuousRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; -import dev.isxander.controlify.utils.Easings; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.Easings; import net.minecraft.client.multiplayer.MultiPlayerGameMode; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -25,9 +26,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.concurrent.atomic.AtomicBoolean; + @Mixin(MultiPlayerGameMode.class) public class MultiPlayerGameModeMixin { - @Unique private ContinuousRumbleEffect blockBreakRumble = null; + @Unique private RumbleEffectInstance blockBreakRumble = null; + @Unique private AtomicBoolean blockBreakStopped; @Inject( method = "lambda$startDestroyBlock$1", @@ -74,21 +78,22 @@ private boolean onAbortBreakingBlock(boolean original) { @Unique private void startRumble(BlockState state) { stopRumble(); - var effect = ContinuousRumbleEffect.builder() + var stopped = new AtomicBoolean(); + blockBreakStopped = stopped; + var effect = RumbleEffect.continuous() .byTick(tick -> new RumbleState( 0.02f + (float)Easings.easeInQuad(Math.min(1, state.getBlock().defaultDestroyTime() / 20f)) * 0.25f, 0.01f )) .minTime(1) - .build(); + .stopCondition(stopped::get); - blockBreakRumble = effect; - ControlifyApi.get().playRumbleEffect(RumbleSource.INTERACTION, effect); + blockBreakRumble = ControlifyApi.get().playRumbleEffect(CUtil.rl("block_break"), effect).orElse(null); } @Unique private void stopRumble() { if (blockBreakRumble != null) { - blockBreakRumble.stop(); + blockBreakStopped.set(true); blockBreakRumble = null; } } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/damage/ClientPacketListenerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/damage/ClientPacketListenerMixin.java index f8257a718..5370886f1 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/damage/ClientPacketListenerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/damage/ClientPacketListenerMixin.java @@ -7,8 +7,8 @@ package dev.isxander.controlify.mixins.feature.rumble.damage; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.rumble.BasicRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.player.LocalPlayer; @@ -56,18 +56,16 @@ private void onHurtAnimation(ClientboundHurtAnimationPacket packet, CallbackInfo @Unique private void playIncomingDamageRumble() { ControlifyApi.get().playRumbleEffect( - RumbleSource.PLAYER, - BasicRumbleEffect.constant(0.8f, 0.5f, 5) + CUtil.rl("incoming_damage"), + RumbleEffect.finite().constant(0.8f, 0.5f, 5) ); } @Unique private void playOutgoingDamageRumble() { ControlifyApi.get().playRumbleEffect( - RumbleSource.INTERACTION, - BasicRumbleEffect.seq( - BasicRumbleEffect.constant(0.18f, 0.4f, 1), - BasicRumbleEffect.constant(0.06f, 0.16f, 1) - ) + CUtil.rl("outgoing_damage"), + RumbleEffect.finite().constant(0.18f, 0.4f, 1) + .then(RumbleEffect.finite().constant(0.06f, 0.16f, 1)) ); } } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/explosion/ClientPacketListenerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/explosion/ClientPacketListenerMixin.java index a6c5b011f..bbfb5b460 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/explosion/ClientPacketListenerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/explosion/ClientPacketListenerMixin.java @@ -7,9 +7,9 @@ package dev.isxander.controlify.mixins.feature.rumble.explosion; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.rumble.BasicRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.network.protocol.game.ClientboundExplodePacket; @@ -32,18 +32,16 @@ private void onClientExplosion(ClientboundExplodePacket packet, CallbackInfo ci) } ControlifyApi.get().playRumbleEffect( - RumbleSource.WORLD, - BasicRumbleEffect.seq( - BasicRumbleEffect.constant(magnitude, magnitude, 2), // initial boom - BasicRumbleEffect.byTime(t -> { + CUtil.rl("explosion"), + RumbleEffect.finite().constant(magnitude, magnitude, 2) // initial boom + .then(RumbleEffect.finite().byTime(t -> { float decay = 1f - t; decay *= decay; return new RumbleState( magnitude * 0.8f * decay, magnitude * 0.2f * decay ); - }, 8) // low-frequency aftershock - ) + }, 8)) // low-frequency aftershock ); } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/explosion/LightningBoltMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/explosion/LightningBoltMixin.java index a9aa814bb..bad9fb55e 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/explosion/LightningBoltMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/explosion/LightningBoltMixin.java @@ -8,9 +8,9 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.rumble.BasicRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.world.entity.LightningBolt; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -21,11 +21,9 @@ public class LightningBoltMixin { private boolean onLightningStrike(boolean client) { if (client) { ControlifyApi.get().playRumbleEffect( - RumbleSource.WORLD, - BasicRumbleEffect.seq( - BasicRumbleEffect.constant(1f, 0.2f, 6), // initial boom - BasicRumbleEffect.byTime(t -> new RumbleState(0f, 1 - t*0.2f), 10) // explosion - ) + CUtil.rl("lightning"), + RumbleEffect.finite().constant(1f, 0.2f, 6) // initial boom + .then(RumbleEffect.finite().byTime(t -> new RumbleState(0f, 1 - t*0.2f), 10)) // explosion ); } return client; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/fishing/FishingHookMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/fishing/FishingHookMixin.java index 5eb4de535..2be9370f5 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/fishing/FishingHookMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/fishing/FishingHookMixin.java @@ -8,8 +8,9 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.rumble.ContinuousRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.projectile.FishingHook; @@ -26,18 +27,17 @@ public class FishingHookMixin { @Shadow private boolean biting; @Unique private boolean isLocalPlayerHook; - @Unique private ContinuousRumbleEffect bitingRumble; + @Unique private RumbleEffectInstance bitingRumble; @ModifyExpressionValue(method = "onSyncedDataUpdated", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/syncher/SynchedEntityData;get(Lnet/minecraft/network/syncher/EntityDataAccessor;)Ljava/lang/Object;", ordinal = 1)) private Object onBitingStateUpdated(Object bitingObj) { var biting = (boolean) bitingObj; if (isLocalPlayerHook) { if (biting && !this.biting) { - this.bitingRumble = ContinuousRumbleEffect.builder() - .constant(0f, 0.05f) - .build(); + var effect = RumbleEffect.continuous() + .constant(0f, 0.05f); - ControlifyApi.get().playRumbleEffect(RumbleSource.INTERACTION, this.bitingRumble); + this.bitingRumble = ControlifyApi.get().playRumbleEffect(CUtil.rl("fishing_bite"), effect).orElse(null); } else if (!biting && this.biting) { stopBitingRumble(); } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/itembreak/LocalPlayerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/itembreak/LocalPlayerMixin.java index dc44ed737..fcd5d365c 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/itembreak/LocalPlayerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/itembreak/LocalPlayerMixin.java @@ -7,9 +7,9 @@ package dev.isxander.controlify.mixins.feature.rumble.itembreak; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.rumble.BasicRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; @@ -20,8 +20,8 @@ public class LocalPlayerMixin extends LivingEntityMixin { @Override protected void onBreakItemParticles(ItemStack stack, CallbackInfo ci) { ControlifyApi.get().playRumbleEffect( - RumbleSource.PLAYER, - BasicRumbleEffect.byTick(tick -> new RumbleState(tick <= 4 ? 1f : 0f, 1f), 10) + CUtil.rl("item_break"), + RumbleEffect.finite().byTick(tick -> new RumbleState(tick <= 4 ? 1f : 0f, 1f), 10) ); } } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/levelevents/LevelEventHandlerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/levelevents/LevelEventHandlerMixin.java index e2f6a2f75..828fea31f 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/levelevents/LevelEventHandlerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/levelevents/LevelEventHandlerMixin.java @@ -7,10 +7,10 @@ package dev.isxander.controlify.mixins.feature.rumble.levelevents; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.rumble.BasicRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; -import dev.isxander.controlify.utils.Easings; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.utils.CUtil; +import dev.isxander.controlify.impl.utils.Easings; import net.minecraft.client.renderer.*; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.LevelEvent; @@ -25,11 +25,9 @@ public class LevelEventHandlerMixin { private void onLevelEvent(int eventId, BlockPos pos, int data, CallbackInfo ci) { switch (eventId) { case LevelEvent.SOUND_ANVIL_USED -> ControlifyApi.get().playRumbleEffect( - RumbleSource.GUI, - BasicRumbleEffect.seq( - BasicRumbleEffect.constant(1f, 0.5f, 2), - BasicRumbleEffect.empty(5) - ).repeat(3) + CUtil.rl("anvil"), + RumbleEffect.finite().constant(1f, 0.5f, 2) + .then(RumbleEffect.finite().constant(0f, 0f, 5)).repeat(3) ); } } @@ -38,25 +36,21 @@ private void onLevelEvent(int eventId, BlockPos pos, int data, CallbackInfo ci) private void onGlobalLevelEvent(int eventId, BlockPos pos, int data, CallbackInfo ci) { switch (eventId) { case LevelEvent.SOUND_DRAGON_DEATH -> ControlifyApi.get().playRumbleEffect( - RumbleSource.WORLD, - BasicRumbleEffect.seq( - BasicRumbleEffect.constant(1f, 1f, 194), - BasicRumbleEffect.byTime(t -> { + CUtil.rl("dragon_death"), + RumbleEffect.finite().constant(1f, 1f, 194) + .then(RumbleEffect.finite().byTime(t -> { float easeOutQuad = (float) Easings.easeOutQuad(t); return new RumbleState(1 - easeOutQuad, 1 - easeOutQuad); - }, 63) - ).prioritised(10) + }, 63)) ); case LevelEvent.SOUND_WITHER_BOSS_SPAWN -> ControlifyApi.get().playRumbleEffect( - RumbleSource.WORLD, - BasicRumbleEffect.seq( - BasicRumbleEffect.constant(1f, 1f, 9), - BasicRumbleEffect.constant(0.1f, 1f, 14), - BasicRumbleEffect.byTime(t -> { + CUtil.rl("wither_spawn"), + RumbleEffect.finite().constant(1f, 1f, 9) + .then(RumbleEffect.finite().constant(0.1f, 1f, 14)) + .then(RumbleEffect.finite().byTime(t -> { float easeOutQuad = 1 - (1 - t) * (1 - t); return new RumbleState(0f, 1 - easeOutQuad); - }, 56) - ).prioritised(10) + }, 56)) ); } } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/slowblock/LocalPlayerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/slowblock/LocalPlayerMixin.java index cb290e01d..76660ecc5 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/slowblock/LocalPlayerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/slowblock/LocalPlayerMixin.java @@ -8,9 +8,10 @@ import com.mojang.authlib.GameProfile; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.rumble.ContinuousRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.ClientInput; @@ -29,7 +30,7 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer { @Shadow public ClientInput input; - @Unique private ContinuousRumbleEffect slowBlockRumble = null; + @Unique private RumbleEffectInstance slowBlockRumble = null; public LocalPlayerMixin(ClientLevel world, GameProfile profile) { super(world, profile); @@ -53,22 +54,21 @@ private void manageSlowBlockRumble(CallbackInfo ci) { } @Unique private void ensureRumbleStarted() { - if (slowBlockRumble == null || slowBlockRumble.isFinished()) { - slowBlockRumble = ContinuousRumbleEffect.builder() + if (slowBlockRumble == null || slowBlockRumble.hasFinished()) { + var effect = RumbleEffect.continuous() .byTick(i -> { float movementAmount = input.getMoveVector().length(); return new RumbleState(0.3f * movementAmount, 0.5f * movementAmount); }) - .timeout(100) - .build(); - ControlifyApi.get().playRumbleEffect(RumbleSource.PLAYER, slowBlockRumble); + .timeout(100); + slowBlockRumble = ControlifyApi.get().playRumbleEffect(CUtil.rl("slow_block"), effect).orElse(null); } else { - slowBlockRumble.heartbeat(); + slowBlockRumble.keepAlive(); } } @Unique private void ensureRumbleStopped() { - if (slowBlockRumble != null && !slowBlockRumble.isFinished()) { + if (slowBlockRumble != null && !slowBlockRumble.hasFinished()) { slowBlockRumble.stop(); } } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/useitem/ClientPacketListenerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/useitem/ClientPacketListenerMixin.java index 16b1821d4..1ece139df 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/useitem/ClientPacketListenerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/useitem/ClientPacketListenerMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.rumble.useitem; -import dev.isxander.controlify.rumble.ContinuousRumbleEffect; -import dev.isxander.controlify.rumble.effects.UseItemEffectHolder; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; +import dev.isxander.controlify.impl.controller.rumble.effects.UseItemEffectHolder; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.network.protocol.game.ClientboundRespawnPacket; @@ -21,7 +21,7 @@ public class ClientPacketListenerMixin { @Inject(method = "handleRespawn", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;player:Lnet/minecraft/client/player/LocalPlayer;", opcode = Opcodes.PUTFIELD)) private void clearUseItemRumble(ClientboundRespawnPacket packet, CallbackInfo ci) { - ContinuousRumbleEffect effect = ((UseItemEffectHolder) Minecraft.getInstance().player).controlify$getUseItemEffect(); + RumbleEffectInstance effect = ((UseItemEffectHolder) Minecraft.getInstance().player).controlify$getUseItemEffect(); if (effect != null) effect.stop(); } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/useitem/LocalPlayerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/useitem/LocalPlayerMixin.java index ab93c1261..691227213 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/useitem/LocalPlayerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/useitem/LocalPlayerMixin.java @@ -7,8 +7,11 @@ package dev.isxander.controlify.mixins.feature.rumble.useitem; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.rumble.*; -import dev.isxander.controlify.rumble.effects.UseItemEffectHolder; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleEffectInstance; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.controller.rumble.effects.UseItemEffectHolder; +import dev.isxander.controlify.impl.utils.CUtil; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.item.BowItem; @@ -21,48 +24,42 @@ @Mixin(LocalPlayer.class) public abstract class LocalPlayerMixin extends LivingEntityMixin implements UseItemEffectHolder { - @Unique private ContinuousRumbleEffect useItemRumble; + @Unique private RumbleEffectInstance useItemRumble; @Override protected void onStartUsingItem(InteractionHand hand, CallbackInfo ci, ItemStack stack) { switch (stack.getUseAnimation()) { - case BOW -> startRumble(ContinuousRumbleEffect.builder() + case BOW -> startRumble(RumbleEffect.continuous() .byTick(tick -> new RumbleState( tick % 7 <= 3 && tick > BowItem.MAX_DRAW_DURATION ? 0.1f : 0f, BowItem.getPowerForTime(tick) - )) - .build()); + ))); case CROSSBOW -> { int chargeDuration = CrossbowItem.getChargeDuration( stack, (LocalPlayer) (Object) this ); - startRumble(ContinuousRumbleEffect.builder() + startRumble(RumbleEffect.continuous() .byTick(tick -> new RumbleState( 0f, (float) tick / chargeDuration )) - .timeout(chargeDuration) - .build()); + .timeout(chargeDuration)); } - case BLOCK, SPYGLASS -> startRumble(ContinuousRumbleEffect.builder() + case BLOCK, SPYGLASS -> startRumble(RumbleEffect.continuous() .byTick(tick -> new RumbleState( 0f, tick % 4 / 4f * 0.12f + 0.05f - )) - .build()); - case EAT, DRINK -> startRumble(ContinuousRumbleEffect.builder() - .constant(0.1f, 0.2f) - .build()); - case TOOT_HORN -> startRumble(ContinuousRumbleEffect.builder() + ))); + case EAT, DRINK -> startRumble(RumbleEffect.continuous() + .constant(0.1f, 0.2f)); + case TOOT_HORN -> startRumble(RumbleEffect.continuous() .byTick(tick -> new RumbleState( Math.min(1f, tick / 10f), 0.25f - )) - .build()); - case SPEAR -> startRumble(ContinuousRumbleEffect.builder() - .constant(0.3f, 0.3f) - .build()); + ))); + case SPEAR -> startRumble(RumbleEffect.continuous() + .constant(0.3f, 0.3f)); } } @@ -79,13 +76,13 @@ protected void onStopUsingItem(CallbackInfo ci) { } } - @Unique private void startRumble(ContinuousRumbleEffect effect) { - ControlifyApi.get().playRumbleEffect(RumbleSource.INTERACTION, effect); - this.useItemRumble = effect; + @Unique private void startRumble(RumbleEffect effect) { + if (useItemRumble != null) useItemRumble.stop(); + this.useItemRumble = ControlifyApi.get().playRumbleEffect(CUtil.rl("use_item"), effect).orElse(null); } @Override - public @Nullable ContinuousRumbleEffect controlify$getUseItemEffect() { + public @Nullable RumbleEffectInstance controlify$getUseItemEffect() { return useItemRumble; } } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/waterland/LocalPlayerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/waterland/LocalPlayerMixin.java index dc2d5c5b9..01d3e86c6 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/rumble/waterland/LocalPlayerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/rumble/waterland/LocalPlayerMixin.java @@ -7,10 +7,11 @@ package dev.isxander.controlify.mixins.feature.rumble.waterland; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.rumble.BasicRumbleEffect; -import dev.isxander.controlify.rumble.RumbleSource; -import dev.isxander.controlify.rumble.RumbleState; +import dev.isxander.controlify.api.controller.rumble.RumbleEffect; +import dev.isxander.controlify.api.controller.rumble.RumbleState; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.utils.CUtil; +import java.util.Objects; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -20,8 +21,6 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Objects; - @Mixin(LocalPlayer.class) public abstract class LocalPlayerMixin extends PlayerMixin { protected LocalPlayerMixin(EntityType entityType, Level level) { @@ -34,7 +33,7 @@ protected void splashRumble(CallbackInfo ci) { return; } - ControlifyApi.get().getCurrentController().flatMap(ControllerEntity::rumble).ifPresent(rumble -> { + ControlifyApi.get().getCurrentController().flatMap(ControllerImpl::rumble).ifPresent(rumble -> { Entity entity = Objects.requireNonNullElse(this.getControllingPassenger(), this); float f = entity == this ? 0.2F : 0.9F; Vec3 vec3 = entity.getDeltaMovement(); @@ -42,9 +41,9 @@ protected void splashRumble(CallbackInfo ci) { if (impactForce >= 0.05f) { float multiplier = Math.min(1, impactForce / 0.5f); - rumble.rumbleManager().play( - RumbleSource.PLAYER, - BasicRumbleEffect.byTime( + rumble.playEffect( + CUtil.rl("water_land"), + RumbleEffect.finite().byTime( t -> new RumbleState(multiplier * (1 - t), multiplier * 0.5f), impactForce < 0.25f ? 10 : 20 ) diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/ContainerEventHandlerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/ContainerEventHandlerMixin.java index 261c441a6..8cfe4936a 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/ContainerEventHandlerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/ContainerEventHandlerMixin.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.mixins.feature.screenop; -import dev.isxander.controlify.screenop.CustomFocus; +import dev.isxander.controlify.impl.screenop.CustomFocus; import net.minecraft.client.gui.components.events.ContainerEventHandler; import net.minecraft.client.gui.components.events.GuiEventListener; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/GuiMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/GuiMixin.java index 0ad891a81..73f1a0292 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/GuiMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/GuiMixin.java @@ -8,8 +8,8 @@ import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Local; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.keyboard.KeyboardOverlayScreen; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardOverlayScreen; import net.minecraft.client.gui.screens.Screen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/ScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/ScreenMixin.java index 48bc4eb46..2a9ebf951 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/ScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/ScreenMixin.java @@ -7,10 +7,10 @@ package dev.isxander.controlify.mixins.feature.screenop; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.screenop.ScreenProcessorFactory; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.screenop.ScreenProcessorFactory; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; import net.minecraft.client.gui.screens.Screen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/bundle/BundleMouseActionsMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/bundle/BundleMouseActionsMixin.java index a9a7f4038..f5d6f1967 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/bundle/BundleMouseActionsMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/bundle/BundleMouseActionsMixin.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.bundle; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.compat.vanilla.BundleItemSlotControllerAction; -import dev.isxander.controlify.screenop.compat.vanilla.ItemSlotControllerAction; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.compat.vanilla.BundleItemSlotControllerAction; +import dev.isxander.controlify.impl.screenop.compat.vanilla.ItemSlotControllerAction; import net.minecraft.client.gui.BundleMouseActions; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; @@ -20,7 +20,7 @@ public abstract class BundleMouseActionsMixin implements ItemSlotControllerActio protected abstract void toggleSelectedBundleItem(ItemStack bundleItem, int slotIndex, int selectedItem); @Override - public boolean controlify$onControllerInput(ItemStack stack, int hoveredSlotIndex, ControllerEntity controller) { + public boolean controlify$onControllerInput(ItemStack stack, int hoveredSlotIndex, ControllerImpl controller) { return BundleItemSlotControllerAction.onControllerInput(stack, hoveredSlotIndex, controller, this::toggleSelectedBundleItem); } } diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/ChatComponentMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/ChatComponentMixin.java index 14f3a0e88..9a1da99be 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/ChatComponentMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/ChatComponentMixin.java @@ -9,8 +9,8 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.screenop.keyboard.ChatKeyboardDucky; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.screenop.keyboard.ChatKeyboardDucky; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.gui.components.ChatComponent; import net.minecraft.client.gui.screens.ChatScreen; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/ChatScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/ChatScreenMixin.java index 6e5637684..4e257c61c 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/ChatScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/ChatScreenMixin.java @@ -11,9 +11,9 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.mojang.blaze3d.platform.InputConstants; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.ChatScreenProcessor; -import dev.isxander.controlify.screenop.keyboard.*; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.ChatScreenProcessor; +import dev.isxander.controlify.impl.screenop.keyboard.*; import net.minecraft.client.gui.components.CommandSuggestions; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.components.events.GuiEventListener; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/CommandSuggestionsMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/CommandSuggestionsMixin.java index 77189c7e5..4963ec618 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/CommandSuggestionsMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/chat/CommandSuggestionsMixin.java @@ -7,9 +7,9 @@ package dev.isxander.controlify.mixins.feature.screenop.impl.chat; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.screenop.keyboard.ChatKeyboardDucky; -import dev.isxander.controlify.screenop.compat.vanilla.ChatScreenProcessor; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.screenop.keyboard.ChatKeyboardDucky; +import dev.isxander.controlify.impl.screenop.compat.vanilla.ChatScreenProcessor; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.CommandSuggestions; import net.minecraft.client.gui.screens.ChatScreen; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/AbstractContainerScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/AbstractContainerScreenMixin.java index b90198bfd..bf0e10033 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/AbstractContainerScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/AbstractContainerScreenMixin.java @@ -9,12 +9,12 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalRef; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.AbstractContainerScreenProcessor; -import dev.isxander.controlify.screenop.compat.vanilla.ItemSlotControllerAction; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.AbstractContainerScreenProcessor; +import dev.isxander.controlify.impl.screenop.compat.vanilla.ItemSlotControllerAction; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.ItemSlotMouseAction; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; @@ -74,7 +74,7 @@ private void triggerSlotHovered(GuiGraphicsExtractor graphics, int mouseX, int m } } - @Unique protected boolean handleControllerItemSlotActions(ControllerEntity controller) { + @Unique protected boolean handleControllerItemSlotActions(ControllerImpl controller) { for (ItemSlotMouseAction itemSlotMouseAction : this.itemSlotMouseActions) { if (itemSlotMouseAction instanceof ItemSlotControllerAction itemSlotControllerAction && itemSlotMouseAction.matches(this.hoveredSlot) diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/AbstractRecipeBookScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/AbstractRecipeBookScreenMixin.java index f8fcdadfa..1a8e89175 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/AbstractRecipeBookScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/AbstractRecipeBookScreenMixin.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.container; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.RecipeBookScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.RecipeBookScreenProcessor; import net.minecraft.client.gui.screens.inventory.*; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; import net.minecraft.client.gui.screens.recipebook.RecipeUpdateListener; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/CreativeModeInventoryScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/CreativeModeInventoryScreenMixin.java index 5e1925e3d..16d00a8ee 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/CreativeModeInventoryScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/container/CreativeModeInventoryScreenMixin.java @@ -6,12 +6,12 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.container; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.CreativeModeInventoryScreenProcessor; -import dev.isxander.controlify.screenop.compat.vanilla.EditBoxComponentProcessor; -import dev.isxander.controlify.screenop.keyboard.InputTarget; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.CreativeModeInventoryScreenProcessor; +import dev.isxander.controlify.impl.screenop.compat.vanilla.EditBoxComponentProcessor; +import dev.isxander.controlify.impl.screenop.keyboard.InputTarget; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractButtonMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractButtonMixin.java index 146ecfb6e..3eee8f6b9 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractButtonMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractButtonMixin.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.elements; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.AbstractButtonComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.AbstractButtonComponentProcessor; import net.minecraft.client.gui.components.AbstractButton; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractContainerEventHandlerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractContainerEventHandlerMixin.java index 58d629604..7b0010289 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractContainerEventHandlerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractContainerEventHandlerMixin.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.elements; -import dev.isxander.controlify.screenop.CustomFocus; +import dev.isxander.controlify.impl.screenop.CustomFocus; import net.minecraft.client.gui.components.events.AbstractContainerEventHandler; import net.minecraft.client.gui.components.events.GuiEventListener; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractSliderButtonMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractSliderButtonMixin.java index 9404aa0c5..c9972879a 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractSliderButtonMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractSliderButtonMixin.java @@ -7,10 +7,10 @@ package dev.isxander.controlify.mixins.feature.screenop.impl.elements; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.SliderComponentProcessor; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.SliderComponentProcessor; import net.minecraft.client.InputType; import net.minecraft.client.gui.components.AbstractSliderButton; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractWidgetMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractWidgetMixin.java index 2c3503a84..09abcf156 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractWidgetMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/AbstractWidgetMixin.java @@ -7,10 +7,10 @@ package dev.isxander.controlify.mixins.feature.screenop.impl.elements; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.controller.ControllerEntity; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.controller.ControllerImpl; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.input.MouseButtonEvent; import org.spongepowered.asm.mixin.Mixin; @@ -29,7 +29,7 @@ private boolean openKeyboardInVmouseMode(AbstractWidget instance, MouseButtonEve assert MinecraftUtil.getScreen() != null; Controlify controlify = Controlify.instance(); - ControllerEntity controller = controlify.getCurrentController().orElse(null); + ControllerImpl controller = controlify.getCurrentController().orElse(null); if (controller != null && controlify.virtualMouseHandler().isVirtualMouseEnabled()) { var screenProcessor = ScreenProcessorProvider.provide(MinecraftUtil.getScreen()); diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/ContainerObjectSelectionListEntryMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/ContainerObjectSelectionListEntryMixin.java index 21de78b44..fcc42c018 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/ContainerObjectSelectionListEntryMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/ContainerObjectSelectionListEntryMixin.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.elements; -import dev.isxander.controlify.screenop.CustomFocus; +import dev.isxander.controlify.impl.screenop.CustomFocus; import net.minecraft.client.gui.components.ContainerObjectSelectionList; import net.minecraft.client.gui.components.events.GuiEventListener; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/EditBoxMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/EditBoxMixin.java index 47c767f6c..8a8d90a1a 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/EditBoxMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/elements/EditBoxMixin.java @@ -11,14 +11,14 @@ import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.EditBoxComponentProcessor; -import dev.isxander.controlify.screenop.keyboard.CommonKeyboardHints; -import dev.isxander.controlify.screenop.keyboard.ComponentKeyboardBehaviour; -import dev.isxander.controlify.screenop.keyboard.KeyboardOverlayScreen; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.EditBoxComponentProcessor; +import dev.isxander.controlify.impl.screenop.keyboard.CommonKeyboardHints; +import dev.isxander.controlify.impl.screenop.keyboard.ComponentKeyboardBehaviour; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardOverlayScreen; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphicsExtractor; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/CreateWorldScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/CreateWorldScreenMixin.java index 3e437fc10..7e08af07b 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/CreateWorldScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/CreateWorldScreenMixin.java @@ -7,12 +7,12 @@ package dev.isxander.controlify.mixins.feature.screenop.impl.outofgame; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.CreateWorldScreenProcessor; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.CreateWorldScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/DirectJoinServerScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/DirectJoinServerScreenMixin.java index 4db72e6fa..80a8889ba 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/DirectJoinServerScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/DirectJoinServerScreenMixin.java @@ -9,9 +9,9 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.AddServerLikeScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.AddServerLikeScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.DirectJoinServerScreen; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/JoinMultiplayerScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/JoinMultiplayerScreenMixin.java index af33f0054..39e5bab56 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/JoinMultiplayerScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/JoinMultiplayerScreenMixin.java @@ -9,9 +9,9 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.JoinMultiplayerScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.JoinMultiplayerScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; import net.minecraft.client.gui.screens.multiplayer.ServerSelectionList; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/LanguageSelectionListEntryMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/LanguageSelectionListEntryMixin.java index 22b00f5c8..9e8466a67 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/LanguageSelectionListEntryMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/LanguageSelectionListEntryMixin.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.outofgame; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.LanguageSelectionListComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.LanguageSelectionListComponentProcessor; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/ManageServerScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/ManageServerScreenMixin.java index 38e8500f1..5035c7777 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/ManageServerScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/ManageServerScreenMixin.java @@ -9,9 +9,9 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.AddServerLikeScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.AddServerLikeScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.EditBox; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/OptionsScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/OptionsScreenMixin.java index 145ddb2e1..48488c1e1 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/OptionsScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/OptionsScreenMixin.java @@ -9,9 +9,9 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.OptionsScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.OptionsScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.options.OptionsScreen; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/OptionsSubScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/OptionsSubScreenMixin.java index a15f368aa..699a40fe5 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/OptionsSubScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/OptionsSubScreenMixin.java @@ -9,9 +9,9 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.OptionsSubScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.OptionsSubScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.options.OptionsSubScreen; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/PauseScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/PauseScreenMixin.java index 2a18151c5..a943897ef 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/PauseScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/PauseScreenMixin.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.outofgame; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.PauseScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.PauseScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.PauseScreen; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/SelectWorldScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/SelectWorldScreenMixin.java index 50ecb363a..ed68fe563 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/SelectWorldScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/SelectWorldScreenMixin.java @@ -9,12 +9,12 @@ import com.llamalad7.mixinextras.expression.Definition; import com.llamalad7.mixinextras.expression.Expression; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import dev.isxander.controlify.api.buttonguide.ButtonGuideApi; -import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.SelectWorldScreenProcessor; +import dev.isxander.controlify.api.gui.ButtonGuideApi; +import dev.isxander.controlify.api.gui.ButtonGuidePredicate; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.SelectWorldScreenProcessor; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/ServerSelectionListEntryMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/ServerSelectionListEntryMixin.java index acb1a5cc4..1d99a05c7 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/ServerSelectionListEntryMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/ServerSelectionListEntryMixin.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.outofgame; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.ServerSelectionListEntryComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.ServerSelectionListEntryComponentProcessor; import net.minecraft.client.gui.screens.multiplayer.ServerSelectionList; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/TitleScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/TitleScreenMixin.java index 02a6caf34..2406f90d2 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/TitleScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/TitleScreenMixin.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.outofgame; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.TitleScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.TitleScreenProcessor; import net.minecraft.client.gui.screens.TitleScreen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/WorldSelectionListEntryMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/WorldSelectionListEntryMixin.java index ddd0adb43..369566173 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/WorldSelectionListEntryMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/outofgame/WorldSelectionListEntryMixin.java @@ -6,9 +6,9 @@ */ package dev.isxander.controlify.mixins.feature.screenop.impl.outofgame; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ComponentProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.WorldListEntryComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessor; +import dev.isxander.controlify.impl.screenop.ComponentProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.WorldListEntryComponentProcessor; import net.minecraft.client.gui.screens.worldselection.WorldSelectionList; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/sign/AbstractSignEditScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/sign/AbstractSignEditScreenMixin.java index c3557bf1f..7c4e87d18 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/sign/AbstractSignEditScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/screenop/impl/sign/AbstractSignEditScreenMixin.java @@ -13,12 +13,12 @@ import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.mojang.blaze3d.platform.InputConstants; import dev.isxander.controlify.api.ControlifyApi; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ScreenProcessorProvider; -import dev.isxander.controlify.screenop.compat.vanilla.AbstractSignEditScreenProcessor; -import dev.isxander.controlify.screenop.keyboard.KeyboardLayouts; -import dev.isxander.controlify.screenop.keyboard.KeyboardWidget; -import dev.isxander.controlify.screenop.keyboard.MixinInputTarget; +import dev.isxander.controlify.impl.screenop.ScreenProcessor; +import dev.isxander.controlify.impl.screenop.ScreenProcessorProvider; +import dev.isxander.controlify.impl.screenop.compat.vanilla.AbstractSignEditScreenProcessor; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardLayouts; +import dev.isxander.controlify.impl.screenop.keyboard.KeyboardWidget; +import dev.isxander.controlify.impl.screenop.keyboard.MixinInputTarget; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.events.GuiEventListener; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/settingsbutton/ControlsScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/settingsbutton/ControlsScreenMixin.java index 1e82fa3fb..209ce2ab7 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/settingsbutton/ControlsScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/settingsbutton/ControlsScreenMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.settingsbutton; -import dev.isxander.controlify.gui.screen.ControlifySettingsScreen; -import dev.isxander.controlify.utils.MinecraftUtil; +import dev.isxander.controlify.impl.gui.screen.ControlifySettingsScreen; +import dev.isxander.controlify.impl.utils.MinecraftUtil; import net.minecraft.client.Options; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.options.OptionsSubScreen; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/util/ConnectScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/util/ConnectScreenMixin.java index a9c45a63a..4edf13e1b 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/util/ConnectScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/util/ConnectScreenMixin.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.mixins.feature.util; -import dev.isxander.controlify.Controlify; +import dev.isxander.controlify.impl.Controlify; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.ConnectScreen; import net.minecraft.client.multiplayer.ServerData; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/GuiMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/GuiMixin.java index 1e2aa11d7..666d8c0ad 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/GuiMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/GuiMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.virtualmouse; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseHandler; import net.minecraft.client.gui.screens.Screen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/InputConstantsMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/InputConstantsMixin.java index 474b93537..0f12d09ee 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/InputConstantsMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/InputConstantsMixin.java @@ -9,9 +9,9 @@ import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.sugar.Local; import com.mojang.blaze3d.platform.InputConstants; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.bindings.ControlifyBindings; -import dev.isxander.controlify.controller.ControllerEntity; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.bindings.ControlifyBindings; +import dev.isxander.controlify.impl.controller.ControllerImpl; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -21,7 +21,7 @@ public class InputConstantsMixin { @ModifyReturnValue(method = "isKeyDown", at = @At("RETURN")) private static boolean modifyIsKeyDown(boolean keyDown, @Local(argsOnly = true, name = "key") int key) { if (key == InputConstants.KEY_LSHIFT) { - ControllerEntity controller = Controlify.instance().getCurrentController().orElse(null); + ControllerImpl controller = Controlify.instance().getCurrentController().orElse(null); if (controller == null) return keyDown; return keyDown diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/MinecraftMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/MinecraftMixin.java index 286ad0ed1..321ab4f71 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/MinecraftMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/MinecraftMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.virtualmouse; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.virtualmouse.VirtualMouseHandler; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.virtualmouse.VirtualMouseHandler; import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/MouseHandlerMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/MouseHandlerMixin.java index 3104db56b..a3ff78cc9 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/MouseHandlerMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/MouseHandlerMixin.java @@ -8,8 +8,8 @@ import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.mojang.blaze3d.platform.Window; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.InputMode; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.api.InputMode; import net.minecraft.client.MouseHandler; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/AbstractContainerScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/AbstractContainerScreenMixin.java index 1b6a9dde1..488da187f 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/AbstractContainerScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/AbstractContainerScreenMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.virtualmouse.snapping; -import dev.isxander.controlify.api.vmousesnapping.ISnapBehaviour; -import dev.isxander.controlify.api.vmousesnapping.SnapPoint; +import dev.isxander.controlify.impl.api.vmousesnapping.ISnapBehaviour; +import dev.isxander.controlify.impl.api.vmousesnapping.SnapPoint; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.world.inventory.AbstractContainerMenu; import org.joml.Vector2i; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/AbstractRecipeBookScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/AbstractRecipeBookScreenMixin.java index 54dd287ce..4272aa49b 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/AbstractRecipeBookScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/AbstractRecipeBookScreenMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.virtualmouse.snapping; -import dev.isxander.controlify.api.vmousesnapping.SnapPoint; -import dev.isxander.controlify.virtualmouse.SnapUtils; +import dev.isxander.controlify.impl.api.vmousesnapping.SnapPoint; +import dev.isxander.controlify.impl.virtualmouse.SnapUtils; import net.minecraft.client.gui.screens.inventory.*; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; import net.minecraft.world.inventory.AbstractContainerMenu; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/CreativeModeInventoryScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/CreativeModeInventoryScreenMixin.java index dd3157dcb..ec3db9e2d 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/CreativeModeInventoryScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/CreativeModeInventoryScreenMixin.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.mixins.feature.virtualmouse.snapping; -import dev.isxander.controlify.api.vmousesnapping.SnapPoint; +import dev.isxander.controlify.impl.api.vmousesnapping.SnapPoint; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; import net.minecraft.world.item.CreativeModeTab; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/EnchantmentScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/EnchantmentScreenMixin.java index d1500bfba..fb2da8f33 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/EnchantmentScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/EnchantmentScreenMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.virtualmouse.snapping; -import dev.isxander.controlify.api.vmousesnapping.ISnapBehaviour; -import dev.isxander.controlify.api.vmousesnapping.SnapPoint; +import dev.isxander.controlify.impl.api.vmousesnapping.ISnapBehaviour; +import dev.isxander.controlify.impl.api.vmousesnapping.SnapPoint; import net.minecraft.client.gui.screens.inventory.EnchantmentScreen; import net.minecraft.world.inventory.EnchantmentMenu; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/LoomScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/LoomScreenMixin.java index 7c7200803..ef2aac6ce 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/LoomScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/LoomScreenMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.virtualmouse.snapping; -import dev.isxander.controlify.api.vmousesnapping.ISnapBehaviour; -import dev.isxander.controlify.api.vmousesnapping.SnapPoint; +import dev.isxander.controlify.impl.api.vmousesnapping.ISnapBehaviour; +import dev.isxander.controlify.impl.api.vmousesnapping.SnapPoint; import net.minecraft.client.gui.screens.inventory.LoomScreen; import net.minecraft.core.Holder; import net.minecraft.world.inventory.LoomMenu; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/ScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/ScreenMixin.java index ee2b5dc2f..3215273cc 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/ScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/ScreenMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.virtualmouse.snapping; -import dev.isxander.controlify.api.vmousesnapping.ISnapBehaviour; -import dev.isxander.controlify.api.vmousesnapping.SnapPoint; +import dev.isxander.controlify.impl.api.vmousesnapping.ISnapBehaviour; +import dev.isxander.controlify.impl.api.vmousesnapping.SnapPoint; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.events.GuiEventListener; diff --git a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/StonecutterScreenMixin.java b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/StonecutterScreenMixin.java index 0280af8b2..3cdf5e6dd 100644 --- a/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/StonecutterScreenMixin.java +++ b/src/main/java/dev/isxander/controlify/mixins/feature/virtualmouse/snapping/StonecutterScreenMixin.java @@ -6,8 +6,8 @@ */ package dev.isxander.controlify.mixins.feature.virtualmouse.snapping; -import dev.isxander.controlify.api.vmousesnapping.ISnapBehaviour; -import dev.isxander.controlify.api.vmousesnapping.SnapPoint; +import dev.isxander.controlify.impl.api.vmousesnapping.ISnapBehaviour; +import dev.isxander.controlify.impl.api.vmousesnapping.SnapPoint; import net.minecraft.client.gui.screens.inventory.StonecutterScreen; import net.minecraft.world.inventory.StonecutterMenu; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/dev/isxander/controlify/rumble/BasicRumbleEffect.java b/src/main/java/dev/isxander/controlify/rumble/BasicRumbleEffect.java deleted file mode 100644 index 89a3d45a2..000000000 --- a/src/main/java/dev/isxander/controlify/rumble/BasicRumbleEffect.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.rumble; - -import dev.isxander.controlify.utils.MinecraftUtil; -import net.minecraft.client.gui.screens.Screen; -import org.apache.commons.lang3.Validate; - -import java.util.Arrays; -import java.util.Objects; -import java.util.function.BooleanSupplier; -import java.util.function.Function; - -public final class BasicRumbleEffect implements RumbleEffect { - private final RumbleState[] keyframes; - private int tick = 0; - private boolean finished; - private int priority = 0; - private BooleanSupplier earlyFinishCondition = () -> false; - - public BasicRumbleEffect(RumbleState[] keyframes) { - this.keyframes = keyframes; - } - - @Override - public void tick() { - tick++; - if (tick >= keyframes.length || earlyFinishCondition.getAsBoolean()) - finished = true; - } - - @Override - public RumbleState currentState() { - if (tick == 0) - throw new IllegalStateException("Effect hasn't ticked yet."); - - return keyframes[tick - 1]; - } - - @Override - public int age() { - return tick; - } - - @Override - public boolean isFinished() { - return finished; - } - - @Override - public int priority() { - return priority; - } - - public BasicRumbleEffect prioritised(int priority) { - this.priority = priority; - return this; - } - - public RumbleState[] states() { - return keyframes; - } - - public BasicRumbleEffect earlyFinish(BooleanSupplier condition) { - var current = earlyFinishCondition; - this.earlyFinishCondition = () -> current.getAsBoolean() || condition.getAsBoolean(); - return this; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; - var that = (BasicRumbleEffect) obj; - return Arrays.equals(this.states(), that.states()) - && this.priority() == that.priority(); - } - - @Override - public int hashCode() { - return Objects.hash(Arrays.hashCode(this.states()), this.priority()); - } - - @Override - public String toString() { - return "RumbleEffect[" + - "states=" + Arrays.toString(this.states()) + ',' + - "priority=" + this.priority() + ']'; - } - - public BasicRumbleEffect seq(BasicRumbleEffect other) { - return BasicRumbleEffect.seq(this, other); - } - - public BasicRumbleEffect repeat(int count) { - Validate.isTrue(count > 0, "count must be greater than 0"); - - if (count == 1) return this; - - BasicRumbleEffect effect = this; - for (int i = 0; i < count - 1; i++) { - effect = BasicRumbleEffect.seq(effect, this); - } - return effect; - } - - /** - * Creates a rumble effect where the state is determined by the tick. - * - * @param stateFunction the function that takes a tick and returns the state for that tick. - * @param durationTicks how many ticks the effect should last for. - */ - public static BasicRumbleEffect byTick(Function stateFunction, int durationTicks) { - RumbleState[] states = new RumbleState[durationTicks]; - for (int i = 0; i < durationTicks; i++) { - states[i] = stateFunction.apply(i); - } - return new BasicRumbleEffect(states); - } - - /** - * Creates a rumble effect from a function that takes a time value from 0, start, to 1, end, and returns that tick. - * - * @param stateFunction the function that takes the time value and returns the state for that tick. - * @param durationTicks how many ticks the effect should last for. - */ - public static BasicRumbleEffect byTime(Function stateFunction, int durationTicks) { - return BasicRumbleEffect.byTick(tick -> stateFunction.apply((float) tick / (float) durationTicks), durationTicks); - } - - /** - * Creates a rumble effect that has a constant state. - * - * @param strong the strong motor magnitude. - * @param weak the weak motor magnitude - * @param durationTicks how many ticks the effect should last for. - */ - public static BasicRumbleEffect constant(float strong, float weak, int durationTicks) { - return BasicRumbleEffect.byTick(tick -> new RumbleState(strong, weak), durationTicks); - } - - public static BasicRumbleEffect empty(int durationTicks) { - return BasicRumbleEffect.byTick(tick -> new RumbleState(0f, 0f), durationTicks); - } - - public static BasicRumbleEffect seq(BasicRumbleEffect... effects) { - RumbleState[] states = Arrays.stream(effects) - .flatMap(effect -> Arrays.stream(effect.states())) - .toArray(RumbleState[]::new); - - return new BasicRumbleEffect(states); - } - - public static BooleanSupplier finishOnScreenChange() { - Screen screen = MinecraftUtil.getScreen(); - return () -> screen != MinecraftUtil.getScreen(); - } -} diff --git a/src/main/java/dev/isxander/controlify/rumble/ContinuousRumbleEffect.java b/src/main/java/dev/isxander/controlify/rumble/ContinuousRumbleEffect.java deleted file mode 100644 index 5b14b14d4..000000000 --- a/src/main/java/dev/isxander/controlify/rumble/ContinuousRumbleEffect.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.rumble; - -import net.minecraft.client.Minecraft; -import net.minecraft.util.Mth; -import net.minecraft.world.phys.Vec3; -import org.apache.commons.lang3.Validate; - -import java.util.function.BooleanSupplier; -import java.util.function.Function; -import java.util.function.Supplier; - -public class ContinuousRumbleEffect implements RumbleEffect { - private final Function stateFunction; - private final int priority; - private final int timeout; - private final int minTime; - private int tick; - private int age; - private boolean stopped; - private BooleanSupplier stopCondition; - - public ContinuousRumbleEffect(Function stateFunction, int priority, int timeout, int minTime, BooleanSupplier stopCondition) { - this.stateFunction = stateFunction; - this.priority = priority; - this.timeout = timeout; - this.minTime = minTime; - this.stopCondition = stopCondition; - } - - @Override - public void tick() { - tick++; - age++; - if (stopCondition.getAsBoolean()) - stop(); - } - - @Override - public RumbleState currentState() { - if (tick == 0) - throw new IllegalStateException("Effect hasn't ticked yet."); - - return stateFunction.apply(tick - 1); - } - - public void stop() { - stopped = true; - } - - public void heartbeat() { - age = 0; - } - - @Override - public int age() { - return tick; - } - - @Override - public boolean isFinished() { - return (stopped || (timeout > 0 && age >= timeout)) && tick >= minTime; - } - - @Override - public int priority() { - return this.priority; - } - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private Function stateFunction; - private int priority; - private int timeout = -1; - private int minTime; - private InWorldProperties inWorldProperties; - private BooleanSupplier stopCondition = () -> false; - - private Builder() { - } - - public Builder byTick(Function stateFunction) { - this.stateFunction = stateFunction; - return this; - } - - public Builder constant(RumbleState state) { - this.stateFunction = tick -> state; - return this; - } - - public Builder constant(float strong, float weak) { - return this.constant(new RumbleState(strong, weak)); - } - - public Builder timeout(int timeoutTicks) { - Validate.isTrue(timeoutTicks >= 0, "the timeout cannot be negative!"); - - this.timeout = timeoutTicks; - return this; - } - - public Builder minTime(int minTimeTicks) { - Validate.isTrue(minTimeTicks >= 0, "the minimum time cannot be negative!"); - - this.minTime = minTimeTicks; - return this; - } - - public Builder priority(int priority) { - this.priority = priority; - return this; - } - - public Builder inWorld(Supplier sourceLocation, float min, float max, float effectRange, Function fallofFunction) { - this.inWorldProperties = new InWorldProperties(sourceLocation, min, max, effectRange, fallofFunction); - stopCondition(() -> Minecraft.getInstance().getCameraEntity() == null); - return this; - } - - public Builder stopCondition(BooleanSupplier stopCondition) { - BooleanSupplier oldStopCondition = this.stopCondition; - this.stopCondition = () -> stopCondition.getAsBoolean() || oldStopCondition.getAsBoolean(); - return this; - } - - public ContinuousRumbleEffect build() { - Validate.notNull(stateFunction, "stateFunction cannot be null!"); - Validate.isTrue(minTime <= timeout || timeout == -1, "the minimum time cannot be greater than the timeout!"); - - var stateFunction = this.stateFunction; - if (inWorldProperties != null) - stateFunction = inWorldProperties.modify(stateFunction); - - return new ContinuousRumbleEffect(stateFunction, priority, timeout, minTime, stopCondition); - } - - private record InWorldProperties(Supplier sourceLocation, float minMagnitude, float maxMagnitude, float effectRange, Function fallofFunction) { - private Function modify(Function stateFunction) { - return tick -> { - if (Minecraft.getInstance().getCameraEntity() == null) - return RumbleState.NONE; - - float distanceSqr = (float) Minecraft.getInstance().getCameraEntity().distanceToSqr(sourceLocation.get()); - float normalizedDistance = Mth.clamp(distanceSqr / (effectRange * effectRange), 0, 1); - float multiplier = Mth.lerp(fallofFunction.apply(1f - normalizedDistance), minMagnitude, maxMagnitude); - - return stateFunction.apply(tick).mul(multiplier); - }; - } - } - } -} diff --git a/src/main/java/dev/isxander/controlify/rumble/RumbleCapable.java b/src/main/java/dev/isxander/controlify/rumble/RumbleCapable.java deleted file mode 100644 index 283bd06c2..000000000 --- a/src/main/java/dev/isxander/controlify/rumble/RumbleCapable.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.rumble; - -public interface RumbleCapable { - boolean setRumble(float strongMagnitude, float weakMagnitude); - - boolean supportsRumble(); - - RumbleState applyRumbleSourceStrength(RumbleState state, RumbleSource source); -} diff --git a/src/main/java/dev/isxander/controlify/rumble/RumbleEffect.java b/src/main/java/dev/isxander/controlify/rumble/RumbleEffect.java deleted file mode 100644 index 365470449..000000000 --- a/src/main/java/dev/isxander/controlify/rumble/RumbleEffect.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.rumble; - -public interface RumbleEffect extends Comparable { - void tick(); - RumbleState currentState(); - - boolean isFinished(); - - int priority(); - int age(); - - @Override - default int compareTo(RumbleEffect o) { - int priorityCompare = Integer.compare(o.priority(), this.priority()); - if (priorityCompare != 0) return priorityCompare; - return Integer.compare(this.age(), o.age()); - } -} diff --git a/src/main/java/dev/isxander/controlify/rumble/RumbleManager.java b/src/main/java/dev/isxander/controlify/rumble/RumbleManager.java deleted file mode 100644 index 0639896c5..000000000 --- a/src/main/java/dev/isxander/controlify/rumble/RumbleManager.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.rumble; - -import dev.isxander.controlify.controller.rumble.RumbleComponent; -import org.jetbrains.annotations.NotNull; - -import java.util.Comparator; -import java.util.PriorityQueue; -import java.util.Queue; - -public class RumbleManager { - private final RumbleComponent controller; - private final Queue effectQueue; - - private boolean silent, wasSilent; - - public RumbleManager(RumbleComponent controller) { - this.controller = controller; - this.effectQueue = new PriorityQueue<>(Comparator.comparing(RumbleEffectInstance::effect)); - } - - @Deprecated - public void play(RumbleEffect effect) { - play(RumbleSource.MASTER, effect); - } - - public void play(RumbleSource source, RumbleEffect effect) { - effectQueue.add(new RumbleEffectInstance(source, effect)); - } - - public void tick() { - effectQueue.removeIf(e -> e.effect().isFinished()); - effectQueue.forEach(e -> e.effect().tick()); - - if (effectQueue.isEmpty()) { - clearRumble(); - return; - } - - float strong = 0f, weak = 0f; - for (RumbleEffectInstance effect : effectQueue) { - RumbleState effectState = controller.settings().applyRumbleStrength(effect.effect().currentState(), effect.source()); - strong = Math.max(strong, effectState.strong()); - weak = Math.max(weak, effectState.weak()); - } - RumbleState state = new RumbleState(strong, weak); - - if (state.isZero()) { - clearRumble(); - return; - } - - if (silent) { - clearRumble(); - } else { - controller.queueRumble(state); - wasSilent = false; - } - } - - private void clearRumble() { - if (wasSilent) - return; - - controller.queueRumble(RumbleState.NONE); - wasSilent = true; - } - - public void clearEffects() { - effectQueue.clear(); - } - - public void setSilent(boolean silent) { - this.silent = silent; - } - - public boolean isPlaying() { - return !effectQueue.isEmpty(); - } - - private record RumbleEffectInstance(RumbleSource source, RumbleEffect effect) implements Comparable { - @Override - public int compareTo(@NotNull RumbleManager.RumbleEffectInstance o) { - return effect.compareTo(o.effect); - } - } -} diff --git a/src/main/java/dev/isxander/controlify/rumble/RumbleSource.java b/src/main/java/dev/isxander/controlify/rumble/RumbleSource.java deleted file mode 100644 index 5fe9d27d9..000000000 --- a/src/main/java/dev/isxander/controlify/rumble/RumbleSource.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2026 isXander - * This file is part of Controlify. - * - * SPDX-License-Identifier: LGPL-3.0-or-later - */ -package dev.isxander.controlify.rumble; - -import com.google.gson.JsonObject; -import com.mojang.serialization.Codec; -import dev.isxander.controlify.utils.CUtil; -import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; -import net.minecraft.resources.Identifier; - -import java.util.*; - -public record RumbleSource(Identifier id) { - public static final Codec CODEC = Identifier.CODEC - .xmap(RumbleSource::get, RumbleSource::id); - - private static final Map SOURCES = new Object2ObjectLinkedOpenHashMap<>(); - - public static final RumbleSource - MASTER = register("master"), - PLAYER = register("player"), - WORLD = register("world"), - INTERACTION = register("interaction"), - GUI = register("gui"); - - public static RumbleSource get(Identifier id) { - RumbleSource source = SOURCES.get(id); - if (source == null) { - CUtil.LOGGER.warn("Unknown rumble source: {}. Using master.", id); - return MASTER; - } - return source; - } - - public static Collection values() { - return SOURCES.values(); - } - - public static JsonObject getDefaultJson() { - JsonObject object = new JsonObject(); - for (RumbleSource source : SOURCES.values()) { - object.addProperty(source.id().toString(), 1f); - } - return object; - } - - public static Map getDefaultMap() { - Map map = new HashMap<>(); - - for (RumbleSource source : SOURCES.values()) { - map.put(source.id(), 1f); - } - - return map; - } - - public static RumbleSource register(Identifier id) { - var source = new RumbleSource(id); - SOURCES.put(id, source); - return source; - } - - public static RumbleSource register(String identifier, String path) { - return register(Identifier.fromNamespaceAndPath(identifier, path)); - } - - private static RumbleSource register(String path) { - return register("controlify", path); - } -} diff --git a/src/main/resources/assets/controlify/controller/activators.json b/src/main/resources/assets/controlify/controller/activators.json new file mode 100644 index 000000000..0db3279e4 --- /dev/null +++ b/src/main/resources/assets/controlify/controller/activators.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/src/main/resources/assets/controlify/contextual/facts/container.json b/src/main/resources/assets/controlify/controller/contextual/facts/container.json similarity index 100% rename from src/main/resources/assets/controlify/contextual/facts/container.json rename to src/main/resources/assets/controlify/controller/contextual/facts/container.json diff --git a/src/main/resources/assets/controlify/contextual/facts/in_game.json b/src/main/resources/assets/controlify/controller/contextual/facts/in_game.json similarity index 100% rename from src/main/resources/assets/controlify/contextual/facts/in_game.json rename to src/main/resources/assets/controlify/controller/contextual/facts/in_game.json diff --git a/src/main/resources/assets/controlify/contextual/guide/container.json b/src/main/resources/assets/controlify/controller/contextual/guide/container.json similarity index 100% rename from src/main/resources/assets/controlify/contextual/guide/container.json rename to src/main/resources/assets/controlify/controller/contextual/guide/container.json diff --git a/src/main/resources/assets/controlify/contextual/guide/in_game.json b/src/main/resources/assets/controlify/controller/contextual/guide/in_game.json similarity index 100% rename from src/main/resources/assets/controlify/contextual/guide/in_game.json rename to src/main/resources/assets/controlify/controller/contextual/guide/in_game.json diff --git a/src/main/resources/assets/controlify/contextual/trigger_effect/in_game.json b/src/main/resources/assets/controlify/controller/contextual/trigger_effect/in_game.json similarity index 100% rename from src/main/resources/assets/controlify/contextual/trigger_effect/in_game.json rename to src/main/resources/assets/controlify/controller/contextual/trigger_effect/in_game.json diff --git a/src/main/resources/assets/controlify/controllers/controller_identification.json5 b/src/main/resources/assets/controlify/controller/controller_identification.json5 similarity index 100% rename from src/main/resources/assets/controlify/controllers/controller_identification.json5 rename to src/main/resources/assets/controlify/controller/controller_identification.json5 diff --git a/src/main/resources/assets/controlify/controllers/default_bind/default.json b/src/main/resources/assets/controlify/controller/default_bind/default.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/default_bind/default.json rename to src/main/resources/assets/controlify/controller/default_bind/default.json diff --git a/src/main/resources/assets/controlify/controllers/default_bind/dualsense.json b/src/main/resources/assets/controlify/controller/default_bind/dualsense.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/default_bind/dualsense.json rename to src/main/resources/assets/controlify/controller/default_bind/dualsense.json diff --git a/src/main/resources/assets/controlify/controllers/default_bind/switch.json b/src/main/resources/assets/controlify/controller/default_bind/switch.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/default_bind/switch.json rename to src/main/resources/assets/controlify/controller/default_bind/switch.json diff --git a/src/main/resources/assets/controlify/controllers/default_config.json b/src/main/resources/assets/controlify/controller/default_config.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/default_config.json rename to src/main/resources/assets/controlify/controller/default_config.json diff --git a/src/main/resources/assets/controlify/controllers/font_mappings/default.json b/src/main/resources/assets/controlify/controller/font_mapping/default.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/font_mappings/default.json rename to src/main/resources/assets/controlify/controller/font_mapping/default.json diff --git a/src/main/resources/assets/controlify/controllers/font_mappings/dualsense.json b/src/main/resources/assets/controlify/controller/font_mapping/dualsense.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/font_mappings/dualsense.json rename to src/main/resources/assets/controlify/controller/font_mapping/dualsense.json diff --git a/src/main/resources/assets/controlify/controllers/font_mappings/dualshock3.json b/src/main/resources/assets/controlify/controller/font_mapping/dualshock3.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/font_mappings/dualshock3.json rename to src/main/resources/assets/controlify/controller/font_mapping/dualshock3.json diff --git a/src/main/resources/assets/controlify/controllers/font_mappings/dualshock4.json b/src/main/resources/assets/controlify/controller/font_mapping/dualshock4.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/font_mappings/dualshock4.json rename to src/main/resources/assets/controlify/controller/font_mapping/dualshock4.json diff --git a/src/main/resources/assets/controlify/controllers/font_mappings/steam_controller.json b/src/main/resources/assets/controlify/controller/font_mapping/steam_controller.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/font_mappings/steam_controller.json rename to src/main/resources/assets/controlify/controller/font_mapping/steam_controller.json diff --git a/src/main/resources/assets/controlify/controllers/font_mappings/steam_deck.json b/src/main/resources/assets/controlify/controller/font_mapping/steam_deck.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/font_mappings/steam_deck.json rename to src/main/resources/assets/controlify/controller/font_mapping/steam_deck.json diff --git a/src/main/resources/assets/controlify/controllers/font_mappings/switch.json b/src/main/resources/assets/controlify/controller/font_mapping/switch.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/font_mappings/switch.json rename to src/main/resources/assets/controlify/controller/font_mapping/switch.json diff --git a/src/main/resources/assets/controlify/controllers/font_mappings/xbox_one.json b/src/main/resources/assets/controlify/controller/font_mapping/xbox_one.json similarity index 100% rename from src/main/resources/assets/controlify/controllers/font_mappings/xbox_one.json rename to src/main/resources/assets/controlify/controller/font_mapping/xbox_one.json diff --git a/src/main/resources/assets/controlify/controllers/gamecontrollerdb-sdl2.txt b/src/main/resources/assets/controlify/controller/gamecontrollerdb-sdl2.txt similarity index 100% rename from src/main/resources/assets/controlify/controllers/gamecontrollerdb-sdl2.txt rename to src/main/resources/assets/controlify/controller/gamecontrollerdb-sdl2.txt diff --git a/src/main/resources/assets/controlify/controllers/gamecontrollerdb-sdl3.txt b/src/main/resources/assets/controlify/controller/gamecontrollerdb-sdl3.txt similarity index 100% rename from src/main/resources/assets/controlify/controllers/gamecontrollerdb-sdl3.txt rename to src/main/resources/assets/controlify/controller/gamecontrollerdb-sdl3.txt diff --git a/src/main/resources/assets/controlify/haptics/navigate.ogg b/src/main/resources/assets/controlify/controller/haptics/navigate.ogg similarity index 100% rename from src/main/resources/assets/controlify/haptics/navigate.ogg rename to src/main/resources/assets/controlify/controller/haptics/navigate.ogg diff --git a/src/main/resources/assets/controlify/keyboard_layout/full/en_us.json b/src/main/resources/assets/controlify/controller/keyboard_layout/full/en_us.json similarity index 100% rename from src/main/resources/assets/controlify/keyboard_layout/full/en_us.json rename to src/main/resources/assets/controlify/controller/keyboard_layout/full/en_us.json diff --git a/src/main/resources/assets/controlify/keyboard_layout/server_ip/en_us.json b/src/main/resources/assets/controlify/controller/keyboard_layout/server_ip/en_us.json similarity index 100% rename from src/main/resources/assets/controlify/keyboard_layout/server_ip/en_us.json rename to src/main/resources/assets/controlify/controller/keyboard_layout/server_ip/en_us.json diff --git a/src/main/resources/assets/controlify/keyboard_layout/simple/en_us.json b/src/main/resources/assets/controlify/controller/keyboard_layout/simple/en_us.json similarity index 100% rename from src/main/resources/assets/controlify/keyboard_layout/simple/en_us.json rename to src/main/resources/assets/controlify/controller/keyboard_layout/simple/en_us.json diff --git a/src/main/resources/assets/controlify/radial_icons.json b/src/main/resources/assets/controlify/controller/radial_icons.json similarity index 100% rename from src/main/resources/assets/controlify/radial_icons.json rename to src/main/resources/assets/controlify/controller/radial_icons.json diff --git a/src/main/resources/assets/controlify/controller/rumble_sources.json b/src/main/resources/assets/controlify/controller/rumble_sources.json new file mode 100644 index 000000000..9944fa8ec --- /dev/null +++ b/src/main/resources/assets/controlify/controller/rumble_sources.json @@ -0,0 +1,16 @@ +{ + "controlify:incoming_damage": "controlify:player", + "controlify:water_land": "controlify:player", + "controlify:slow_block": "controlify:player", + "controlify:outgoing_damage": "controlify:interaction", + "controlify:item_break": "controlify:interaction", + "controlify:use_item": "controlify:interaction", + "controlify:block_break": "controlify:interaction", + "controlify:fishing_bite": "controlify:interaction", + "controlify:explosion": "controlify:world", + "controlify:lightning": "controlify:world", + "controlify:dragon_death": "controlify:world", + "controlify:wither_spawn": "controlify:world", + "controlify:anvil": "controlify:gui", + "controlify:test_vibration": "controlify:master" +} diff --git a/src/main/resources/controlify-compat.iris.mixins.json b/src/main/resources/controlify-compat.iris.mixins.json index fcae699ce..a9128e320 100644 --- a/src/main/resources/controlify-compat.iris.mixins.json +++ b/src/main/resources/controlify-compat.iris.mixins.json @@ -1,5 +1,5 @@ { - "package": "dev.isxander.controlify.compatibility.iris.mixins", + "package": "dev.isxander.controlify.impl.compatibility.iris.mixins", "required": false, "minVersion": "0.8", "mixinextras": { @@ -11,7 +11,7 @@ "overwrites": { "requireAnnotations": true }, - "plugin": "dev.isxander.controlify.compatibility.iris.IrisMixinPlugin", + "plugin": "dev.isxander.controlify.impl.compatibility.iris.IrisMixinPlugin", "compatibilityLevel": "JAVA_25", "client": [ ], diff --git a/src/main/resources/controlify-compat.reeses-sodium-options.mixins.json b/src/main/resources/controlify-compat.reeses-sodium-options.mixins.json index 42ac8ca05..00ca7ef32 100644 --- a/src/main/resources/controlify-compat.reeses-sodium-options.mixins.json +++ b/src/main/resources/controlify-compat.reeses-sodium-options.mixins.json @@ -1,5 +1,5 @@ { - "package": "dev.isxander.controlify.compatibility.rso.mixins", + "package": "dev.isxander.controlify.impl.compatibility.rso.mixins", "required": false, "minVersion": "0.8", "mixinextras": { @@ -11,7 +11,7 @@ "overwrites": { "requireAnnotations": true }, - "plugin": "dev.isxander.controlify.compatibility.rso.RSOMixinPlugin", + "plugin": "dev.isxander.controlify.impl.compatibility.rso.RSOMixinPlugin", "compatibilityLevel": "JAVA_25", "client": [ "SodiumVideoOptionsScreenMixin" diff --git a/src/main/resources/controlify-compat.rrls.mixins.json b/src/main/resources/controlify-compat.rrls.mixins.json index d55a01ad9..1c06b7207 100644 --- a/src/main/resources/controlify-compat.rrls.mixins.json +++ b/src/main/resources/controlify-compat.rrls.mixins.json @@ -1,5 +1,5 @@ { - "package": "dev.isxander.controlify.compatibility.rrls.mixins", + "package": "dev.isxander.controlify.impl.compatibility.rrls.mixins", "required": false, "minVersion": "0.8", "mixinextras": { @@ -8,7 +8,7 @@ "injectors": { "defaultRequire": 0 }, - "plugin": "dev.isxander.controlify.compatibility.rrls.RrlsMixinPlugin", + "plugin": "dev.isxander.controlify.impl.compatibility.rrls.RrlsMixinPlugin", "compatibilityLevel": "JAVA_25", "client": [ ], diff --git a/src/main/resources/controlify-compat.simple-voice-chat.mixins.json b/src/main/resources/controlify-compat.simple-voice-chat.mixins.json index a6d1d1394..83cb1bb85 100644 --- a/src/main/resources/controlify-compat.simple-voice-chat.mixins.json +++ b/src/main/resources/controlify-compat.simple-voice-chat.mixins.json @@ -1,5 +1,5 @@ { - "package": "dev.isxander.controlify.compatibility.simplevoicechat.mixins", + "package": "dev.isxander.controlify.impl.compatibility.simplevoicechat.mixins", "required": false, "minVersion": "0.8", "mixinextras": { @@ -11,7 +11,7 @@ "overwrites": { "requireAnnotations": true }, - "plugin": "dev.isxander.controlify.compatibility.simplevoicechat.SVCMixinPlugin", + "plugin": "dev.isxander.controlify.impl.compatibility.simplevoicechat.SVCMixinPlugin", "compatibilityLevel": "JAVA_25", "client": [ ], diff --git a/src/main/resources/controlify-compat.sodium.mixins.json b/src/main/resources/controlify-compat.sodium.mixins.json index 542e4aaa1..892b0b4e0 100644 --- a/src/main/resources/controlify-compat.sodium.mixins.json +++ b/src/main/resources/controlify-compat.sodium.mixins.json @@ -1,5 +1,5 @@ { - "package": "dev.isxander.controlify.compatibility.sodium.mixins", + "package": "dev.isxander.controlify.impl.compatibility.sodium.mixins", "required": false, "minVersion": "0.8", "mixinextras": { @@ -11,7 +11,7 @@ "overwrites": { "requireAnnotations": true }, - "plugin": "dev.isxander.controlify.compatibility.sodium.SodiumMixinPlugin", + "plugin": "dev.isxander.controlify.impl.compatibility.sodium.SodiumMixinPlugin", "compatibilityLevel": "JAVA_25", "client": [ "VideoSettingsScreenMixin" diff --git a/src/main/resources/controlify-compat.yacl.mixins.json b/src/main/resources/controlify-compat.yacl.mixins.json index 2da3063e2..dfd9fdf92 100644 --- a/src/main/resources/controlify-compat.yacl.mixins.json +++ b/src/main/resources/controlify-compat.yacl.mixins.json @@ -1,5 +1,5 @@ { - "package": "dev.isxander.controlify.compatibility.yacl.mixins", + "package": "dev.isxander.controlify.impl.compatibility.yacl.mixins", "required": true, "minVersion": "0.8", "mixinextras": { @@ -11,7 +11,7 @@ "overwrites": { "requireAnnotations": true }, - "plugin": "dev.isxander.controlify.compatibility.yacl.YACLMixinPlugin", + "plugin": "dev.isxander.controlify.impl.compatibility.yacl.YACLMixinPlugin", "compatibilityLevel": "JAVA_25", "client": [ "CyclingControllerElementMixin", diff --git a/src/main/resources/resourcepacks/legacy_console/assets/controlify/contextual/guide/in_game.json b/src/main/resources/resourcepacks/legacy_console/assets/controlify/contextual/guide/in_game.json deleted file mode 100644 index 99a4c520c..000000000 --- a/src/main/resources/resourcepacks/legacy_console/assets/controlify/contextual/guide/in_game.json +++ /dev/null @@ -1,1194 +0,0 @@ -{ - "replace": true, - "rules": [ - { - "for": "controlify:jump", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:riding_happy_ghast" - ] - }, - "then": { - "translate": "controlify.guide.ingame.fly_up" - } - }, - { - "for": "controlify:jump", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "any_of": [ - "controlify:riding_saddled_camel", - "controlify:riding_saddled_nautilus" - ] - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.dash" - } - }, - { - "for": "controlify:jump", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:riding_saddled_equine" - ] - }, - "then": { - "translate": "key.jump" - } - }, - { - "for": "controlify:jump", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:creative_flying" - ] - }, - "then": { - "translate": "controlify.guide.ingame.fly_up" - } - }, - { - "for": "controlify:jump", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:in_water" - ] - }, - "then": { - "translate": "controlify.guide.ingame.swim_up" - } - }, - { - "for": "controlify:jump", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:on_climbable" - ] - }, - "then": { - "translate": "controlify.guide.ingame.climb_up" - } - }, - { - "for": "controlify:jump", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:on_ground" - ] - }, - "then": { - "translate": "key.jump" - } - }, - { - "for": "controlify:jump", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:can_elytra_fly" - ] - }, - "then": { - "translate": "controlify.guide.ingame.start_elytra" - } - }, - { - "for": "controlify:sneak", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:in_vehicle" - ] - }, - "then": { - "translate": "controlify.guide.ingame.dismount" - } - }, - { - "for": "controlify:sneak", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:creative_flying" - ] - }, - "then": { - "translate": "controlify.guide.ingame.fly_down" - } - }, - { - "for": "controlify:sneak", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:in_water" - ], - "none_of": [ - "controlify:on_ground" - ] - }, - "then": { - "translate": "controlify.guide.ingame.swim_down" - } - }, - { - "for": "controlify:sneak", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:on_climbable" - ] - }, - "then": { - "translate": "controlify.guide.ingame.climb_down" - } - }, - { - "for": "controlify:inventory", - "where": "right", - "if": "controlify:verbosity_reduced", - "then": { - "translate": "controlify.guide.ingame.inventory" - } - }, - { - "for": "controlify:attack", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_entity", - "controlify:is_spectator" - ] - }, - "then": { - "translate": "controlify.guide.ingame.spectate" - } - }, - { - "for": "controlify:attack", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_entity" - ], - "none_of": [ - "controlify:is_spectator" - ] - }, - "then": { - "translate": "controlify.guide.ingame.attack" - } - }, - { - "for": "controlify:attack", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_block", - "controlify:main_hand_is_tool" - ] - }, - "then": { - "translate": "controlify.guide.ingame.mine" - } - }, - { - "for": "controlify:attack", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_block" - ] - }, - "then": { - "translate": "controlify.guide.ingame.break" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_entity", - "controlify:is_spectator" - ] - }, - "then": { - "translate": "controlify.guide.ingame.spectate" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_merchant" - ] - }, - "then": { - "translate": "controlify.guide.ingame.trade" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_chest_boat", - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.open" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_container_minecart" - ] - }, - "then": { - "translate": "controlify.guide.ingame.open" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_rideable" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.ride" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_closed_openable" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.open" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_open_openable" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.close" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_container" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.open" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_button" - ] - }, - "then": { - "translate": "controlify.guide.ingame.press" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_lever" - ] - }, - "then": { - "translate": "controlify.guide.ingame.toggle" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_bell" - ] - }, - "then": { - "translate": "controlify.guide.ingame.ring" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_bed" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.sleep" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_crafting_table" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.craft" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_furnace" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.smelt" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_smoker" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.cook" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_brewing_stand" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.brew" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_enchanting_table" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.enchant" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_smithing_table" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.smith" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_repair_station" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.repair" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_stonecutter" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.cut_stone" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_loom" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.weave" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_cartography_table" - ], - "none_of": [ - "controlify:sneaking" - ] - }, - "then": { - "translate": "controlify.guide.ingame.edit_map" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "items": "#c:tools/bow" - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.shoot" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "predicates": { - "minecraft:charged_projectiles": {} - } - } - } - ], - "none_of": [ - { - "slot": "controlify:main_hand", - "item": { - "components": { - "minecraft:charged_projectiles": [] - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.shoot" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "items": "minecraft:crossbow", - "components": { - "minecraft:charged_projectiles": [] - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.load" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "predicates": { - "minecraft:blocks_attacks": {} - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.block" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "predicates": { - "minecraft:consumable": {} - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.consume" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "any_of": [ - { - "slot": "controlify:main_hand", - "item": { - "items": "#c:tools/trident" - } - }, - { - "slot": "controlify:main_hand", - "item": { - "items": "#minecraft:spears" - } - }, - { - "slot": "controlify:main_hand", - "item": { - "items": "#minecraft:eggs" - } - }, - { - "slot": "controlify:main_hand", - "item": { - "items": [ - "minecraft:snowball", - "minecraft:splash_potion", - "minecraft:lingering_potion", - "minecraft:experience_bottle", - "minecraft:ender_pearl", - "minecraft:wind_charge" - ] - } - } - ] - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.throw" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:fishing_hook_cast", - { - "slot": "controlify:main_hand", - "item": { - "items": "#c:tools/fishing_rod" - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.reel_in" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "items": "#c:tools/fishing_rod" - } - } - ], - "none_of": [ - "controlify:fishing_hook_cast" - ] - }, - "then": { - "translate": "controlify.guide.ingame.cast" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "items": "#c:tools/brush" - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.brush" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "items": "minecraft:spyglass" - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.zoom" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "predicates": { - "minecraft:instrument": {} - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.play" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:main_hand", - "item": { - "predicates": { - "minecraft:equippable": {} - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.equip" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_block", - "controlify:main_hand_is_block_item" - ] - }, - "then": { - "translate": "controlify.guide.ingame.place" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "items": "#c:tools/bow" - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.shoot" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "predicates": { - "minecraft:charged_projectiles": {} - } - } - } - ], - "none_of": [ - { - "slot": "controlify:off_hand", - "item": { - "components": { - "minecraft:charged_projectiles": [] - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.shoot" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "items": "minecraft:crossbow", - "components": { - "minecraft:charged_projectiles": [] - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.load" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "predicates": { - "minecraft:blocks_attacks": {} - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.block" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "predicates": { - "minecraft:consumable": {} - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.consume" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "any_of": [ - { - "slot": "controlify:off_hand", - "item": { - "items": "#c:tools/trident" - } - }, - { - "slot": "controlify:off_hand", - "item": { - "items": "#minecraft:spears" - } - }, - { - "slot": "controlify:off_hand", - "item": { - "items": "#minecraft:eggs" - } - }, - { - "slot": "controlify:off_hand", - "item": { - "items": [ - "minecraft:snowball", - "minecraft:splash_potion", - "minecraft:lingering_potion", - "minecraft:experience_bottle", - "minecraft:ender_pearl", - "minecraft:wind_charge" - ] - } - } - ] - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.throw" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:fishing_hook_cast", - { - "slot": "controlify:off_hand", - "item": { - "items": "#c:tools/fishing_rod" - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.reel_in" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "items": "#c:tools/fishing_rod" - } - } - ], - "none_of": [ - "controlify:fishing_hook_cast" - ] - }, - "then": { - "translate": "controlify.guide.ingame.cast" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "items": "#c:tools/brush" - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.brush" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "items": "minecraft:spyglass" - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.zoom" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "predicates": { - "minecraft:instrument": {} - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.play" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - { - "slot": "controlify:off_hand", - "item": { - "predicates": { - "minecraft:equippable": {} - } - } - } - ] - }, - "then": { - "translate": "controlify.guide.ingame.equip" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_block", - "controlify:off_hand_is_block_item" - ] - }, - "then": { - "translate": "controlify.guide.ingame.place" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_entity" - ], - "none_of": [ - "controlify:is_spectator" - ] - }, - "then": { - "translate": "controlify.guide.ingame.interact" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:looking_at_block" - ] - }, - "then": { - "translate": "controlify.guide.ingame.use" - } - }, - { - "for": "controlify:use", - "where": "right", - "if": { - "all_of": [ - "controlify:verbosity_minimal", - "controlify:has_item_in_either_hand" - ] - }, - "then": { - "translate": "controlify.guide.ingame.use" - } - }, - { - "for": "controlify:drop", - "where": "left", - "if": { - "all_of": [ - "controlify:verbosity_reduced", - "controlify:has_item_in_main_hand" - ] - }, - "then": { - "translate": "controlify.guide.ingame.drop" - } - } - ] -} diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/ControlifyBootstrap.java b/src/neoforge/java/dev/isxander/controlify/neoforge/ControlifyBootstrap.java index 9b4429b30..a90e1c441 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/ControlifyBootstrap.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/ControlifyBootstrap.java @@ -6,14 +6,14 @@ */ package dev.isxander.controlify.neoforge; -import dev.isxander.controlify.Controlify; -import dev.isxander.controlify.gui.screen.ControlifySettingsScreen; +import dev.isxander.controlify.impl.Controlify; +import dev.isxander.controlify.impl.gui.screen.ControlifySettingsScreen; import dev.isxander.controlify.neoforge.platform.NeoforgePlatformMainImpl; import dev.isxander.controlify.neoforge.platform.client.NeoforgePlatformClientImpl; -import dev.isxander.controlify.platform.Environment; -import dev.isxander.controlify.platform.client.PlatformClientUtil; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.server.ControlifyServer; +import dev.isxander.controlify.impl.platform.Environment; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.server.ControlifyServer; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.ModLoadingContext; import net.neoforged.fml.common.Mod; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/compatibility/NeoforgeCompatMixinPlatform.java b/src/neoforge/java/dev/isxander/controlify/neoforge/compatibility/NeoforgeCompatMixinPlatform.java index 9a950488a..526a883f0 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/compatibility/NeoforgeCompatMixinPlatform.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/compatibility/NeoforgeCompatMixinPlatform.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.neoforge.compatibility; -import dev.isxander.controlify.compatibility.CompatMixinPlatform; +import dev.isxander.controlify.impl.compatibility.CompatMixinPlatform; import net.neoforged.fml.loading.FMLLoader; public final class NeoforgeCompatMixinPlatform implements CompatMixinPlatform { diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/NeoforgePlatformMainImpl.java b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/NeoforgePlatformMainImpl.java index f48c17bb5..9621975bd 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/NeoforgePlatformMainImpl.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/NeoforgePlatformMainImpl.java @@ -6,16 +6,16 @@ */ package dev.isxander.controlify.neoforge.platform; -import dev.isxander.controlify.api.entrypoint.ControlifyEntrypoint; +import dev.isxander.controlify.impl.api.entrypoint.ControlifyEntrypoint; import dev.isxander.controlify.neoforge.platform.network.C2SNetworkApiNeoforge; import dev.isxander.controlify.neoforge.platform.network.S2CNetworkApiNeoforge; -import dev.isxander.controlify.platform.Environment; -import dev.isxander.controlify.platform.main.PlatformMainUtilImpl; -import dev.isxander.controlify.platform.main.events.CommandRegistrationCallbackEvent; -import dev.isxander.controlify.platform.main.events.HandshakeCompletionEvent; -import dev.isxander.controlify.platform.main.events.PlayerJoinedEvent; -import dev.isxander.controlify.platform.network.C2SNetworkApi; -import dev.isxander.controlify.platform.network.S2CNetworkApi; +import dev.isxander.controlify.impl.platform.Environment; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtilImpl; +import dev.isxander.controlify.impl.platform.main.events.CommandRegistrationCallbackEvent; +import dev.isxander.controlify.impl.platform.main.events.HandshakeCompletionEvent; +import dev.isxander.controlify.impl.platform.main.events.PlayerJoinedEvent; +import dev.isxander.controlify.impl.platform.network.C2SNetworkApi; +import dev.isxander.controlify.impl.platform.network.S2CNetworkApi; import net.minecraft.core.Registry; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgeCreativeTabHelper.java b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgeCreativeTabHelper.java index 9525543e7..ee0070999 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgeCreativeTabHelper.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgeCreativeTabHelper.java @@ -7,7 +7,7 @@ package dev.isxander.controlify.neoforge.platform.client; import dev.isxander.controlify.neoforge.mixins.CreativeModeInventoryScreenAccessor; -import dev.isxander.controlify.platform.client.CreativeTabHelper; +import dev.isxander.controlify.impl.platform.client.CreativeTabHelper; import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; import net.minecraft.world.item.CreativeModeTab; import net.neoforged.neoforge.client.gui.CreativeTabsScreenPage; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgePlatformClientImpl.java b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgePlatformClientImpl.java index 306cd8b2f..28c1e0ae2 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgePlatformClientImpl.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgePlatformClientImpl.java @@ -7,14 +7,14 @@ package dev.isxander.controlify.neoforge.platform.client; import dev.isxander.controlify.neoforge.platform.VanillaKeyMappingHolder; -import dev.isxander.controlify.platform.client.CreativeTabHelper; -import dev.isxander.controlify.platform.client.HudRenderLayer; -import dev.isxander.controlify.platform.client.PlatformClientUtilImpl; -import dev.isxander.controlify.platform.client.events.DisconnectedEvent; -import dev.isxander.controlify.platform.client.events.LifecycleEvent; -import dev.isxander.controlify.platform.client.events.ScreenRenderEvent; -import dev.isxander.controlify.platform.client.events.TickEvent; -import dev.isxander.controlify.platform.client.resource.ControlifyReloadListener; +import dev.isxander.controlify.impl.platform.client.CreativeTabHelper; +import dev.isxander.controlify.impl.platform.client.HudRenderLayer; +import dev.isxander.controlify.impl.platform.client.PlatformClientUtilImpl; +import dev.isxander.controlify.impl.platform.client.events.DisconnectedEvent; +import dev.isxander.controlify.impl.platform.client.events.LifecycleEvent; +import dev.isxander.controlify.impl.platform.client.events.ScreenRenderEvent; +import dev.isxander.controlify.impl.platform.client.events.TickEvent; +import dev.isxander.controlify.impl.platform.client.resource.ControlifyReloadListener; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/C2SNetworkApiNeoforge.java b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/C2SNetworkApiNeoforge.java index 172a09708..4183116ec 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/C2SNetworkApiNeoforge.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/C2SNetworkApiNeoforge.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.neoforge.platform.network; -import dev.isxander.controlify.platform.network.C2SNetworkApi; +import dev.isxander.controlify.impl.platform.network.C2SNetworkApi; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/S2CNetworkApiNeoforge.java b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/S2CNetworkApiNeoforge.java index b665cb3df..1bf206584 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/S2CNetworkApiNeoforge.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/S2CNetworkApiNeoforge.java @@ -6,10 +6,9 @@ */ package dev.isxander.controlify.neoforge.platform.network; -import dev.isxander.controlify.platform.Environment; -import dev.isxander.controlify.platform.main.PlatformMainUtil; -import dev.isxander.controlify.platform.network.C2SNetworkApi; -import dev.isxander.controlify.platform.network.S2CNetworkApi; +import dev.isxander.controlify.impl.platform.Environment; +import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; +import dev.isxander.controlify.impl.platform.network.S2CNetworkApi; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.Identifier; diff --git a/src/test/java/dev/isxander/controlify/config/ConfigMigrationTestHelper.java b/src/test/java/dev/isxander/controlify/impl/config/ConfigMigrationTestHelper.java similarity index 95% rename from src/test/java/dev/isxander/controlify/config/ConfigMigrationTestHelper.java rename to src/test/java/dev/isxander/controlify/impl/config/ConfigMigrationTestHelper.java index dec14d037..2e7a4d99c 100644 --- a/src/test/java/dev/isxander/controlify/config/ConfigMigrationTestHelper.java +++ b/src/test/java/dev/isxander/controlify/impl/config/ConfigMigrationTestHelper.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.config; +package dev.isxander.controlify.impl.config; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.mojang.serialization.JsonOps; -import dev.isxander.controlify.config.dto.profile.ProfileConfig; +import dev.isxander.controlify.impl.config.dto.profile.ProfileConfig; import org.junit.jupiter.api.Assertions; import java.io.IOException; diff --git a/src/test/java/dev/isxander/controlify/contextual/FactDependencyGraphTest.java b/src/test/java/dev/isxander/controlify/impl/contextual/FactDependencyGraphTest.java similarity index 98% rename from src/test/java/dev/isxander/controlify/contextual/FactDependencyGraphTest.java rename to src/test/java/dev/isxander/controlify/impl/contextual/FactDependencyGraphTest.java index 02cd302fa..51096c70a 100644 --- a/src/test/java/dev/isxander/controlify/contextual/FactDependencyGraphTest.java +++ b/src/test/java/dev/isxander/controlify/impl/contextual/FactDependencyGraphTest.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.contextual; +package dev.isxander.controlify.impl.contextual; import net.minecraft.resources.Identifier; import org.junit.jupiter.api.Test; From 3fdbdb002863cec2692e77fd15c880e4514e4fd5 Mon Sep 17 00:00:00 2001 From: isxander Date: Mon, 19 Oct 2026 16:41:36 +0100 Subject: [PATCH 12/12] repackage the fabric and neoforge sourcesets --- build.gradle.kts | 8 +- .../{ => impl}/ControlifyBootstrap.java | 6 +- .../FabricCompatMixinPlatform.java | 2 +- .../compatibility/ModMenuIntegration.java | 2 +- .../platform/FabricBackedEventHandler.java | 2 +- .../platform/FabricPlatformMainImpl.java | 6 +- .../client/FAPIApiCreativeTabHelper.java | 2 +- .../client/FabricPlatformClientImpl.java | 2 +- .../platform/network/C2SNetworkApiFabric.java | 2 +- .../platform/network/FabricPacketWrapper.java | 2 +- .../platform/network/S2CNetworkApiFabric.java | 2 +- .../controllers/contextual/guide/in_game.json | 1194 +++++++++++++++++ .../{ => impl}/ControlifyBootstrap.java | 6 +- .../NeoforgeCompatMixinPlatform.java | 2 +- .../platform/NeoforgePlatformMainImpl.java | 6 +- .../platform/VanillaKeyMappingHolder.java | 2 +- .../client/NeoforgeCreativeTabHelper.java | 2 +- .../client/NeoforgePlatformClientImpl.java | 4 +- .../network/C2SNetworkApiNeoforge.java | 2 +- .../network/NeoforgePacketWrapper.java | 2 +- .../network/S2CNetworkApiNeoforge.java | 2 +- .../neoforge/mixins/OptionsMixin.java | 2 +- 22 files changed, 1227 insertions(+), 33 deletions(-) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/ControlifyBootstrap.java (83%) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/compatibility/FabricCompatMixinPlatform.java (88%) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/compatibility/ModMenuIntegration.java (89%) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/platform/FabricBackedEventHandler.java (93%) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/platform/FabricPlatformMainImpl.java (95%) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/platform/client/FAPIApiCreativeTabHelper.java (95%) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/platform/client/FabricPlatformClientImpl.java (98%) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/platform/network/C2SNetworkApiFabric.java (96%) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/platform/network/FabricPacketWrapper.java (95%) rename src/fabric/java/dev/isxander/controlify/fabric/{ => impl}/platform/network/S2CNetworkApiFabric.java (96%) create mode 100644 src/main/resources/resourcepacks/legacy_console/assets/controlify/controllers/contextual/guide/in_game.json rename src/neoforge/java/dev/isxander/controlify/neoforge/{ => impl}/ControlifyBootstrap.java (85%) rename src/neoforge/java/dev/isxander/controlify/neoforge/{ => impl}/compatibility/NeoforgeCompatMixinPlatform.java (88%) rename src/neoforge/java/dev/isxander/controlify/neoforge/{ => impl}/platform/NeoforgePlatformMainImpl.java (95%) rename src/neoforge/java/dev/isxander/controlify/neoforge/{ => impl}/platform/VanillaKeyMappingHolder.java (81%) rename src/neoforge/java/dev/isxander/controlify/neoforge/{ => impl}/platform/client/NeoforgeCreativeTabHelper.java (95%) rename src/neoforge/java/dev/isxander/controlify/neoforge/{ => impl}/platform/client/NeoforgePlatformClientImpl.java (97%) rename src/neoforge/java/dev/isxander/controlify/neoforge/{ => impl}/platform/network/C2SNetworkApiNeoforge.java (97%) rename src/neoforge/java/dev/isxander/controlify/neoforge/{ => impl}/platform/network/NeoforgePacketWrapper.java (94%) rename src/neoforge/java/dev/isxander/controlify/neoforge/{ => impl}/platform/network/S2CNetworkApiNeoforge.java (97%) diff --git a/build.gradle.kts b/build.gradle.kts index c515be924..31d95785b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -177,10 +177,10 @@ manifests { fabricModJson(sourceSets.fabric.get()) { from(commonManifest) - entrypoint("modmenu", "dev.isxander.controlify.fabric.compatibility.ModMenuIntegration") - entrypoint("main", "dev.isxander.controlify.fabric.ControlifyBootstrap") - entrypoint("client", "dev.isxander.controlify.fabric.ControlifyBootstrap") - entrypoint("server", "dev.isxander.controlify.fabric.ControlifyBootstrap") + entrypoint("modmenu", "dev.isxander.controlify.fabric.impl.compatibility.ModMenuIntegration") + entrypoint("main", "dev.isxander.controlify.fabric.impl.ControlifyBootstrap") + entrypoint("client", "dev.isxander.controlify.fabric.impl.ControlifyBootstrap") + entrypoint("server", "dev.isxander.controlify.fabric.impl.ControlifyBootstrap") dependency("fabricloader", REQUIRED, "[0.19,)") mixin("controlify-platform.fabric.mixins.json") diff --git a/src/fabric/java/dev/isxander/controlify/fabric/ControlifyBootstrap.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/ControlifyBootstrap.java similarity index 83% rename from src/fabric/java/dev/isxander/controlify/fabric/ControlifyBootstrap.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/ControlifyBootstrap.java index e719426ad..9936cf34d 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/ControlifyBootstrap.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/ControlifyBootstrap.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric; +package dev.isxander.controlify.fabric.impl; import dev.isxander.controlify.impl.Controlify; -import dev.isxander.controlify.fabric.platform.client.FabricPlatformClientImpl; -import dev.isxander.controlify.fabric.platform.FabricPlatformMainImpl; +import dev.isxander.controlify.fabric.impl.platform.client.FabricPlatformClientImpl; +import dev.isxander.controlify.fabric.impl.platform.FabricPlatformMainImpl; import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; import dev.isxander.controlify.impl.server.ControlifyServer; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/compatibility/FabricCompatMixinPlatform.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/compatibility/FabricCompatMixinPlatform.java similarity index 88% rename from src/fabric/java/dev/isxander/controlify/fabric/compatibility/FabricCompatMixinPlatform.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/compatibility/FabricCompatMixinPlatform.java index b025c8736..b4e87a999 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/compatibility/FabricCompatMixinPlatform.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/compatibility/FabricCompatMixinPlatform.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric.compatibility; +package dev.isxander.controlify.fabric.impl.compatibility; import dev.isxander.controlify.impl.compatibility.CompatMixinPlatform; import net.fabricmc.loader.api.FabricLoader; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/compatibility/ModMenuIntegration.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/compatibility/ModMenuIntegration.java similarity index 89% rename from src/fabric/java/dev/isxander/controlify/fabric/compatibility/ModMenuIntegration.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/compatibility/ModMenuIntegration.java index 28cb8a801..43a5af25c 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/compatibility/ModMenuIntegration.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/compatibility/ModMenuIntegration.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric.compatibility; +package dev.isxander.controlify.fabric.impl.compatibility; //? if mod_menu { diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricBackedEventHandler.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/FabricBackedEventHandler.java similarity index 93% rename from src/fabric/java/dev/isxander/controlify/fabric/platform/FabricBackedEventHandler.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/platform/FabricBackedEventHandler.java index eeb2d14ad..84eb767ae 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricBackedEventHandler.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/FabricBackedEventHandler.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric.platform; +package dev.isxander.controlify.fabric.impl.platform; import dev.isxander.controlify.impl.platform.EventHandler; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricPlatformMainImpl.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/FabricPlatformMainImpl.java similarity index 95% rename from src/fabric/java/dev/isxander/controlify/fabric/platform/FabricPlatformMainImpl.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/platform/FabricPlatformMainImpl.java index 7f650640d..04529ffa4 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/FabricPlatformMainImpl.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/FabricPlatformMainImpl.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric.platform; +package dev.isxander.controlify.fabric.impl.platform; import dev.isxander.controlify.impl.api.entrypoint.ControlifyEntrypoint; -import dev.isxander.controlify.fabric.platform.network.C2SNetworkApiFabric; -import dev.isxander.controlify.fabric.platform.network.S2CNetworkApiFabric; +import dev.isxander.controlify.fabric.impl.platform.network.C2SNetworkApiFabric; +import dev.isxander.controlify.fabric.impl.platform.network.S2CNetworkApiFabric; import dev.isxander.controlify.impl.platform.Environment; import dev.isxander.controlify.impl.platform.main.PlatformMainUtilImpl; import dev.isxander.controlify.impl.platform.main.events.CommandRegistrationCallbackEvent; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FAPIApiCreativeTabHelper.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/client/FAPIApiCreativeTabHelper.java similarity index 95% rename from src/fabric/java/dev/isxander/controlify/fabric/platform/client/FAPIApiCreativeTabHelper.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/platform/client/FAPIApiCreativeTabHelper.java index dfbc9e63c..5ab1973b7 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FAPIApiCreativeTabHelper.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/client/FAPIApiCreativeTabHelper.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric.platform.client; +package dev.isxander.controlify.fabric.impl.platform.client; import dev.isxander.controlify.impl.platform.client.CreativeTabHelper; import net.fabricmc.fabric.api.client.creativetab.v1.FabricCreativeModeInventoryScreen; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FabricPlatformClientImpl.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/client/FabricPlatformClientImpl.java similarity index 98% rename from src/fabric/java/dev/isxander/controlify/fabric/platform/client/FabricPlatformClientImpl.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/platform/client/FabricPlatformClientImpl.java index 90971484d..45764d668 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/client/FabricPlatformClientImpl.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/client/FabricPlatformClientImpl.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric.platform.client; +package dev.isxander.controlify.fabric.impl.platform.client; import dev.isxander.controlify.impl.platform.client.CreativeTabHelper; import dev.isxander.controlify.impl.platform.client.HudRenderLayer; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/C2SNetworkApiFabric.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/network/C2SNetworkApiFabric.java similarity index 96% rename from src/fabric/java/dev/isxander/controlify/fabric/platform/network/C2SNetworkApiFabric.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/platform/network/C2SNetworkApiFabric.java index 6de311d99..cbfbbd397 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/C2SNetworkApiFabric.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/network/C2SNetworkApiFabric.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric.platform.network; +package dev.isxander.controlify.fabric.impl.platform.network; import dev.isxander.controlify.impl.platform.network.C2SNetworkApi; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/FabricPacketWrapper.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/network/FabricPacketWrapper.java similarity index 95% rename from src/fabric/java/dev/isxander/controlify/fabric/platform/network/FabricPacketWrapper.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/platform/network/FabricPacketWrapper.java index e19e300d7..2bde4e2f3 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/FabricPacketWrapper.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/network/FabricPacketWrapper.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric.platform.network; +package dev.isxander.controlify.fabric.impl.platform.network; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.minecraft.network.FriendlyByteBuf; diff --git a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/S2CNetworkApiFabric.java b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/network/S2CNetworkApiFabric.java similarity index 96% rename from src/fabric/java/dev/isxander/controlify/fabric/platform/network/S2CNetworkApiFabric.java rename to src/fabric/java/dev/isxander/controlify/fabric/impl/platform/network/S2CNetworkApiFabric.java index cfa43b0fe..0409070fe 100644 --- a/src/fabric/java/dev/isxander/controlify/fabric/platform/network/S2CNetworkApiFabric.java +++ b/src/fabric/java/dev/isxander/controlify/fabric/impl/platform/network/S2CNetworkApiFabric.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.fabric.platform.network; +package dev.isxander.controlify.fabric.impl.platform.network; import dev.isxander.controlify.impl.platform.network.S2CNetworkApi; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; diff --git a/src/main/resources/resourcepacks/legacy_console/assets/controlify/controllers/contextual/guide/in_game.json b/src/main/resources/resourcepacks/legacy_console/assets/controlify/controllers/contextual/guide/in_game.json new file mode 100644 index 000000000..99a4c520c --- /dev/null +++ b/src/main/resources/resourcepacks/legacy_console/assets/controlify/controllers/contextual/guide/in_game.json @@ -0,0 +1,1194 @@ +{ + "replace": true, + "rules": [ + { + "for": "controlify:jump", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:riding_happy_ghast" + ] + }, + "then": { + "translate": "controlify.guide.ingame.fly_up" + } + }, + { + "for": "controlify:jump", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "any_of": [ + "controlify:riding_saddled_camel", + "controlify:riding_saddled_nautilus" + ] + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.dash" + } + }, + { + "for": "controlify:jump", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:riding_saddled_equine" + ] + }, + "then": { + "translate": "key.jump" + } + }, + { + "for": "controlify:jump", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:creative_flying" + ] + }, + "then": { + "translate": "controlify.guide.ingame.fly_up" + } + }, + { + "for": "controlify:jump", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:in_water" + ] + }, + "then": { + "translate": "controlify.guide.ingame.swim_up" + } + }, + { + "for": "controlify:jump", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:on_climbable" + ] + }, + "then": { + "translate": "controlify.guide.ingame.climb_up" + } + }, + { + "for": "controlify:jump", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:on_ground" + ] + }, + "then": { + "translate": "key.jump" + } + }, + { + "for": "controlify:jump", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:can_elytra_fly" + ] + }, + "then": { + "translate": "controlify.guide.ingame.start_elytra" + } + }, + { + "for": "controlify:sneak", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:in_vehicle" + ] + }, + "then": { + "translate": "controlify.guide.ingame.dismount" + } + }, + { + "for": "controlify:sneak", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:creative_flying" + ] + }, + "then": { + "translate": "controlify.guide.ingame.fly_down" + } + }, + { + "for": "controlify:sneak", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:in_water" + ], + "none_of": [ + "controlify:on_ground" + ] + }, + "then": { + "translate": "controlify.guide.ingame.swim_down" + } + }, + { + "for": "controlify:sneak", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:on_climbable" + ] + }, + "then": { + "translate": "controlify.guide.ingame.climb_down" + } + }, + { + "for": "controlify:inventory", + "where": "right", + "if": "controlify:verbosity_reduced", + "then": { + "translate": "controlify.guide.ingame.inventory" + } + }, + { + "for": "controlify:attack", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_entity", + "controlify:is_spectator" + ] + }, + "then": { + "translate": "controlify.guide.ingame.spectate" + } + }, + { + "for": "controlify:attack", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_entity" + ], + "none_of": [ + "controlify:is_spectator" + ] + }, + "then": { + "translate": "controlify.guide.ingame.attack" + } + }, + { + "for": "controlify:attack", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_block", + "controlify:main_hand_is_tool" + ] + }, + "then": { + "translate": "controlify.guide.ingame.mine" + } + }, + { + "for": "controlify:attack", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_block" + ] + }, + "then": { + "translate": "controlify.guide.ingame.break" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_entity", + "controlify:is_spectator" + ] + }, + "then": { + "translate": "controlify.guide.ingame.spectate" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_merchant" + ] + }, + "then": { + "translate": "controlify.guide.ingame.trade" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_chest_boat", + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.open" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_container_minecart" + ] + }, + "then": { + "translate": "controlify.guide.ingame.open" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_rideable" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.ride" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_closed_openable" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.open" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_open_openable" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.close" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_container" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.open" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_button" + ] + }, + "then": { + "translate": "controlify.guide.ingame.press" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_lever" + ] + }, + "then": { + "translate": "controlify.guide.ingame.toggle" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_bell" + ] + }, + "then": { + "translate": "controlify.guide.ingame.ring" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_bed" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.sleep" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_crafting_table" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.craft" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_furnace" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.smelt" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_smoker" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.cook" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_brewing_stand" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.brew" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_enchanting_table" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.enchant" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_smithing_table" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.smith" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_repair_station" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.repair" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_stonecutter" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.cut_stone" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_loom" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.weave" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_cartography_table" + ], + "none_of": [ + "controlify:sneaking" + ] + }, + "then": { + "translate": "controlify.guide.ingame.edit_map" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "items": "#c:tools/bow" + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.shoot" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "predicates": { + "minecraft:charged_projectiles": {} + } + } + } + ], + "none_of": [ + { + "slot": "controlify:main_hand", + "item": { + "components": { + "minecraft:charged_projectiles": [] + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.shoot" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "items": "minecraft:crossbow", + "components": { + "minecraft:charged_projectiles": [] + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.load" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "predicates": { + "minecraft:blocks_attacks": {} + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.block" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "predicates": { + "minecraft:consumable": {} + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.consume" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "any_of": [ + { + "slot": "controlify:main_hand", + "item": { + "items": "#c:tools/trident" + } + }, + { + "slot": "controlify:main_hand", + "item": { + "items": "#minecraft:spears" + } + }, + { + "slot": "controlify:main_hand", + "item": { + "items": "#minecraft:eggs" + } + }, + { + "slot": "controlify:main_hand", + "item": { + "items": [ + "minecraft:snowball", + "minecraft:splash_potion", + "minecraft:lingering_potion", + "minecraft:experience_bottle", + "minecraft:ender_pearl", + "minecraft:wind_charge" + ] + } + } + ] + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.throw" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:fishing_hook_cast", + { + "slot": "controlify:main_hand", + "item": { + "items": "#c:tools/fishing_rod" + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.reel_in" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "items": "#c:tools/fishing_rod" + } + } + ], + "none_of": [ + "controlify:fishing_hook_cast" + ] + }, + "then": { + "translate": "controlify.guide.ingame.cast" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "items": "#c:tools/brush" + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.brush" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "items": "minecraft:spyglass" + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.zoom" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "predicates": { + "minecraft:instrument": {} + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.play" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:main_hand", + "item": { + "predicates": { + "minecraft:equippable": {} + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.equip" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_block", + "controlify:main_hand_is_block_item" + ] + }, + "then": { + "translate": "controlify.guide.ingame.place" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "items": "#c:tools/bow" + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.shoot" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "predicates": { + "minecraft:charged_projectiles": {} + } + } + } + ], + "none_of": [ + { + "slot": "controlify:off_hand", + "item": { + "components": { + "minecraft:charged_projectiles": [] + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.shoot" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "items": "minecraft:crossbow", + "components": { + "minecraft:charged_projectiles": [] + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.load" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "predicates": { + "minecraft:blocks_attacks": {} + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.block" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "predicates": { + "minecraft:consumable": {} + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.consume" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "any_of": [ + { + "slot": "controlify:off_hand", + "item": { + "items": "#c:tools/trident" + } + }, + { + "slot": "controlify:off_hand", + "item": { + "items": "#minecraft:spears" + } + }, + { + "slot": "controlify:off_hand", + "item": { + "items": "#minecraft:eggs" + } + }, + { + "slot": "controlify:off_hand", + "item": { + "items": [ + "minecraft:snowball", + "minecraft:splash_potion", + "minecraft:lingering_potion", + "minecraft:experience_bottle", + "minecraft:ender_pearl", + "minecraft:wind_charge" + ] + } + } + ] + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.throw" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:fishing_hook_cast", + { + "slot": "controlify:off_hand", + "item": { + "items": "#c:tools/fishing_rod" + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.reel_in" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "items": "#c:tools/fishing_rod" + } + } + ], + "none_of": [ + "controlify:fishing_hook_cast" + ] + }, + "then": { + "translate": "controlify.guide.ingame.cast" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "items": "#c:tools/brush" + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.brush" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "items": "minecraft:spyglass" + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.zoom" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "predicates": { + "minecraft:instrument": {} + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.play" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + { + "slot": "controlify:off_hand", + "item": { + "predicates": { + "minecraft:equippable": {} + } + } + } + ] + }, + "then": { + "translate": "controlify.guide.ingame.equip" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_block", + "controlify:off_hand_is_block_item" + ] + }, + "then": { + "translate": "controlify.guide.ingame.place" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_entity" + ], + "none_of": [ + "controlify:is_spectator" + ] + }, + "then": { + "translate": "controlify.guide.ingame.interact" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:looking_at_block" + ] + }, + "then": { + "translate": "controlify.guide.ingame.use" + } + }, + { + "for": "controlify:use", + "where": "right", + "if": { + "all_of": [ + "controlify:verbosity_minimal", + "controlify:has_item_in_either_hand" + ] + }, + "then": { + "translate": "controlify.guide.ingame.use" + } + }, + { + "for": "controlify:drop", + "where": "left", + "if": { + "all_of": [ + "controlify:verbosity_reduced", + "controlify:has_item_in_main_hand" + ] + }, + "then": { + "translate": "controlify.guide.ingame.drop" + } + } + ] +} diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/ControlifyBootstrap.java b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/ControlifyBootstrap.java similarity index 85% rename from src/neoforge/java/dev/isxander/controlify/neoforge/ControlifyBootstrap.java rename to src/neoforge/java/dev/isxander/controlify/neoforge/impl/ControlifyBootstrap.java index a90e1c441..e6bbafe73 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/ControlifyBootstrap.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/ControlifyBootstrap.java @@ -4,12 +4,12 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.neoforge; +package dev.isxander.controlify.neoforge.impl; import dev.isxander.controlify.impl.Controlify; import dev.isxander.controlify.impl.gui.screen.ControlifySettingsScreen; -import dev.isxander.controlify.neoforge.platform.NeoforgePlatformMainImpl; -import dev.isxander.controlify.neoforge.platform.client.NeoforgePlatformClientImpl; +import dev.isxander.controlify.neoforge.impl.platform.NeoforgePlatformMainImpl; +import dev.isxander.controlify.neoforge.impl.platform.client.NeoforgePlatformClientImpl; import dev.isxander.controlify.impl.platform.Environment; import dev.isxander.controlify.impl.platform.client.PlatformClientUtil; import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/compatibility/NeoforgeCompatMixinPlatform.java b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/compatibility/NeoforgeCompatMixinPlatform.java similarity index 88% rename from src/neoforge/java/dev/isxander/controlify/neoforge/compatibility/NeoforgeCompatMixinPlatform.java rename to src/neoforge/java/dev/isxander/controlify/neoforge/impl/compatibility/NeoforgeCompatMixinPlatform.java index 526a883f0..cbd96bf63 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/compatibility/NeoforgeCompatMixinPlatform.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/compatibility/NeoforgeCompatMixinPlatform.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.neoforge.compatibility; +package dev.isxander.controlify.neoforge.impl.compatibility; import dev.isxander.controlify.impl.compatibility.CompatMixinPlatform; import net.neoforged.fml.loading.FMLLoader; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/NeoforgePlatformMainImpl.java b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/NeoforgePlatformMainImpl.java similarity index 95% rename from src/neoforge/java/dev/isxander/controlify/neoforge/platform/NeoforgePlatformMainImpl.java rename to src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/NeoforgePlatformMainImpl.java index 9621975bd..89c5683b4 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/NeoforgePlatformMainImpl.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/NeoforgePlatformMainImpl.java @@ -4,11 +4,11 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.neoforge.platform; +package dev.isxander.controlify.neoforge.impl.platform; import dev.isxander.controlify.impl.api.entrypoint.ControlifyEntrypoint; -import dev.isxander.controlify.neoforge.platform.network.C2SNetworkApiNeoforge; -import dev.isxander.controlify.neoforge.platform.network.S2CNetworkApiNeoforge; +import dev.isxander.controlify.neoforge.impl.platform.network.C2SNetworkApiNeoforge; +import dev.isxander.controlify.neoforge.impl.platform.network.S2CNetworkApiNeoforge; import dev.isxander.controlify.impl.platform.Environment; import dev.isxander.controlify.impl.platform.main.PlatformMainUtilImpl; import dev.isxander.controlify.impl.platform.main.events.CommandRegistrationCallbackEvent; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/VanillaKeyMappingHolder.java b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/VanillaKeyMappingHolder.java similarity index 81% rename from src/neoforge/java/dev/isxander/controlify/neoforge/platform/VanillaKeyMappingHolder.java rename to src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/VanillaKeyMappingHolder.java index accd824a7..f4b0c0799 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/VanillaKeyMappingHolder.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/VanillaKeyMappingHolder.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.neoforge.platform; +package dev.isxander.controlify.neoforge.impl.platform; import net.minecraft.client.KeyMapping; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgeCreativeTabHelper.java b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/client/NeoforgeCreativeTabHelper.java similarity index 95% rename from src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgeCreativeTabHelper.java rename to src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/client/NeoforgeCreativeTabHelper.java index ee0070999..187967041 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgeCreativeTabHelper.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/client/NeoforgeCreativeTabHelper.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.neoforge.platform.client; +package dev.isxander.controlify.neoforge.impl.platform.client; import dev.isxander.controlify.neoforge.mixins.CreativeModeInventoryScreenAccessor; import dev.isxander.controlify.impl.platform.client.CreativeTabHelper; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgePlatformClientImpl.java b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/client/NeoforgePlatformClientImpl.java similarity index 97% rename from src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgePlatformClientImpl.java rename to src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/client/NeoforgePlatformClientImpl.java index 28c1e0ae2..0720148c3 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/client/NeoforgePlatformClientImpl.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/client/NeoforgePlatformClientImpl.java @@ -4,9 +4,9 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.neoforge.platform.client; +package dev.isxander.controlify.neoforge.impl.platform.client; -import dev.isxander.controlify.neoforge.platform.VanillaKeyMappingHolder; +import dev.isxander.controlify.neoforge.impl.platform.VanillaKeyMappingHolder; import dev.isxander.controlify.impl.platform.client.CreativeTabHelper; import dev.isxander.controlify.impl.platform.client.HudRenderLayer; import dev.isxander.controlify.impl.platform.client.PlatformClientUtilImpl; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/C2SNetworkApiNeoforge.java b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/network/C2SNetworkApiNeoforge.java similarity index 97% rename from src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/C2SNetworkApiNeoforge.java rename to src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/network/C2SNetworkApiNeoforge.java index 4183116ec..5d2468cef 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/C2SNetworkApiNeoforge.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/network/C2SNetworkApiNeoforge.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.neoforge.platform.network; +package dev.isxander.controlify.neoforge.impl.platform.network; import dev.isxander.controlify.impl.platform.network.C2SNetworkApi; import net.minecraft.network.FriendlyByteBuf; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/NeoforgePacketWrapper.java b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/network/NeoforgePacketWrapper.java similarity index 94% rename from src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/NeoforgePacketWrapper.java rename to src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/network/NeoforgePacketWrapper.java index 40259d655..1b9812903 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/NeoforgePacketWrapper.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/network/NeoforgePacketWrapper.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.neoforge.platform.network; +package dev.isxander.controlify.neoforge.impl.platform.network; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/S2CNetworkApiNeoforge.java b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/network/S2CNetworkApiNeoforge.java similarity index 97% rename from src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/S2CNetworkApiNeoforge.java rename to src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/network/S2CNetworkApiNeoforge.java index 1bf206584..ef0584c6b 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/platform/network/S2CNetworkApiNeoforge.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/impl/platform/network/S2CNetworkApiNeoforge.java @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: LGPL-3.0-or-later */ -package dev.isxander.controlify.neoforge.platform.network; +package dev.isxander.controlify.neoforge.impl.platform.network; import dev.isxander.controlify.impl.platform.Environment; import dev.isxander.controlify.impl.platform.main.PlatformMainUtil; diff --git a/src/neoforge/java/dev/isxander/controlify/neoforge/mixins/OptionsMixin.java b/src/neoforge/java/dev/isxander/controlify/neoforge/mixins/OptionsMixin.java index f2a1c493d..b7f707481 100644 --- a/src/neoforge/java/dev/isxander/controlify/neoforge/mixins/OptionsMixin.java +++ b/src/neoforge/java/dev/isxander/controlify/neoforge/mixins/OptionsMixin.java @@ -6,7 +6,7 @@ */ package dev.isxander.controlify.neoforge.mixins; -import dev.isxander.controlify.neoforge.platform.VanillaKeyMappingHolder; +import dev.isxander.controlify.neoforge.impl.platform.VanillaKeyMappingHolder; import net.minecraft.client.KeyMapping; import net.minecraft.client.Options; import org.spongepowered.asm.mixin.Mixin;