From 9b3cf5cf9f214634150af712753717527d22d46a Mon Sep 17 00:00:00 2001 From: MrTJP Date: Sun, 10 Dec 2023 15:38:02 -0500 Subject: [PATCH] feat: add ic workbench auto-compile setting --- .../projectred_fabrication/lang/en_us.json | 3 + .../data/FabricationLanguageProvider.java | 3 + .../fabrication/editor/EditorDataUtils.java | 2 + .../editor/ICEditorStateMachine.java | 88 ++++++++++++++++++- .../gui/screen/ICWorkbenchCompileTab.java | 35 ++++++++ .../fabrication/init/FabricationUnlocal.java | 27 +++--- 6 files changed, 144 insertions(+), 14 deletions(-) diff --git a/fabrication/src/main/generated/assets/projectred_fabrication/lang/en_us.json b/fabrication/src/main/generated/assets/projectred_fabrication/lang/en_us.json index 39cba5c16..079167385 100644 --- a/fabrication/src/main/generated/assets/projectred_fabrication/lang/en_us.json +++ b/fabrication/src/main/generated/assets/projectred_fabrication/lang/en_us.json @@ -76,6 +76,9 @@ "projectred_fabrication.tooltip.size": "Size", "projectred_fabrication.tooltip.tile_count": "Tile count", "projectred_fabrication.tooltip.top": "Top", + "projectred_fabrication.ui.auto_compile": "Auto-compile", + "projectred_fabrication.ui.auto_compile_description": "Enable to auto-compile design on change", + "projectred_fabrication.ui.auto_compile_disabled": "Disabled. Design is too complex", "projectred_fabrication.ui.blueprint_dim": "Dimensions", "projectred_fabrication.ui.blueprint_info": "Blueprint Info", "projectred_fabrication.ui.blueprint_layers": "Layers", diff --git a/fabrication/src/main/java/mrtjp/projectred/fabrication/data/FabricationLanguageProvider.java b/fabrication/src/main/java/mrtjp/projectred/fabrication/data/FabricationLanguageProvider.java index 3cd2b138d..c7137f1e3 100644 --- a/fabrication/src/main/java/mrtjp/projectred/fabrication/data/FabricationLanguageProvider.java +++ b/fabrication/src/main/java/mrtjp/projectred/fabrication/data/FabricationLanguageProvider.java @@ -86,6 +86,9 @@ protected void addTranslations() { add(UL_COMPILE_DONE, "Done (%d/%d)"); add(UL_COMPILE_READY, "Ready to compile"); add(UL_COMPILE_FAILED, "Compile failed"); + add(UL_AUTO_COMPILE, "Auto-compile"); + add(UL_AUTO_COMPILE_DESCRIPTION, "Enable to auto-compile design on change"); + add(UL_AUTO_COMPILE_DISABLED, "Disabled. Design is too complex"); add(UL_SIM_RUNNING, "Simulation running"); add(UL_YIELD_CALCULATOR, "Yield Calculator"); diff --git a/fabrication/src/main/java/mrtjp/projectred/fabrication/editor/EditorDataUtils.java b/fabrication/src/main/java/mrtjp/projectred/fabrication/editor/EditorDataUtils.java index 15129168c..e129dcce2 100644 --- a/fabrication/src/main/java/mrtjp/projectred/fabrication/editor/EditorDataUtils.java +++ b/fabrication/src/main/java/mrtjp/projectred/fabrication/editor/EditorDataUtils.java @@ -25,6 +25,8 @@ public class EditorDataUtils { public static final String KEY_FLAT_MAP = "flat_map"; // String public static final String KEY_SIMULATION = "sim_cont"; // CompoundTag public static final String KEY_COMPILER_LOG = "compiler_log"; // CompoundTag + public static final String KEY_AUTO_COMPILE_ENABLE = "auto_compile_enable"; // boolean + public static final String KEY_AUTO_COMPILE_ALLOWED = "auto_compile_allowed"; // boolean // ICIssuesLog public static final String KEY_COMPLETED_STEPS = "completed_steps"; // int diff --git a/fabrication/src/main/java/mrtjp/projectred/fabrication/editor/ICEditorStateMachine.java b/fabrication/src/main/java/mrtjp/projectred/fabrication/editor/ICEditorStateMachine.java index e8e3fc155..0a7353f80 100644 --- a/fabrication/src/main/java/mrtjp/projectred/fabrication/editor/ICEditorStateMachine.java +++ b/fabrication/src/main/java/mrtjp/projectred/fabrication/editor/ICEditorStateMachine.java @@ -5,6 +5,7 @@ import mrtjp.fengine.TileCoord; import mrtjp.fengine.api.ICFlatMap; import mrtjp.fengine.api.ICStepThroughAssembler; +import mrtjp.projectred.core.Configurator; import mrtjp.projectred.fabrication.engine.BaseTile; import mrtjp.projectred.fabrication.engine.ICSimulationContainer; import mrtjp.projectred.fabrication.engine.IIOConnectionTile; @@ -31,8 +32,10 @@ public class ICEditorStateMachine { public static final int KEY_COMPILER_LOG_NODE_ADDED = 2; public static final int KEY_COMPILER_LOG_NODE_EXECUTED = 3; public static final int KEY_COMPILER_LOG_PROBLEM_ADDED = 4; + public static final int KEY_AUTO_COMPILE_STATE = 5; public static final int KEY_CLIENT_COMPILE_CLICKED = 10; + public static final int KEY_CLIENT_AUTO_COMPILE_TOGGLED = 11; private final ICWorkbenchEditor editor; @@ -59,7 +62,8 @@ public class ICEditorStateMachine { private String lastCompiledFlatMap = PRFabricationEngine.EMPTY_FLAT_MAP_SERIALIZED; - private boolean autoCompileOnChange = false; //TODO client-side toggle + private boolean autoCompileAvailable = true; + private boolean enableAutoCompile = true; public ICEditorStateMachine(ICWorkbenchEditor editor, @Nullable StateMachineCallback callback) { this.editor = editor; @@ -81,6 +85,9 @@ public void save(CompoundTag tag) { CompoundTag logTag = new CompoundTag(); compilerLog.save(logTag); tag.put(KEY_COMPILER_LOG, logTag); + + tag.putBoolean(KEY_AUTO_COMPILE_ENABLE, enableAutoCompile); + tag.putBoolean(KEY_AUTO_COMPILE_ALLOWED, autoCompileAvailable); } public void load(CompoundTag tag) { @@ -88,18 +95,22 @@ public void load(CompoundTag tag) { lastCompiledFlatMap = tag.getString(KEY_FLAT_MAP); simulationContainer.load(tag.getCompound(KEY_SIMULATION)); compilerLog.load(tag.getCompound(KEY_COMPILER_LOG)); + enableAutoCompile = tag.getBoolean(KEY_AUTO_COMPILE_ENABLE); + autoCompileAvailable = tag.getBoolean(KEY_AUTO_COMPILE_ALLOWED); } public void writeDesc(MCDataOutput out) { out.writeByte(currentState); simulationContainer.writeDesc(out); compilerLog.writeDesc(out); + writeAutoCompileState(out); } public void readDesc(MCDataInput in) { currentState = in.readUByte(); simulationContainer.readDesc(in); compilerLog.readDesc(in); + readAutoCompileState(in); } public void reset() { @@ -108,6 +119,7 @@ public void reset() { public void readStateMachineStream(MCDataInput in, int key) { switch (key) { + // Server -> Client packets case KEY_STATE_CHANGED: enterStateOnClient(in.readUByte()); break; @@ -117,9 +129,18 @@ public void readStateMachineStream(MCDataInput in, int key) { case KEY_COMPILER_LOG_PROBLEM_ADDED: compilerLog.readLogStream(in, key); break; + case KEY_AUTO_COMPILE_STATE: + readAutoCompileState(in); + break; + + // Client -> Server packets case KEY_CLIENT_COMPILE_CLICKED: onCompileTriggered(); break; + case KEY_CLIENT_AUTO_COMPILE_TOGGLED: + setAutoCompileAndSend(!enableAutoCompile); + break; + default: throw new IllegalArgumentException("Unknown compiler stream key: " + key); } @@ -147,23 +168,74 @@ public void onInputRegistersChanged(int rotation, Function changeF } //endregion + //region Server-side utilities + private void sendAutoCompileState() { + writeAutoCompileState(getStateMachineStream(KEY_AUTO_COMPILE_STATE)); + } + + private boolean checkAutoCompileAvailable() { + if (Configurator.autoCompileTileLimit == -1) return true; + if (Configurator.autoCompileTileLimit == 0) return false; + return editor.getTileMap().getTileCount() <= Configurator.autoCompileTileLimit; + } + + private void setAutoCompileAndSend(boolean enable) { + boolean oldAvailable = autoCompileAvailable; + boolean oldEnabled = enableAutoCompile; + + autoCompileAvailable = checkAutoCompileAvailable(); + enableAutoCompile = autoCompileAvailable && enable; + + if (oldAvailable != autoCompileAvailable || oldEnabled != enableAutoCompile) { + sendAutoCompileState(); + } + } + + private void writeAutoCompileState(MCDataOutput out) { + int acState = (autoCompileAvailable ? 0x1 : 0) | (enableAutoCompile ? 0x2 : 0); + out.writeByte(acState); + } + //endregion + //region Client-side utilities + private void readAutoCompileState(MCDataInput in) { + byte acState = in.readByte(); + autoCompileAvailable = (acState & 0x1) != 0; + enableAutoCompile = (acState & 0x2) != 0; + } + public void sendCompileButtonClicked() { // Notifies server to call onCompileTriggered getStateMachineStream(KEY_CLIENT_COMPILE_CLICKED); } + + public void sendAutoCompileToggled() { + getStateMachineStream(KEY_CLIENT_AUTO_COMPILE_TOGGLED); + } + public boolean canTriggerCompile() { return states[currentState].canTransitionTo(STATE_COMPILING); } + public boolean isCompiling() { return currentState == STATE_COMPILING; } + public boolean isSimulating() { return currentState == STATE_SIMULATING; } + public boolean didLastCompileFailed() { return getCompilerLog().getErrorCount() > 0; } + + public boolean isAutoCompileEnabled() { + return enableAutoCompile; + } + + public boolean isAutoCompileAvailable() { + return autoCompileAvailable; + } //endregion private void enterState(int id, boolean force) { @@ -258,7 +330,7 @@ private class StateAwaitingCompile implements State { @Override public void onTick(long time) { - if (autoCompileOnChange) { + if (enableAutoCompile) { enterStateAndSend(STATE_COMPILING); } } @@ -272,6 +344,18 @@ public void onCompileTriggered() { public boolean canTransitionTo(int id) { return id == STATE_COMPILING; } + + @Override + public void onStateEntered(int previousStateId) { + // Set to same state to force re-check of availability + setAutoCompileAndSend(enableAutoCompile); + } + + @Override + public void onTileMapChanged() { + // Set to same state to force re-check of availability + setAutoCompileAndSend(enableAutoCompile); + } } private class StateCompiling implements State { diff --git a/fabrication/src/main/java/mrtjp/projectred/fabrication/gui/screen/ICWorkbenchCompileTab.java b/fabrication/src/main/java/mrtjp/projectred/fabrication/gui/screen/ICWorkbenchCompileTab.java index 137f3a7ea..63b6697ea 100644 --- a/fabrication/src/main/java/mrtjp/projectred/fabrication/gui/screen/ICWorkbenchCompileTab.java +++ b/fabrication/src/main/java/mrtjp/projectred/fabrication/gui/screen/ICWorkbenchCompileTab.java @@ -13,6 +13,7 @@ import mrtjp.projectred.fabrication.gui.*; import mrtjp.projectred.lib.Point; import mrtjp.projectred.redui.AbstractButtonNode; +import mrtjp.projectred.redui.AbstractCheckboxNode; import mrtjp.projectred.redui.AbstractGuiNode; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiComponent; @@ -58,6 +59,10 @@ private void initSubNodes() { compileButton.setSize(18, 18); addChild(compileButton); + AutoCompileCheckbox autoCompileCheckbox = new AutoCompileCheckbox(); + autoCompileCheckbox.setPosition(230, 16); + addChild(autoCompileCheckbox); + ICRenderNode icRenderNode = new ICRenderNode(editor, this); icRenderNode.setPosition(7, 18); icRenderNode.setSize(197, 197); @@ -316,6 +321,36 @@ protected void buildTooltip(List tooltip) { } } + private class AutoCompileCheckbox extends AbstractCheckboxNode { + + @Override + protected boolean isDisabled() { + return !editor.getStateMachine().isAutoCompileAvailable(); + } + + @Override + protected boolean isChecked() { + return editor.getStateMachine().isAutoCompileEnabled(); + } + + @Override + protected void onClicked() { + editor.getStateMachine().sendAutoCompileToggled(); + } + + @Override + protected void buildTooltip(List tooltip) { + tooltip.add(new TranslatableComponent(UL_AUTO_COMPILE)); + tooltip.add(new TranslatableComponent(UL_AUTO_COMPILE_DESCRIPTION).withStyle(UNIFORM_GRAY)); + if (isDisabled()) { + tooltip.add(new TextComponent(" ") + .withStyle(UNIFORM_RED) + .append(new TranslatableComponent(UL_AUTO_COMPILE_DISABLED) + .withStyle(UNIFORM_GRAY))); + } + } + } + private class ProblemsTab extends SimpleUVTab { public ProblemsTab(AbstractGuiNode tabBodyNode, String unlocalTabName, TabButtonNode.TabSide side, int u, int v, ResourceLocation texture) { diff --git a/fabrication/src/main/java/mrtjp/projectred/fabrication/init/FabricationUnlocal.java b/fabrication/src/main/java/mrtjp/projectred/fabrication/init/FabricationUnlocal.java index ff7cafc38..4ea30c5ea 100644 --- a/fabrication/src/main/java/mrtjp/projectred/fabrication/init/FabricationUnlocal.java +++ b/fabrication/src/main/java/mrtjp/projectred/fabrication/init/FabricationUnlocal.java @@ -47,18 +47,21 @@ public class FabricationUnlocal { public static final String UL_NO_WARNINGS = PREFIX + "problems.no_warnings"; // General workbench UI - public static final String UL_PLACE_BLUEPRINT = PREFIX + "ui.place_blueprint"; - public static final String UL_BLUEPRINT_INFO = PREFIX + "ui.blueprint_info"; - public static final String UL_BLUEPRINT_NAME = PREFIX + "ui.blueprint_name"; - public static final String UL_BLUEPRINT_OWNER = PREFIX + "ui.blueprint_owner"; - public static final String UL_BLUEPRINT_DIM = PREFIX + "ui.blueprint_dim"; - public static final String UL_BLUEPRINT_LAYERS = PREFIX + "ui.blueprint_layers"; - public static final String UL_COMPILE = PREFIX + "ui.compile"; - public static final String UL_COMPILE_PROGRESS = PREFIX + "ui.compile_progress"; - public static final String UL_COMPILE_DONE = PREFIX + "ui.compile_done"; - public static final String UL_COMPILE_READY = PREFIX + "ui.compile_ready"; - public static final String UL_COMPILE_FAILED = PREFIX + "ui.compile_failed"; - public static final String UL_SIM_RUNNING = PREFIX + "ui.sim_running"; + public static final String UL_PLACE_BLUEPRINT = PREFIX + "ui.place_blueprint"; + public static final String UL_BLUEPRINT_INFO = PREFIX + "ui.blueprint_info"; + public static final String UL_BLUEPRINT_NAME = PREFIX + "ui.blueprint_name"; + public static final String UL_BLUEPRINT_OWNER = PREFIX + "ui.blueprint_owner"; + public static final String UL_BLUEPRINT_DIM = PREFIX + "ui.blueprint_dim"; + public static final String UL_BLUEPRINT_LAYERS = PREFIX + "ui.blueprint_layers"; + public static final String UL_COMPILE = PREFIX + "ui.compile"; + public static final String UL_COMPILE_PROGRESS = PREFIX + "ui.compile_progress"; + public static final String UL_COMPILE_DONE = PREFIX + "ui.compile_done"; + public static final String UL_COMPILE_READY = PREFIX + "ui.compile_ready"; + public static final String UL_COMPILE_FAILED = PREFIX + "ui.compile_failed"; + public static final String UL_AUTO_COMPILE = PREFIX + "ui.auto_compile"; + public static final String UL_AUTO_COMPILE_DESCRIPTION = PREFIX + "ui.auto_compile_description"; + public static final String UL_AUTO_COMPILE_DISABLED = PREFIX + "ui.auto_compile_disabled"; + public static final String UL_SIM_RUNNING = PREFIX + "ui.sim_running"; public static final String UL_YIELD_CALCULATOR = PREFIX + "ui.yield_calculator"; public static final String UL_LITHOGRAPHY_PIPELINE = PREFIX + "ui.lithography_pipeline";