1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-05-31 21:54:12 +00:00

Move computer events to a single point

This abstraction never made much sense on InputHandler, as we only leave
the default methods on ServerComputer.

We now add a new class (ComputerEvents), which has a series of *static*
methods, that can queue an event on a ComputerEvents.Receiver object.
This is a bit of an odd indirection (why not just make them instance
methods on Receiver?!), but I don't really want those methods leaking
everywhere.
This commit is contained in:
Jonathan Coates 2025-01-18 19:18:09 +00:00
parent 6739c4c6c0
commit 938eb38ad5
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
7 changed files with 112 additions and 69 deletions

View File

@ -9,7 +9,8 @@ import dan200.computercraft.shared.computer.menu.ServerInputHandler;
import javax.annotation.Nullable;
/**
* Handles user-provided input, forwarding it to a computer. This is used
* Handles user-provided input, forwarding it to a computer. This describes the "shape" of both the client-and
* server-side input handlers.
*
* @see ServerInputHandler
* @see ServerComputer
@ -21,29 +22,17 @@ public interface InputHandler {
queueEvent(event, null);
}
default void keyDown(int key, boolean repeat) {
queueEvent("key", new Object[]{ key, repeat });
}
void keyDown(int key, boolean repeat);
default void keyUp(int key) {
queueEvent("key_up", new Object[]{ key });
}
void keyUp(int key);
default void mouseClick(int button, int x, int y) {
queueEvent("mouse_click", new Object[]{ button, x, y });
}
void mouseClick(int button, int x, int y);
default void mouseUp(int button, int x, int y) {
queueEvent("mouse_up", new Object[]{ button, x, y });
}
void mouseUp(int button, int x, int y);
default void mouseDrag(int button, int x, int y) {
queueEvent("mouse_drag", new Object[]{ button, x, y });
}
void mouseDrag(int button, int x, int y);
default void mouseScroll(int direction, int x, int y) {
queueEvent("mouse_scroll", new Object[]{ direction, x, y });
}
void mouseScroll(int direction, int x, int y);
void shutdown();

View File

@ -12,6 +12,7 @@ import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.WorkMonitor;
import dan200.computercraft.core.computer.Computer;
import dan200.computercraft.core.computer.ComputerEnvironment;
import dan200.computercraft.core.computer.ComputerEvents;
import dan200.computercraft.core.computer.ComputerSide;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.impl.ApiFactories;
@ -34,7 +35,7 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
public class ServerComputer implements InputHandler, ComputerEnvironment {
public class ServerComputer implements ComputerEnvironment, ComputerEvents.Receiver {
private final int instanceID;
private final UUID instanceUUID = UUID.randomUUID();
@ -86,24 +87,24 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
}
}
public ComputerFamily getFamily() {
public final ComputerFamily getFamily() {
return family;
}
public ServerLevel getLevel() {
public final ServerLevel getLevel() {
return level;
}
public BlockPos getPosition() {
public final BlockPos getPosition() {
return position;
}
public void setPosition(ServerLevel level, BlockPos pos) {
public final void setPosition(ServerLevel level, BlockPos pos) {
this.level = level;
position = pos.immutable();
}
protected void markTerminalChanged() {
protected final void markTerminalChanged() {
terminalChanged.set(true);
}
@ -117,11 +118,11 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
sendToAllInteracting(c -> new ComputerTerminalClientMessage(c, getTerminalState()));
}
public TerminalState getTerminalState() {
public final TerminalState getTerminalState() {
return TerminalState.create(terminal);
}
public void keepAlive() {
public final void keepAlive() {
ticksSincePing = 0;
}
@ -134,7 +135,7 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
*
* @return What sides on the computer have changed.
*/
public int pollRedstoneChanges() {
public final int pollRedstoneChanges() {
return computer.pollRedstoneChanges();
}
@ -147,7 +148,7 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
computer.unload();
}
public void close() {
public final void close() {
unload();
ServerContext.get(level.getServer()).registry().remove(this);
}
@ -176,97 +177,98 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
protected void onRemoved() {
}
public int getInstanceID() {
public final int getInstanceID() {
return instanceID;
}
public UUID getInstanceUUID() {
public final UUID getInstanceUUID() {
return instanceUUID;
}
public int getID() {
public final int getID() {
return computer.getID();
}
public @Nullable String getLabel() {
public final @Nullable String getLabel() {
return computer.getLabel();
}
public boolean isOn() {
public final boolean isOn() {
return computer.isOn();
}
public ComputerState getState() {
public final ComputerState getState() {
if (!computer.isOn()) return ComputerState.OFF;
return computer.isBlinking() ? ComputerState.BLINKING : ComputerState.ON;
}
@Override
public void turnOn() {
public final void turnOn() {
computer.turnOn();
}
@Override
public void shutdown() {
public final void shutdown() {
computer.shutdown();
}
@Override
public void reboot() {
public final void reboot() {
computer.reboot();
}
@Override
public void queueEvent(String event, @Nullable Object[] arguments) {
public final void queueEvent(String event, @Nullable Object[] arguments) {
computer.queueEvent(event, arguments);
}
public int getRedstoneOutput(ComputerSide side) {
public final void queueEvent(String event) {
queueEvent(event, null);
}
public final int getRedstoneOutput(ComputerSide side) {
return computer.isOn() ? computer.getRedstone().getExternalOutput(side) : 0;
}
public void setRedstoneInput(ComputerSide side, int level, int bundledState) {
public final void setRedstoneInput(ComputerSide side, int level, int bundledState) {
computer.getRedstone().setInput(side, level, bundledState);
}
public int getBundledRedstoneOutput(ComputerSide side) {
public final int getBundledRedstoneOutput(ComputerSide side) {
return computer.isOn() ? computer.getRedstone().getExternalBundledOutput(side) : 0;
}
public void setPeripheral(ComputerSide side, @Nullable IPeripheral peripheral) {
public final void setPeripheral(ComputerSide side, @Nullable IPeripheral peripheral) {
computer.getEnvironment().setPeripheral(side, peripheral);
}
@Nullable
public IPeripheral getPeripheral(ComputerSide side) {
public final IPeripheral getPeripheral(ComputerSide side) {
return computer.getEnvironment().getPeripheral(side);
}
public void setLabel(@Nullable String label) {
public final void setLabel(@Nullable String label) {
computer.setLabel(label);
}
@Override
public double getTimeOfDay() {
public final double getTimeOfDay() {
return (level.getDayTime() + 6000) % 24000 / 1000.0;
}
@Override
public int getDay() {
public final int getDay() {
return (int) ((level.getDayTime() + 6000) / 24000) + 1;
}
@Override
public MetricsObserver getMetrics() {
public final MetricsObserver getMetrics() {
return metrics;
}
public WorkMonitor getMainThreadMonitor() {
public final WorkMonitor getMainThreadMonitor() {
return computer.getMainThreadMonitor();
}
@Override
public @Nullable WritableMount createRootMount() {
public final WritableMount createRootMount() {
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "computer/" + computer.getID(), Config.computerSpaceLimit);
}
}

View File

@ -7,6 +7,7 @@ package dan200.computercraft.shared.computer.menu;
import dan200.computercraft.core.apis.handles.ByteBufferChannel;
import dan200.computercraft.core.apis.transfer.TransferredFile;
import dan200.computercraft.core.apis.transfer.TransferredFiles;
import dan200.computercraft.core.computer.ComputerEvents;
import dan200.computercraft.shared.computer.upload.FileSlice;
import dan200.computercraft.shared.computer.upload.FileUpload;
import dan200.computercraft.shared.computer.upload.UploadResult;
@ -56,13 +57,13 @@ public class ServerInputState<T extends AbstractContainerMenu & ComputerMenu> im
@Override
public void keyDown(int key, boolean repeat) {
keysDown.add(key);
owner.getComputer().keyDown(key, repeat);
ComputerEvents.keyDown(owner.getComputer(), key, repeat);
}
@Override
public void keyUp(int key) {
keysDown.remove(key);
owner.getComputer().keyUp(key);
ComputerEvents.keyUp(owner.getComputer(), key);
}
@Override
@ -71,7 +72,7 @@ public class ServerInputState<T extends AbstractContainerMenu & ComputerMenu> im
lastMouseY = y;
lastMouseDown = button;
owner.getComputer().mouseClick(button, x, y);
ComputerEvents.mouseClick(owner.getComputer(), button, x, y);
}
@Override
@ -80,7 +81,7 @@ public class ServerInputState<T extends AbstractContainerMenu & ComputerMenu> im
lastMouseY = y;
lastMouseDown = -1;
owner.getComputer().mouseUp(button, x, y);
ComputerEvents.mouseUp(owner.getComputer(), button, x, y);
}
@Override
@ -89,7 +90,7 @@ public class ServerInputState<T extends AbstractContainerMenu & ComputerMenu> im
lastMouseY = y;
lastMouseDown = button;
owner.getComputer().mouseDrag(button, x, y);
ComputerEvents.mouseDrag(owner.getComputer(), button, x, y);
}
@Override
@ -97,7 +98,7 @@ public class ServerInputState<T extends AbstractContainerMenu & ComputerMenu> im
lastMouseX = x;
lastMouseY = y;
owner.getComputer().mouseScroll(direction, x, y);
ComputerEvents.mouseScroll(owner.getComputer(), direction, x, y);
}
@Override
@ -169,9 +170,9 @@ public class ServerInputState<T extends AbstractContainerMenu & ComputerMenu> im
public void close() {
var computer = owner.getComputer();
var keys = keysDown.iterator();
while (keys.hasNext()) computer.keyUp(keys.nextInt());
while (keys.hasNext()) ComputerEvents.keyUp(computer, keys.nextInt());
if (lastMouseDown != -1) computer.mouseUp(lastMouseDown, lastMouseX, lastMouseY);
if (lastMouseDown != -1) ComputerEvents.mouseUp(computer, lastMouseDown, lastMouseX, lastMouseY);
keysDown.clear();
lastMouseDown = -1;

View File

@ -148,7 +148,9 @@ object TestHooks {
GameTestRegistry.getAllTestFunctions().add(
TestFunction(
testName, testName, testInfo.template.ifEmpty { testName },
testName,
testName,
testInfo.template.ifEmpty { testName },
testInfo.timeoutTicks,
0,
true,

View File

@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicLong;
* <li>Passes main thread tasks to the {@link MainThreadScheduler.Executor}.</li>
* </ul>
*/
public class Computer {
public class Computer implements ComputerEvents.Receiver {
private static final int START_DELAY = 50;
// Various properties of the computer
@ -114,6 +114,7 @@ public class Computer {
executor.queueStop(false, true);
}
@Override
public void queueEvent(String event, @Nullable Object[] args) {
executor.queueEvent(event, args);
}

View File

@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package dan200.computercraft.core.computer;
import javax.annotation.Nullable;
/**
* Built-in events that can be queued on a computer.
*/
public final class ComputerEvents {
private ComputerEvents() {
}
public static void keyDown(Receiver receiver, int key, boolean repeat) {
receiver.queueEvent("key", new Object[]{ key, repeat });
}
public static void keyUp(Receiver receiver, int key) {
receiver.queueEvent("key_up", new Object[]{ key });
}
public static void mouseClick(Receiver receiver, int button, int x, int y) {
receiver.queueEvent("mouse_click", new Object[]{ button, x, y });
}
public static void mouseUp(Receiver receiver, int button, int x, int y) {
receiver.queueEvent("mouse_up", new Object[]{ button, x, y });
}
public static void mouseDrag(Receiver receiver, int button, int x, int y) {
receiver.queueEvent("mouse_drag", new Object[]{ button, x, y });
}
public static void mouseScroll(Receiver receiver, int direction, int x, int y) {
receiver.queueEvent("mouse_scroll", new Object[]{ direction, x, y });
}
/**
* An object that can receive computer events.
*/
@FunctionalInterface
public interface Receiver {
void queueEvent(String event, @Nullable Object[] arguments);
}
}

View File

@ -8,6 +8,7 @@ import dan200.computercraft.core.apis.handles.ArrayByteChannel;
import dan200.computercraft.core.apis.transfer.TransferredFile;
import dan200.computercraft.core.apis.transfer.TransferredFiles;
import dan200.computercraft.core.computer.Computer;
import dan200.computercraft.core.computer.ComputerEvents;
import dan200.computercraft.core.util.StringUtil;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWDropCallback;
@ -92,7 +93,7 @@ public class InputState {
// Queue the "key" event and add to the down set
var repeat = keysDown.get(key);
keysDown.set(key);
computer.queueEvent("key", new Object[]{ key, repeat });
ComputerEvents.keyDown(computer, key, repeat);
}
}
@ -100,7 +101,7 @@ public class InputState {
// Queue the "key_up" event and remove from the down set
if (key >= 0 && keysDown.get(key)) {
keysDown.set(key, false);
computer.queueEvent("key_up", new Object[]{ key });
ComputerEvents.keyUp(computer, key);
}
switch (key) {
@ -115,12 +116,12 @@ public class InputState {
public void onMouseClick(int button, int action) {
switch (action) {
case GLFW.GLFW_PRESS -> {
computer.queueEvent("mouse_click", new Object[]{ button + 1, lastMouseX + 1, lastMouseY + 1 });
ComputerEvents.mouseClick(computer, button + 1, lastMouseX + 1, lastMouseY + 1);
lastMouseButton = button;
}
case GLFW.GLFW_RELEASE -> {
if (button == lastMouseButton) {
computer.queueEvent("mouse_click", new Object[]{ button + 1, lastMouseX + 1, lastMouseY + 1 });
ComputerEvents.mouseUp(computer, button + 1, lastMouseX + 1, lastMouseY + 1);
lastMouseButton = -1;
}
}
@ -133,13 +134,13 @@ public class InputState {
lastMouseX = mouseX;
lastMouseY = mouseY;
if (lastMouseButton != -1) {
computer.queueEvent("mouse_drag", new Object[]{ lastMouseButton + 1, mouseX + 1, mouseY + 1 });
ComputerEvents.mouseDrag(computer, lastMouseButton + 1, mouseX + 1, mouseY + 1);
}
}
public void onMouseScroll(double yOffset) {
if (yOffset != 0) {
computer.queueEvent("mouse_scroll", new Object[]{ yOffset < 0 ? 1 : -1, lastMouseX + 1, lastMouseY + 1 });
ComputerEvents.mouseScroll(computer, yOffset < 0 ? 1 : -1, lastMouseX + 1, lastMouseY + 1);
}
}