Skip to content

Commit

Permalink
fix: crash when rotating ic gates with hotkey
Browse files Browse the repository at this point in the history
  • Loading branch information
MrTJP committed May 4, 2024
1 parent 064cadf commit d6ba66c
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class ICEditorStateMachine {

private final ICSimulationContainer simulationContainer = new ICSimulationContainer();
private final ICCompilerLog compilerLog = new ICCompilerLog(this);
private final boolean isClientSide;

private int lastCompiledFormat = 0;
private long lastSimStartTime = 0;
Expand All @@ -69,9 +70,10 @@ public class ICEditorStateMachine {
private boolean autoCompileAvailable = true;
private boolean enableAutoCompile = true;

public ICEditorStateMachine(ICWorkbenchEditor editor, @Nullable StateMachineCallback callback) {
public ICEditorStateMachine(ICWorkbenchEditor editor, @Nullable StateMachineCallback callback, boolean isClientSide) {
this.editor = editor;
this.callback = callback;
this.isClientSide = isClientSide;
}

public ICCompilerLog getCompilerLog() {
Expand Down Expand Up @@ -168,18 +170,22 @@ public void onChunkLoad() {

//region State Machine events
public void onTick(long time) {
assertServer();
states[currentState].onTick(time);
}

public void onTileMapChanged() {
assertServer();
states[currentState].onTileMapChanged();
}

public void onCompileTriggered() {
assertServer();
states[currentState].onCompileTriggered();
}

public void onInputRegistersChanged(int rotation, Function<Short, Short> changeFunction) {
assertServer();
states[currentState].onInputRegistersChanged(rotation, changeFunction);
}
//endregion
Expand Down Expand Up @@ -217,6 +223,12 @@ private void setLastSimStartTimeAndSend(long time) {
lastSimStartTime = time;
getStateMachineStream(KEY_SIM_START_TIME_CHANGED).writeLong(time);
}

private void assertServer() {
if (isClientSide) {
throw new RuntimeException("Server-side operation performed on client! Report to ProjectRed developers");
}
}
//endregion

//region Client-side utilities
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class ICWorkbenchEditor implements ICEditorStateMachine.StateMachineCallb

private final IICWorkbenchEditorNetwork network;
private final BaseTileMap tileMap = new BaseTileMap(this);
private final ICEditorStateMachine stateMachine = new ICEditorStateMachine(this, this);
private final ICEditorStateMachine stateMachine;

private final ArrayList<IICEditorTool> toolList = ICEditorToolType.createToolList();
private final List<TileCoord> neighborChangeList = new LinkedList<>();
Expand All @@ -54,6 +54,7 @@ public class ICWorkbenchEditor implements ICEditorStateMachine.StateMachineCallb

public ICWorkbenchEditor(IICWorkbenchEditorNetwork network) {
this.network = network;
this.stateMachine = new ICEditorStateMachine(this, this, network.isClientSide());
for (IICEditorTool t : toolList) t.bindEditor(this);
}

Expand Down Expand Up @@ -296,7 +297,9 @@ public void queueNeighborChange(TileCoord pos) {

public void markTileChange() {
network.markSave();
stateMachine.onTileMapChanged();
if (!network.isClientSide()) {
stateMachine.onTileMapChanged();
}
}

public void markDirty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,17 @@ public void renderZone(CCRenderState ccrs, MultiBufferSource getter, PoseStack p
}

@Override
@OnlyIn(Dist.CLIENT)
public void buildToolTip(List<Component> tooltip) {
String keyName = Objects.requireNonNullElse(GLFW.glfwGetKeyName(keyCode, 0), "???");
tooltip.add(Component.literal("[" + keyName + "] ").append(text).withStyle(ICWorkbenchEditor.UNIFORM_GRAY));
}

@Override
public boolean canRespondToKey(int glfwKeyCode, int glfwFlags) {
return glfwKeyCode == keyCode;
}

@Override
public boolean onKeyPressed(int glfwKeyCode, int glfwFlags) {
if (glfwKeyCode == keyCode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import mrtjp.fengine.TileCoord;
import mrtjp.projectred.fabrication.editor.ICEditorToolType;
import mrtjp.projectred.fabrication.engine.BaseTile;
import net.covers1624.quack.collection.FastStream;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.network.chat.Component;
import net.minecraftforge.api.distmarker.Dist;
Expand All @@ -16,13 +17,16 @@

import javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;

import static mrtjp.projectred.fabrication.ProjectRedFabrication.LOGGER;
import static mrtjp.projectred.fabrication.editor.tools.IICEditorTool.internalToGlobalCuboid;
import static mrtjp.projectred.fabrication.editor.tools.IICEditorTool.toNearestPosition;

public class InteractTool extends BaseICEditorTool {

private static final int KEY_MOUSE_CLICK = 0;
private static final int KEY_KEY_PRESS = 1;

private final Vector3 initialMouseDown = new Vector3();
private boolean leftMouseDown;
private boolean rightMouseDown;
Expand All @@ -34,27 +38,46 @@ public ICEditorToolType getToolType() {

@Override
public void readPacket(MCDataInput input) {
int key = input.readByte();
switch (key) {
case KEY_MOUSE_CLICK -> readClickPacket(input);
case KEY_KEY_PRESS -> readKeyPressPacket(input);
default -> LOGGER.error("Received invalid packet type for InteractTool: {}", key);
}
}

private void readClickPacket(MCDataInput input) {
TileCoord pos = new TileCoord(input.readByte(), input.readByte(), input.readByte());
byte b = input.readByte();

int z = b & 0x7F;
boolean leftClick = (b & 0x80) != 0;

Optional<BaseTile> tile = getEditor().getTileMap().getBaseTile(pos);
tile.ifPresent(t -> {
var zone = t.getInteractionZones()[z];
BaseTile tile = getEditor().getTileMap().getBaseTile(pos).orElse(null);
if (tile == null) return;

if (leftClick) {
zone.onLeftClick();
}
else {
zone.onRightClick();
}
});
var zone = tile.getInteractionZones()[z];

if (leftClick) {
zone.onLeftClick();
} else {
zone.onRightClick();
}
}

private void executeTool(Vector3 startMouseDown, Vector3 endMouseDown) {
private void readKeyPressPacket(MCDataInput input) {
TileCoord pos = new TileCoord(input.readByte(), input.readByte(), input.readByte());
int glfwKeyCode = input.readInt();
int glfwFlags = input.readInt();

BaseTile tile = getEditor().getTileMap().getBaseTile(pos).orElse(null);
if (tile == null) return;

for (var z : tile.getInteractionZones()) {
z.onKeyPressed(glfwKeyCode, glfwFlags);
}
}

private void sendClick(Vector3 startMouseDown, Vector3 endMouseDown) {
TileCoord start = toNearestPosition(startMouseDown);
TileCoord end = toNearestPosition(endMouseDown);
if (!start.equals(end)) return;
Expand All @@ -68,10 +91,18 @@ private void executeTool(Vector3 startMouseDown, Vector3 endMouseDown) {
byte b = (byte) ((endZone.index & 0x7F) | (leftMouseDown ? 0x80 : 0x00));

getEditor().getToolStream(this)
.writeByte(KEY_MOUSE_CLICK)
.writeByte(start.x).writeByte(start.y).writeByte(start.z)
.writeByte(b);
}

private void sendKeyPress(TileCoord pos, int glfwKeyCode, int glfwFlags) {
getEditor().getToolStream(this)
.writeByte(KEY_KEY_PRESS)
.writeByte(pos.x).writeByte(pos.y).writeByte(pos.z)
.writeInt(glfwKeyCode).writeInt(glfwFlags);
}

@Override
public boolean toolStart(Vector3 mousePosition, int glfwMouseButton) {
if (glfwMouseButton == GLFW.GLFW_MOUSE_BUTTON_LEFT) {
Expand All @@ -92,7 +123,8 @@ public boolean toolStart(Vector3 mousePosition, int glfwMouseButton) {
public boolean toolReleased(Vector3 mousePosition, int glfwMouseButton) {
if ((glfwMouseButton == GLFW.GLFW_MOUSE_BUTTON_LEFT && leftMouseDown) ||
(glfwMouseButton == GLFW.GLFW_MOUSE_BUTTON_RIGHT && rightMouseDown)) {
executeTool(initialMouseDown, mousePosition);

sendClick(initialMouseDown, mousePosition);
leftMouseDown = false;
rightMouseDown = false;
return true;
Expand Down Expand Up @@ -149,10 +181,9 @@ public boolean toolKeyPressed(Vector3 mousePosition, int glfwKeyCode, int glfwFl
BaseTile tile = getEditor().getTileMap().getBaseTile(coord).orElse(null);
if (tile == null) return false;

for (var zone : tile.getInteractionZones()) {
if (zone.onKeyPressed(glfwKeyCode, glfwFlags)) {
return true;
}
if (FastStream.of(tile.getInteractionZones()).anyMatch(z -> z.canRespondToKey(glfwKeyCode, glfwFlags))) {
sendKeyPress(coord, glfwKeyCode, glfwFlags);
return true;
}

return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,14 @@ public interface InteractionZone {
@OnlyIn(Dist.CLIENT)
void buildToolTip(List<Component> tooltip);

/**
* Client-side check to see if this zone can respond to a key press. If true, client sends packet
* to respond to key press via {@link #onKeyPressed(int, int)}.
*/
boolean canRespondToKey(int glfwKeyCode, int glfwFlags);

/**
* Server-side key press event. Called if client-side {@link #canRespondToKey(int, int)} returns true.
*/
boolean onKeyPressed(int glfwKeyCode, int glfwFlags);
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public void buildToolTip(List<Component> tooltip) {
tooltipBuilder.accept(tooltip);
}

@Override
public boolean canRespondToKey(int glfwKeyCode, int glfwFlags) {
return false;
}

@Override
public boolean onKeyPressed(int glfwKeyCode, int glfwFlags) {
return false;
Expand Down

0 comments on commit d6ba66c

Please sign in to comment.